diff --git a/.circleci/config.yml b/.circleci/config.yml index f018b76bd..cd6efe2a3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,9 @@ workflows: - prep-build-test: requires: - prep-deps + - prep-build-test-metrics: + requires: + - prep-deps - prep-build-storybook: requires: - prep-deps @@ -34,6 +37,12 @@ workflows: - test-e2e-firefox: requires: - prep-build-test + - test-e2e-chrome-metrics: + requires: + - prep-build-test-metrics + - test-e2e-firefox-metrics: + requires: + - prep-build-test-metrics - test-unit: requires: - prep-deps @@ -58,6 +67,8 @@ workflows: - test-mozilla-lint - test-e2e-chrome - test-e2e-firefox + - test-e2e-chrome-metrics + - test-e2e-firefox-metrics - benchmark: requires: - prep-build-test @@ -122,8 +133,9 @@ jobs: prep-build: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + resource_class: medium+ environment: - NODE_OPTIONS: --max_old_space_size=1024 + NODE_OPTIONS: --max_old_space_size=2048 steps: - checkout - attach_workspace: @@ -143,8 +155,9 @@ jobs: prep-build-test: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + resource_class: medium+ environment: - NODE_OPTIONS: --max_old_space_size=1024 + NODE_OPTIONS: --max_old_space_size=2048 steps: - checkout - attach_workspace: @@ -160,6 +173,27 @@ jobs: paths: - dist-test + prep-build-test-metrics: + docker: + - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + resource_class: medium+ + environment: + NODE_OPTIONS: --max_old_space_size=2048 + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Build extension for testing metrics + command: yarn build:test:metrics + - run: + name: Move test build to 'dist-test-metrics' to avoid conflict with production build + command: mv ./dist ./dist-test-metrics + - persist_to_workspace: + root: . + paths: + - dist-test-metrics + prep-build-storybook: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 @@ -243,6 +277,28 @@ jobs: path: test-artifacts destination: test-artifacts + test-e2e-chrome-metrics: + docker: + - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Move test build to dist + command: mv ./dist-test-metrics ./dist + - run: + name: test:e2e:chrome:metrics + command: | + if .circleci/scripts/test-run-e2e + then + yarn test:e2e:chrome:metrics + fi + no_output_timeout: 20m + - store_artifacts: + path: test-artifacts + destination: test-artifacts + test-e2e-firefox: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 @@ -268,6 +324,31 @@ jobs: path: test-artifacts destination: test-artifacts + test-e2e-firefox-metrics: + docker: + - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + steps: + - checkout + - run: + name: Install Firefox + command: ./.circleci/scripts/firefox-install + - attach_workspace: + at: . + - run: + name: Move test build to dist + command: mv ./dist-test-metrics ./dist + - run: + name: test:e2e:firefox:metrics + command: | + if .circleci/scripts/test-run-e2e + then + yarn test:e2e:firefox:metrics + fi + no_output_timeout: 20m + - store_artifacts: + path: test-artifacts + destination: test-artifacts + benchmark: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 diff --git a/.eslintrc.js b/.eslintrc.js index 35541a9ba..184f6ce89 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -197,6 +197,7 @@ module.exports = { 'stylelint.config.js', 'development/**/*.js', 'test/e2e/**/*.js', + 'test/lib/wait-until-called.js', 'test/env.js', 'test/setup.js', ], diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d35290252..3c2610e72 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,5 +9,4 @@ updates: interval: "daily" allow: - dependency-name: "@metamask/*" - - dependency-name: "eth-contract-metadata" versioning-strategy: "lockfile-only" diff --git a/.storybook/main.js b/.storybook/main.js index 74acf6fb8..2411f2066 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,3 +1,7 @@ +const path = require('path') + +const CopyWebpackPlugin = require('copy-webpack-plugin') + module.exports = { stories: ['../ui/app/**/*.stories.js'], addons: [ @@ -5,4 +9,36 @@ module.exports = { '@storybook/addon-actions', '@storybook/addon-backgrounds' ], + webpackFinal: async (config) => { + config.module.strictExportPresence = true + config.module.rules.push({ + test: /\.scss$/, + loaders: [ + 'style-loader', + { + loader: 'css-loader', + options: { + import: false, + url: false, + }, + }, + 'resolve-url-loader', + { + loader: 'sass-loader', + options: { + sourceMap: true, + }, + }, + ], + }) + config.plugins.push(new CopyWebpackPlugin({ + patterns: [ + { + from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'), + to: path.join('fonts', 'fontawesome'), + }, + ], + })) + return config + }, } diff --git a/.storybook/preview.js b/.storybook/preview.js index b28733bad..c3115997c 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,6 +1,6 @@ import React from 'react' import { addDecorator, addParameters } from '@storybook/react' -import { withKnobs } from '@storybook/addon-knobs/react' +import { withKnobs } from '@storybook/addon-knobs' import { I18nProvider, LegacyI18nProvider } from '../ui/app/contexts/i18n' import { Provider } from 'react-redux' import configureStore from '../ui/app/store/store' @@ -8,10 +8,13 @@ import '../ui/app/css/index.scss' import en from '../app/_locales/en/messages' addParameters({ - backgrounds: [ - { name: 'light', value: '#FFFFFF'}, - { name: 'dark', value: '#333333' }, - ], + backgrounds: { + default: 'light', + values: [ + { name: 'light', value: '#FFFFFF'}, + { name: 'dark', value: '#333333' }, + ], + } }) const styles = { diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js deleted file mode 100644 index be7dfecea..000000000 --- a/.storybook/webpack.config.js +++ /dev/null @@ -1,41 +0,0 @@ -const path = require('path') - -const CopyWebpackPlugin = require('copy-webpack-plugin') - -module.exports = { - module: { - strictExportPresence: true, - rules: [ - { - test: /\.scss$/, - loaders: [ - 'style-loader', - { - loader: 'css-loader', - options: { - import: false, - url: false, - }, - }, - 'resolve-url-loader', - { - loader: 'sass-loader', - options: { - sourceMap: true, - }, - }, - ], - }, - ], - }, - plugins: [ - new CopyWebpackPlugin({ - patterns: [ - { - from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'), - to: path.join('fonts', 'fontawesome'), - }, - ], - }), - ], -} diff --git a/CHANGELOG.md b/CHANGELOG.md index d4e86a996..a716a51ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ ## Current Develop Branch +## 8.1.6 Wed Dec 02 2020 +- [#9916](https://github.com/MetaMask/metamask-extension/pull/9916): Fix QR code scans interpretting payment requests as token addresses +- [#9847](https://github.com/MetaMask/metamask-extension/pull/9847): Add alt text for images in list items +- [#9960](https://github.com/MetaMask/metamask-extension/pull/9960): Ensure watchAsset returns errors for invalid token symbols +- [#9968](https://github.com/MetaMask/metamask-extension/pull/9968): Adds tokens from v1.19.0 of metamask/contract-metadata to add token lists +- [#9970](https://github.com/MetaMask/metamask-extension/pull/9970): Etherscan links support Goerli network +- [#9899](https://github.com/MetaMask/metamask-extension/pull/9899): Show price impact warnings on swaps quote screen +- [#9867](https://github.com/MetaMask/metamask-extension/pull/9867): Replace use of ethgasstation +- [#9984](https://github.com/MetaMask/metamask-extension/pull/9984): Show correct gas estimates when users don't have sufficient balance for contract transaction +- [#9993](https://github.com/MetaMask/metamask-extension/pull/9993): Add 48x48 MetaMask icon for use by browsers + ## 8.1.5 Wed Nov 18 2020 - [#9871](https://github.com/MetaMask/metamask-extension/pull/9871): Show send text upon hover in main asset list - [#9855](https://github.com/MetaMask/metamask-extension/pull/9855): Make edit icon and account name in account details modal focusable diff --git a/app/_locales/am/messages.json b/app/_locales/am/messages.json index 92ada3d3b..227bbcb84 100644 --- a/app/_locales/am/messages.json +++ b/app/_locales/am/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "የሰንሰለት መታወቂያ" }, - "chartOnlyAvailableEth": { - "message": "ቻርት የሚገኘው በ Ethereum አውታረ መረቦች ላይ ብቻ ነው።" - }, "chromeRequiredForHardwareWallets": { "message": "ከሃርድዌርዎ ቋት ጋር ለመገናኘት MetaMask በ Google Chrome ላይ መጠቀም አለብዎት።" }, @@ -398,9 +395,6 @@ "fast": { "message": "ፈጣን" }, - "faster": { - "message": "በፍጥነት" - }, "fiat": { "message": "ፊያት", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "ማስፈንጠሪያዎች" }, - "liveGasPricePredictions": { - "message": "ቀጥታ የነዳጅ ዋጋ ትንበያዎች" - }, "loadMore": { "message": "ተጨማሪ ጫን" }, @@ -1015,9 +1006,6 @@ "slow": { "message": "ቀስ" }, - "slower": { - "message": "ዘገምተኛ" - }, "somethingWentWrong": { "message": "ኤጭ! የሆነ ችግር ተፈጥሯል።" }, @@ -1162,9 +1150,6 @@ "transactionSubmitted": { "message": "ግብይቱ የቀረበው በነዳጅ ዋጋ $1በ$2ነው።" }, - "transactionTime": { - "message": "የግብይት ጊዜ" - }, "transactionUpdated": { "message": "ግብይት የዘመነው በ $2ነው።" }, diff --git a/app/_locales/ar/messages.json b/app/_locales/ar/messages.json index 070e0ab64..39a3df7c0 100644 --- a/app/_locales/ar/messages.json +++ b/app/_locales/ar/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "معرّف السلسلة" }, - "chartOnlyAvailableEth": { - "message": "الرسم البياني متاح فقط على شبكات إيثيريوم." - }, "chromeRequiredForHardwareWallets": { "message": "تحتاج إلى استخدام MetaMask على Google Chrome للاتصال بمحفظة الأجهزة الخاصة بك." }, @@ -398,9 +395,6 @@ "fast": { "message": "سريع" }, - "faster": { - "message": "أسرع" - }, "fileImportFail": { "message": "استيراد الملف لا ينجح؟ انقر هنا!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "الروابط" }, - "liveGasPricePredictions": { - "message": "توقعات أسعار الجاس الحية" - }, "loadMore": { "message": "تحميل المزيد" }, @@ -1011,9 +1002,6 @@ "slow": { "message": "بطيء" }, - "slower": { - "message": "أبطأ" - }, "somethingWentWrong": { "message": "عذراً! حدث خطأ ما." }, @@ -1158,9 +1146,6 @@ "transactionSubmitted": { "message": "تم تقديم المعاملة برسوم $1 من عملة جاس في $2." }, - "transactionTime": { - "message": "وقت المعاملة" - }, "transactionUpdated": { "message": "تم تحديث المعاملة في $2." }, diff --git a/app/_locales/bg/messages.json b/app/_locales/bg/messages.json index 30c39d8cf..ec998b1ce 100644 --- a/app/_locales/bg/messages.json +++ b/app/_locales/bg/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Идентификатор на веригата" }, - "chartOnlyAvailableEth": { - "message": "Диаграмата е достъпна само в мрежи на Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "За да се свържете с хардуерния си портфейл, трябва да използвате MetaMask в Google Chrome." }, @@ -398,9 +395,6 @@ "fast": { "message": "Бързо" }, - "faster": { - "message": "По-бързо" - }, "fileImportFail": { "message": "Импортирането на файл не работи? Натиснете тук!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Връзки" }, - "liveGasPricePredictions": { - "message": "Прогнози на живо за цената на газа" - }, "loadMore": { "message": "Зареди повече" }, @@ -1014,9 +1005,6 @@ "slow": { "message": "Бавно" }, - "slower": { - "message": "По-бавно" - }, "somethingWentWrong": { "message": "Упс! Нещо се обърка." }, @@ -1161,9 +1149,6 @@ "transactionSubmitted": { "message": "Транзакция, изпратена с такса за газ от $1 при $2." }, - "transactionTime": { - "message": "Време на транзакция" - }, "transactionUpdated": { "message": "Транзакцията е актуализирана на $2." }, diff --git a/app/_locales/bn/messages.json b/app/_locales/bn/messages.json index 3b07cc64f..2840c8470 100644 --- a/app/_locales/bn/messages.json +++ b/app/_locales/bn/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "চেন আইডি" }, - "chartOnlyAvailableEth": { - "message": "শুধুমাত্র Ethereum নেটওয়ার্কগুলিতে চার্ট উপলভ্য। " - }, "chromeRequiredForHardwareWallets": { "message": "আপনার হার্ডওয়্যার ওয়ালেটের সাথে সংযোগ করতে আপনাকে Google Chrome এ MetaMask ব্যবহার করতে হবে। " }, @@ -398,9 +395,6 @@ "fast": { "message": "দ্রুত" }, - "faster": { - "message": "দ্রুততর" - }, "fiat": { "message": "ফিয়াট", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "লিঙ্কসমূহ" }, - "liveGasPricePredictions": { - "message": "সরাসরি গ্যাসের মূল্যের অনুমান" - }, "loadMore": { "message": "আরও লোড করুন" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "মন্থর" }, - "slower": { - "message": "ধীর গতির" - }, "somethingWentWrong": { "message": "ওহো! কিছু সমস্যা হয়েছে।" }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "$2 এ $1 এর গ্যাস ফী সহ লেনদেন জমা করা হয়েছে।" }, - "transactionTime": { - "message": "লেনদেনের সময়" - }, "transactionUpdated": { "message": "লেনদেন $2 এ আপডেট করা হয়েছে।" }, diff --git a/app/_locales/ca/messages.json b/app/_locales/ca/messages.json index 29b2bb7e3..571da2f5f 100644 --- a/app/_locales/ca/messages.json +++ b/app/_locales/ca/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "Cadena ID" }, - "chartOnlyAvailableEth": { - "message": "Mostra només els disponibles a les xarxes Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Necessites fer servir MetaMask amb Google Chrome per a connectar-te al teu Moneder Hardware." }, @@ -395,9 +392,6 @@ "fast": { "message": "Ràpid" }, - "faster": { - "message": "Més ràpid" - }, "fileImportFail": { "message": "La importació no funciona? Fes clic aquí!", "description": "Helps user import their account from a JSON file" @@ -566,9 +560,6 @@ "links": { "message": "Enllaços" }, - "liveGasPricePredictions": { - "message": "Prediccions del preu del gas en directe" - }, "loadMore": { "message": "Carregar Més" }, @@ -996,9 +987,6 @@ "slow": { "message": "Lent" }, - "slower": { - "message": "Més lent" - }, "somethingWentWrong": { "message": "Ui! Alguna cosa ha fallat." }, @@ -1134,9 +1122,6 @@ "transactionSubmitted": { "message": "Transacció enviada amb un preu del gas de $1 a $2." }, - "transactionTime": { - "message": "Temps de transacció" - }, "transactionUpdated": { "message": "Transacció actualitzada a $2." }, diff --git a/app/_locales/da/messages.json b/app/_locales/da/messages.json index cb6109a44..f4765f987 100644 --- a/app/_locales/da/messages.json +++ b/app/_locales/da/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Kæde-ID" }, - "chartOnlyAvailableEth": { - "message": "Skema kun tilgængeligt på Ethereum-netværk." - }, "chromeRequiredForHardwareWallets": { "message": "Du skal bruge MetaMask i Google Chrome for at forbinde med din Hardware Wallet." }, @@ -398,9 +395,6 @@ "fast": { "message": "Hurtig" }, - "faster": { - "message": "Hurtigere" - }, "fileImportFail": { "message": "Virker filimportering ikke? Klik her!", "description": "Helps user import their account from a JSON file" @@ -569,9 +563,6 @@ "likeToAddTokens": { "message": "Ønsker du at tilføje disse tokens?" }, - "liveGasPricePredictions": { - "message": "Live forudsigelser af brændstofpriser" - }, "loadMore": { "message": "Indlæs Mere" }, @@ -996,9 +987,6 @@ "slow": { "message": "Langsom" }, - "slower": { - "message": "Langsommere" - }, "somethingWentWrong": { "message": "Ups! Noget gik galt." }, @@ -1134,9 +1122,6 @@ "transactionSubmitted": { "message": "Transaktion indsendt med brændstofgebyr på $1 til $2." }, - "transactionTime": { - "message": "Transaktionstid" - }, "transactionUpdated": { "message": "Transaktion opdateret til $2." }, diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index c656bd935..bfd714822 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -158,9 +158,6 @@ "cancelled": { "message": "Abgebrochen" }, - "chartOnlyAvailableEth": { - "message": "Die Grafik ist nur in Ethereum-Netzwerken verfügbar." - }, "chromeRequiredForHardwareWallets": { "message": "Sie müssen MetaMask unter Google Chrome nutzen, um sich mit Ihrem Hardware-Wallet zu verbinden." }, @@ -386,9 +383,6 @@ "fast": { "message": "Schnell" }, - "faster": { - "message": "Schneller" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -564,9 +558,6 @@ "likeToAddTokens": { "message": "Möchtest du diese Token hinzufügen?" }, - "liveGasPricePredictions": { - "message": "Live-Gaspreisprognosen" - }, "loadMore": { "message": "Mehr laden" }, @@ -987,9 +978,6 @@ "slow": { "message": "Langsam" }, - "slower": { - "message": "Langsamer" - }, "somethingWentWrong": { "message": "Hoppla! Da hat etwas nicht geklappt." }, @@ -1128,9 +1116,6 @@ "transactionSubmitted": { "message": "Transaktion mit einer Gasgebühr von $1 bei $2 übermittelt." }, - "transactionTime": { - "message": "Transaktionszeit" - }, "transactionUpdated": { "message": "Transaktion für $2 aktualisiert." }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 45d38521d..eab1d1077 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "Αναγνωριστικό Αλυσίδας" }, - "chartOnlyAvailableEth": { - "message": "Το διάγραμμα είναι διαθέσιμο μόνο σε δίκτυα Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Θα πρέπει να χρησιμοποιήσετε το MetaMask στο Google Chrome για να συνδεθείτε στο Πορτοφόλι Υλικού." }, @@ -395,9 +392,6 @@ "fast": { "message": "Γρήγορα" }, - "faster": { - "message": "Πιο γρήγορα" - }, "fiat": { "message": "Εντολή", "description": "Exchange type" @@ -576,9 +570,6 @@ "links": { "message": "Σύνδεσμοι" }, - "liveGasPricePredictions": { - "message": "Ζωντανές Προβλέψεις Τιμής Καυσίμου" - }, "loadMore": { "message": "Φόρτωση Περισσότερων" }, @@ -1015,9 +1006,6 @@ "slow": { "message": "Αργά" }, - "slower": { - "message": "Πιο αργά" - }, "somethingWentWrong": { "message": "Ουπς! Κάτι πήγε στραβά." }, @@ -1159,9 +1147,6 @@ "transactionSubmitted": { "message": "Η συναλλαγή στάλθηκε με τέλος gas του $1 σε $2." }, - "transactionTime": { - "message": "Χρόνος Συναλλαγής" - }, "transactionUpdated": { "message": "Η συναλλαγή ενημερώθηκε σε $2." }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 8a00369f4..16e21905a 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -245,9 +245,6 @@ "chainId": { "message": "Chain ID" }, - "chartOnlyAvailableEth": { - "message": "Chart only available on Ethereum networks." - }, "chromeRequiredForHardwareWallets": { "message": "You need to use MetaMask on Google Chrome in order to connect to your Hardware Wallet." }, @@ -660,9 +657,6 @@ "fast": { "message": "Fast" }, - "faster": { - "message": "Faster" - }, "fastest": { "message": "Fastest" }, @@ -914,9 +908,6 @@ "links": { "message": "Links" }, - "liveGasPricePredictions": { - "message": "Live Gas Price Predictions" - }, "loadMore": { "message": "Load More" }, @@ -1491,9 +1482,6 @@ "showSeedPhrase": { "message": "Show seed phrase" }, - "showTransactionTimeDescription": { - "message": "Select this to display pending transaction time estimates in the activity tab while on the Ethereum Mainnet. Note: estimates are approximations based on network conditions." - }, "sigRequest": { "message": "Signature Request" }, @@ -1515,9 +1503,6 @@ "slow": { "message": "Slow" }, - "slower": { - "message": "Slower" - }, "somethingWentWrong": { "message": "Oops! Something went wrong." }, @@ -1654,16 +1639,6 @@ "swapEstimatedNetworkFeesInfo": { "message": "This is an estimate of the network fee that will be used to complete your swap. The actual amount may change according to network conditions." }, - "swapEstimatedTime": { - "message": "Estimated time:" - }, - "swapEstimatedTimeCalculating": { - "message": "Calculating..." - }, - "swapEstimatedTimeFull": { - "message": "$1 $2", - "description": "This message shows bolded swapEstimatedTime message, which is substited for $1, followed by either the estimated remaining transaction time in mm:ss, or the swapEstimatedTimeCalculating message, which are substituted for $2." - }, "swapFailedErrorDescription": { "message": "Your funds are safe and still available in your wallet." }, @@ -1741,6 +1716,20 @@ "message": "Your $1 will be added to your account once this transaction has processed.", "description": "This message communicates the token that is being transferred. It is shown on the awaiting swap screen. The $1 will be a token symbol." }, + "swapPriceDifference": { + "message": "You are about to swap $1 $2 (~$3) for $4 $5 (~$6).", + "description": "This message represents the price slippage for the swap. $1 and $4 are a number (ex: 2.89), $2 and $5 are symbols (ex: ETH), and $3 and $6 are fiat currency amounts." + }, + "swapPriceDifferenceTitle": { + "message": "Price difference of ~$1%", + "description": "$1 is a number (ex: 1.23) that represents the price difference." + }, + "swapPriceDifferenceTooltip": { + "message": "The difference in market prices can be affected by fees taken by intermediaries, size of market, size of trade, or market inefficiencies." + }, + "swapPriceDifferenceUnavailable": { + "message": "Market price is unavailable. Make sure you feel comfortable with the returned amount before proceeding." + }, "swapProcessing": { "message": "Processing" }, @@ -1857,9 +1846,6 @@ "swapsAdvancedOptions": { "message": "Advanced Options" }, - "swapsAlmostDone": { - "message": "Almost done..." - }, "swapsBestQuote": { "message": "Best quote" }, @@ -1998,9 +1984,6 @@ "transactionSubmitted": { "message": "Transaction submitted with gas fee of $1 at $2." }, - "transactionTime": { - "message": "Transaction Time" - }, "transactionUpdated": { "message": "Transaction updated at $2." }, diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 542a8724f..55f77bb00 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -139,9 +139,6 @@ "chainId": { "message": "ID Cadena" }, - "chartOnlyAvailableEth": { - "message": "Tabla solo disponible en redes Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Hay que usar MetaMask en Google Chrome para poder conectarse con tu Monedero Físico." }, @@ -322,9 +319,6 @@ "fast": { "message": "Rápido" }, - "faster": { - "message": "Más Rápido" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -470,9 +464,6 @@ "links": { "message": "Enlaces" }, - "liveGasPricePredictions": { - "message": "Previsiones en vivo del precio de Gas" - }, "loadMore": { "message": "Cargar Más" }, @@ -801,9 +792,6 @@ "slow": { "message": "Lento" }, - "slower": { - "message": "Más lento" - }, "somethingWentWrong": { "message": "¡Ups! Algo funcionó mal." }, @@ -912,9 +900,6 @@ "transactionSubmitted": { "message": "Se propuso la transacción con una comisión de gas de $1, en $2." }, - "transactionTime": { - "message": "Tiempo de Transacción" - }, "transactionUpdated": { "message": "Se actualizó la transacción en $2." }, diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 46b86e032..1073b7e31 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "ID de cadena" }, - "chartOnlyAvailableEth": { - "message": "Chart está disponible únicamente en las redes de Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Debes utilizar MetaMask en Google Chrome para poder conectarte a tu billetera de hardware." }, @@ -395,9 +392,6 @@ "fast": { "message": "Rápido" }, - "faster": { - "message": "Más rápido" - }, "fiat": { "message": "Dinero fiduciario", "description": "Exchange type" @@ -570,9 +564,6 @@ "links": { "message": "Enlaces" }, - "liveGasPricePredictions": { - "message": "Predicciones del precio del gas en vivo" - }, "loadMore": { "message": "Cargar más" }, @@ -1003,9 +994,6 @@ "slow": { "message": "Lento" }, - "slower": { - "message": "Más lento" - }, "somethingWentWrong": { "message": "¡Vaya! Se produjo un error." }, @@ -1144,9 +1132,6 @@ "transactionSubmitted": { "message": "Se envió la transacción con una tasa de gas de $1 en $2." }, - "transactionTime": { - "message": "Tiempo de transacción" - }, "transactionUpdated": { "message": "La transacción se actualizó en $2." }, diff --git a/app/_locales/et/messages.json b/app/_locales/et/messages.json index 93ae71db0..681daaac3 100644 --- a/app/_locales/et/messages.json +++ b/app/_locales/et/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Ahela ID" }, - "chartOnlyAvailableEth": { - "message": "Tabel on saadaval vaid Ethereumi võrkudes." - }, "chromeRequiredForHardwareWallets": { "message": "Riistvararahakoti ühendamiseks peate kasutama MetaMaski Google Chrome'is." }, @@ -398,9 +395,6 @@ "fast": { "message": "Kiire" }, - "faster": { - "message": "Kiiremini" - }, "fileImportFail": { "message": "Faili importimine ei toimi? Klõpsake siia!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Lingid" }, - "liveGasPricePredictions": { - "message": "Gaasihinna prognoosid reaalajas" - }, "loadMore": { "message": "Laadi rohkem" }, @@ -1008,9 +999,6 @@ "slow": { "message": "Aeglane" }, - "slower": { - "message": "Aeglasem" - }, "somethingWentWrong": { "message": "Oih! Midagi läks valesti." }, @@ -1155,9 +1143,6 @@ "transactionSubmitted": { "message": "Tehing edastatud gaasihinnaga $1 asukohas $2." }, - "transactionTime": { - "message": "Tehingu aeg" - }, "transactionUpdated": { "message": "Tehing on uuendatud $2." }, diff --git a/app/_locales/fa/messages.json b/app/_locales/fa/messages.json index 5713eed42..15cb8b997 100644 --- a/app/_locales/fa/messages.json +++ b/app/_locales/fa/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "آی دی زنجیره" }, - "chartOnlyAvailableEth": { - "message": "تنها قابل دسترس را در شبکه های ایتریوم جدول بندی نمایید" - }, "chromeRequiredForHardwareWallets": { "message": "برای وصل شدن به کیف سخت افزار شما باید MetaMask را در گوگل کروم استفاده نمایید." }, @@ -398,9 +395,6 @@ "fast": { "message": "سریع" }, - "faster": { - "message": "سریع تر" - }, "fiat": { "message": "حکم قانونی", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "لینک ها" }, - "liveGasPricePredictions": { - "message": "پیش بینی های قیمت گاز" - }, "loadMore": { "message": "بارگیری بیشتر" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "آهسته" }, - "slower": { - "message": "آهسته تر" - }, "somethingWentWrong": { "message": "اوه! مشکلی پیش آمده." }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "معامله با فیس گاز 1$1 در 2$2 ارائه شد." }, - "transactionTime": { - "message": "زمان معامله" - }, "transactionUpdated": { "message": "معامله به 1$2 بروزرسانی شد." }, diff --git a/app/_locales/fi/messages.json b/app/_locales/fi/messages.json index 76eab95d3..1aa3be909 100644 --- a/app/_locales/fi/messages.json +++ b/app/_locales/fi/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Ketjun tunnus" }, - "chartOnlyAvailableEth": { - "message": "Kaavio saatavilla vain Ethereum-verkoissa." - }, "chromeRequiredForHardwareWallets": { "message": "Sinun tarvitsee käyttää MetaMaskia Google Chromessa voidaksesi yhdistää laitteistokukkaroosi." }, @@ -398,9 +395,6 @@ "fast": { "message": "Nopea" }, - "faster": { - "message": "Nopeammin" - }, "fiat": { "message": "Kiinteä", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "Linkit" }, - "liveGasPricePredictions": { - "message": "Polttoaineen hintojen live-ennusteet" - }, "loadMore": { "message": "Lataa lisää" }, @@ -1015,9 +1006,6 @@ "slow": { "message": "Hidas" }, - "slower": { - "message": "Hitaammin" - }, "somethingWentWrong": { "message": "Hupsis! Jotakin meni pieleen." }, @@ -1162,9 +1150,6 @@ "transactionSubmitted": { "message": "Tapahtuma toimitettu $1 bensataksalla kohdassa $2." }, - "transactionTime": { - "message": "Tapahtuman aika" - }, "transactionUpdated": { "message": "Tapahtuma päivitetty – $2." }, diff --git a/app/_locales/fil/messages.json b/app/_locales/fil/messages.json index 150838e9c..fa048b96d 100644 --- a/app/_locales/fil/messages.json +++ b/app/_locales/fil/messages.json @@ -146,9 +146,6 @@ "cancelled": { "message": "Nakansela" }, - "chartOnlyAvailableEth": { - "message": "Available lang ang chart sa mga Ethereum network." - }, "chromeRequiredForHardwareWallets": { "message": "Kailangan mong gamitin ang MetaMask sa Google Chrome upang makakonekta sa iyong Hardware Wallet." }, @@ -371,9 +368,6 @@ "fast": { "message": "Mabilis" }, - "faster": { - "message": "Mas Mabilis" - }, "fileImportFail": { "message": "Hindi gumagana ang pag-import ng file? Mag-click dito!", "description": "Helps user import their account from a JSON file" @@ -529,9 +523,6 @@ "links": { "message": "Mga Link" }, - "liveGasPricePredictions": { - "message": "Mga Live na Prediksyon sa Presyo ng Gas" - }, "loadMore": { "message": "Mag-load Pa" }, @@ -924,9 +915,6 @@ "slow": { "message": "Mabagal" }, - "slower": { - "message": "Mas Mabagal" - }, "somethingWentWrong": { "message": "Oops! Nagkaroon ng problema." }, @@ -1062,9 +1050,6 @@ "transactionSubmitted": { "message": "Nasumite ang transaksyon nang may gas fee na $1 sa $2." }, - "transactionTime": { - "message": "Oras ng Transaksyon" - }, "transactionUpdated": { "message": "Na-update ang transaksyon sa $2." }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index 69f7ffb2c..f05faf62c 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -158,9 +158,6 @@ "chainId": { "message": "ID de chaîne" }, - "chartOnlyAvailableEth": { - "message": "Tableau disponible uniquement sur les réseaux Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Pour connecter votre portefeuille hardware, vous devez utiliser MetaMask pour Google Chrome." }, @@ -389,9 +386,6 @@ "fast": { "message": "Rapide" }, - "faster": { - "message": "Plus rapide" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -573,9 +567,6 @@ "links": { "message": "Liens" }, - "liveGasPricePredictions": { - "message": "Prévisions des prix de l'essence en direct" - }, "loadMore": { "message": "Charger plus" }, @@ -1000,9 +991,6 @@ "slow": { "message": "Lente" }, - "slower": { - "message": "Plus lent" - }, "somethingWentWrong": { "message": "Oups ! Quelque chose a mal tourné. " }, @@ -1141,9 +1129,6 @@ "transactionSubmitted": { "message": "Transaction envoyée sur $2." }, - "transactionTime": { - "message": "Heure de la transaction" - }, "transactionUpdated": { "message": "Transaction mise à jour sur $2." }, diff --git a/app/_locales/he/messages.json b/app/_locales/he/messages.json index b2642a218..71900e7e7 100644 --- a/app/_locales/he/messages.json +++ b/app/_locales/he/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "מזהה שרשרת" }, - "chartOnlyAvailableEth": { - "message": "טבלה זמינה רק ברשתות אתריום." - }, "chromeRequiredForHardwareWallets": { "message": "עליך להשתמש ב-MetaMask בגוגל כרום כדי להתחבר לארנק החומרה שלך." }, @@ -398,9 +395,6 @@ "fast": { "message": "מהיר" }, - "faster": { - "message": "מהר יותר" - }, "fiat": { "message": "פיאט", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "קישורים" }, - "liveGasPricePredictions": { - "message": "תחזיות מחירי גז בשידור חי" - }, "loadMore": { "message": "טען עוד" }, @@ -1012,9 +1003,6 @@ "slow": { "message": "אטי" }, - "slower": { - "message": "לאט יותר" - }, "somethingWentWrong": { "message": "אופס! משהו השתבש." }, @@ -1159,9 +1147,6 @@ "transactionSubmitted": { "message": "עסקה הוגשה עם עמלת דלק של $1 ב-$2." }, - "transactionTime": { - "message": "זמן העסקה" - }, "transactionUpdated": { "message": "העסקה עודכנה ב- $2." }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index f759ed46a..3cba3b1d1 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "चेन आई.डी." }, - "chartOnlyAvailableEth": { - "message": "केवल ईथरअम नेटवर्क पर उपलब्ध चार्ट।" - }, "chromeRequiredForHardwareWallets": { "message": "अपने हार्डवेयर वॉलेट से कनेक्ट करने के लिए आपको Google Chrome में MetaMask का उपयोग करना ज़रूरी है।" }, @@ -398,9 +395,6 @@ "fast": { "message": "तेज़" }, - "faster": { - "message": "तीव्र" - }, "fiat": { "message": "फ़्लैट", "description": "Exchange type" @@ -576,9 +570,6 @@ "likeToAddTokens": { "message": "क्या आप इन टोकन को जोड़ना चाहेंगे?" }, - "liveGasPricePredictions": { - "message": "लाइव गैस की कीमत की भविष्यवाणी" - }, "loadMore": { "message": "और लोड करें" }, @@ -1012,9 +1003,6 @@ "slow": { "message": "धीमा" }, - "slower": { - "message": "धीमा" - }, "somethingWentWrong": { "message": "ओह! कुछ गलत हो गया।" }, @@ -1159,9 +1147,6 @@ "transactionSubmitted": { "message": "$2 पर $1 के गैस शुल्क के साथ ट्रांज़ैक्शन दर्ज किया गया।" }, - "transactionTime": { - "message": "ट्रांज़ैक्शन का समय" - }, "transactionUpdated": { "message": "$2 पर ट्रांज़ैक्शन अपडेट किया गया।" }, diff --git a/app/_locales/hr/messages.json b/app/_locales/hr/messages.json index eb4f9eae1..42ffcb611 100644 --- a/app/_locales/hr/messages.json +++ b/app/_locales/hr/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Identifikacijska oznaka bloka" }, - "chartOnlyAvailableEth": { - "message": "Grafikon je dostupan samo na mrežama Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Trebate upotrebljavati MetaMask u pregledniku Google Chrome kako biste ga povezali s vašim hardverskim novčanikom." }, @@ -398,9 +395,6 @@ "fast": { "message": "Brzo" }, - "faster": { - "message": "Brže" - }, "fileImportFail": { "message": "Uvoženje datoteke ne radi? Kliknite ovdje.", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Poveznice" }, - "liveGasPricePredictions": { - "message": "Predviđanja uživo za cijenu goriva" - }, "loadMore": { "message": "Učitaj više" }, @@ -1011,9 +1002,6 @@ "slow": { "message": "Sporo" }, - "slower": { - "message": "Sporije" - }, "somethingWentWrong": { "message": "Ups! Nešto je pošlo po zlu." }, @@ -1155,9 +1143,6 @@ "transactionSubmitted": { "message": "Transakcija je poslana s naknadom za gorivo od $1 u $2." }, - "transactionTime": { - "message": "Vrijeme transkacije" - }, "transactionUpdated": { "message": "Transakcija je ažurirana u $2." }, diff --git a/app/_locales/hu/messages.json b/app/_locales/hu/messages.json index effc61461..cf3dda940 100644 --- a/app/_locales/hu/messages.json +++ b/app/_locales/hu/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Lánc azonosítója" }, - "chartOnlyAvailableEth": { - "message": "A diagram csak Ethereum hálózatokon érhető el" - }, "chromeRequiredForHardwareWallets": { "message": "A MetaMask-ot Google Chrome-mal kell használnia a Hardveres pénztárcához való csatlakozáshoz." }, @@ -398,9 +395,6 @@ "fast": { "message": "Gyors" }, - "faster": { - "message": "Gyorsabban" - }, "fileImportFail": { "message": "Nem működik a fájl importálása? Kattintson ide!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Linkek" }, - "liveGasPricePredictions": { - "message": "Élő előrejelzések gázárak alakulására" - }, "loadMore": { "message": "Továbbiak betöltése" }, @@ -1011,9 +1002,6 @@ "slow": { "message": "Lassú" }, - "slower": { - "message": "Lassabban" - }, "somethingWentWrong": { "message": "Hoppá! Valami hiba történt..." }, @@ -1155,9 +1143,6 @@ "transactionSubmitted": { "message": "Tranzakció jóváhagyva $1 üzemanyag költséggel $2-kor." }, - "transactionTime": { - "message": "Tranzakció ideje" - }, "transactionUpdated": { "message": "Tranzakció frissítve $2-nál" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index fceea2c05..da00b134a 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID Rantai" }, - "chartOnlyAvailableEth": { - "message": "Grafik hanya tersedia pada jaringan Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Anda harus menggunakan MetaMask di Google Chrome untuk menyambung ke dompet Perangkat Keras Anda." }, @@ -392,9 +389,6 @@ "fast": { "message": "Cepat" }, - "faster": { - "message": "Lebih Cepat" - }, "fileImportFail": { "message": "Impor berkas tidak tersedia? Klik di sini!", "description": "Helps user import their account from a JSON file" @@ -569,9 +563,6 @@ "links": { "message": "Tautan" }, - "liveGasPricePredictions": { - "message": "Prediksi Harga Gas Langsung" - }, "loadMore": { "message": "Muat Lainnya" }, @@ -1002,9 +993,6 @@ "slow": { "message": "Lambat" }, - "slower": { - "message": "Lebih Lambat" - }, "somethingWentWrong": { "message": "Ups! Terjadi sesuatu." }, @@ -1143,9 +1131,6 @@ "transactionSubmitted": { "message": "Transaksi diajukan dengan biaya gas sebesar $1 di $2." }, - "transactionTime": { - "message": "Waktu Transaksi" - }, "transactionUpdated": { "message": "Transaksi diperbarui di $2." }, diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index da1dcdc8b..f0a6c950d 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -229,9 +229,6 @@ "chainId": { "message": "Blockchain ID" }, - "chartOnlyAvailableEth": { - "message": "Grafico disponibile solo per le reti Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Devi usare MetaMask con Google Chrome per connettere il tuo Portafoglio Hardware" }, @@ -630,9 +627,6 @@ "fast": { "message": "Veloce" }, - "faster": { - "message": "Più veloce" - }, "feeAssociatedRequest": { "message": "Una tassa è associata a questa richiesta." }, @@ -851,9 +845,6 @@ "links": { "message": "Collegamenti" }, - "liveGasPricePredictions": { - "message": "Previsione del prezzo del gas in tempo reale" - }, "loadMore": { "message": "Carica di più" }, @@ -1382,9 +1373,6 @@ "showSeedPhrase": { "message": "Mostra frase seed" }, - "showTransactionTimeDescription": { - "message": "Seleziona per mostrare nella scheda attività una stima dei tempi di transazione per le transazioni in corso sulla rete Ethereum principale. Nota: la stima è approssimativa basata sulle condizioni della rete." - }, "sigRequest": { "message": "Firma Richiesta" }, @@ -1406,9 +1394,6 @@ "slow": { "message": "Lenta" }, - "slower": { - "message": "Più lenta" - }, "somethingWentWrong": { "message": "Oops! Qualcosa è andato storto." }, @@ -1600,9 +1585,6 @@ "transactionSubmitted": { "message": "Transazione inviata alle $2." }, - "transactionTime": { - "message": "Tempo Conferma Transazione" - }, "transactionUpdated": { "message": "Transazione aggiornata alle $2." }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index e0360ced8..728676097 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -115,9 +115,6 @@ "cancel": { "message": "キャンセル" }, - "chartOnlyAvailableEth": { - "message": "チャートはEthereumネットワークでのみ利用可能です。" - }, "confirm": { "message": "確認" }, diff --git a/app/_locales/kn/messages.json b/app/_locales/kn/messages.json index baeeba4a0..8c6c0a9e1 100644 --- a/app/_locales/kn/messages.json +++ b/app/_locales/kn/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ಚೈನ್ ID" }, - "chartOnlyAvailableEth": { - "message": "ಎಥೆರಿಯಮ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳಲ್ಲಿ ಮಾತ್ರವೇ ಚಾರ್ಟ್‌ಗಳು ಲಭ್ಯವಿರುತ್ತವೆ." - }, "chromeRequiredForHardwareWallets": { "message": "ನಿಮ್ಮ ಹಾರ್ಡ್‌ವೇರ್ ವ್ಯಾಲೆಟ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸುವ ಸಲುವಾಗಿ Google Chrome ನಲ್ಲಿ ನಿಮಗೆ MetaMask ಅನ್ನು ಬಳಸುವ ಅಗತ್ಯವಿದೆ." }, @@ -398,9 +395,6 @@ "fast": { "message": "ವೇಗ" }, - "faster": { - "message": "ವೇಗವಾಗಿ" - }, "fiat": { "message": "ಫಿಯೆಟ್", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "ಲಿಂಕ್‌ಗಳು" }, - "liveGasPricePredictions": { - "message": "ಲೈವ್ ಗ್ಯಾಸ್ ಬೆಲೆಯ ಭವಿಷ್ಯಗಳು" - }, "loadMore": { "message": "ಇನ್ನಷ್ಟು ಲೋಡ್ ಮಾಡಿ" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "ನಿಧಾನ" }, - "slower": { - "message": "ನಿಧಾನ" - }, "somethingWentWrong": { "message": "ಓಹ್‌‍! ಏನೋ ತಪ್ಪಾಗಿದೆ." }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "ವಹಿವಾಟನ್ನು $2 ನಲ್ಲಿ $1 ಗ್ಯಾಸ್ ಶುಲ್ಕದೊಂದಿಗೆ ರಚಿಸಲಾಗಿದೆ." }, - "transactionTime": { - "message": "ವಹಿವಾಟು ಸಮಯ" - }, "transactionUpdated": { "message": "$2 ನಲ್ಲಿ ವಹಿವಾಟನ್ನು ನವೀಕರಿಸಲಾಗಿದೆ." }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 1b16838f1..43c6278b1 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "체인 ID" }, - "chartOnlyAvailableEth": { - "message": "이더리움 네트워크에서만 사용 가능한 차트." - }, "chromeRequiredForHardwareWallets": { "message": "하드웨어 지갑을 연결하기 위해서는 구글 크롬에서 메타마스크를 사용하셔야 합니다." }, @@ -395,9 +392,6 @@ "fast": { "message": "빠름" }, - "faster": { - "message": "빨라짐" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -573,9 +567,6 @@ "links": { "message": "링크" }, - "liveGasPricePredictions": { - "message": "실시간 가스 가격 예측" - }, "loadMore": { "message": "더 많이 로딩" }, @@ -1009,9 +1000,6 @@ "slow": { "message": "느림" }, - "slower": { - "message": "느려짐" - }, "somethingWentWrong": { "message": "헉! 뭔가 잘못됐어요." }, @@ -1156,9 +1144,6 @@ "transactionSubmitted": { "message": "$1의 가스 요금으로 트랜잭션이 제출됨 $2." }, - "transactionTime": { - "message": "트랜잭션 시간" - }, "transactionUpdated": { "message": "트랜잭션이 수정됨 $2." }, diff --git a/app/_locales/lt/messages.json b/app/_locales/lt/messages.json index 37b05da6e..3158cb579 100644 --- a/app/_locales/lt/messages.json +++ b/app/_locales/lt/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Grandinės ID" }, - "chartOnlyAvailableEth": { - "message": "Diagramos yra tik „Ethereum“ tinkluose." - }, "chromeRequiredForHardwareWallets": { "message": "Norėdami prisijungti prie aparatinės įrangos slaptažodinės, „MetaMask“ naudokitės „Google Chrome“ naršyklėje." }, @@ -398,9 +395,6 @@ "fast": { "message": "Greitas" }, - "faster": { - "message": "Greičiau" - }, "fiat": { "message": "Standartinė valiuta", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "Nuorodos" }, - "liveGasPricePredictions": { - "message": "Tiesioginiai dujų kainos spėjimai" - }, "loadMore": { "message": "Įkelti daugiau" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "Lėtas" }, - "slower": { - "message": "Lėčiau" - }, "somethingWentWrong": { "message": "Vaje! Kažkas negerai." }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "Operacija pateikta $2 su $1 dujų mokesčiu." }, - "transactionTime": { - "message": "Operacijos laikas" - }, "transactionUpdated": { "message": "Operacija atnaujinta$2." }, diff --git a/app/_locales/lv/messages.json b/app/_locales/lv/messages.json index 1586d9f5b..43b5a6375 100644 --- a/app/_locales/lv/messages.json +++ b/app/_locales/lv/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Ķēdes ID" }, - "chartOnlyAvailableEth": { - "message": "Grafiks pieejams vienīgi Ethereum tīklos." - }, "chromeRequiredForHardwareWallets": { "message": "MetaMask ir jāpalaiž pārlūkprogrammā Google Chrome, lai varētu pievienot aparatūras maku." }, @@ -398,9 +395,6 @@ "fast": { "message": "Ātrs" }, - "faster": { - "message": "Ātrāk" - }, "fileImportFail": { "message": "Vai faila importēšanas iespēja nedarbojas? Klikšķiniet šeit!", "description": "Helps user import their account from a JSON file" @@ -575,9 +569,6 @@ "links": { "message": "Saites" }, - "liveGasPricePredictions": { - "message": "Reāllaika Gas cenu prognozes" - }, "loadMore": { "message": "Ielādēt vairāk" }, @@ -1014,9 +1005,6 @@ "slow": { "message": "Lēns" }, - "slower": { - "message": "Lēnāk" - }, "somethingWentWrong": { "message": "Ak vai! Radās problēma." }, @@ -1161,9 +1149,6 @@ "transactionSubmitted": { "message": "Darījums iesniegts ar maksu par Gas $1 pie $2." }, - "transactionTime": { - "message": "Darījuma ilgums" - }, "transactionUpdated": { "message": "Darījums atjaunināts $2." }, diff --git a/app/_locales/ms/messages.json b/app/_locales/ms/messages.json index d141c683b..e64b4f582 100644 --- a/app/_locales/ms/messages.json +++ b/app/_locales/ms/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID Rantaian" }, - "chartOnlyAvailableEth": { - "message": "Carta hanya tersedia di rangkaian Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Anda perlu menggunakan MetaMask di Google Chrome untuk menyambung kepada Dompet Perkakasan anda." }, @@ -392,9 +389,6 @@ "fast": { "message": "Cepat" }, - "faster": { - "message": "Lebih cepat" - }, "fileImportFail": { "message": "Pengimportan fail tidak berfungsi? Klik di sini!", "description": "Helps user import their account from a JSON file" @@ -565,9 +559,6 @@ "links": { "message": "Pautan" }, - "liveGasPricePredictions": { - "message": "Ramalan Harga Gas Langsung" - }, "loadMore": { "message": "Muat Lagi" }, @@ -995,9 +986,6 @@ "slow": { "message": "Perlahan" }, - "slower": { - "message": "Lebih Perlahan" - }, "somethingWentWrong": { "message": "Alamak! Ada yang tak kena." }, @@ -1139,9 +1127,6 @@ "transactionSubmitted": { "message": "Transaksi dihantar dengan fi gas sebanyak $1 pada $2." }, - "transactionTime": { - "message": "Masa Transaksi" - }, "transactionUpdated": { "message": "Transaksi dikemaskini pada $2." }, diff --git a/app/_locales/no/messages.json b/app/_locales/no/messages.json index 80f116b75..816ea9ed8 100644 --- a/app/_locales/no/messages.json +++ b/app/_locales/no/messages.json @@ -164,9 +164,6 @@ "chainId": { "message": "Blokkjede " }, - "chartOnlyAvailableEth": { - "message": "Diagram kun tilgjengelig på Ethereum-nettverk." - }, "chromeRequiredForHardwareWallets": { "message": "Du må bruke MetaMask på Google Chrome for å koble deg til maskinvare-lommeboken." }, @@ -395,9 +392,6 @@ "fast": { "message": "Høy" }, - "faster": { - "message": "Raskere " - }, "fileImportFail": { "message": "Virker ikke filimporteringen? Trykk her!", "description": "Helps user import their account from a JSON file" @@ -566,9 +560,6 @@ "links": { "message": "Lenker " }, - "liveGasPricePredictions": { - "message": "Prisforutsigelse av datakraft i sanntid" - }, "loadMore": { "message": "Last mer " }, @@ -996,9 +987,6 @@ "slow": { "message": "Lav" }, - "slower": { - "message": "Saktere" - }, "somethingWentWrong": { "message": "Oisann! Noe gikk galt. " }, @@ -1137,9 +1125,6 @@ "transactionSubmitted": { "message": "Transaksjon sendt med datakraftavgift på $1 til $2." }, - "transactionTime": { - "message": "Transaksjonstid" - }, "transactionUpdated": { "message": "Transaksjonen oppdatert på $2." }, diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index 7f3dc09a9..e1a1c8c9a 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "Identyfikator łańcucha" }, - "chartOnlyAvailableEth": { - "message": "Wykres dostępny tylko w sieciach Ethereum" - }, "chromeRequiredForHardwareWallets": { "message": "Żeby połączyć się z portfelem sprzętowym, należy uruchomić MetaMask z przeglądarką Google Chrome." }, @@ -398,9 +395,6 @@ "fast": { "message": "Szybko" }, - "faster": { - "message": "Szybciej" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "Łącza" }, - "liveGasPricePredictions": { - "message": "Przewidywanie ceny gazu na żywo" - }, "loadMore": { "message": "Załaduj więcej" }, @@ -1012,9 +1003,6 @@ "slow": { "message": "Powoli" }, - "slower": { - "message": "Wolniej" - }, "somethingWentWrong": { "message": "Ups! Coś poszło nie tak." }, @@ -1153,9 +1141,6 @@ "transactionSubmitted": { "message": "Transakcja wykonana z opłatą za gaz w wysokości $1 – $2." }, - "transactionTime": { - "message": "Czas transakcji" - }, "transactionUpdated": { "message": "Transakcja zaktualizowana – $2." }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index 8973b3544..154668b75 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -161,9 +161,6 @@ "chainId": { "message": "ID da Cadeia" }, - "chartOnlyAvailableEth": { - "message": "Tabela disponível apenas em redes de Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Você precisa usar o MetaMask no Google Chrome para se conectar à sua Carteira de Hardware." }, @@ -392,9 +389,6 @@ "fast": { "message": "Rápido" }, - "faster": { - "message": "Mais rápido" - }, "fiat": { "message": "Ordem", "description": "Exchange type" @@ -570,9 +564,6 @@ "likeToAddTokens": { "message": "Deseja adicionar esses tokens?" }, - "liveGasPricePredictions": { - "message": "Previsões de Preços de Gás Ao Vivo" - }, "loadMore": { "message": "Carregar Mais" }, @@ -1006,9 +997,6 @@ "slow": { "message": "Lento" }, - "slower": { - "message": "Mais lento" - }, "somethingWentWrong": { "message": "Opa! Algo deu errado." }, @@ -1147,9 +1135,6 @@ "transactionSubmitted": { "message": "Transação enviada com taxa de gás de $1 a $2." }, - "transactionTime": { - "message": "Hora da Transação" - }, "transactionUpdated": { "message": "Transação atualizada às $2." }, diff --git a/app/_locales/ro/messages.json b/app/_locales/ro/messages.json index 890b5758b..7c5cc0c8a 100644 --- a/app/_locales/ro/messages.json +++ b/app/_locales/ro/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID lanț" }, - "chartOnlyAvailableEth": { - "message": "Grafic disponibil numai pe rețelele Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Trebuie să folosiți MetaMask în Google Chrome pentru a vă conecta la portofelul hardware." }, @@ -398,9 +395,6 @@ "fast": { "message": "Rapid" }, - "faster": { - "message": "Mai repede" - }, "fileImportFail": { "message": "Importarea fișierului nu funcționează? Dați clic aici!", "description": "Helps user import their account from a JSON file" @@ -569,9 +563,6 @@ "links": { "message": "Link-uri" }, - "liveGasPricePredictions": { - "message": "Predicții live de preț în gas" - }, "loadMore": { "message": "Încărcați mai multe" }, @@ -1005,9 +996,6 @@ "slow": { "message": "Lent" }, - "slower": { - "message": "Mai încet" - }, "somethingWentWrong": { "message": "Hopa! A apărut o eroare." }, @@ -1149,9 +1137,6 @@ "transactionSubmitted": { "message": "Tranzacția a fost trimisă, cu o taxă gas de $1 la $2." }, - "transactionTime": { - "message": "Ora tranzacției" - }, "transactionUpdated": { "message": "Tranzacție actualizată la $2." }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index c33af5cd1..b528ec886 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -166,9 +166,6 @@ "chainId": { "message": "ID сети" }, - "chartOnlyAvailableEth": { - "message": "Диаграмма доступна только в сетях Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Вам необходимо использовать MetaMask в Google Chrome, чтобы подключиться к своему аппаратному кошельку." }, @@ -427,9 +424,6 @@ "fast": { "message": "Быстро" }, - "faster": { - "message": "Быстрее" - }, "fiat": { "message": "Валюта", "description": "Exchange type" @@ -608,9 +602,6 @@ "links": { "message": "Ссылки" }, - "liveGasPricePredictions": { - "message": "Прогноз цены газа в режиме реального времени" - }, "loadMore": { "message": "Загрузить еще" }, @@ -1054,9 +1045,6 @@ "slow": { "message": "Медленно" }, - "slower": { - "message": "Медленнее" - }, "somethingWentWrong": { "message": "Опс! Что-то пошло не так." }, @@ -1201,9 +1189,6 @@ "transactionSubmitted": { "message": "Сделка подана с оплатой за газ в размере 1$ за 2$." }, - "transactionTime": { - "message": "Время транзакции" - }, "transactionUpdated": { "message": "Транзакция обновлена до $2." }, diff --git a/app/_locales/sk/messages.json b/app/_locales/sk/messages.json index 08bd00cc6..86e9040ab 100644 --- a/app/_locales/sk/messages.json +++ b/app/_locales/sk/messages.json @@ -161,9 +161,6 @@ "chainId": { "message": "ID reťazca" }, - "chartOnlyAvailableEth": { - "message": "Graf je k dispozícii iba v sieťach Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Ak sa chcete pripojiť k svojej hardvérovej peňaženke, musíte v Google Chrome použiť MetaMask." }, @@ -392,9 +389,6 @@ "fast": { "message": "Rýchle" }, - "faster": { - "message": "Rýchlejšie" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -563,9 +557,6 @@ "links": { "message": "Odkazy" }, - "liveGasPricePredictions": { - "message": "Predpoveď cien GAS naživo" - }, "loadMore": { "message": "Načítať viac" }, @@ -981,9 +972,6 @@ "slow": { "message": "Pomalé" }, - "slower": { - "message": "Pomalší" - }, "somethingWentWrong": { "message": "Och! Niečo zlyhalo." }, @@ -1122,9 +1110,6 @@ "transactionSubmitted": { "message": "Transakcia bola odoslaná s poplatkom za GAS z $1 na $2." }, - "transactionTime": { - "message": "Čas transakcie" - }, "transactionUpdated": { "message": "Transakcia bola aktualizovaná na $2." }, diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index 8c92173c0..ffb268e59 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID verige" }, - "chartOnlyAvailableEth": { - "message": "Grafikon na voljo le v glavnih omrežjih." - }, "chromeRequiredForHardwareWallets": { "message": "Za uporabo strojne denarnice potrebujete Google Chrome." }, @@ -398,9 +395,6 @@ "fast": { "message": "Hiter" }, - "faster": { - "message": "Hitrejši" - }, "fiat": { "message": "Klasične", "description": "Exchange type" @@ -570,9 +564,6 @@ "links": { "message": "Povezave" }, - "liveGasPricePredictions": { - "message": "Napovedi o gas price" - }, "loadMore": { "message": "Naloži več" }, @@ -1000,9 +991,6 @@ "slow": { "message": "Počasen" }, - "slower": { - "message": "Počasnejši" - }, "somethingWentWrong": { "message": "Oops! Nekaj je šlo narobe." }, @@ -1147,9 +1135,6 @@ "transactionSubmitted": { "message": "Transakcija z gas fee $1 oddana na $2." }, - "transactionTime": { - "message": "Transakcijski čas" - }, "transactionUpdated": { "message": "Transakcija na $2 spremenjena." }, diff --git a/app/_locales/sr/messages.json b/app/_locales/sr/messages.json index bb2276471..7aea49f76 100644 --- a/app/_locales/sr/messages.json +++ b/app/_locales/sr/messages.json @@ -164,9 +164,6 @@ "cancelled": { "message": "Otkazano" }, - "chartOnlyAvailableEth": { - "message": "Grafikon dostupan jedino na mrežama Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Da biste se povezali sa Vašim hardverskim novčanikom morate da koristite MetaMask na Google Chrome-u." }, @@ -395,9 +392,6 @@ "fast": { "message": "Брзо" }, - "faster": { - "message": "Brže" - }, "fiat": { "message": "Dekret", "description": "Exchange type" @@ -576,9 +570,6 @@ "links": { "message": "Veze" }, - "liveGasPricePredictions": { - "message": "Predviđanja cene gasa uživo" - }, "loadMore": { "message": "Učitati više" }, @@ -1009,9 +1000,6 @@ "slow": { "message": "Споро" }, - "slower": { - "message": "Sporije" - }, "somethingWentWrong": { "message": "Ups! Nešto nije u redu." }, @@ -1150,9 +1138,6 @@ "transactionSubmitted": { "message": "Transakcija je podnešena sa gas naknadom od $1 na $2." }, - "transactionTime": { - "message": "Vreme transakcije" - }, "transactionUpdated": { "message": "Transakcija je ažurirana na $2." }, diff --git a/app/_locales/sv/messages.json b/app/_locales/sv/messages.json index d902d2fe2..183d1064f 100644 --- a/app/_locales/sv/messages.json +++ b/app/_locales/sv/messages.json @@ -161,9 +161,6 @@ "cancelled": { "message": "Avbruten" }, - "chartOnlyAvailableEth": { - "message": "Tabellen är endast tillgänglig på Ethereum-nätverk." - }, "chromeRequiredForHardwareWallets": { "message": "Du måste använda MetaMask på Google Chrome för att ansluta till din hårdvaruplånbok." }, @@ -392,9 +389,6 @@ "fast": { "message": "Snabb" }, - "faster": { - "message": "Snabbare" - }, "fileImportFail": { "message": "Fungerar inte filimporten? Klicka här!", "description": "Helps user import their account from a JSON file" @@ -569,9 +563,6 @@ "links": { "message": "Länkar" }, - "liveGasPricePredictions": { - "message": "Liveuppdaterad gaspris-förutsägelser" - }, "loadMore": { "message": "Ladda mer" }, @@ -1002,9 +993,6 @@ "slow": { "message": "Långsamt" }, - "slower": { - "message": "Långsammare" - }, "somethingWentWrong": { "message": "Hoppsan! Något gick fel." }, @@ -1140,9 +1128,6 @@ "transactionSubmitted": { "message": "Överföring angedd med gasavgift på $1 vid $2." }, - "transactionTime": { - "message": "Transaktionstid" - }, "transactionUpdated": { "message": "Transaktionen uppdaterades $2." }, diff --git a/app/_locales/sw/messages.json b/app/_locales/sw/messages.json index 25911569a..f5516ae5f 100644 --- a/app/_locales/sw/messages.json +++ b/app/_locales/sw/messages.json @@ -161,9 +161,6 @@ "chainId": { "message": "Utambulisho wa Mnyororo" }, - "chartOnlyAvailableEth": { - "message": "Zogoa inapatikana kwenye mitandao ya Ethereum pekee." - }, "chromeRequiredForHardwareWallets": { "message": "Unapaswa kutumia MetaMask kwenye Google Chrome ili kuungnisha kwenye Waleti yako ya Programu Maunzi." }, @@ -392,9 +389,6 @@ "fast": { "message": "Haraka" }, - "faster": { - "message": "Ingiza" - }, "fileImportFail": { "message": "Kuhamisha faili hakufanyi kazi? Bofya hapa!", "description": "Helps user import their account from a JSON file" @@ -566,9 +560,6 @@ "links": { "message": "Viungo" }, - "liveGasPricePredictions": { - "message": "Utabiri wa moja kwa moja wa Bei ya Gesi" - }, "loadMore": { "message": "Pak zAIDI" }, @@ -996,9 +987,6 @@ "slow": { "message": "Polepole" }, - "slower": { - "message": "Taratibu" - }, "somethingWentWrong": { "message": "Ayaa! Hitilafu fulani imetokea." }, @@ -1143,9 +1131,6 @@ "transactionSubmitted": { "message": "Muamala umewasilishwa ukiwa na ada ya gesi ya$1 mnamo $2." }, - "transactionTime": { - "message": "Muda wa Muamala" - }, "transactionUpdated": { "message": "Muamala umesasishwa mnamo $2." }, diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json index 951958eff..330d10cb7 100644 --- a/app/_locales/th/messages.json +++ b/app/_locales/th/messages.json @@ -190,9 +190,6 @@ "fast": { "message": "เร็ว" }, - "faster": { - "message": "เร็วขึ้น" - }, "fiat": { "message": "เงินตรา", "description": "Exchange type" @@ -477,9 +474,6 @@ "signed": { "message": "ลงชื่อแล้ว" }, - "slower": { - "message": "ช้าลง" - }, "stateLogs": { "message": "บันทึกของสถานะ" }, diff --git a/app/_locales/uk/messages.json b/app/_locales/uk/messages.json index 53c845fe1..c613908bd 100644 --- a/app/_locales/uk/messages.json +++ b/app/_locales/uk/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "ID мережі" }, - "chartOnlyAvailableEth": { - "message": "Таблиця доступна тільки в мережах Ethereum." - }, "chromeRequiredForHardwareWallets": { "message": "Щоб підключитися до апаратного гаманця, розширення MetaMask потрібно використовувати в Google Chrome." }, @@ -398,9 +395,6 @@ "fast": { "message": "Швидка" }, - "faster": { - "message": "Швидше" - }, "fiat": { "message": "Вказівка", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "Посилання" }, - "liveGasPricePredictions": { - "message": "Прогнози ціни на пальне наживо" - }, "loadMore": { "message": "Завантажити більше" }, @@ -1018,9 +1009,6 @@ "slow": { "message": "Повільна" }, - "slower": { - "message": "Повільніше" - }, "somethingWentWrong": { "message": "Ой! Щось пішло не так." }, @@ -1165,9 +1153,6 @@ "transactionSubmitted": { "message": "Транзакція надіслана з оплатою за газ $1 о $2." }, - "transactionTime": { - "message": "Час транзакції" - }, "transactionUpdated": { "message": "Час оновлення транзакції: $2." }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 6330781c6..1a0631b6a 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "链 ID" }, - "chartOnlyAvailableEth": { - "message": "聊天功能仅对以太坊网络开放。" - }, "chromeRequiredForHardwareWallets": { "message": "您需要通过 Google Chrome 浏览器使用 MetaMask ,连接个人硬件钱包。" }, @@ -398,9 +395,6 @@ "fast": { "message": "快" }, - "faster": { - "message": "快捷操作" - }, "fiat": { "message": "FIAT", "description": "Exchange type" @@ -570,9 +564,6 @@ "links": { "message": "链接" }, - "liveGasPricePredictions": { - "message": "实时天然气价格预测" - }, "loadMore": { "message": "加载更多" }, @@ -1000,9 +991,6 @@ "slow": { "message": "慢" }, - "slower": { - "message": "降速" - }, "somethingWentWrong": { "message": "哎呀!出问题了。" }, @@ -1147,9 +1135,6 @@ "transactionSubmitted": { "message": "在 $2 提交的交易单,其天然气费为 $1 。" }, - "transactionTime": { - "message": "交易时间" - }, "transactionUpdated": { "message": "交易单已于 $2 更新。" }, diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index 3f4ec252d..c58f87eea 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -167,9 +167,6 @@ "chainId": { "message": "鏈 ID" }, - "chartOnlyAvailableEth": { - "message": "圖表僅適用於以太坊網路。" - }, "chromeRequiredForHardwareWallets": { "message": "您需要在 Google Chrome 瀏覽器使用 MetaMask 連結您的硬體錢包" }, @@ -398,9 +395,6 @@ "fast": { "message": "快" }, - "faster": { - "message": "更快" - }, "fiat": { "message": "法定貨幣", "description": "Exchange type" @@ -579,9 +573,6 @@ "links": { "message": "連結" }, - "liveGasPricePredictions": { - "message": "即時 Gas 價格預估" - }, "loadMore": { "message": "載入更多" }, @@ -997,9 +988,6 @@ "slow": { "message": "慢" }, - "slower": { - "message": "更慢" - }, "somethingWentWrong": { "message": "糟糕!出了點問題。" }, @@ -1144,9 +1132,6 @@ "transactionSubmitted": { "message": "交易送出 手續費 $1 時間 $2" }, - "transactionTime": { - "message": "交易時間" - }, "transactionUpdated": { "message": "交易狀態更新 時間 $2" }, diff --git a/app/images/icon-48.png b/app/images/icon-48.png new file mode 100644 index 000000000..91d0467a1 Binary files /dev/null and b/app/images/icon-48.png differ diff --git a/app/manifest/_base.json b/app/manifest/_base.json index c16bc2fbf..e27c3285f 100644 --- a/app/manifest/_base.json +++ b/app/manifest/_base.json @@ -1,7 +1,13 @@ { "author": "https://metamask.io", "background": { - "scripts": ["bg-libs.js", "background.js"], + "scripts": [ + "initSentry.js", + "lockdown.cjs", + "runLockdown.js", + "bg-libs.js", + "background.js" + ], "persistent": true }, "browser_action": { @@ -30,7 +36,7 @@ "content_scripts": [ { "matches": ["file://*/*", "http://*/*", "https://*/*"], - "js": ["contentscript.js"], + "js": ["lockdown.cjs", "runLockdown.js", "contentscript.js"], "run_at": "document_start", "all_frames": true }, @@ -46,6 +52,7 @@ "19": "images/icon-19.png", "32": "images/icon-32.png", "38": "images/icon-38.png", + "48": "images/icon-48.png", "64": "images/icon-64.png", "128": "images/icon-128.png", "512": "images/icon-512.png" @@ -64,6 +71,6 @@ "notifications" ], "short_name": "__MSG_appName__", - "version": "8.1.5", + "version": "8.1.6", "web_accessible_resources": ["inpage.js", "phishing.html"] } diff --git a/app/phishing.html b/app/phishing.html index 583a50140..1c913db2e 100644 --- a/app/phishing.html +++ b/app/phishing.html @@ -2,6 +2,8 @@ Ethereum Phishing Detection - MetaMask + + diff --git a/app/popup.html b/app/popup.html index 0c3d70407..4d29f6153 100644 --- a/app/popup.html +++ b/app/popup.html @@ -10,6 +10,9 @@
+ + + diff --git a/app/scripts/background.js b/app/scripts/background.js index c57710bd2..fa1e48a10 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -3,7 +3,6 @@ */ // these need to run before anything else /* eslint-disable import/first,import/order */ -import './lib/freezeGlobals' import setupFetchDebugging from './lib/setupFetchDebugging' /* eslint-enable import/order */ @@ -29,7 +28,6 @@ import createStreamSink from './lib/createStreamSink' import NotificationManager from './lib/notification-manager' import MetamaskController from './metamask-controller' import rawFirstTimeState from './first-time-state' -import setupSentry from './lib/setupSentry' import getFirstPreferredLangCode from './lib/get-first-preferred-lang-code' import getObjStructure from './lib/getObjStructure' import setupEnsIpfsResolver from './lib/ens-ipfs/setup' @@ -41,18 +39,16 @@ import { } from './lib/enums' /* eslint-enable import/first */ +const { sentry } = global const firstTimeState = { ...rawFirstTimeState } log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn') const platform = new ExtensionPlatform() + const notificationManager = new NotificationManager() global.METAMASK_NOTIFIER = notificationManager -// setup sentry error reporting -const release = platform.getVersion() -const sentry = setupSentry({ release }) - let popupIsOpen = false let notificationIsOpen = false const openMetamaskTabsIDs = {} diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index 6c1c213a6..1fda6dccc 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -1,5 +1,5 @@ import Web3 from 'web3' -import contracts from 'eth-contract-metadata' +import contracts from '@metamask/contract-metadata' import { warn } from 'loglevel' import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi' import { MAINNET } from './network/enums' @@ -32,7 +32,7 @@ export default class DetectTokensController { } /** - * For each token in eth-contract-metadata, find check selectedAddress balance. + * For each token in @metamask/contract-metadata, find check selectedAddress balance. */ async detectNewTokens() { if (!this.isActive) { diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js new file mode 100644 index 000000000..23e6dfcf2 --- /dev/null +++ b/app/scripts/controllers/metametrics.js @@ -0,0 +1,366 @@ +import { merge, omit } from 'lodash' +import ObservableStore from 'obs-store' +import { bufferToHex, sha3 } from 'ethereumjs-util' +import { ENVIRONMENT_TYPE_BACKGROUND } from '../lib/enums' +import { + METAMETRICS_ANONYMOUS_ID, + METAMETRICS_BACKGROUND_PAGE_OBJECT, +} from '../../../shared/constants/metametrics' + +/** + * Used to determine whether or not to attach a user's metametrics id + * to events that include on-chain data. This helps to prevent identifying + * a user by being able to trace their activity on etherscan/block exploring + */ +const trackableSendCounts = { + 1: true, + 10: true, + 30: true, + 50: true, + 100: true, + 250: true, + 500: true, + 1000: true, + 2500: true, + 5000: true, + 10000: true, + 25000: true, +} + +export function sendCountIsTrackable(sendCount) { + return Boolean(trackableSendCounts[sendCount]) +} + +/** + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsContext} MetaMetricsContext + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventPayload} MetaMetricsEventPayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions + * @typedef {import('../../../shared/constants/metametrics').SegmentEventPayload} SegmentEventPayload + * @typedef {import('../../../shared/constants/metametrics').SegmentInterface} SegmentInterface + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPagePayload} MetaMetricsPagePayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageOptions} MetaMetricsPageOptions + */ + +/** + * @typedef {Object} MetaMetricsControllerState + * @property {?string} metaMetricsId - The user's metaMetricsId that will be + * attached to all non-anonymized event payloads + * @property {?boolean} participateInMetaMetrics - The user's preference for + * participating in the MetaMetrics analytics program. This setting controls + * whether or not events are tracked + * @property {number} metaMetricsSendCount - How many send transactions have + * been tracked through this controller. Used to prevent attaching sensitive + * data that can be traced through on chain data. + */ + +export default class MetaMetricsController { + /** + * @param {Object} segment - an instance of analytics-node for tracking + * events that conform to the new MetaMetrics tracking plan. + * @param {Object} segmentLegacy - an instance of analytics-node for + * tracking legacy schema events. Will eventually be phased out + * @param {Object} preferencesStore - The preferences controller store, used + * to access and subscribe to preferences that will be attached to events + * @param {function} onNetworkDidChange - Used to attach a listener to the + * networkDidChange event emitted by the networkController + * @param {function} getCurrentChainId - Gets the current chain id from the + * network controller + * @param {function} getNetworkIdentifier - Gets the current network + * identifier from the network controller + * @param {string} version - The version of the extension + * @param {string} environment - The environment the extension is running in + * @param {MetaMetricsControllerState} initState - State to initialized with + */ + constructor({ + segment, + segmentLegacy, + preferencesStore, + onNetworkDidChange, + getCurrentChainId, + getNetworkIdentifier, + version, + environment, + initState, + }) { + const prefState = preferencesStore.getState() + this.chainId = getCurrentChainId() + this.network = getNetworkIdentifier() + this.locale = prefState.currentLocale.replace('_', '-') + this.version = + environment === 'production' ? version : `${version}-${environment}` + + this.store = new ObservableStore({ + participateInMetaMetrics: null, + metaMetricsId: null, + metaMetricsSendCount: 0, + ...initState, + }) + + preferencesStore.subscribe(({ currentLocale }) => { + this.locale = currentLocale.replace('_', '-') + }) + + onNetworkDidChange(() => { + this.chainId = getCurrentChainId() + this.network = getNetworkIdentifier() + }) + this.segment = segment + this.segmentLegacy = segmentLegacy + } + + generateMetaMetricsId() { + return bufferToHex( + sha3( + String(Date.now()) + + String(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)), + ), + ) + } + + /** + * Setter for the `participateInMetaMetrics` property + * + * @param {boolean} participateInMetaMetrics - Whether or not the user wants + * to participate in MetaMetrics + * @returns {string|null} the string of the new metametrics id, or null + * if not set + */ + setParticipateInMetaMetrics(participateInMetaMetrics) { + let { metaMetricsId } = this.state + if (participateInMetaMetrics && !metaMetricsId) { + metaMetricsId = this.generateMetaMetricsId() + } else if (participateInMetaMetrics === false) { + metaMetricsId = null + } + this.store.updateState({ participateInMetaMetrics, metaMetricsId }) + return metaMetricsId + } + + get state() { + return this.store.getState() + } + + setMetaMetricsSendCount(val) { + this.store.updateState({ metaMetricsSendCount: val }) + } + + /** + * Build the context object to attach to page and track events. + * @private + * @param {Pick} [referrer] - dapp origin that initialized + * the notification window. + * @param {Pick} [page] - page object describing the current + * view of the extension. Defaults to the background-process object. + * @returns {MetaMetricsContext} + */ + _buildContext(referrer, page = METAMETRICS_BACKGROUND_PAGE_OBJECT) { + return { + app: { + name: 'MetaMask Extension', + version: this.version, + }, + userAgent: window.navigator.userAgent, + page, + referrer, + } + } + + /** + * Build's the event payload, processing all fields into a format that can be + * fed to Segment's track method + * @private + * @param { + * Omit + * } rawPayload - raw payload provided to trackEvent + * @returns {SegmentEventPayload} - formatted event payload for segment + */ + _buildEventPayload(rawPayload) { + const { + event, + properties, + revenue, + value, + currency, + category, + page, + referrer, + environmentType = ENVIRONMENT_TYPE_BACKGROUND, + } = rawPayload + return { + event, + properties: { + // These values are omitted from properties because they have special meaning + // in segment. https://segment.com/docs/connections/spec/track/#properties. + // to avoid accidentally using these inappropriately, you must add them as top + // level properties on the event payload. We also exclude locale to prevent consumers + // from overwriting this context level property. We track it as a property + // because not all destinations map locale from context. + ...omit(properties, ['revenue', 'locale', 'currency', 'value']), + revenue, + value, + currency, + category, + network: this.network, + locale: this.locale, + chain_id: this.chainId, + environment_type: environmentType, + }, + context: this._buildContext(referrer, page), + } + } + + /** + * Perform validation on the payload and update the id type to use before + * sending to Segment. Also examines the options to route and handle the + * event appropriately. + * @private + * @param {SegmentEventPayload} payload - properties to attach to event + * @param {MetaMetricsEventOptions} [options] - options for routing and + * handling the event + * @returns {Promise} + */ + _track(payload, options) { + const { + isOptIn, + metaMetricsId: metaMetricsIdOverride, + matomoEvent, + flushImmediately, + } = options || {} + let idType = 'userId' + let idValue = this.state.metaMetricsId + let excludeMetaMetricsId = options?.excludeMetaMetricsId ?? false + // This is carried over from the old implementation, and will likely need + // to be updated to work with the new tracking plan. I think we should use + // a config setting for this instead of trying to match the event name + const isSendFlow = Boolean(payload.event.match(/^send|^confirm/iu)) + if ( + isSendFlow && + this.state.metaMetricsSendCount && + !sendCountIsTrackable(this.state.metaMetricsSendCount + 1) + ) { + excludeMetaMetricsId = true + } + // If we are tracking sensitive data we will always use the anonymousId + // property as well as our METAMETRICS_ANONYMOUS_ID. This prevents us from + // associating potentially identifiable information with a specific id. + // During the opt in flow we will track all events, but do so with the + // anonymous id. The one exception to that rule is after the user opts in + // to MetaMetrics. When that happens we receive back the user's new + // MetaMetrics id before it is fully persisted to state. To avoid a race + // condition we explicitly pass the new id to the track method. In that + // case we will track the opt in event to the user's id. In all other cases + // we use the metaMetricsId from state. + if (excludeMetaMetricsId || (isOptIn && !metaMetricsIdOverride)) { + idType = 'anonymousId' + idValue = METAMETRICS_ANONYMOUS_ID + } else if (isOptIn && metaMetricsIdOverride) { + idValue = metaMetricsIdOverride + } + payload[idType] = idValue + + // Promises will only resolve when the event is sent to segment. For any + // event that relies on this promise being fulfilled before performing UI + // updates, or otherwise delaying user interaction, supply the + // 'flushImmediately' flag to the trackEvent method. + return new Promise((resolve, reject) => { + const callback = (err) => { + if (err) { + return reject(err) + } + return resolve() + } + + const target = matomoEvent === true ? this.segmentLegacy : this.segment + + target.track(payload, callback) + if (flushImmediately) { + target.flush() + } + }) + } + + /** + * track a page view with Segment + * @param {MetaMetricsPagePayload} payload - details of the page viewed + * @param {MetaMetricsPageOptions} [options] - options for handling the page + * view + */ + trackPage({ name, params, environmentType, page, referrer }, options) { + if (this.state.participateInMetaMetrics === false) { + return + } + + if (this.state.participateInMetaMetrics === null && !options?.isOptInPath) { + return + } + const { metaMetricsId } = this.state + const idTrait = metaMetricsId ? 'userId' : 'anonymousId' + const idValue = metaMetricsId ?? METAMETRICS_ANONYMOUS_ID + this.segment.page({ + [idTrait]: idValue, + name, + properties: { + params, + locale: this.locale, + network: this.network, + chain_id: this.chainId, + environment_type: environmentType, + }, + context: this._buildContext(referrer, page), + }) + } + + /** + * track a metametrics event, performing necessary payload manipulation and + * routing the event to the appropriate segment source. Will split events + * with sensitiveProperties into two events, tracking the sensitiveProperties + * with the anonymousId only. + * @param {MetaMetricsEventPayload} payload - details of the event + * @param {MetaMetricsEventOptions} [options] - options for handling/routing the event + * @returns {Promise} + */ + async trackEvent(payload, options) { + // event and category are required fields for all payloads + if (!payload.event || !payload.category) { + throw new Error('Must specify event and category.') + } + + if (!this.state.participateInMetaMetrics && !options?.isOptIn) { + return + } + + // We might track multiple events if sensitiveProperties is included, this array will hold + // the promises returned from this._track. + const events = [] + + if (payload.sensitiveProperties) { + // sensitiveProperties will only be tracked using the anonymousId property and generic id + // If the event options already specify to exclude the metaMetricsId we throw an error as + // a signal to the developer that the event was implemented incorrectly + if (options?.excludeMetaMetricsId === true) { + throw new Error( + 'sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag', + ) + } + + const combinedProperties = merge( + payload.sensitiveProperties, + payload.properties, + ) + + events.push( + this._track( + this._buildEventPayload({ + ...payload, + properties: combinedProperties, + }), + { ...options, excludeMetaMetricsId: true }, + ), + ) + } + + events.push(this._track(this._buildEventPayload(payload), options)) + + await Promise.all(events) + } +} diff --git a/app/scripts/controllers/network/createInfuraClient.js b/app/scripts/controllers/network/createInfuraClient.js index 52048a775..0d1514d61 100644 --- a/app/scripts/controllers/network/createInfuraClient.js +++ b/app/scripts/controllers/network/createInfuraClient.js @@ -1,5 +1,4 @@ -import mergeMiddleware from 'json-rpc-engine/src/mergeMiddleware' -import createScaffoldMiddleware from 'json-rpc-engine/src/createScaffoldMiddleware' +import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine' import createBlockReRefMiddleware from 'eth-json-rpc-middleware/block-ref' import createRetryOnEmptyMiddleware from 'eth-json-rpc-middleware/retryOnEmpty' import createBlockCacheMiddleware from 'eth-json-rpc-middleware/block-cache' diff --git a/app/scripts/controllers/network/createJsonRpcClient.js b/app/scripts/controllers/network/createJsonRpcClient.js index b3c9cb062..cc8e9edc5 100644 --- a/app/scripts/controllers/network/createJsonRpcClient.js +++ b/app/scripts/controllers/network/createJsonRpcClient.js @@ -1,5 +1,4 @@ -import createAsyncMiddleware from 'json-rpc-engine/src/createAsyncMiddleware' -import mergeMiddleware from 'json-rpc-engine/src/mergeMiddleware' +import { createAsyncMiddleware, mergeMiddleware } from 'json-rpc-engine' import createFetchMiddleware from 'eth-json-rpc-middleware/fetch' import createBlockRefRewriteMiddleware from 'eth-json-rpc-middleware/block-ref-rewrite' import createBlockCacheMiddleware from 'eth-json-rpc-middleware/block-cache' diff --git a/app/scripts/controllers/network/createMetamaskMiddleware.js b/app/scripts/controllers/network/createMetamaskMiddleware.js index 1d1291eea..f4e9c5d1a 100644 --- a/app/scripts/controllers/network/createMetamaskMiddleware.js +++ b/app/scripts/controllers/network/createMetamaskMiddleware.js @@ -1,5 +1,4 @@ -import mergeMiddleware from 'json-rpc-engine/src/mergeMiddleware' -import createScaffoldMiddleware from 'json-rpc-engine/src/createScaffoldMiddleware' +import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine' import createWalletSubprovider from 'eth-json-rpc-middleware/wallet' import { createPendingNonceMiddleware, diff --git a/app/scripts/controllers/network/middleware/pending.js b/app/scripts/controllers/network/middleware/pending.js index fe243ec28..905e44129 100644 --- a/app/scripts/controllers/network/middleware/pending.js +++ b/app/scripts/controllers/network/middleware/pending.js @@ -1,4 +1,4 @@ -import createAsyncMiddleware from 'json-rpc-engine/src/createAsyncMiddleware' +import { createAsyncMiddleware } from 'json-rpc-engine' import { formatTxMetaForRpcResult } from '../util' export function createPendingNonceMiddleware({ getPendingNonce }) { diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index 5527d8628..016331bce 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -2,7 +2,7 @@ import assert from 'assert' import EventEmitter from 'events' import ObservableStore from 'obs-store' import ComposedStore from 'obs-store/lib/composed' -import JsonRpcEngine from 'json-rpc-engine' +import { JsonRpcEngine } from 'json-rpc-engine' import providerFromEngine from 'eth-json-rpc-middleware/providerFromEngine' import log from 'loglevel' import { @@ -195,6 +195,11 @@ export default class NetworkController extends EventEmitter { return this.providerStore.getState() } + getNetworkIdentifier() { + const provider = this.providerStore.getState() + return provider.type === 'rpc' ? provider.rpcUrl : provider.type + } + // // Private // diff --git a/app/scripts/controllers/permissions/index.js b/app/scripts/controllers/permissions/index.js index dac4eef94..2e3c12775 100644 --- a/app/scripts/controllers/permissions/index.js +++ b/app/scripts/controllers/permissions/index.js @@ -1,6 +1,5 @@ import nanoid from 'nanoid' -import JsonRpcEngine from 'json-rpc-engine' -import asMiddleware from 'json-rpc-engine/src/asMiddleware' +import { JsonRpcEngine } from 'json-rpc-engine' import ObservableStore from 'obs-store' import log from 'loglevel' import { CapabilitiesController as RpcCap } from 'rpc-cap' @@ -109,7 +108,7 @@ export class PermissionsController { }), ) - return asMiddleware(engine) + return engine.asMiddleware() } /** diff --git a/app/scripts/controllers/permissions/permissionsMethodMiddleware.js b/app/scripts/controllers/permissions/permissionsMethodMiddleware.js index eae072495..f2eec6cf4 100644 --- a/app/scripts/controllers/permissions/permissionsMethodMiddleware.js +++ b/app/scripts/controllers/permissions/permissionsMethodMiddleware.js @@ -1,4 +1,4 @@ -import createAsyncMiddleware from 'json-rpc-engine/src/createAsyncMiddleware' +import { createAsyncMiddleware } from 'json-rpc-engine' import { ethErrors } from 'eth-json-rpc-errors' /** diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 5e376a797..bfba2835b 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -1,12 +1,12 @@ import { strict as assert } from 'assert' import ObservableStore from 'obs-store' +import { ethErrors } from 'eth-json-rpc-errors' import { normalize as normalizeAddress } from 'eth-sig-util' -import { isValidAddress, sha3, bufferToHex } from 'ethereumjs-util' +import { isValidAddress } from 'ethereumjs-util' import ethers from 'ethers' import log from 'loglevel' import { isPrefixedFormattedHexString } from '../lib/util' import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens' -import { addInternalMethodPrefix } from './permissions' import { NETWORK_TYPE_TO_ID_MAP } from './network/enums' export default class PreferencesController { @@ -47,10 +47,8 @@ export default class PreferencesController { // perform sensitive operations. featureFlags: { showIncomingTransactions: true, - transactionTime: false, }, knownMethodData: {}, - participateInMetaMetrics: null, firstTimeFlowType: null, currentLocale: opts.initLangCode, identities: {}, @@ -62,9 +60,6 @@ export default class PreferencesController { useNativeCurrencyAsPrimaryCurrency: true, }, completedOnboarding: false, - metaMetricsId: null, - metaMetricsSendCount: 0, - // ENS decentralized website resolution ipfsGateway: 'dweb.link', ...opts.initState, @@ -121,38 +116,6 @@ export default class PreferencesController { this.store.updateState({ usePhishDetect: val }) } - /** - * Setter for the `participateInMetaMetrics` property - * - * @param {boolean} bool - Whether or not the user wants to participate in MetaMetrics - * @returns {string|null} the string of the new metametrics id, or null if not set - * - */ - setParticipateInMetaMetrics(bool) { - this.store.updateState({ participateInMetaMetrics: bool }) - let metaMetricsId = null - if (bool && !this.store.getState().metaMetricsId) { - metaMetricsId = bufferToHex( - sha3( - String(Date.now()) + - String(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)), - ), - ) - this.store.updateState({ metaMetricsId }) - } else if (bool === false) { - this.store.updateState({ metaMetricsId }) - } - return metaMetricsId - } - - getParticipateInMetaMetrics() { - return this.store.getState().participateInMetaMetrics - } - - setMetaMetricsSendCount(val) { - this.store.updateState({ metaMetricsSendCount: val }) - } - /** * Setter for the `firstTimeFlowType` property * @@ -171,22 +134,6 @@ export default class PreferencesController { return this.store.getState().assetImages } - addSuggestedERC20Asset(tokenOpts) { - this._validateERC20AssetParams(tokenOpts) - const suggested = this.getSuggestedTokens() - const { rawAddress, symbol, decimals, image } = tokenOpts - const address = normalizeAddress(rawAddress) - const newEntry = { - address, - symbol, - decimals, - image, - unlisted: !LISTED_CONTRACT_ADDRESSES.includes(address.toLowerCase()), - } - suggested[address] = newEntry - this.store.updateState({ suggestedTokens: suggested }) - } - /** * Add new methodData to state, to avoid requesting this information again through Infura * @@ -200,37 +147,21 @@ export default class PreferencesController { } /** - * RPC engine middleware for requesting new asset added + * wallet_watchAsset request handler. * - * @param {any} req - * @param {any} res - * @param {Function} next - * @param {Function} end + * @param {Object} req - The watchAsset JSON-RPC request object. */ - async requestWatchAsset(req, res, next, end) { - if ( - req.method === 'metamask_watchAsset' || - req.method === addInternalMethodPrefix('watchAsset') - ) { - const { type, options } = req.params - switch (type) { - case 'ERC20': { - const result = await this._handleWatchAssetERC20(options) - if (result instanceof Error) { - end(result) - } else { - res.result = result - end() - } - return - } - default: - end(new Error(`Asset of type ${type} not supported`)) - return - } - } + async requestWatchAsset(req) { + const { type, options } = req.params - next() + switch (type) { + case 'ERC20': + return await this._handleWatchAssetERC20(options) + default: + throw ethErrors.rpc.invalidParams( + `Asset of type "${type}" not supported.`, + ) + } } /** @@ -775,21 +706,17 @@ export default class PreferencesController { * */ async _handleWatchAssetERC20(tokenMetadata) { - const { address, symbol, decimals, image } = tokenMetadata - const rawAddress = address - try { - this._validateERC20AssetParams({ rawAddress, symbol, decimals }) - } catch (err) { - return err - } - const tokenOpts = { rawAddress, decimals, symbol, image } - this.addSuggestedERC20Asset(tokenOpts) - return this.openPopup().then(() => { - const tokenAddresses = this.getTokens().filter( - (token) => token.address === normalizeAddress(rawAddress), - ) - return tokenAddresses.length > 0 - }) + this._validateERC20AssetParams(tokenMetadata) + + const address = normalizeAddress(tokenMetadata.address) + const { symbol, decimals, image } = tokenMetadata + this._addSuggestedERC20Asset(address, symbol, decimals, image) + + await this.openPopup() + const tokenAddresses = this.getTokens().filter( + (token) => token.address === address, + ) + return tokenAddresses.length > 0 } /** @@ -800,24 +727,41 @@ export default class PreferencesController { * doesn't fulfill requirements * */ - _validateERC20AssetParams(opts) { - const { rawAddress, symbol, decimals } = opts - if (!rawAddress || !symbol || typeof decimals === 'undefined') { - throw new Error( - `Cannot suggest token without address, symbol, and decimals`, + _validateERC20AssetParams({ address, symbol, decimals }) { + if (!address || !symbol || typeof decimals === 'undefined') { + throw ethErrors.rpc.invalidParams( + `Must specify address, symbol, and decimals.`, ) } + if (typeof symbol !== 'string') { + throw ethErrors.rpc.invalidParams(`Invalid symbol: not a string.`) + } if (!(symbol.length < 7)) { - throw new Error(`Invalid symbol ${symbol} more than six characters`) + throw ethErrors.rpc.invalidParams( + `Invalid symbol "${symbol}": longer than 6 characters.`, + ) } const numDecimals = parseInt(decimals, 10) if (isNaN(numDecimals) || numDecimals > 36 || numDecimals < 0) { - throw new Error( - `Invalid decimals ${decimals} must be at least 0, and not over 36`, + throw ethErrors.rpc.invalidParams( + `Invalid decimals "${decimals}": must be 0 <= 36.`, ) } - if (!isValidAddress(rawAddress)) { - throw new Error(`Invalid address ${rawAddress}`) + if (!isValidAddress(address)) { + throw ethErrors.rpc.invalidParams(`Invalid address "${address}".`) } } + + _addSuggestedERC20Asset(address, symbol, decimals, image) { + const newEntry = { + address, + symbol, + decimals, + image, + unlisted: !LISTED_CONTRACT_ADDRESSES.includes(address), + } + const suggested = this.getSuggestedTokens() + suggested[address] = newEntry + this.store.updateState({ suggestedTokens: suggested }) + } } diff --git a/app/scripts/controllers/threebox.js b/app/scripts/controllers/threebox.js index 2459d79e2..ec73e2651 100644 --- a/app/scripts/controllers/threebox.js +++ b/app/scripts/controllers/threebox.js @@ -7,7 +7,7 @@ const Box = process.env.IN_TEST /* eslint-enable import/order */ import log from 'loglevel' -import JsonRpcEngine from 'json-rpc-engine' +import { JsonRpcEngine } from 'json-rpc-engine' import providerFromEngine from 'eth-json-rpc-middleware/providerFromEngine' import Migrator from '../lib/migrator' import migrations from '../migrations' diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index c905c3e1c..0c6f3c6ac 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -929,15 +929,8 @@ export default class TransactionController extends EventEmitter { if (txMeta.txReceipt.status === '0x0') { this._trackMetaMetricsEvent({ event: 'Swap Failed', + sensitiveProperties: { ...txMeta.swapMetaData }, category: 'swaps', - excludeMetaMetricsId: false, - }) - - this._trackMetaMetricsEvent({ - event: 'Swap Failed', - properties: { ...txMeta.swapMetaData }, - category: 'swaps', - excludeMetaMetricsId: true, }) } else { const tokensReceived = getSwapsTokensReceivedFromTxMeta( @@ -965,19 +958,12 @@ export default class TransactionController extends EventEmitter { this._trackMetaMetricsEvent({ event: 'Swap Completed', category: 'swaps', - excludeMetaMetricsId: false, - }) - - this._trackMetaMetricsEvent({ - event: 'Swap Completed', - category: 'swaps', - properties: { + sensitiveProperties: { ...txMeta.swapMetaData, token_to_amount_received: tokensReceived, quote_vs_executionRatio: quoteVsExecutionRatio, estimated_vs_used_gasRatio: estimatedVsUsedGasRatio, }, - excludeMetaMetricsId: true, }) } } diff --git a/app/scripts/controllers/transactions/tx-gas-utils.js b/app/scripts/controllers/transactions/tx-gas-utils.js index 71d8d27fb..cf75d8919 100644 --- a/app/scripts/controllers/transactions/tx-gas-utils.js +++ b/app/scripts/controllers/transactions/tx-gas-utils.js @@ -1,6 +1,7 @@ import EthQuery from 'ethjs-query' import log from 'loglevel' import ethUtil from 'ethereumjs-util' +import { cloneDeep } from 'lodash' import { hexToBn, BnMultiplyByFraction, bnToHex } from '../../lib/util' /** @@ -56,7 +57,13 @@ export default class TxGasUtil { @returns {string} the estimated gas limit as a hex string */ async estimateTxGas(txMeta) { - const { txParams } = txMeta + const txParams = cloneDeep(txMeta.txParams) + + // `eth_estimateGas` can fail if the user has insufficient balance for the + // value being sent, or for the gas cost. We don't want to check their + // balance here, we just want the gas estimate. The gas price is removed + // to skip those balance checks. We check balance elsewhere. + delete txParams.gasPrice // estimate tx gas requirements return await this.query.estimateGas(txParams) diff --git a/app/scripts/initSentry.js b/app/scripts/initSentry.js new file mode 100644 index 000000000..70ea7b936 --- /dev/null +++ b/app/scripts/initSentry.js @@ -0,0 +1,7 @@ +import setupSentry from './lib/setupSentry' + +// setup sentry error reporting +global.sentry = setupSentry({ + release: process.env.METAMASK_VERSION, + getState: () => global.getSentryState?.() || {}, +}) diff --git a/app/scripts/lib/enums.js b/app/scripts/lib/enums.js index 543e8db36..d93030f2c 100644 --- a/app/scripts/lib/enums.js +++ b/app/scripts/lib/enums.js @@ -25,6 +25,8 @@ const MESSAGE_TYPE = { ETH_SIGN_TYPED_DATA: 'eth_signTypedData', LOG_WEB3_USAGE: 'metamask_logInjectedWeb3Usage', PERSONAL_SIGN: 'personal_sign', + WATCH_ASSET: 'wallet_watchAsset', + WATCH_ASSET_LEGACY: 'metamask_watchAsset', } export { diff --git a/app/scripts/lib/freezeGlobals.js b/app/scripts/lib/freezeGlobals.js deleted file mode 100644 index 08b201bee..000000000 --- a/app/scripts/lib/freezeGlobals.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Freezes the Promise global and prevents its reassignment. - */ -import deepFreeze from 'deep-freeze-strict' - -if (process.env.IN_TEST !== 'true' && process.env.METAMASK_ENV !== 'test') { - freeze(global, 'Promise') -} - -/** - * Makes a key:value pair on a target object immutable, with limitations. - * The key cannot be reassigned or deleted, and the value is recursively frozen - * using Object.freeze. - * - * Because of JavaScript language limitations, this is does not mean that the - * value is completely immutable. It is, however, better than nothing. - * - * @param {Object} target - The target object to freeze a property on. - * @param {string} key - The key to freeze. - * @param {any} [value] - The value to freeze, if different from the existing value on the target. - * @param {boolean} [enumerable=true] - If given a value, whether the property is enumerable. - */ -function freeze(target, key, value, enumerable = true) { - const opts = { - configurable: false, - writable: false, - } - - if (value === undefined) { - target[key] = deepFreeze(target[key]) - } else { - opts.value = deepFreeze(value) - opts.enumerable = enumerable - } - - Object.defineProperty(target, key, opts) -} diff --git a/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js b/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js index fff0afb16..b87047cd2 100644 --- a/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js +++ b/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js @@ -1,7 +1,9 @@ import handlers from './handlers' const handlerMap = handlers.reduce((map, handler) => { - map.set(handler.methodName, handler.implementation) + for (const methodName of handler.methodNames) { + map.set(methodName, handler.implementation) + } return map }, new Map()) diff --git a/app/scripts/lib/rpc-method-middleware/handlers/index.js b/app/scripts/lib/rpc-method-middleware/handlers/index.js index bc87cb309..74e26b675 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/index.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/index.js @@ -1,4 +1,5 @@ import logWeb3Usage from './log-web3-usage' +import watchAsset from './watch-asset' -const handlers = [logWeb3Usage] +const handlers = [logWeb3Usage, watchAsset] export default handlers diff --git a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js index 290c52b94..c80303223 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js @@ -8,7 +8,7 @@ import { MESSAGE_TYPE } from '../../enums' */ const logWeb3Usage = { - methodName: MESSAGE_TYPE.LOG_WEB3_USAGE, + methodNames: [MESSAGE_TYPE.LOG_WEB3_USAGE], implementation: logWeb3UsageHandler, } export default logWeb3Usage @@ -43,17 +43,19 @@ function logWeb3UsageHandler(req, res, _next, end, { origin, sendMetrics }) { if (!recordedWeb3Usage[origin][path]) { recordedWeb3Usage[origin][path] = true - sendMetrics({ - event: `Website Used window.web3`, - category: 'inpage_provider', - properties: { action, web3Path: path }, - eventContext: { + sendMetrics( + { + event: `Website Used window.web3`, + category: 'inpage_provider', + properties: { action, web3Path: path }, referrer: { url: origin, }, }, - excludeMetaMetricsId: true, - }) + { + excludeMetaMetricsId: true, + }, + ) } res.result = true diff --git a/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js new file mode 100644 index 000000000..1c5f4c1db --- /dev/null +++ b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js @@ -0,0 +1,40 @@ +import { MESSAGE_TYPE } from '../../enums' + +const watchAsset = { + methodNames: [MESSAGE_TYPE.WATCH_ASSET, MESSAGE_TYPE.WATCH_ASSET_LEGACY], + implementation: watchAssetHandler, +} +export default watchAsset + +/** + * @typedef {Object} WatchAssetOptions + * @property {Function} handleWatchAssetRequest - The wallet_watchAsset method implementation. + */ + +/** + * @typedef {Object} WatchAssetParam + * @property {string} type - The type of the asset to watch. + * @property {Object} options - Watch options for the asset. + */ + +/** + * @param {import('json-rpc-engine').JsonRpcRequest} req - The JSON-RPC request object. + * @param {import('json-rpc-engine').JsonRpcResponse} res - The JSON-RPC response object. + * @param {Function} _next - The json-rpc-engine 'next' callback. + * @param {Function} end - The json-rpc-engine 'end' callback. + * @param {WatchAssetOptions} options + */ +async function watchAssetHandler( + req, + res, + _next, + end, + { handleWatchAssetRequest }, +) { + try { + res.result = await handleWatchAssetRequest(req) + return end() + } catch (error) { + return end(error) + } +} diff --git a/app/scripts/lib/segment.js b/app/scripts/lib/segment.js new file mode 100644 index 000000000..e5b67ab18 --- /dev/null +++ b/app/scripts/lib/segment.js @@ -0,0 +1,101 @@ +import Analytics from 'analytics-node' + +const isDevOrTestEnvironment = Boolean( + process.env.METAMASK_DEBUG || process.env.IN_TEST, +) +const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null +const SEGMENT_LEGACY_WRITE_KEY = process.env.SEGMENT_LEGACY_WRITE_KEY ?? null +const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null + +// flushAt controls how many events are sent to segment at once. Segment will +// hold onto a queue of events until it hits this number, then it sends them as +// a batch. This setting defaults to 20, but in development we likely want to +// see events in real time for debugging, so this is set to 1 to disable the +// queueing mechanism. +const SEGMENT_FLUSH_AT = + process.env.METAMASK_ENVIRONMENT === 'production' ? undefined : 1 + +// flushInterval controls how frequently the queue is flushed to segment. +// This happens regardless of the size of the queue. The default setting is +// 10,000ms (10 seconds). This default is rather high, though thankfully +// using the background process as our event handler means we don't have to +// deal with short lived sessions that happen faster than the interval +// e.g confirmations. This is set to 5,000ms (5 seconds) arbitrarily with the +// intent of having a value less than 10 seconds. +const SEGMENT_FLUSH_INTERVAL = 5000 + +/** + * Creates a mock segment module for usage in test environments. This is used + * when building the application in test mode to catch event calls and prevent + * them from being sent to segment. It is also used in unit tests to mock and + * spy on the methods to ensure proper behavior + * @param {number} flushAt - number of events to queue before sending to segment + * @param {number} flushInterval - ms interval to flush queue and send to segment + * @returns {SegmentInterface} + */ +export const createSegmentMock = ( + flushAt = SEGMENT_FLUSH_AT, + flushInterval = SEGMENT_FLUSH_INTERVAL, +) => { + const segmentMock = { + // Internal queue to keep track of events and properly mimic segment's + // queueing behavior. + queue: [], + + /** + * Used to immediately send all queued events and reset the queue to zero. + * For our purposes this simply triggers the callback method registered with + * the event. + */ + flush() { + segmentMock.queue.forEach(([_, callback]) => { + callback() + }) + segmentMock.queue = [] + }, + + /** + * Track an event and add it to the queue. If the queue size reaches the + * flushAt threshold, flush the queue. + */ + track(payload, callback = () => undefined) { + segmentMock.queue.push([payload, callback]) + + if (segmentMock.queue.length >= flushAt) { + segmentMock.flush() + } + }, + + /** + * A true NOOP, these methods are either not used or do not await callback + * and therefore require no functionality. + */ + page() { + // noop + }, + identify() { + // noop + }, + } + // Mimic the flushInterval behavior with an interval + setInterval(segmentMock.flush, flushInterval) + return segmentMock +} + +export const segment = + !SEGMENT_WRITE_KEY || (isDevOrTestEnvironment && !SEGMENT_HOST) + ? createSegmentMock(SEGMENT_FLUSH_AT, SEGMENT_FLUSH_INTERVAL) + : new Analytics(SEGMENT_WRITE_KEY, { + host: SEGMENT_HOST, + flushAt: SEGMENT_FLUSH_AT, + flushInterval: SEGMENT_FLUSH_INTERVAL, + }) + +export const segmentLegacy = + !SEGMENT_LEGACY_WRITE_KEY || (isDevOrTestEnvironment && !SEGMENT_HOST) + ? createSegmentMock(SEGMENT_FLUSH_AT, SEGMENT_FLUSH_INTERVAL) + : new Analytics(SEGMENT_LEGACY_WRITE_KEY, { + host: SEGMENT_HOST, + flushAt: SEGMENT_FLUSH_AT, + flushInterval: SEGMENT_FLUSH_INTERVAL, + }) diff --git a/app/scripts/lib/setupWeb3.js b/app/scripts/lib/setupWeb3.js index 8f196a94e..9dc74ddb2 100644 --- a/app/scripts/lib/setupWeb3.js +++ b/app/scripts/lib/setupWeb3.js @@ -27,7 +27,12 @@ export default function setupWeb3(log) { web3.setProvider = function () { log.debug('MetaMask - overrode web3.setProvider') } - log.debug('MetaMask - injected web3') + Object.defineProperty(web3, '__isMetaMaskShim__', { + value: true, + enumerable: false, + configurable: false, + writable: false, + }) Object.defineProperty(window.ethereum, '_web3Ref', { enumerable: false, @@ -180,12 +185,13 @@ export default function setupWeb3(log) { }, }) - Object.defineProperty(global, 'web3', { + Object.defineProperty(window, 'web3', { enumerable: false, writable: true, configurable: true, value: web3Proxy, }) + log.debug('MetaMask - injected web3') window.ethereum._publicConfigStore.subscribe((state) => { // if the auto refresh on network change is false do not @@ -231,7 +237,7 @@ export default function setupWeb3(log) { // reload the page function triggerReset() { - global.location.reload() + window.location.reload() } /** diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index e6678054d..a7517c5db 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -4,7 +4,7 @@ import pump from 'pump' import Dnode from 'dnode' import ObservableStore from 'obs-store' import asStream from 'obs-store/lib/asStream' -import RpcEngine from 'json-rpc-engine' +import { JsonRpcEngine } from 'json-rpc-engine' import { debounce } from 'lodash' import createEngineStream from 'json-rpc-middleware-stream/engineStream' import createFilterMiddleware from 'eth-json-rpc-filters' @@ -18,13 +18,12 @@ import TrezorKeyring from 'eth-trezor-keyring' import LedgerBridgeKeyring from '@metamask/eth-ledger-bridge-keyring' import EthQuery from 'eth-query' import nanoid from 'nanoid' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { AddressBookController, CurrencyRateController, PhishingController, } from '@metamask/controllers' -import { getTrackMetaMetricsEvent } from '../../shared/modules/metametrics' import { getBackgroundMetaMetricState } from '../../ui/app/selectors' import { TRANSACTION_STATUSES } from '../../shared/constants/transaction' import ComposableObservableStore from './lib/ComposableObservableStore' @@ -58,7 +57,8 @@ import getRestrictedMethods from './controllers/permissions/restrictedMethods' import nodeify from './lib/nodeify' import accountImporter from './account-import-strategies' import seedPhraseVerifier from './lib/seed-phrase-verifier' -import { ENVIRONMENT_TYPE_BACKGROUND } from './lib/enums' +import MetaMetricsController from './controllers/metametrics' +import { segment, segmentLegacy } from './lib/segment' export default class MetamaskController extends EventEmitter { /** @@ -115,35 +115,24 @@ export default class MetamaskController extends EventEmitter { migrateAddressBookState: this.migrateAddressBookState.bind(this), }) - this.trackMetaMetricsEvent = getTrackMetaMetricsEvent( - this.platform.getVersion(), - () => { - const participateInMetaMetrics = this.preferencesController.getParticipateInMetaMetrics() - const { - currentLocale, - metaMetricsId, - } = this.preferencesController.store.getState() - const chainId = this.networkController.getCurrentChainId() - const provider = this.networkController.getProviderConfig() - const network = - provider.type === 'rpc' ? provider.rpcUrl : provider.type - return { - participateInMetaMetrics, - metaMetricsId, - environmentType: ENVIRONMENT_TYPE_BACKGROUND, - chainId, - network, - context: { - page: { - path: '/background-process', - title: 'Background Process', - url: '/background-process', - }, - locale: currentLocale.replace('_', '-'), - }, - } - }, - ) + this.metaMetricsController = new MetaMetricsController({ + segment, + segmentLegacy, + preferencesStore: this.preferencesController.store, + onNetworkDidChange: this.networkController.on.bind( + this.networkController, + 'networkDidChange', + ), + getNetworkIdentifier: this.networkController.getNetworkIdentifier.bind( + this.networkController, + ), + getCurrentChainId: this.networkController.getCurrentChainId.bind( + this.networkController, + ), + version: this.platform.getVersion(), + environment: process.env.METAMASK_ENVIRONMENT, + initState: initState.MetaMetricsController, + }) this.appStateController = new AppStateController({ addUnlockListener: this.on.bind(this, 'unlock'), @@ -298,9 +287,9 @@ export default class MetamaskController extends EventEmitter { ), provider: this.provider, blockTracker: this.blockTracker, - trackMetaMetricsEvent: this.trackMetaMetricsEvent, + trackMetaMetricsEvent: this.metaMetricsController.trackEvent, getParticipateInMetrics: () => - this.preferencesController.getParticipateInMetaMetrics(), + this.metaMetricsController.state.participateInMetaMetrics, }) this.txController.on('newUnapprovedTx', () => opts.showUserConfirmation()) @@ -362,6 +351,7 @@ export default class MetamaskController extends EventEmitter { TransactionController: this.txController.store, KeyringController: this.keyringController.store, PreferencesController: this.preferencesController.store, + MetaMetricsController: this.metaMetricsController.store, AddressBookController: this.addressBookController, CurrencyController: this.currencyRateController, NetworkController: this.networkController.store, @@ -388,6 +378,7 @@ export default class MetamaskController extends EventEmitter { TypesMessageManager: this.typedMessageManager.memStore, KeyringController: this.keyringController.memStore, PreferencesController: this.preferencesController.store, + MetaMetricsController: this.metaMetricsController.store, AddressBookController: this.addressBookController, CurrencyController: this.currencyRateController, AlertController: this.alertController.store, @@ -528,6 +519,7 @@ export default class MetamaskController extends EventEmitter { threeBoxController, txController, swapsController, + metaMetricsController, } = this return { @@ -825,6 +817,16 @@ export default class MetamaskController extends EventEmitter { swapsController.setSwapsLiveness, swapsController, ), + + // MetaMetrics + trackMetaMetricsEvent: nodeify( + metaMetricsController.trackEvent, + metaMetricsController, + ), + trackMetaMetricsPage: nodeify( + metaMetricsController.trackPage, + metaMetricsController, + ), } } @@ -1935,7 +1937,7 @@ export default class MetamaskController extends EventEmitter { isInternal = false, }) { // setup json rpc engine stack - const engine = new RpcEngine() + const engine = new JsonRpcEngine() const { provider, blockTracker } = this // create filter polyfill middleware @@ -1967,7 +1969,10 @@ export default class MetamaskController extends EventEmitter { engine.push( createMethodMiddleware({ origin, - sendMetrics: this.trackMetaMetricsEvent, + sendMetrics: this.metaMetricsController.trackEvent, + handleWatchAssetRequest: this.preferencesController.requestWatchAsset.bind( + this.preferencesController, + ), }), ) // filter and subscription polyfills @@ -1979,12 +1984,6 @@ export default class MetamaskController extends EventEmitter { this.permissionsController.createMiddleware({ origin, extensionId }), ) } - // watch asset - engine.push( - this.preferencesController.requestWatchAsset.bind( - this.preferencesController, - ), - ) // forward to metamask primary provider engine.push(providerAsMiddleware(provider)) return engine @@ -2180,16 +2179,20 @@ export default class MetamaskController extends EventEmitter { metamask: metamaskState, }) - this.trackMetaMetricsEvent({ - event: name, - category: 'Background', - matomoEvent: true, - properties: { - action, - ...additionalProperties, - ...customVariables, + this.metaMetricsController.trackEvent( + { + event: name, + category: 'Background', + properties: { + action, + ...additionalProperties, + ...customVariables, + }, }, - }) + { + matomoEvent: true, + }, + ) } /** @@ -2424,7 +2427,7 @@ export default class MetamaskController extends EventEmitter { */ setParticipateInMetaMetrics(bool, cb) { try { - const metaMetricsId = this.preferencesController.setParticipateInMetaMetrics( + const metaMetricsId = this.metaMetricsController.setParticipateInMetaMetrics( bool, ) cb(null, metaMetricsId) @@ -2438,7 +2441,7 @@ export default class MetamaskController extends EventEmitter { setMetaMetricsSendCount(val, cb) { try { - this.preferencesController.setMetaMetricsSendCount(val) + this.metaMetricsController.setMetaMetricsSendCount(val) cb(null) return } catch (err) { diff --git a/app/scripts/migrations/049.js b/app/scripts/migrations/049.js new file mode 100644 index 000000000..6a9b6ea43 --- /dev/null +++ b/app/scripts/migrations/049.js @@ -0,0 +1,44 @@ +import { cloneDeep } from 'lodash' + +const version = 49 + +/** + * Migrate metaMetrics state to the new MetaMetrics controller + */ +export default { + version, + async migrate(originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData) + versionedData.meta.version = version + const state = versionedData.data + versionedData.data = transformState(state) + return versionedData + }, +} + +function transformState(state = {}) { + if (state.PreferencesController) { + const { + metaMetricsId, + participateInMetaMetrics, + metaMetricsSendCount, + } = state.PreferencesController + state.MetaMetricsController = state.MetaMetricsController ?? {} + + if (metaMetricsId !== undefined) { + state.MetaMetricsController.metaMetricsId = metaMetricsId + delete state.PreferencesController.metaMetricsId + } + + if (participateInMetaMetrics !== undefined) { + state.MetaMetricsController.participateInMetaMetrics = participateInMetaMetrics + delete state.PreferencesController.participateInMetaMetrics + } + + if (metaMetricsSendCount !== undefined) { + state.MetaMetricsController.metaMetricsSendCount = metaMetricsSendCount + delete state.PreferencesController.metaMetricsSendCount + } + } + return state +} diff --git a/app/scripts/migrations/050.js b/app/scripts/migrations/050.js new file mode 100644 index 000000000..af2873873 --- /dev/null +++ b/app/scripts/migrations/050.js @@ -0,0 +1,32 @@ +import { cloneDeep } from 'lodash' + +const version = 50 + +const LEGACY_LOCAL_STORAGE_KEYS = [ + 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', + 'METASWAP_GAS_PRICE_ESTIMATES', + 'cachedFetch', + 'BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', + 'BASIC_PRICE_ESTIMATES', + 'BASIC_GAS_AND_TIME_API_ESTIMATES', + 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', + 'GAS_API_ESTIMATES_LAST_RETRIEVED', + 'GAS_API_ESTIMATES', +] + +/** + * Migrate metaMetrics state to the new MetaMetrics controller + */ +export default { + version, + async migrate(originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData) + versionedData.meta.version = version + + LEGACY_LOCAL_STORAGE_KEYS.forEach((key) => + window.localStorage.removeItem(key), + ) + + return versionedData + }, +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index b10848db1..32424673e 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -53,6 +53,8 @@ const migrations = [ require('./046').default, require('./047').default, require('./048').default, + require('./049').default, + require('./050').default, ] export default migrations diff --git a/app/scripts/runLockdown.js b/app/scripts/runLockdown.js new file mode 100644 index 000000000..00bc7658f --- /dev/null +++ b/app/scripts/runLockdown.js @@ -0,0 +1,7 @@ +// Freezes all intrinsics +// eslint-disable-next-line no-undef,import/unambiguous +lockdown({ + errorTaming: 'unsafe', + mathTaming: 'unsafe', + dateTaming: 'unsafe', +}) diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 5b5932a50..f1f4a7b78 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -1,13 +1,9 @@ -// this must run before anything else -import './lib/freezeGlobals' - // polyfills import 'abortcontroller-polyfill/dist/polyfill-patch-fetch' import '@formatjs/intl-relativetimeformat/polyfill' import { EventEmitter } from 'events' import PortStream from 'extension-port-stream' - import extension from 'extensionizer' import Dnode from 'dnode' @@ -16,9 +12,8 @@ import EthQuery from 'eth-query' import StreamProvider from 'web3-stream-provider' import log from 'loglevel' import launchMetaMaskUi from '../../ui' -import { setupMultiplex } from './lib/stream-utils' -import setupSentry from './lib/setupSentry' import ExtensionPlatform from './platforms/extension' +import { setupMultiplex } from './lib/stream-utils' import { ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_POPUP, @@ -31,13 +26,6 @@ async function start() { // create platform global global.platform = new ExtensionPlatform() - // setup sentry error reporting - const release = global.platform.getVersion() - setupSentry({ - release, - getState: () => window.getSentryState?.() || {}, - }) - // identify window type (popup, notification) const windowType = getEnvironmentType() diff --git a/development/build/index.js b/development/build/index.js index cc75d8398..facf87b61 100755 --- a/development/build/index.js +++ b/development/build/index.js @@ -3,11 +3,6 @@ // // run any task with "yarn build ${taskName}" // -global.globalThis = global // eslint-disable-line node/no-unsupported-features/es-builtins -require('lavamoat-core/lib/ses.umd.js') - -lockdown() // eslint-disable-line no-undef - const livereload = require('gulp-livereload') const { createTask, diff --git a/development/build/scripts.js b/development/build/scripts.js index cf19060c6..2f6b577e4 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -1,18 +1,18 @@ const fs = require('fs') const gulp = require('gulp') const watch = require('gulp-watch') +const pify = require('pify') +const pump = pify(require('pump')) const source = require('vinyl-source-stream') const buffer = require('vinyl-buffer') const log = require('fancy-log') const { assign } = require('lodash') const watchify = require('watchify') const browserify = require('browserify') -const envify = require('envify/custom') +const envify = require('loose-envify/custom') const sourcemaps = require('gulp-sourcemaps') const sesify = require('sesify') const terser = require('gulp-terser-js') -const pify = require('pify') -const endOfStream = pify(require('end-of-stream')) const { makeStringTransform } = require('browserify-transform-tools') const conf = require('rc')('metamask', { @@ -22,6 +22,8 @@ const conf = require('rc')('metamask', { SEGMENT_LEGACY_WRITE_KEY: process.env.SEGMENT_LEGACY_WRITE_KEY, }) +const baseManifest = require('../../app/manifest/_base.json') + const packageJSON = require('../../package.json') const { createTask, @@ -37,11 +39,10 @@ const dependencies = Object.keys( ) const materialUIDependencies = ['@material-ui/core'] const reactDepenendencies = dependencies.filter((dep) => dep.match(/react/u)) -const d3Dependencies = ['c3', 'd3'] const externalDependenciesMap = { background: ['3box'], - ui: [...materialUIDependencies, ...reactDepenendencies, ...d3Dependencies], + ui: [...materialUIDependencies, ...reactDepenendencies], } function createScriptTasks({ browserPlatforms, livereload }) { @@ -97,7 +98,12 @@ function createScriptTasks({ browserPlatforms, livereload }) { } function createTasksForBuildJsExtension({ taskPrefix, devMode, testing }) { - const standardBundles = ['background', 'ui', 'phishing-detect'] + const standardBundles = [ + 'background', + 'ui', + 'phishing-detect', + 'initSentry', + ] const standardSubtasks = standardBundles.map((filename) => { return createTask( @@ -200,33 +206,19 @@ function createScriptTasks({ browserPlatforms, livereload }) { bundler.on('log', log) } - let buildStream = bundler.bundle() - - // handle errors - buildStream.on('error', (err) => { - beep() - if (opts.devMode) { - console.warn(err.stack) - } else { - throw err - } - }) - - // process bundles - buildStream = buildStream + const buildPipeline = [ + bundler.bundle(), // convert bundle stream to gulp vinyl stream - .pipe(source(opts.filename)) - // buffer file contents (?) - .pipe(buffer()) - - // Initialize Source Maps - buildStream = buildStream + source(opts.filename), + // Initialize Source Maps + buffer(), // loads map from browserify file - .pipe(sourcemaps.init({ loadMaps: true })) + sourcemaps.init({ loadMaps: true }), + ] // Minification if (!opts.devMode) { - buildStream = buildStream.pipe( + buildPipeline.push( terser({ mangle: { reserved: ['MetamaskInpageProvider'], @@ -242,18 +234,28 @@ function createScriptTasks({ browserPlatforms, livereload }) { if (opts.devMode) { // Use inline source maps for development due to Chrome DevTools bug // https://bugs.chromium.org/p/chromium/issues/detail?id=931675 - buildStream = buildStream.pipe(sourcemaps.write()) + // note: sourcemaps call arity is important + buildPipeline.push(sourcemaps.write()) } else { - buildStream = buildStream.pipe(sourcemaps.write('../sourcemaps')) + buildPipeline.push(sourcemaps.write('../sourcemaps')) } // write completed bundles browserPlatforms.forEach((platform) => { const dest = `./dist/${platform}` - buildStream = buildStream.pipe(gulp.dest(dest)) + buildPipeline.push(gulp.dest(dest)) }) - await endOfStream(buildStream) + // process bundles + if (opts.devMode) { + try { + await pump(buildPipeline) + } catch (err) { + gracefulError(err) + } + } else { + await pump(buildPipeline) + } } } @@ -331,14 +333,6 @@ function createScriptTasks({ browserPlatforms, livereload }) { let bundler = browserify(browserifyOpts) .transform('babelify') - // Transpile any dependencies using the object spread/rest operator - // because it is incompatible with `esprima`, which is used by `envify` - // See https://github.com/jquery/esprima/issues/1927 - .transform('babelify', { - only: ['./**/node_modules/libp2p'], - global: true, - plugins: ['@babel/plugin-proposal-object-rest-spread'], - }) .transform('brfs') if (opts.buildLib) { @@ -362,6 +356,7 @@ function createScriptTasks({ browserPlatforms, livereload }) { envify({ METAMASK_DEBUG: opts.devMode, METAMASK_ENVIRONMENT: environment, + METAMASK_VERSION: baseManifest.version, METAMETRICS_PROJECT_ID: process.env.METAMETRICS_PROJECT_ID, NODE_ENV: opts.devMode ? 'development' : 'production', IN_TEST: opts.testing ? 'true' : false, @@ -406,10 +401,6 @@ function createScriptTasks({ browserPlatforms, livereload }) { } } -function beep() { - process.stdout.write('\x07') -} - function getEnvironment({ devMode, test }) { // get environment slug if (devMode) { @@ -429,3 +420,12 @@ function getEnvironment({ devMode, test }) { } return 'other' } + +function beep() { + process.stdout.write('\x07') +} + +function gracefulError(err) { + console.warn(err) + beep() +} diff --git a/development/build/static.js b/development/build/static.js index 8a9263935..142f290d1 100644 --- a/development/build/static.js +++ b/development/build/static.js @@ -19,7 +19,7 @@ const copyTargets = [ dest: `images`, }, { - src: `./node_modules/eth-contract-metadata/images/`, + src: `./node_modules/@metamask/contract-metadata/images/`, dest: `images/contract`, }, { @@ -44,6 +44,16 @@ const copyTargets = [ pattern: `*.html`, dest: ``, }, + { + src: `./node_modules/ses/dist/`, + pattern: `lockdown.cjs`, + dest: ``, + }, + { + src: `./app/scripts/`, + pattern: `runLockdown.js`, + dest: ``, + }, ] const languageTags = new Set() diff --git a/development/build/task.js b/development/build/task.js index 553a06956..1ed252413 100644 --- a/development/build/task.js +++ b/development/build/task.js @@ -68,7 +68,9 @@ function runInChildProcess(task) { ) } return instrumentForTaskStats(taskName, async () => { - const childProcess = spawn('yarn', ['build', taskName, '--skip-stats']) + const childProcess = spawn('yarn', ['build', taskName, '--skip-stats'], { + env: process.env, + }) // forward logs to main process // skip the first stdout event (announcing the process command) childProcess.stdout.once('data', () => { @@ -85,7 +87,7 @@ function runInChildProcess(task) { if (errCode !== 0) { reject( new Error( - `MetaMask build: runInChildProcess for task "${taskName}" encountered an error`, + `MetaMask build: runInChildProcess for task "${taskName}" encountered an error ${errCode}`, ), ) return diff --git a/package.json b/package.json index 3e73f2d8c..f11903fbb 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "benchmark:chrome": "SELENIUM_BROWSER=chrome node test/e2e/benchmark.js", "benchmark:firefox": "SELENIUM_BROWSER=firefox node test/e2e/benchmark.js", "build:test": "yarn build test", + "build:test:metrics": "SEGMENT_HOST='http://localhost:9090' SEGMENT_WRITE_KEY='FAKE' SEGMENT_LEGACY_WRITE_KEY='FAKE' yarn build test", "test": "yarn test:unit && yarn lint", "dapp": "node development/static-server.js node_modules/@metamask/test-dapp/dist --port 8080", "dapp-chain": "GANACHE_ARGS='-b 2' concurrently -k -n ganache,dapp -p '[{time}][{name}]' 'yarn ganache:start' 'sleep 5 && yarn dapp'", @@ -22,7 +23,9 @@ "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/permissions/*.js\"", "test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive", "test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh", + "test:e2e:chrome:metrics": "SELENIUM_BROWSER=chrome mocha test/e2e/metrics.spec.js", "test:e2e:firefox": "SELENIUM_BROWSER=firefox test/e2e/run-all.sh", + "test:e2e:firefox:metrics": "SELENIUM_BROWSER=firefox mocha test/e2e/metrics.spec.js", "test:coverage": "nyc --silent --check-coverage yarn test:unit:strict && nyc --silent --no-clean yarn test:unit:lax && nyc report --reporter=text --reporter=html", "test:coverage:strict": "nyc --check-coverage yarn test:unit:strict", "test:coverage:path": "nyc --check-coverage yarn test:unit:path", @@ -57,6 +60,9 @@ "**/knex/minimist": "^1.2.5", "**/optimist/minimist": "^1.2.5", "**/socketcluster/minimist": "^1.2.5", + "**/redux/symbol-observable": "^2.0.3", + "**/redux-devtools-instrument/symbol-observable": "^2.0.3", + "**/rxjs/symbol-observable": "^2.0.3", "3box/ipfs/ipld-zcash/zcash-bitcore-lib/lodash": "^4.17.19", "3box/ipfs/ipld-zcash/zcash-bitcore-lib/elliptic": "^6.5.3", "3box/**/libp2p-crypto/node-forge": "^0.10.0", @@ -70,10 +76,11 @@ "@formatjs/intl-relativetimeformat": "^5.2.6", "@fortawesome/fontawesome-free": "^5.13.0", "@material-ui/core": "^4.11.0", + "@metamask/contract-metadata": "^1.19.0", "@metamask/controllers": "^4.2.0", "@metamask/eth-ledger-bridge-keyring": "^0.2.6", "@metamask/eth-token-tracker": "^3.0.1", - "@metamask/etherscan-link": "^1.3.0", + "@metamask/etherscan-link": "^1.4.0", "@metamask/inpage-provider": "^6.1.0", "@metamask/jazzicon": "^2.0.0", "@metamask/logo": "^2.5.0", @@ -87,18 +94,15 @@ "await-semaphore": "^0.1.1", "bignumber.js": "^4.1.0", "bn.js": "^4.11.7", - "c3": "^0.7.10", "classnames": "^2.2.6", "content-hash": "^2.5.2", "copy-to-clipboard": "^3.0.8", "currency-formatter": "^1.4.2", - "d3": "^5.15.0", "debounce-stream": "^2.0.0", "deep-freeze-strict": "1.1.1", "dnode": "^1.2.2", "end-of-stream": "^1.4.4", "eth-block-tracker": "^4.4.2", - "eth-contract-metadata": "^1.16.0", "eth-ens-namehash": "^2.0.8", "eth-json-rpc-errors": "^2.0.2", "eth-json-rpc-filters": "^4.2.1", @@ -120,14 +124,15 @@ "ethjs-contract": "^0.2.3", "ethjs-ens": "^2.0.0", "ethjs-query": "^0.3.4", - "extension-port-stream": "^1.0.0", + "extension-port-stream": "^2.0.0", "extensionizer": "^1.0.1", "fast-json-patch": "^2.0.4", "fuse.js": "^3.2.0", "human-standard-token-abi": "^2.0.0", - "json-rpc-engine": "^5.3.0", + "json-rpc-engine": "^6.1.0", "json-rpc-middleware-stream": "^2.1.1", "jsonschema": "^1.2.4", + "localforage": "^1.9.0", "lodash": "^4.17.19", "loglevel": "^1.4.1", "luxon": "^1.24.1", @@ -188,11 +193,11 @@ "@metamask/forwarder": "^1.1.0", "@metamask/test-dapp": "^4.0.1", "@sentry/cli": "^1.58.0", - "@storybook/addon-actions": "^5.3.14", - "@storybook/addon-backgrounds": "^5.3.14", - "@storybook/addon-knobs": "^5.3.14", - "@storybook/core": "^5.3.14", - "@storybook/react": "^5.3.14", + "@storybook/addon-actions": "^6.1.9", + "@storybook/addon-backgrounds": "^6.1.9", + "@storybook/addon-knobs": "^6.1.9", + "@storybook/core": "^6.1.9", + "@storybook/react": "^6.1.9", "@storybook/storybook-deployer": "^2.8.6", "@testing-library/react": "^10.4.8", "@testing-library/react-hooks": "^3.2.1", @@ -214,7 +219,6 @@ "css-loader": "^2.1.1", "del": "^3.0.0", "deps-dump": "^1.1.0", - "envify": "^4.1.0", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.15.1", "eslint": "^7.7.0", @@ -250,8 +254,8 @@ "gulp-zip": "^4.0.0", "jsdom": "^11.2.0", "koa": "^2.7.0", - "lavamoat-core": "^6.1.0", "lockfile-lint": "^4.0.0", + "loose-envify": "^1.4.0", "mocha": "^7.2.0", "nock": "^9.0.14", "node-fetch": "^2.6.1", @@ -270,10 +274,11 @@ "regenerator-runtime": "^0.13.3", "remote-redux-devtools": "^0.5.16", "remotedev-server": "^0.3.1", - "resolve-url-loader": "^2.3.0", + "resolve-url-loader": "^3.1.2", "sass-loader": "^7.0.1", "selenium-webdriver": "^4.0.0-alpha.5", "serve-handler": "^6.1.2", + "ses": "0.11.0", "sesify": "^4.2.1", "sesify-viz": "^3.0.10", "sinon": "^9.0.0", diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js new file mode 100644 index 000000000..7bd2c4c5e --- /dev/null +++ b/shared/constants/metametrics.js @@ -0,0 +1,140 @@ +// Type Imports +/** + * @typedef {import('../../app/scripts/lib/enums').EnvironmentType} EnvironmentType + */ + +// Type Declarations +/** + * Used to attach context of where the user was at in the application when the + * event was triggered. Also included as full details of the current page in + * page events. + * @typedef {Object} MetaMetricsPageObject + * @property {string} [path] - the path of the current page (e.g /home) + * @property {string} [title] - the title of the current page (e.g 'home') + * @property {string} [url] - the fully qualified url of the current page + */ + +/** + * For metamask, this is the dapp that triggered an interaction + * @typedef {Object} MetaMetricsReferrerObject + * @property {string} [url] - the origin of the dapp issuing the + * notification + */ + +/** + * We attach context to every meta metrics event that help to qualify our + * analytics. This type has all optional values because it represents a + * returned object from a method call. Ideally app and userAgent are + * defined on every event. This is confirmed in the getTrackMetaMetricsEvent + * function, but still provides the consumer a way to override these values if + * necessary. + * @typedef {Object} MetaMetricsContext + * @property {Object} app + * @property {string} app.name - the name of the application tracking the event + * @property {string} app.version - the version of the application + * @property {string} userAgent - the useragent string of the user + * @property {MetaMetricsPageObject} [page] - an object representing details of + * the current page + * @property {MetaMetricsReferrerObject} [referrer] - for metamask, this is the + * dapp that triggered an interaction + */ + +/** + * @typedef {Object} MetaMetricsEventPayload + * @property {string} event - event name to track + * @property {string} category - category to associate event to + * @property {string} [environmentType] - The type of environment this event + * occurred in. Defaults to the background process type + * @property {object} [properties] - object of custom values to track, keys + * in this object must be in snake_case + * @property {object} [sensitiveProperties] - Object of sensitive values to + * track. Keys in this object must be in snake_case. These properties will be + * sent in an additional event that excludes the user's metaMetricsId + * @property {number} [revenue] - amount of currency that event creates in + * revenue for MetaMask + * @property {string} [currency] - ISO 4127 format currency for events with + * revenue, defaults to US dollars + * @property {number} [value] - Abstract business "value" attributable to + * customers who trigger this event + * @property {MetaMetricsPageObject} [page] - the page/route that the event + * occurred on + * @property {MetaMetricsReferrerObject} [referrer] - the origin of the dapp + * that triggered the event + */ + +/** + * @typedef {Object} MetaMetricsEventOptions + * @property {boolean} [isOptIn] - happened during opt in/out workflow + * @property {boolean} [flushImmediately] - When true will automatically flush + * the segment queue after tracking the event. Recommended if the result of + * tracking the event must be known before UI transition or update + * @property {boolean} [excludeMetaMetricsId] - whether to exclude the user's + * metametrics id for anonymity + * @property {string} [metaMetricsId] - an override for the metaMetricsId in + * the event one is created as part of an asynchronous workflow, such as + * awaiting the result of the metametrics opt-in function that generates the + * user's metametrics id + * @property {boolean} [matomoEvent] - is this event a holdover from matomo + * that needs further migration? when true, sends the data to a special + * segment source that marks the event data as not conforming to our schema + */ + +/** + * Represents the shape of data sent to the segment.track method. + * @typedef {Object} SegmentEventPayload + * @property {string} [userId] - The metametrics id for the user + * @property {string} [anonymousId] - An anonymousId that is used to track + * sensitive data while preserving anonymity. + * @property {string} event - name of the event to track + * @property {Object} properties - properties to attach to the event + * @property {MetaMetricsContext} context - the context the event occurred in + */ + +/** + * @typedef {Object} MetaMetricsPagePayload + * @property {string} name - The name of the page that was viewed + * @property {Object} [params] - The variadic parts of the page url + * example (route: `/asset/:asset`, path: `/asset/ETH`) + * params: { asset: 'ETH' } + * @property {EnvironmentType} environmentType - the environment type that the + * page was viewed in + * @property {MetaMetricsPageObject} [page] - the details of the page + * @property {MetaMetricsReferrerObject} [referrer] - dapp that triggered the page + * view + */ + +/** + * @typedef {Object} MetaMetricsPageOptions + * @property {boolean} [isOptInPath] - is the current path one of the pages in + * the onboarding workflow? If true and participateInMetaMetrics is null track + * the page view + */ + +export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000' + +/** + * This object is used to identify events that are triggered by the background + * process. + * @type {MetaMetricsPageObject} + */ +export const METAMETRICS_BACKGROUND_PAGE_OBJECT = { + path: '/background-process', + title: 'Background Process', + url: '/background-process', +} + +/** + * @typedef {Object} SegmentInterface + * @property {SegmentEventPayload[]} queue - A queue of events to be sent when + * the flushAt limit has been reached, or flushInterval occurs + * @property {() => void} flush - Immediately flush the queue, resetting it to + * an empty array and sending the pending events to Segment + * @property {( + * payload: SegmentEventPayload, + * callback: (err?: Error) => void + * ) => void} track - Track an event with Segment, using the internal batching + * mechanism to optimize network requests + * @property {(payload: Object) => void} page - Track a page view with Segment + * @property {() => void} identify - Identify an anonymous user. We do not + * currently use this method. + */ diff --git a/shared/constants/tokens.js b/shared/constants/tokens.js index a31c1ec18..27b240f7b 100644 --- a/shared/constants/tokens.js +++ b/shared/constants/tokens.js @@ -1,8 +1,8 @@ -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' /** * A normalized list of addresses exported as part of the contractMap in - * eth-contract-metadata. Used primarily to validate if manually entered + * @metamask/contract-metadata. Used primarily to validate if manually entered * contract addresses do not match one of our listed tokens */ export const LISTED_CONTRACT_ADDRESSES = Object.keys( diff --git a/shared/modules/README.md b/shared/modules/README.md new file mode 100644 index 000000000..5b6e0ffd6 --- /dev/null +++ b/shared/modules/README.md @@ -0,0 +1,3 @@ +### Shared Modules + +This folder is reserved for modules that can be used globally within both the background and ui applications. diff --git a/shared/modules/metametrics.js b/shared/modules/metametrics.js deleted file mode 100644 index 523ac6933..000000000 --- a/shared/modules/metametrics.js +++ /dev/null @@ -1,302 +0,0 @@ -import Analytics from 'analytics-node' -import { merge, omit, pick } from 'lodash' - -// flushAt controls how many events are sent to segment at once. Segment -// will hold onto a queue of events until it hits this number, then it sends -// them as a batch. This setting defaults to 20, but that is too high for -// notification workflows. We also cannot send each event as singular payloads -// because it seems to bombard segment and potentially cause event loss. -// I chose 5 here because it is sufficiently high enough to optimize our network -// requests, while also being low enough to be reasonable. -const flushAt = process.env.METAMASK_ENVIRONMENT === 'production' ? 5 : 1 -// flushInterval controls how frequently the queue is flushed to segment. -// This happens regardless of the size of the queue. The default setting is -// 10,000ms (10 seconds). This default is absurdly high for our typical user -// flow through confirmations. I have chosen 10 ms here because it works really -// well with our wrapped track function. The track function returns a promise -// that is only fulfilled when it has been sent to segment. A 10 ms delay is -// negligible to the user, but allows us to properly batch events that happen -// in rapid succession. -const flushInterval = 10 - -export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000' - -const segmentNoop = { - track(_, callback = () => undefined) { - // Need to call the callback so that environments without a segment id still - // resolve the promise from trackMetaMetricsEvent - return callback() - }, - page() { - // noop - }, - identify() { - // noop - }, -} - -/** - * Used to determine whether or not to attach a user's metametrics id - * to events that include on-chain data. This helps to prevent identifying - * a user by being able to trace their activity on etherscan/block exploring - */ -const trackableSendCounts = { - 1: true, - 10: true, - 30: true, - 50: true, - 100: true, - 250: true, - 500: true, - 1000: true, - 2500: true, - 5000: true, - 10000: true, - 25000: true, -} - -export function sendCountIsTrackable(sendCount) { - return Boolean(trackableSendCounts[sendCount]) -} - -const isDevOrTestEnvironment = Boolean( - process.env.METAMASK_DEBUG || process.env.IN_TEST, -) - -// This allows us to overwrite the metric destination for testing purposes -const host = process.env.SEGMENT_HOST ?? undefined - -// We do not want to track events on development builds unless specifically -// provided a SEGMENT_WRITE_KEY. This also holds true for test environments and -// E2E, which is handled in the build process by never providing the SEGMENT_WRITE_KEY -// when process.env.IN_TEST is truthy -export const segment = - !process.env.SEGMENT_WRITE_KEY || (isDevOrTestEnvironment && !host) - ? segmentNoop - : new Analytics(process.env.SEGMENT_WRITE_KEY, { - host, - flushAt, - flushInterval, - }) - -export const segmentLegacy = - !process.env.SEGMENT_LEGACY_WRITE_KEY || (isDevOrTestEnvironment && !host) - ? segmentNoop - : new Analytics(process.env.SEGMENT_LEGACY_WRITE_KEY, { - host, - flushAt, - flushInterval, - }) - -/** - * We attach context to every meta metrics event that help to qualify our analytics. - * This type has all optional values because it represents a returned object from a - * method call. Ideally app and userAgent are defined on every event. This is confirmed - * in the getTrackMetaMetricsEvent function, but still provides the consumer a way to - * override these values if necessary. - * @typedef {Object} MetaMetricsContext - * @property {Object} app - * @property {string} app.name - the name of the application tracking the event - * @property {string} app.version - the version of the application - * @property {string} userAgent - the useragent string of the user - * @property {Object} [page] - an object representing details of the current page - * @property {string} [page.path] - the path of the current page (e.g /home) - * @property {string} [page.title] - the title of the current page (e.g 'home') - * @property {string} [page.url] - the fully qualified url of the current page - * @property {Object} [referrer] - for metamask, this is the dapp that triggered an interaction - * @property {string} [referrer.url] - the origin of the dapp issuing the notification - */ - -/** - * page and referrer from the MetaMetricsContext are very dynamic in nature and may be - * provided as part of the initial context payload when creating the trackMetaMetricsEvent function, - * or at the event level when calling the trackMetaMetricsEvent function. - * @typedef {Pick} MetaMetricsDynamicContext - */ - -/** - * @typedef {import('../../app/scripts/lib/enums').EnvironmentType} EnvironmentType - */ - -/** - * @typedef {Object} MetaMetricsRequiredState - * @property {bool} participateInMetaMetrics - has the user opted into metametrics - * @property {string} [metaMetricsId] - the user's metaMetricsId, if they have opted in - * @property {MetaMetricsDynamicContext} context - context about the event - * @property {string} chainId - the chain id of the current network - * @property {string} locale - the locale string of the current user - * @property {string} network - the name of the current network - * @property {EnvironmentType} environmentType - environment that the event happened in - * @property {string} [metaMetricsSendCount] - number of transactions sent, used to add metametricsId - * intermittently to events with onchain data attached to them used to protect identity of users. - */ - -/** - * @typedef {Object} MetaMetricsEventPayload - * @property {string} event - event name to track - * @property {string} category - category to associate event to - * @property {boolean} [isOptIn] - happened during opt in/out workflow - * @property {object} [properties] - object of custom values to track, snake_case - * @property {object} [sensitiveProperties] - Object of sensitive values to track, snake_case. - * These properties will be sent in an additional event that excludes the user's metaMetricsId. - * @property {number} [revenue] - amount of currency that event creates in revenue for MetaMask - * @property {string} [currency] - ISO 4127 format currency for events with revenue, defaults to US dollars - * @property {number} [value] - Abstract "value" that this event has for MetaMask. - * @property {boolean} [excludeMetaMetricsId] - whether to exclude the user's metametrics id for anonymity - * @property {string} [metaMetricsId] - an override for the metaMetricsId in the event one is created as part - * of an asynchronous workflow, such as awaiting the result of the metametrics opt-in function that generates the - * user's metametrics id. - * @property {boolean} [matomoEvent] - is this event a holdover from matomo that needs further migration? - * when true, sends the data to a special segment source that marks the event data as not conforming to our - * ideal schema - * @property {MetaMetricsDynamicContext} [eventContext] - additional context to attach to event - */ - -/** - * Returns a function for tracking Segment events. - * - * @param {string} metamaskVersion - The current version of the MetaMask extension. - * @param {() => MetaMetricsRequiredState} getDynamicState - A function returning required fields - * @returns {(payload: MetaMetricsEventPayload) => Promise} function to track an event - */ -export function getTrackMetaMetricsEvent(metamaskVersion, getDynamicState) { - const version = - process.env.METAMASK_ENVIRONMENT === 'production' - ? metamaskVersion - : `${metamaskVersion}-${process.env.METAMASK_ENVIRONMENT}` - - return function trackMetaMetricsEvent({ - event, - category, - isOptIn, - properties = {}, - sensitiveProperties, - revenue, - currency, - value, - metaMetricsId: metaMetricsIdOverride, - excludeMetaMetricsId: excludeId, - matomoEvent = false, - eventContext = {}, - }) { - if (!event || !category) { - throw new Error('Must specify event and category.') - } - // Uses recursion to track a duplicate event with sensitive properties included, - // but metaMetricsId excluded - if (sensitiveProperties) { - if (excludeId === true) { - throw new Error( - 'sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag', - ) - } - trackMetaMetricsEvent({ - event, - category, - isOptIn, - properties: merge(sensitiveProperties, properties), - revenue, - currency, - value, - excludeMetaMetricsId: true, - matomoEvent, - eventContext, - }) - } - const { - participateInMetaMetrics, - context: providedContext, - metaMetricsId, - environmentType, - chainId, - locale, - network, - metaMetricsSendCount, - } = getDynamicState() - - let excludeMetaMetricsId = excludeId ?? false - - // This is carried over from the old implementation, and will likely need - // to be updated to work with the new tracking plan. I think we should use - // a config setting for this instead of trying to match the event name - const isSendFlow = Boolean(event.match(/^send|^confirm/u)) - if ( - isSendFlow && - metaMetricsSendCount && - !sendCountIsTrackable(metaMetricsSendCount + 1) - ) { - excludeMetaMetricsId = true - } - - if (!participateInMetaMetrics && !isOptIn) { - return Promise.resolve() - } - - /** @type {MetaMetricsContext} */ - const context = { - app: { - name: 'MetaMask Extension', - version, - }, - userAgent: window.navigator.userAgent, - ...pick(providedContext, ['page', 'referrer']), - ...pick(eventContext, ['page', 'referrer']), - } - - const trackOptions = { - event, - properties: { - // These values are omitted from properties because they have special meaning - // in segment. https://segment.com/docs/connections/spec/track/#properties. - // to avoid accidentally using these inappropriately, you must add them as top - // level properties on the event payload. We also exclude locale to prevent consumers - // from overwriting this context level property. We track it as a property - // because not all destinations map locale from context. - ...omit(properties, ['revenue', 'locale', 'currency', 'value']), - revenue, - value, - currency, - category, - network, - locale, - chain_id: chainId, - environment_type: environmentType, - }, - context, - } - - // If we are tracking sensitive data we will always use the anonymousId property - // as well as our METAMETRICS_ANONYMOUS_ID. This prevents us from associating potentially - // identifiable information with a specific id. During the opt in flow we will track all - // events, but do so with the anonymous id. The one exception to that rule is after the - // user opts in to MetaMetrics. When that happens we receive back the user's new MetaMetrics - // id before it is fully persisted to state. To avoid a race condition we explicitly pass the - // new id to the track method. In that case we will track the opt in event to the user's id. - // In all other cases we use the metaMetricsId from state. - if (excludeMetaMetricsId) { - trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID - } else if (isOptIn && metaMetricsIdOverride) { - trackOptions.userId = metaMetricsIdOverride - } else if (isOptIn) { - trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID - } else { - trackOptions.userId = metaMetricsId - } - - return new Promise((resolve, reject) => { - // This is only safe to do because we have set an extremely low (10ms) flushInterval. - const callback = (err) => { - if (err) { - return reject(err) - } - return resolve() - } - - if (matomoEvent === true) { - segmentLegacy.track(trackOptions, callback) - } else { - segment.track(trackOptions, callback) - } - }) - } -} diff --git a/test/data/fetch-mocks.json b/test/data/fetch-mocks.json index 805d6e33a..886f87697 100644 --- a/test/data/fetch-mocks.json +++ b/test/data/fetch-mocks.json @@ -1,5921 +1,9 @@ { - "ethGasBasic": { + "gasPricesBasic": { "average": 85, - "fastestWait": 0.6, - "fastWait": 0.6, "fast": 200, - "safeLowWait": 4.8, - "blockNum": 6648312, - "avgWait": 4.2, - "block_time": 15.516129032258064, - "speed": 0.7828720873342716, - "fastest": 400, "safeLow": 80 }, - "ethGasPredictTable": [ - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.2632423756, - "pct_remaining5m": 0, - "sum": 7.029975, - "tx_atabove": 4136, - "hashpower_accepting": 10.4166666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.2, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.433788122, - "pct_remaining5m": 0, - "sum": 7.01731875, - "tx_atabove": 4136, - "hashpower_accepting": 10.9375, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.5, - "pct_mined_5m": 0, - "total_seen_5m": 84, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.433788122, - "pct_remaining5m": 0, - "sum": 7.01731875, - "tx_atabove": 4136, - "hashpower_accepting": 10.9375, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.7, - "pct_mined_5m": 0, - "total_seen_5m": 5, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.4638844302, - "pct_remaining5m": 0, - "sum": 7.01731875, - "tx_atabove": 4136, - "hashpower_accepting": 10.9375, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.8, - "pct_mined_5m": 0, - "total_seen_5m": 20, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.4839486356, - "pct_remaining5m": 0, - "sum": 7.01731875, - "tx_atabove": 4136, - "hashpower_accepting": 10.9375, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 1.9, - "pct_mined_5m": 0, - "total_seen_5m": 8, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.7347512039, - "pct_remaining5m": 0, - "sum": 7.0046625, - "tx_atabove": 4136, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2, - "pct_mined_5m": 0, - "total_seen_5m": 52, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 17, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 1, - "sum": 7.0046625, - "tx_atabove": 4136, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2.1, - "pct_mined_5m": 0, - "total_seen_5m": 97, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 20, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 1, - "sum": 7.0040625, - "tx_atabove": 4135, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 2.2, - "pct_mined_5m": 0, - "total_seen_5m": 433, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 68, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 0, - "sum": 6.9986625, - "tx_atabove": 4126, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 50, - "gasprice": 2.3, - "pct_mined_5m": 0, - "total_seen_5m": 14, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 0, - "sum": 6.9980625, - "tx_atabove": 4125, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2.4, - "pct_mined_5m": 0, - "total_seen_5m": 4, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 20, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 37, - "sum": 6.9956625, - "tx_atabove": 4121, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 75, - "gasprice": 2.5, - "pct_mined_5m": 0, - "total_seen_5m": 45, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 79, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 0, - "sum": 6.9788625, - "tx_atabove": 4093, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 2.6, - "pct_mined_5m": 0, - "total_seen_5m": 3, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 27.5, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 100, - "sum": 6.9764625, - "tx_atabove": 4089, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2.7, - "pct_mined_5m": 0, - "total_seen_5m": 3, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 22.5, - "hashpower_accepting2": 7.7447833066, - "pct_remaining5m": 66, - "sum": 6.9740625, - "tx_atabove": 4085, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 2.8, - "pct_mined_5m": 0, - "total_seen_5m": 6, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 20, - "hashpower_accepting2": 7.7548154093, - "pct_remaining5m": 38, - "sum": 6.9686625, - "tx_atabove": 4076, - "hashpower_accepting": 11.4583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 2.9, - "pct_mined_5m": 2, - "total_seen_5m": 36, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 27, - "hashpower_accepting2": 11.5268860353, - "pct_remaining5m": 77, - "sum": 6.8307, - "tx_atabove": 4057, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 127, - "int2": 6.9238, - "pct_remaining30m": 48, - "gasprice": 3, - "pct_mined_5m": 0, - "total_seen_5m": 322, - "pct_mined_30m": 39, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 67, - "hashpower_accepting2": 11.5268860353, - "pct_remaining5m": 100, - "sum": 6.5697, - "tx_atabove": 3622, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 85, - "int2": 6.9238, - "pct_remaining30m": 98, - "gasprice": 3.1, - "pct_mined_5m": 0, - "total_seen_5m": 79, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 71, - "hashpower_accepting2": 11.5268860353, - "pct_remaining5m": 100, - "sum": 6.4311, - "tx_atabove": 3391, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 3.2, - "pct_mined_5m": 0, - "total_seen_5m": 4, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 62, - "hashpower_accepting2": 11.5268860353, - "pct_remaining5m": 100, - "sum": 6.4209, - "tx_atabove": 3374, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 14, - "int2": 6.9238, - "pct_remaining30m": 92, - "gasprice": 3.3, - "pct_mined_5m": 0, - "total_seen_5m": 7, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1472, - "hashpower_accepting2": 11.5569823435, - "pct_remaining5m": 100, - "sum": 6.3951, - "tx_atabove": 3331, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 29, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 3.4, - "pct_mined_5m": 0, - "total_seen_5m": 27, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 307, - "hashpower_accepting2": 11.5670144462, - "pct_remaining5m": 100, - "sum": 6.1521, - "tx_atabove": 2926, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 3.7, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1399, - "hashpower_accepting2": 11.577046549, - "pct_remaining5m": 100, - "sum": 6.1395, - "tx_atabove": 2905, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 3.9, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1005, - "hashpower_accepting2": 11.5971107544, - "pct_remaining5m": 88, - "sum": 6.1035, - "tx_atabove": 2845, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 88, - "gasprice": 4, - "pct_mined_5m": 0, - "total_seen_5m": 9, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1546, - "hashpower_accepting2": 11.6171749599, - "pct_remaining5m": null, - "sum": 5.6151, - "tx_atabove": 2031, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 4.1, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1065, - "hashpower_accepting2": 11.6171749599, - "pct_remaining5m": 100, - "sum": 5.5509, - "tx_atabove": 1924, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 4.3, - "pct_mined_5m": 0, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 459, - "hashpower_accepting2": 11.6171749599, - "pct_remaining5m": 50, - "sum": 5.5137, - "tx_atabove": 1862, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 4.4, - "pct_mined_5m": 0, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 298, - "hashpower_accepting2": 11.6171749599, - "pct_remaining5m": null, - "sum": 5.4903, - "tx_atabove": 1823, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 4.7, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 812, - "hashpower_accepting2": 11.6472712681, - "pct_remaining5m": 0, - "sum": 5.4831, - "tx_atabove": 1811, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 4.8, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 541, - "hashpower_accepting2": 11.6472712681, - "pct_remaining5m": 100, - "sum": 5.4375, - "tx_atabove": 1735, - "hashpower_accepting": 16.6666666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 4.9, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1134, - "hashpower_accepting2": 11.7375601926, - "pct_remaining5m": 100, - "sum": 5.41824375, - "tx_atabove": 1724, - "hashpower_accepting": 17.1875, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 5, - "pct_mined_5m": 0, - "total_seen_5m": 5, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1958, - "hashpower_accepting2": 11.7676565008, - "pct_remaining5m": null, - "sum": 4.9567875, - "tx_atabove": 976, - "hashpower_accepting": 17.7083333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 5.2, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1203.5, - "hashpower_accepting2": 11.8077849117, - "pct_remaining5m": null, - "sum": 4.9507875, - "tx_atabove": 966, - "hashpower_accepting": 17.7083333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 5.3, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 677.5, - "hashpower_accepting2": 11.8378812199, - "pct_remaining5m": null, - "sum": 4.9141875, - "tx_atabove": 905, - "hashpower_accepting": 17.7083333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 100, - "gasprice": 5.5, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 250.99, - "avgdiff": 0, - "expectedWait": 1000, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 3, - "hashpower_accepting2": 13.3928571429, - "pct_remaining5m": 0, - "sum": 3.16120625, - "tx_atabove": 832, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6, - "pct_mined_5m": 100, - "total_seen_5m": 12, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.92, - "avgdiff": 1, - "expectedWait": 23.5990451154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.0248796148, - "pct_remaining5m": 0, - "sum": 3.10120625, - "tx_atabove": 732, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 6.1, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.58, - "avgdiff": 1, - "expectedWait": 22.2247437161, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 14.1753611557, - "pct_remaining5m": 0, - "sum": 3.09640625, - "tx_atabove": 724, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.2, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.55, - "avgdiff": 1, - "expectedWait": 22.1183205662, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.3459069021, - "pct_remaining5m": 0, - "sum": 3.09580625, - "tx_atabove": 723, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 6.3, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.55, - "avgdiff": 1, - "expectedWait": 22.1050535543, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.3960674157, - "pct_remaining5m": 0, - "sum": 3.09460625, - "tx_atabove": 721, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.4, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0785433993, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.5465489567, - "pct_remaining5m": 0, - "sum": 3.09460625, - "tx_atabove": 721, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.5, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0785433993, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.5666131621, - "pct_remaining5m": null, - "sum": 3.09460625, - "tx_atabove": 721, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.6, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0785433993, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 2, - "hashpower_accepting2": 14.6769662921, - "pct_remaining5m": null, - "sum": 3.09460625, - "tx_atabove": 721, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.7, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0785433993, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.7070626003, - "pct_remaining5m": null, - "sum": 3.09400625, - "tx_atabove": 720, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 6.8, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0653002466, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 14.7271268058, - "pct_remaining5m": 0, - "sum": 3.09400625, - "tx_atabove": 720, - "hashpower_accepting": 20.3125, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 6.9, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.54, - "avgdiff": 1, - "expectedWait": 22.0653002466, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 3, - "hashpower_accepting2": 15.4795345104, - "pct_remaining5m": 0, - "sum": 3.06749375, - "tx_atabove": 718, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 11, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.39, - "avgdiff": 1, - "expectedWait": 21.4879808804, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 15.5898876404, - "pct_remaining5m": 0, - "sum": 3.06089375, - "tx_atabove": 707, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7.1, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.36, - "avgdiff": 1, - "expectedWait": 21.3466271869, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 15.5999197432, - "pct_remaining5m": null, - "sum": 3.06029375, - "tx_atabove": 706, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7.2, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.35, - "avgdiff": 1, - "expectedWait": 21.3338230522, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 15.8507223114, - "pct_remaining5m": 0, - "sum": 3.05969375, - "tx_atabove": 705, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7.6, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.35, - "avgdiff": 1, - "expectedWait": 21.3210265977, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 15.8607544141, - "pct_remaining5m": null, - "sum": 3.05909375, - "tx_atabove": 704, - "hashpower_accepting": 21.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 7.7, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 0, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 5.35, - "avgdiff": 1, - "expectedWait": 21.3082378187, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 18.86035313, - "pct_remaining5m": 0, - "sum": 2.8933625, - "tx_atabove": 702, - "hashpower_accepting": 28.125, - "hpa_coef2": -0.067, - "total_seen_30m": 30, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8, - "pct_mined_5m": 100, - "total_seen_5m": 37, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.53, - "avgdiff": 1, - "expectedWait": 18.053913939, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 19.1011235955, - "pct_remaining5m": 0, - "sum": 2.85250625, - "tx_atabove": 655, - "hashpower_accepting": 28.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.1, - "pct_mined_5m": 100, - "total_seen_5m": 5, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.35, - "avgdiff": 1, - "expectedWait": 17.331163684, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 19.1613162119, - "pct_remaining5m": 0, - "sum": 2.84890625, - "tx_atabove": 649, - "hashpower_accepting": 28.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.2, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.33, - "avgdiff": 1, - "expectedWait": 17.268883666, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 19.231540931, - "pct_remaining5m": 0, - "sum": 2.8097375, - "tx_atabove": 647, - "hashpower_accepting": 30.2083333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 8.4, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.17, - "avgdiff": 1, - "expectedWait": 16.6055586875, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 19.5224719101, - "pct_remaining5m": 0, - "sum": 2.777225, - "tx_atabove": 635, - "hashpower_accepting": 31.25, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.5, - "pct_mined_5m": 100, - "total_seen_5m": 12, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.03, - "avgdiff": 1, - "expectedWait": 16.0743526708, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 19.7331460674, - "pct_remaining5m": 0, - "sum": 2.774225, - "tx_atabove": 630, - "hashpower_accepting": 31.25, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 4.02, - "avgdiff": 1, - "expectedWait": 16.0262018751, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 19.8033707865, - "pct_remaining5m": 0, - "sum": 2.72905625, - "tx_atabove": 618, - "hashpower_accepting": 32.8125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.8, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 3.84, - "avgdiff": 1, - "expectedWait": 15.3184234339, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 19.9638844302, - "pct_remaining5m": 0, - "sum": 2.6954, - "tx_atabove": 583, - "hashpower_accepting": 33.3333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 8.9, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 3.72, - "avgdiff": 1, - "expectedWait": 14.8114421454, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 23.6155698234, - "pct_remaining5m": 0, - "sum": 2.3937875, - "tx_atabove": 460, - "hashpower_accepting": 42.7083333333, - "hpa_coef2": -0.067, - "total_seen_30m": 43, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9, - "pct_mined_5m": 100, - "total_seen_5m": 120, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.75, - "avgdiff": 1, - "expectedWait": 10.9549071782, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.0268860353, - "pct_remaining5m": 0, - "sum": 2.30313125, - "tx_atabove": 330, - "hashpower_accepting": 43.2291666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.1, - "pct_mined_5m": 100, - "total_seen_5m": 23, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.51, - "avgdiff": 1, - "expectedWait": 10.0054630618, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 24.1472712681, - "pct_remaining5m": 0, - "sum": 2.287475, - "tx_atabove": 325, - "hashpower_accepting": 43.75, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 9.2, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.47, - "avgdiff": 1, - "expectedWait": 9.8500349165, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.2174959872, - "pct_remaining5m": 0, - "sum": 2.2609625, - "tx_atabove": 323, - "hashpower_accepting": 44.7916666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 9.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.41, - "avgdiff": 1, - "expectedWait": 9.5923173304, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.3880417335, - "pct_remaining5m": 0, - "sum": 2.22239375, - "tx_atabove": 322, - "hashpower_accepting": 46.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.4, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.32, - "avgdiff": 1, - "expectedWait": 9.2293973144, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 24.5284911717, - "pct_remaining5m": 0, - "sum": 2.2091375, - "tx_atabove": 321, - "hashpower_accepting": 46.875, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.5, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.29, - "avgdiff": 1, - "expectedWait": 9.1078574773, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.7391653291, - "pct_remaining5m": 0, - "sum": 2.2073375, - "tx_atabove": 318, - "hashpower_accepting": 46.875, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.6, - "pct_mined_5m": 100, - "total_seen_5m": 8, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.28, - "avgdiff": 1, - "expectedWait": 9.0914780797, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 24.9699036918, - "pct_remaining5m": 0, - "sum": 2.182025, - "tx_atabove": 318, - "hashpower_accepting": 47.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.7, - "pct_mined_5m": 88, - "total_seen_5m": 9, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.22, - "avgdiff": 1, - "expectedWait": 8.8642381788, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 2, - "hashpower_accepting2": 25.1203852327, - "pct_remaining5m": 0, - "sum": 2.16936875, - "tx_atabove": 318, - "hashpower_accepting": 48.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.8, - "pct_mined_5m": 75, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.2, - "avgdiff": 1, - "expectedWait": 8.7527571186, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 25.1705457464, - "pct_remaining5m": 0, - "sum": 2.1561125, - "tx_atabove": 317, - "hashpower_accepting": 48.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 9.9, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 2.17, - "avgdiff": 1, - "expectedWait": 8.637494048, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 36.3864365971, - "pct_remaining5m": 0, - "sum": 1.769825, - "tx_atabove": 306, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 353, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10, - "pct_mined_5m": 99, - "total_seen_5m": 245, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.47, - "avgdiff": 1, - "expectedWait": 5.8698260519, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 36.536918138, - "pct_remaining5m": 0, - "sum": 1.733225, - "tx_atabove": 245, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.1, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.42, - "avgdiff": 1, - "expectedWait": 5.658874382, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 36.7576243981, - "pct_remaining5m": 0, - "sum": 1.733225, - "tx_atabove": 245, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.2, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.42, - "avgdiff": 1, - "expectedWait": 5.658874382, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 36.8378812199, - "pct_remaining5m": 0, - "sum": 1.732625, - "tx_atabove": 244, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.3, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.42, - "avgdiff": 1, - "expectedWait": 5.6554800758, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 36.8679775281, - "pct_remaining5m": 0, - "sum": 1.732025, - "tx_atabove": 243, - "hashpower_accepting": 64.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.4, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.42, - "avgdiff": 1, - "expectedWait": 5.6520878055, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 37.8109951846, - "pct_remaining5m": 0, - "sum": 1.69405625, - "tx_atabove": 243, - "hashpower_accepting": 66.1458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 12, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.5, - "pct_mined_5m": 100, - "total_seen_5m": 53, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.37, - "avgdiff": 1, - "expectedWait": 5.4415081179, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 37.871187801, - "pct_remaining5m": 0, - "sum": 1.69285625, - "tx_atabove": 241, - "hashpower_accepting": 66.1458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.7, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.36, - "avgdiff": 1, - "expectedWait": 5.4349822245, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 38.1019261637, - "pct_remaining5m": 0, - "sum": 1.69285625, - "tx_atabove": 241, - "hashpower_accepting": 66.1458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.8, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.36, - "avgdiff": 1, - "expectedWait": 5.4349822245, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 38.1821829856, - "pct_remaining5m": 0, - "sum": 1.68565625, - "tx_atabove": 229, - "hashpower_accepting": 66.1458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 10.9, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.35, - "avgdiff": 1, - "expectedWait": 5.3959908897, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 40.7002407705, - "pct_remaining5m": 0, - "sum": 1.520525, - "tx_atabove": 228, - "hashpower_accepting": 72.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 84, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11, - "pct_mined_5m": 100, - "total_seen_5m": 84, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.15, - "avgdiff": 1, - "expectedWait": 4.5746262436, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 40.8206260032, - "pct_remaining5m": 0, - "sum": 1.507325, - "tx_atabove": 206, - "hashpower_accepting": 72.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.1, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.13, - "avgdiff": 1, - "expectedWait": 4.5146379708, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 40.8908507223, - "pct_remaining5m": 0, - "sum": 1.507325, - "tx_atabove": 206, - "hashpower_accepting": 72.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.2, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.13, - "avgdiff": 1, - "expectedWait": 4.5146379708, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.4024879615, - "pct_remaining5m": 0, - "sum": 1.49466875, - "tx_atabove": 206, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 15, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.4, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4578596422, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.4827447833, - "pct_remaining5m": 0, - "sum": 1.49466875, - "tx_atabove": 206, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4578596422, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.6131621188, - "pct_remaining5m": 0, - "sum": 1.49406875, - "tx_atabove": 205, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 8, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4551857287, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.6332263242, - "pct_remaining5m": 0, - "sum": 1.49406875, - "tx_atabove": 205, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.7, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4551857287, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.753611557, - "pct_remaining5m": 0, - "sum": 1.49406875, - "tx_atabove": 205, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.8, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4551857287, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 41.7736757624, - "pct_remaining5m": null, - "sum": 1.49406875, - "tx_atabove": 205, - "hashpower_accepting": 73.4375, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 11.9, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.12, - "avgdiff": 1, - "expectedWait": 4.4551857287, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 44.7030497592, - "pct_remaining5m": 0, - "sum": 1.41813125, - "tx_atabove": 205, - "hashpower_accepting": 76.5625, - "hpa_coef2": -0.067, - "total_seen_30m": 96, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12, - "pct_mined_5m": 100, - "total_seen_5m": 39, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.04, - "avgdiff": 1, - "expectedWait": 4.1293964158, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 44.9036918138, - "pct_remaining5m": 0, - "sum": 1.399475, - "tx_atabove": 195, - "hashpower_accepting": 77.0833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 11, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.1, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1.02, - "avgdiff": 1, - "expectedWait": 4.0530715456, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 45.0341091493, - "pct_remaining5m": null, - "sum": 1.38681875, - "tx_atabove": 195, - "hashpower_accepting": 77.6041666667, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.2, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 1, - "avgdiff": 1, - "expectedWait": 4.0020981056, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.1845906902, - "pct_remaining5m": 0, - "sum": 1.3735625, - "tx_atabove": 194, - "hashpower_accepting": 78.125, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.3, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.99, - "avgdiff": 1, - "expectedWait": 3.9493953846, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.1946227929, - "pct_remaining5m": null, - "sum": 1.3735625, - "tx_atabove": 194, - "hashpower_accepting": 78.125, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.4, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.99, - "avgdiff": 1, - "expectedWait": 3.9493953846, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.3752006421, - "pct_remaining5m": 0, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.4955858748, - "pct_remaining5m": 0, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.525682183, - "pct_remaining5m": null, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.7, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.5858747994, - "pct_remaining5m": 0, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.8, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 45.636035313, - "pct_remaining5m": 0, - "sum": 1.36090625, - "tx_atabove": 194, - "hashpower_accepting": 78.6458333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 12.9, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.98, - "avgdiff": 1, - "expectedWait": 3.8997258274, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 46.9903691814, - "pct_remaining5m": 0, - "sum": 1.31028125, - "tx_atabove": 194, - "hashpower_accepting": 80.7291666667, - "hpa_coef2": -0.067, - "total_seen_30m": 47, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13, - "pct_mined_5m": 100, - "total_seen_5m": 34, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.93, - "avgdiff": 1, - "expectedWait": 3.7072162202, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 47.5321027287, - "pct_remaining5m": 0, - "sum": 1.292825, - "tx_atabove": 186, - "hashpower_accepting": 81.25, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.2, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.91, - "avgdiff": 1, - "expectedWait": 3.6430636874, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 47.5621990369, - "pct_remaining5m": 0, - "sum": 1.292825, - "tx_atabove": 186, - "hashpower_accepting": 81.25, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.91, - "avgdiff": 1, - "expectedWait": 3.6430636874, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 47.632423756, - "pct_remaining5m": null, - "sum": 1.292825, - "tx_atabove": 186, - "hashpower_accepting": 81.25, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.4, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.91, - "avgdiff": 1, - "expectedWait": 3.6430636874, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0.5, - "hashpower_accepting2": 48.1440609952, - "pct_remaining5m": 0, - "sum": 1.28016875, - "tx_atabove": 186, - "hashpower_accepting": 81.7708333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.5, - "pct_mined_5m": 100, - "total_seen_5m": 21, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.9, - "avgdiff": 1, - "expectedWait": 3.5972467097, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 48.4550561798, - "pct_remaining5m": 0, - "sum": 1.2651125, - "tx_atabove": 182, - "hashpower_accepting": 82.2916666667, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.6, - "pct_mined_5m": 100, - "total_seen_5m": 10, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.89, - "avgdiff": 1, - "expectedWait": 3.5434913565, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 55.9590690209, - "pct_remaining5m": 0, - "sum": 1.2398, - "tx_atabove": 182, - "hashpower_accepting": 83.3333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 253, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.7, - "pct_mined_5m": 100, - "total_seen_5m": 212, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.87, - "avgdiff": 1, - "expectedWait": 3.4549224112, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 56.0593900482, - "pct_remaining5m": 0, - "sum": 1.226, - "tx_atabove": 159, - "hashpower_accepting": 83.3333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.8, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.86, - "avgdiff": 1, - "expectedWait": 3.4075719515, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 56.1095505618, - "pct_remaining5m": 0, - "sum": 1.226, - "tx_atabove": 159, - "hashpower_accepting": 83.3333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 13.9, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.86, - "avgdiff": 1, - "expectedWait": 3.4075719515, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0.5, - "hashpower_accepting2": 59.6408507223, - "pct_remaining5m": 0, - "sum": 1.13740625, - "tx_atabove": 159, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 119, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14, - "pct_mined_5m": 100, - "total_seen_5m": 115, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1186688184, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 59.7311396469, - "pct_remaining5m": 0, - "sum": 1.13440625, - "tx_atabove": 154, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 14.1, - "pct_mined_5m": 100, - "total_seen_5m": 5, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1093268319, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 59.8214285714, - "pct_remaining5m": 0, - "sum": 1.13440625, - "tx_atabove": 154, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.2, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1093268319, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 60.1524879615, - "pct_remaining5m": 0, - "sum": 1.13380625, - "tx_atabove": 153, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.4, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1074617954, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.1725521669, - "pct_remaining5m": 0, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.5, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.2528089888, - "pct_remaining5m": 0, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.6, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.6440609952, - "pct_remaining5m": 0, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.7, - "pct_mined_5m": 100, - "total_seen_5m": 10, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.6641252006, - "pct_remaining5m": 0, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.8, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 60.6942215088, - "pct_remaining5m": null, - "sum": 1.13320625, - "tx_atabove": 152, - "hashpower_accepting": 86.9791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 14.9, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.78, - "avgdiff": 1, - "expectedWait": 3.1055978775, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 62.9113162119, - "pct_remaining5m": 0, - "sum": 1.0952375, - "tx_atabove": 152, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 65, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15, - "pct_mined_5m": 100, - "total_seen_5m": 48, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.75, - "avgdiff": 1, - "expectedWait": 2.9898926986, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 63.4129213483, - "pct_remaining5m": 0, - "sum": 1.0910375, - "tx_atabove": 145, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 11, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.1, - "pct_mined_5m": 100, - "total_seen_5m": 8, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.75, - "avgdiff": 1, - "expectedWait": 2.9773614832, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 64.4161316212, - "pct_remaining5m": 0, - "sum": 1.0886375, - "tx_atabove": 141, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.5, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.75, - "avgdiff": 1, - "expectedWait": 2.9702243836, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 64.4863563403, - "pct_remaining5m": 0, - "sum": 1.0820375, - "tx_atabove": 130, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.6, - "pct_mined_5m": 50, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9506854521, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 66.1817817014, - "pct_remaining5m": 0, - "sum": 1.0820375, - "tx_atabove": 130, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 24, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.7, - "pct_mined_5m": 100, - "total_seen_5m": 17, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9506854521, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 66.2620385233, - "pct_remaining5m": 0, - "sum": 1.0766375, - "tx_atabove": 121, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 15.8, - "pct_mined_5m": 83, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9347946943, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 67.2853130016, - "pct_remaining5m": 0, - "sum": 1.0766375, - "tx_atabove": 121, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 15, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16, - "pct_mined_5m": 100, - "total_seen_5m": 11, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9347946943, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.2953451043, - "pct_remaining5m": null, - "sum": 1.0748375, - "tx_atabove": 118, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.1, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9295168154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.4458266453, - "pct_remaining5m": 0, - "sum": 1.0748375, - "tx_atabove": 118, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.2, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9295168154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.455858748, - "pct_remaining5m": 0, - "sum": 1.0748375, - "tx_atabove": 118, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 16.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9295168154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.6565008026, - "pct_remaining5m": 0, - "sum": 1.0748375, - "tx_atabove": 118, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.4, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.74, - "avgdiff": 1, - "expectedWait": 2.9295168154, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 67.7267255217, - "pct_remaining5m": 0, - "sum": 1.0742375, - "tx_atabove": 117, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9277596325, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 68.6697431782, - "pct_remaining5m": 0, - "sum": 1.0742375, - "tx_atabove": 117, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 42, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 16.7, - "pct_mined_5m": 100, - "total_seen_5m": 27, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9277596325, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 68.8904494382, - "pct_remaining5m": 0, - "sum": 1.0718375, - "tx_atabove": 113, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 11, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9207414346, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 69.0308988764, - "pct_remaining5m": 0, - "sum": 1.0712375, - "tx_atabove": 112, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 8, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17.1, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9189895153, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.0409309791, - "pct_remaining5m": null, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17.3, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.0710272873, - "pct_remaining5m": 0, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 17.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.08105939, - "pct_remaining5m": 0, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 17.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.1011235955, - "pct_remaining5m": null, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17.8, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.1111556982, - "pct_remaining5m": 0, - "sum": 1.0706375, - "tx_atabove": 111, - "hashpower_accepting": 88.5416666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 17.9, - "pct_mined_5m": 0, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.73, - "avgdiff": 1, - "expectedWait": 2.9172386469, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.7632423756, - "pct_remaining5m": 0, - "sum": 1.05798125, - "tx_atabove": 111, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": 16, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 18, - "pct_mined_5m": 100, - "total_seen_5m": 16, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.8805500054, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.7732744783, - "pct_remaining5m": 0, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 18.1, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.8134028892, - "pct_remaining5m": 0, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 18.5, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.823434992, - "pct_remaining5m": 0, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 18.7, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.8535313002, - "pct_remaining5m": null, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 18.8, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 69.8735955056, - "pct_remaining5m": 0, - "sum": 1.05618125, - "tx_atabove": 108, - "hashpower_accepting": 89.0625, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 18.9, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.72, - "avgdiff": 1, - "expectedWait": 2.875369679, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.3150080257, - "pct_remaining5m": 0, - "sum": 1.043525, - "tx_atabove": 108, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 13, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 19, - "pct_mined_5m": 100, - "total_seen_5m": 11, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8392076024, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.3350722311, - "pct_remaining5m": 0, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 19.3, - "pct_mined_5m": 66, - "total_seen_5m": 3, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.3752006421, - "pct_remaining5m": 0, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 19.4, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.3852327448, - "pct_remaining5m": null, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 19.5, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.4052969502, - "pct_remaining5m": null, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 19.8, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 70.8266452648, - "pct_remaining5m": 0, - "sum": 1.042325, - "tx_atabove": 106, - "hashpower_accepting": 89.5833333333, - "hpa_coef2": -0.067, - "total_seen_30m": 18, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 19.9, - "pct_mined_5m": 100, - "total_seen_5m": 10, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.71, - "avgdiff": 1, - "expectedWait": 2.8358025967, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 75.2708667737, - "pct_remaining5m": 0, - "sum": 0.90310625, - "tx_atabove": 106, - "hashpower_accepting": 95.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 144, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20, - "pct_mined_5m": 100, - "total_seen_5m": 185, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.62, - "avgdiff": 1, - "expectedWait": 2.4672551317, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 75.3009630819, - "pct_remaining5m": null, - "sum": 0.89650625, - "tx_atabove": 95, - "hashpower_accepting": 95.3125, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20.2, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.62, - "avgdiff": 1, - "expectedWait": 2.4510248666, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 75.3210272873, - "pct_remaining5m": 0, - "sum": 0.89650625, - "tx_atabove": 95, - "hashpower_accepting": 95.3125, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 20.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.62, - "avgdiff": 1, - "expectedWait": 2.4510248666, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 77.7387640449, - "pct_remaining5m": 0, - "sum": 0.88385, - "tx_atabove": 95, - "hashpower_accepting": 95.8333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 24, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20.5, - "pct_mined_5m": 100, - "total_seen_5m": 9, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.61, - "avgdiff": 1, - "expectedWait": 2.420199561, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 77.7688603531, - "pct_remaining5m": 0, - "sum": 0.88325, - "tx_atabove": 94, - "hashpower_accepting": 95.8333333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20.7, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.61, - "avgdiff": 1, - "expectedWait": 2.4187478768, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 77.9093097913, - "pct_remaining5m": null, - "sum": 0.87059375, - "tx_atabove": 94, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 20.9, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3883285027, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 79.7752808989, - "pct_remaining5m": 0, - "sum": 0.87059375, - "tx_atabove": 94, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 39, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 21, - "pct_mined_5m": 100, - "total_seen_5m": 36, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3883285027, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 79.7953451043, - "pct_remaining5m": 0, - "sum": 0.86819375, - "tx_atabove": 90, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 21.1, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3826033871, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 79.8154093098, - "pct_remaining5m": null, - "sum": 0.86819375, - "tx_atabove": 90, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 21.4, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3826033871, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 79.845505618, - "pct_remaining5m": 0, - "sum": 0.86819375, - "tx_atabove": 90, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 21.7, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3826033871, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.3069823435, - "pct_remaining5m": 0, - "sum": 0.86819375, - "tx_atabove": 90, - "hashpower_accepting": 96.3541666667, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 21.9, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.6, - "avgdiff": 1, - "expectedWait": 2.3826033871, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.8888443018, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 13, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22, - "pct_mined_5m": 100, - "total_seen_5m": 13, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9089085072, - "pct_remaining5m": null, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22.1, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.91894061, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 22.2, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9289727127, - "pct_remaining5m": null, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22.3, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9490369181, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 22.5, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9791332263, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22.8, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 80.9891653291, - "pct_remaining5m": null, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 22.9, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 81.47070626, - "pct_remaining5m": 0, - "sum": 0.8555375, - "tx_atabove": 90, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 15, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 23, - "pct_mined_5m": 100, - "total_seen_5m": 19, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.352638584, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.4907704655, - "pct_remaining5m": 0, - "sum": 0.8531375, - "tx_atabove": 86, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 23.1, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3469990216, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.5108346709, - "pct_remaining5m": 0, - "sum": 0.8525375, - "tx_atabove": 85, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 23.3, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3455912446, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.6011235955, - "pct_remaining5m": 0, - "sum": 0.8525375, - "tx_atabove": 85, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 23.7, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3455912446, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.621187801, - "pct_remaining5m": 0, - "sum": 0.8525375, - "tx_atabove": 85, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 23.9, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3455912446, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 81.8719903692, - "pct_remaining5m": 0, - "sum": 0.8525375, - "tx_atabove": 85, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 24, - "pct_mined_5m": 100, - "total_seen_5m": 9, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3455912446, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.8820224719, - "pct_remaining5m": 0, - "sum": 0.8501375, - "tx_atabove": 81, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 24.3, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3399685755, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.9121187801, - "pct_remaining5m": 0, - "sum": 0.8501375, - "tx_atabove": 81, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 24.6, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3399685755, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 81.9321829856, - "pct_remaining5m": 0, - "sum": 0.8501375, - "tx_atabove": 81, - "hashpower_accepting": 96.875, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 24.7, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.59, - "avgdiff": 1, - "expectedWait": 2.3399685755, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 83.3868378812, - "pct_remaining5m": 0, - "sum": 0.83688125, - "tx_atabove": 80, - "hashpower_accepting": 97.3958333333, - "hpa_coef2": -0.067, - "total_seen_30m": 24, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 25, - "pct_mined_5m": 100, - "total_seen_5m": 32, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.58, - "avgdiff": 1, - "expectedWait": 2.3091540608, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 83.6276083467, - "pct_remaining5m": 0, - "sum": 0.82128125, - "tx_atabove": 54, - "hashpower_accepting": 97.3958333333, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 26, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.57, - "avgdiff": 1, - "expectedWait": 2.2734107799, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 83.7379614767, - "pct_remaining5m": 0, - "sum": 0.82008125, - "tx_atabove": 52, - "hashpower_accepting": 97.3958333333, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 27, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.57, - "avgdiff": 1, - "expectedWait": 2.2706843231, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 83.9887640449, - "pct_remaining5m": 0, - "sum": 0.81948125, - "tx_atabove": 51, - "hashpower_accepting": 97.3958333333, - "hpa_coef2": -0.067, - "total_seen_30m": 13, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 28, - "pct_mined_5m": 100, - "total_seen_5m": 7, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.57, - "avgdiff": 1, - "expectedWait": 2.2693223212, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 84.0690208668, - "pct_remaining5m": 0, - "sum": 0.806825, - "tx_atabove": 51, - "hashpower_accepting": 97.9166666667, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 29, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.56, - "avgdiff": 1, - "expectedWait": 2.240782197, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 85.8447030498, - "pct_remaining5m": 0, - "sum": 0.7809125, - "tx_atabove": 50, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 55, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 30, - "pct_mined_5m": 100, - "total_seen_5m": 49, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.55, - "avgdiff": 1, - "expectedWait": 2.1834637674, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 85.9751203852, - "pct_remaining5m": 0, - "sum": 0.7743125, - "tx_atabove": 39, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 31, - "pct_mined_5m": 100, - "total_seen_5m": 5, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.169100358, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.1356340289, - "pct_remaining5m": 0, - "sum": 0.7743125, - "tx_atabove": 39, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 32, - "pct_mined_5m": 100, - "total_seen_5m": 4, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.169100358, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.2760834671, - "pct_remaining5m": 0, - "sum": 0.7743125, - "tx_atabove": 39, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 33, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.169100358, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.4165329053, - "pct_remaining5m": 0, - "sum": 0.7737125, - "tx_atabove": 38, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 6, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 34, - "pct_mined_5m": 60, - "total_seen_5m": 5, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1677992881, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0.5, - "hashpower_accepting2": 86.7475922953, - "pct_remaining5m": 0, - "sum": 0.7737125, - "tx_atabove": 38, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 10, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 35, - "pct_mined_5m": 100, - "total_seen_5m": 17, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1677992881, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.7877207063, - "pct_remaining5m": 0, - "sum": 0.7725125, - "tx_atabove": 36, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 36, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1651994891, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.8579454254, - "pct_remaining5m": 0, - "sum": 0.7725125, - "tx_atabove": 36, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 37, - "pct_mined_5m": 66, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1651994891, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.908105939, - "pct_remaining5m": 0, - "sum": 0.7725125, - "tx_atabove": 36, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 38, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1651994891, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 86.9783306581, - "pct_remaining5m": 0, - "sum": 0.7725125, - "tx_atabove": 36, - "hashpower_accepting": 98.9583333333, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 39, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1651994891, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 87.4498394864, - "pct_remaining5m": 0, - "sum": 0.75985625, - "tx_atabove": 36, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 16, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 40, - "pct_mined_5m": 100, - "total_seen_5m": 14, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1379688654, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 89.6167736758, - "pct_remaining5m": 0, - "sum": 0.75805625, - "tx_atabove": 33, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 112, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 41, - "pct_mined_5m": 100, - "total_seen_5m": 57, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.54, - "avgdiff": 1, - "expectedWait": 2.1341239829, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 89.6869983949, - "pct_remaining5m": 0, - "sum": 0.75445625, - "tx_atabove": 27, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 42, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.1264549491, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 89.7070626003, - "pct_remaining5m": null, - "sum": 0.75385625, - "tx_atabove": 26, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 43, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.1251794588, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 89.9478330658, - "pct_remaining5m": 0, - "sum": 0.75385625, - "tx_atabove": 26, - "hashpower_accepting": 99.4791666667, - "hpa_coef2": -0.067, - "total_seen_30m": 9, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 44, - "pct_mined_5m": 100, - "total_seen_5m": 9, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.1251794588, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 90.088282504, - "pct_remaining5m": 0, - "sum": 0.7394, - "tx_atabove": 23, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 8, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 45, - "pct_mined_5m": 100, - "total_seen_5m": 5, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0946783304, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 90.4995987159, - "pct_remaining5m": 0, - "sum": 0.7394, - "tx_atabove": 23, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 17, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 46, - "pct_mined_5m": 100, - "total_seen_5m": 19, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0946783304, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 90.5999197432, - "pct_remaining5m": 0, - "sum": 0.7382, - "tx_atabove": 21, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 47, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0921662239, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 90.6199839486, - "pct_remaining5m": null, - "sum": 0.7382, - "tx_atabove": 21, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 48, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0921662239, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 90.6500802568, - "pct_remaining5m": null, - "sum": 0.7382, - "tx_atabove": 21, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 49, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0921662239, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 94.1412520064, - "pct_remaining5m": 0, - "sum": 0.7382, - "tx_atabove": 21, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 62, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 50, - "pct_mined_5m": 100, - "total_seen_5m": 71, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.53, - "avgdiff": 1, - "expectedWait": 2.0921662239, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 94.2114767255, - "pct_remaining5m": 0, - "sum": 0.7358, - "tx_atabove": 17, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 51, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0871510456, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 94.4422150883, - "pct_remaining5m": 0, - "sum": 0.7358, - "tx_atabove": 17, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 5, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 52, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0871510456, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 94.4723113965, - "pct_remaining5m": null, - "sum": 0.7358, - "tx_atabove": 17, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 54, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0871510456, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 94.4823434992, - "pct_remaining5m": null, - "sum": 0.7346, - "tx_atabove": 15, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 56, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0846479665, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 95.0140449438, - "pct_remaining5m": 0, - "sum": 0.7346, - "tx_atabove": 15, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 27, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 60, - "pct_mined_5m": 100, - "total_seen_5m": 17, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0846479665, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 95.6059390048, - "pct_remaining5m": 0, - "sum": 0.7334, - "tx_atabove": 13, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 28, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 61, - "pct_mined_5m": 100, - "total_seen_5m": 14, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0821478893, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 96.8699839486, - "pct_remaining5m": 0, - "sum": 0.7322, - "tx_atabove": 11, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 21, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 63, - "pct_mined_5m": 100, - "total_seen_5m": 25, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0796508104, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 1, - "hashpower_accepting2": 98.3948635634, - "pct_remaining5m": 0, - "sum": 0.7298, - "tx_atabove": 7, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 83, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 64, - "pct_mined_5m": 100, - "total_seen_5m": 38, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0746656331, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.4149277689, - "pct_remaining5m": 0, - "sum": 0.728, - "tx_atabove": 4, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 65, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0709345939, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.4951845907, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 66, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5052166934, - "pct_remaining5m": null, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 69, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5152487961, - "pct_remaining5m": null, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 70, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5553772071, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 72, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5754414125, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 73, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.5854735152, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 77, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.6055377207, - "pct_remaining5m": null, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 79, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.8663723917, - "pct_remaining5m": 0, - "sum": 0.7274, - "tx_atabove": 3, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 14, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 80, - "pct_mined_5m": 100, - "total_seen_5m": 6, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0696924058, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.8864365971, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 84, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.9466292135, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 88, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 98.9566613162, - "pct_remaining5m": null, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 90, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.0469502408, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 4, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 91, - "pct_mined_5m": 100, - "total_seen_5m": 3, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.1272070626, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 3, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 96, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.1372391653, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 97, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.1472712681, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 99, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.7090690209, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 23, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 100, - "pct_mined_5m": 100, - "total_seen_5m": 22, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.8394863563, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 7, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 101, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.9097110754, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 2, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 120, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.9297752809, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": null, - "int2": 6.9238, - "pct_remaining30m": null, - "gasprice": 134, - "pct_mined_5m": 100, - "total_seen_5m": 2, - "pct_mined_30m": null, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": 0, - "hashpower_accepting2": 99.9498394864, - "pct_remaining5m": 0, - "sum": 0.7268, - "tx_atabove": 2, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 137, - "pct_mined_5m": 100, - "total_seen_5m": 1, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0684509628, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - }, - { - "intercept": 4.8015, - "age": null, - "hashpower_accepting2": 99.9699036918, - "pct_remaining5m": null, - "sum": 0.7256, - "tx_atabove": 0, - "hashpower_accepting": 100, - "hpa_coef2": -0.067, - "total_seen_30m": 1, - "int2": 6.9238, - "pct_remaining30m": 0, - "gasprice": 180, - "pct_mined_5m": null, - "total_seen_5m": null, - "pct_mined_30m": 100, - "tx_atabove_coef": 0.0006, - "average": 600, - "safelow": 600, - "nomine": 550, - "expectedTime": 0.52, - "avgdiff": 1, - "expectedWait": 2.0659703104, - "avgdiff_coef": -1.6459, - "hpa_coef": -0.0243 - } - ], "metametrics": { "mockMetaMetricsResponse": true }, diff --git a/test/e2e/address-book.spec.js b/test/e2e/address-book.spec.js index 6ed55b22b..3d0e2712b 100644 --- a/test/e2e/address-book.spec.js +++ b/test/e2e/address-book.spec.js @@ -29,6 +29,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/benchmark.js b/test/e2e/benchmark.js index 442533c04..a364ed62a 100644 --- a/test/e2e/benchmark.js +++ b/test/e2e/benchmark.js @@ -13,6 +13,7 @@ const ALL_PAGES = Object.values(PAGES) async function measurePage(pageName) { let metrics await withFixtures({ fixtures: 'imported-account' }, async ({ driver }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/ethereum-on.spec.js b/test/e2e/ethereum-on.spec.js index 2d90f23d7..81f178c9d 100644 --- a/test/e2e/ethereum-on.spec.js +++ b/test/e2e/ethereum-on.spec.js @@ -28,6 +28,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/fixtures/metrics-enabled/state.json b/test/e2e/fixtures/metrics-enabled/state.json new file mode 100644 index 000000000..4b0e52e70 --- /dev/null +++ b/test/e2e/fixtures/metrics-enabled/state.json @@ -0,0 +1,168 @@ +{ + "data": { + "AppStateController": { + "connectedStatusPopoverHasBeenShown": false, + "swapsWelcomeMessageHasBeenShown": true + }, + "CachedBalancesController": { + "cachedBalances": { + "4": {}, + "1337": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": "0x15af1d78b58c40000" + } + } + }, + "CurrencyController": { + "conversionDate": 1594348502.519, + "conversionRate": 240.09, + "currentCurrency": "usd", + "nativeCurrency": "ETH" + }, + "IncomingTransactionsController": { + "incomingTransactions": {}, + "incomingTxLastFetchedBlocksByNetwork": { + "goerli": null, + "kovan": null, + "mainnet": null, + "rinkeby": 5570536, + "localhost": 98 + } + }, + "KeyringController": { + "vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}" + }, + "NetworkController": { + "provider": { + "nickname": "Localhost 8545", + "rpcUrl": "http://localhost:8545", + "chainId": "0x539", + "ticker": "ETH", + "type": "rpc" + }, + "network": "1337" + }, + "OnboardingController": { + "onboardingTabs": {}, + "seedPhraseBackedUp": false + }, + "PermissionsMetadata": { + "permissionsLog": [ + { + "id": 1764280960, + "method": "eth_requestAccounts", + "methodType": "restricted", + "origin": "http://127.0.0.1:8080", + "request": { + "method": "eth_requestAccounts", + "jsonrpc": "2.0", + "id": 1764280960, + "origin": "http://127.0.0.1:8080", + "tabId": 2 + }, + "requestTime": 1594348329232, + "response": { + "id": 1764280960, + "jsonrpc": "2.0", + "result": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"] + }, + "responseTime": 1594348332276, + "success": true + } + ], + "permissionsHistory": { + "http://127.0.0.1:8080": { + "eth_accounts": { + "accounts": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": 1594348332276 + }, + "lastApproved": 1594348332276 + } + } + }, + "domainMetadata": { + "http://127.0.0.1:8080": { + "name": "E2E Test Dapp", + "icon": "http://127.0.0.1:8080/metamask-fox.svg", + "lastUpdated": 1594348323811, + "host": "127.0.0.1:8080" + } + } + }, + "PreferencesController": { + "frequentRpcListDetail": [], + "accountTokens": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "rinkeby": [], + "ropsten": [] + } + }, + "assetImages": {}, + "tokens": [], + "suggestedTokens": {}, + "useBlockie": false, + "useNonceField": false, + "usePhishDetect": true, + "featureFlags": { + "showIncomingTransactions": true, + "transactionTime": false + }, + "knownMethodData": {}, + "participateInMetaMetrics": true, + "firstTimeFlowType": "create", + "currentLocale": "en", + "identities": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "name": "Account 1" + } + }, + "lostIdentities": {}, + "forgottenPassword": false, + "preferences": { + "useNativeCurrencyAsPrimaryCurrency": true + }, + "completedOnboarding": true, + "metaMetricsId": "fake-metrics-id", + "metaMetricsSendCount": 0, + "ipfsGateway": "dweb.link", + "selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1" + }, + "config": {}, + "firstTimeInfo": { + "date": 1575697234195, + "version": "7.7.0" + }, + "PermissionsController": { + "permissionsRequests": [], + "permissionsDescriptions": {}, + "domains": { + "http://127.0.0.1:8080": { + "permissions": [ + { + "@context": ["https://github.com/MetaMask/rpc-cap"], + "parentCapability": "eth_accounts", + "id": "f55a1c15-ea48-4088-968e-63be474d42fa", + "date": 1594348332268, + "invoker": "http://127.0.0.1:8080", + "caveats": [ + { + "type": "limitResponseLength", + "value": 1, + "name": "primaryAccountOnly" + }, + { + "type": "filterResponse", + "value": ["0x5cfe73b6021e818b776b421b1c4db2474086a7e1"], + "name": "exposedAccounts" + } + ] + } + ] + } + } + } + }, + "meta": { + "version": 47 + } +} diff --git a/test/e2e/from-import-ui.spec.js b/test/e2e/from-import-ui.spec.js index ec3f68d42..dc5457f7d 100644 --- a/test/e2e/from-import-ui.spec.js +++ b/test/e2e/from-import-ui.spec.js @@ -35,6 +35,7 @@ describe('Using MetaMask with an existing account', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 9e6aa2f9f..926f67177 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -1,5 +1,9 @@ const path = require('path') +const sinon = require('sinon') const createStaticServer = require('../../development/create-static-server') +const { + createSegmentServer, +} = require('../../development/lib/create-segment-server') const Ganache = require('./ganache') const FixtureServer = require('./fixture-server') const { buildWebDriver } = require('./webdriver') @@ -11,10 +15,19 @@ const largeDelayMs = regularDelayMs * 2 const dappPort = 8080 async function withFixtures(options, testSuite) { - const { dapp, fixtures, ganacheOptions, driverOptions, title } = options + const { + dapp, + fixtures, + ganacheOptions, + driverOptions, + mockSegment, + title, + } = options const fixtureServer = new FixtureServer() const ganacheServer = new Ganache() let dappServer + let segmentServer + let segmentStub let webDriver try { @@ -38,11 +51,23 @@ async function withFixtures(options, testSuite) { dappServer.on('error', reject) }) } + if (mockSegment) { + segmentStub = sinon.stub() + segmentServer = createSegmentServer((_request, response, events) => { + for (const event of events) { + segmentStub(event) + } + response.statusCode = 200 + response.end() + }) + await segmentServer.start(9090) + } const { driver } = await buildWebDriver(driverOptions) webDriver = driver await testSuite({ driver, + segmentStub, }) if (process.env.SELENIUM_BROWSER === 'chrome') { @@ -57,7 +82,11 @@ async function withFixtures(options, testSuite) { } } catch (error) { if (webDriver) { - await webDriver.verboseReportOnFailure(title) + try { + await webDriver.verboseReportOnFailure(title) + } catch (verboseReportError) { + console.error(verboseReportError) + } } throw error } finally { @@ -76,6 +105,9 @@ async function withFixtures(options, testSuite) { }) }) } + if (segmentServer) { + await segmentServer.stop() + } } } diff --git a/test/e2e/incremental-security.spec.js b/test/e2e/incremental-security.spec.js index ca204baaf..cb0c67e3c 100644 --- a/test/e2e/incremental-security.spec.js +++ b/test/e2e/incremental-security.spec.js @@ -33,6 +33,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/metamask-responsive-ui.spec.js b/test/e2e/metamask-responsive-ui.spec.js index a3cc26db4..1474960ef 100644 --- a/test/e2e/metamask-responsive-ui.spec.js +++ b/test/e2e/metamask-responsive-ui.spec.js @@ -22,6 +22,7 @@ describe('MetaMask', function () { await ganacheServer.start() const result = await buildWebDriver({ responsive: true }) driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index b98cf9f0b..f7a558ba9 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -23,6 +23,7 @@ describe('MetaMask', function () { await ganacheServer.start() const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/metrics.spec.js b/test/e2e/metrics.spec.js new file mode 100644 index 000000000..585a44e35 --- /dev/null +++ b/test/e2e/metrics.spec.js @@ -0,0 +1,56 @@ +const { strict: assert } = require('assert') +const { By, Key } = require('selenium-webdriver') +const waitUntilCalled = require('../lib/wait-until-called') +const { withFixtures } = require('./helpers') + +/** + * WARNING: These tests must be run using a build created with `yarn build:test:metrics`, so that it has + * the correct Segment host and write keys set. Otherwise this test will fail. + */ +describe('Segment metrics', function () { + this.timeout(0) + + it('should send first three Page metric events upon fullscreen page load', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: 25000000000000000000, + }, + ], + } + await withFixtures( + { + fixtures: 'metrics-enabled', + ganacheOptions, + title: this.test.title, + mockSegment: true, + }, + async ({ driver, segmentStub }) => { + const threeSegmentEventsReceived = waitUntilCalled(segmentStub, null, 3) + await driver.navigate() + + const passwordField = await driver.findElement(By.css('#password')) + await passwordField.sendKeys('correct horse battery staple') + await passwordField.sendKeys(Key.ENTER) + + await threeSegmentEventsReceived + + assert.ok(segmentStub.called, 'Segment should receive metrics') + + const firstSegmentEvent = segmentStub.getCall(0).args[0] + assert.equal(firstSegmentEvent.name, 'Home') + assert.equal(firstSegmentEvent.context.page.path, '/') + + const secondSegmentEvent = segmentStub.getCall(1).args[0] + assert.equal(secondSegmentEvent.name, 'Unlock Page') + assert.equal(secondSegmentEvent.context.page.path, '/unlock') + + const thirdSegmentEvent = segmentStub.getCall(2).args[0] + assert.equal(thirdSegmentEvent.name, 'Home') + assert.equal(thirdSegmentEvent.context.page.path, '/') + }, + ) + }) +}) diff --git a/test/e2e/permissions.spec.js b/test/e2e/permissions.spec.js index 133bade16..4f15b625f 100644 --- a/test/e2e/permissions.spec.js +++ b/test/e2e/permissions.spec.js @@ -28,6 +28,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/send-edit.spec.js b/test/e2e/send-edit.spec.js index b11dde556..3c70d67e0 100644 --- a/test/e2e/send-edit.spec.js +++ b/test/e2e/send-edit.spec.js @@ -30,6 +30,7 @@ describe('Using MetaMask with an existing account', function () { }) const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/signature-request.spec.js b/test/e2e/signature-request.spec.js index 5857f175b..3e4307ffa 100644 --- a/test/e2e/signature-request.spec.js +++ b/test/e2e/signature-request.spec.js @@ -28,6 +28,7 @@ describe('MetaMask', function () { publicAddress = '0x5cfe73b6021e818b776b421b1c4db2474086a7e1' const result = await buildWebDriver() driver = result.driver + await driver.navigate() }) afterEach(async function () { diff --git a/test/e2e/tests/localization.spec.js b/test/e2e/tests/localization.spec.js index 7b17b95cc..5ba5558f7 100644 --- a/test/e2e/tests/localization.spec.js +++ b/test/e2e/tests/localization.spec.js @@ -16,6 +16,7 @@ describe('Localization', function () { await withFixtures( { fixtures: 'localization', ganacheOptions, title: this.test.title }, async ({ driver }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/tests/personal-sign.spec.js b/test/e2e/tests/personal-sign.spec.js index dbead3dbd..462eab11b 100644 --- a/test/e2e/tests/personal-sign.spec.js +++ b/test/e2e/tests/personal-sign.spec.js @@ -21,6 +21,7 @@ describe('Personal sign', function () { title: this.test.title, }, async ({ driver }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/tests/simple-send.spec.js b/test/e2e/tests/simple-send.spec.js index 68128dab7..332117951 100644 --- a/test/e2e/tests/simple-send.spec.js +++ b/test/e2e/tests/simple-send.spec.js @@ -15,6 +15,7 @@ describe('Simple send', function () { await withFixtures( { fixtures: 'imported-account', ganacheOptions, title: this.test.title }, async ({ driver }) => { + await driver.navigate() const passwordField = await driver.findElement(By.css('#password')) await passwordField.sendKeys('correct horse battery staple') await passwordField.sendKeys(Key.ENTER) diff --git a/test/e2e/threebox.spec.js b/test/e2e/threebox.spec.js index 107531bff..55f771a44 100644 --- a/test/e2e/threebox.spec.js +++ b/test/e2e/threebox.spec.js @@ -31,6 +31,7 @@ describe('MetaMask', function () { }) const result = await buildWebDriver({ port: await getPort() }) driver = result.driver + await driver.navigate() }) afterEach(async function () { @@ -189,6 +190,7 @@ describe('MetaMask', function () { before(async function () { const result = await buildWebDriver({ port: await getPort() }) driver2 = result.driver + await driver2.navigate() }) after(async function () { diff --git a/test/e2e/webdriver/index.js b/test/e2e/webdriver/index.js index 267287ff6..024478065 100644 --- a/test/e2e/webdriver/index.js +++ b/test/e2e/webdriver/index.js @@ -15,9 +15,6 @@ async function buildWebDriver({ responsive, port } = {}) { } = await buildBrowserWebDriver(browser, { extensionPath, responsive, port }) await setupFetchMocking(seleniumDriver) const driver = new Driver(seleniumDriver, browser, extensionUrl) - await driver.navigate() - - await driver.delay(1000) return { driver, @@ -45,12 +42,11 @@ async function setupFetchMocking(driver) { window.origFetch = window.fetch.bind(window) window.fetch = async (...args) => { const url = args[0] - if (url.match(/^http(s)?:\/\/ethgasstation\.info\/json\/ethgasAPI.*/u)) { - return { json: async () => clone(mockResponses.ethGasBasic) } - } else if ( - url.match(/http(s?):\/\/ethgasstation\.info\/json\/predictTable.*/u) + // api.metaswap.codefi.network/gasPrices + if ( + url.match(/^http(s)?:\/\/api\.metaswap\.codefi\.network\/gasPrices/u) ) { - return { json: async () => clone(mockResponses.ethGasPredictTable) } + return { json: async () => clone(mockResponses.gasPricesBasic) } } else if (url.match(/chromeextensionmm/u)) { return { json: async () => clone(mockResponses.metametrics) } } else if (url.match(/^https:\/\/(api\.metaswap|.*airswap-dev)/u)) { diff --git a/test/helper.js b/test/helper.js index cbd47c312..38462c6ca 100644 --- a/test/helper.js +++ b/test/helper.js @@ -76,8 +76,9 @@ Object.assign(window, { fetch, Headers, Request, Response }) require('abortcontroller-polyfill/dist/polyfill-patch-fetch') // localStorage -window.localStorage = {} - +window.localStorage = { + removeItem: () => null, +} // override @metamask/logo window.requestAnimationFrame = () => undefined diff --git a/test/lib/wait-until-called.js b/test/lib/wait-until-called.js index 7a2eb2704..752ee7675 100644 --- a/test/lib/wait-until-called.js +++ b/test/lib/wait-until-called.js @@ -9,18 +9,30 @@ * * @param {import('sinon').stub} stub - A sinon stub of a function * @param {unknown} [wrappedThis] - The object the stubbed function was called on, if any (i.e. the `this` value) + * @param {number} [callCount] - The number of calls to wait for. Defaults to 1. * @returns {Promise} A Promise that resolves when the stub has been called */ -export default function waitUntilCalled(stub, wrappedThis = null) { - let wasCalled - const stubHasBeenCalled = new Promise((resolve) => { - wasCalled = resolve +function waitUntilCalled(stub, wrappedThis = null, callCount = 1) { + let numCalls = 0 + let resolve + const stubHasBeenCalled = new Promise((_resolve) => { + resolve = _resolve }) stub.callsFake((...args) => { - if (stub.wrappedMethod) { - stub.wrappedMethod.call(wrappedThis, ...args) + try { + if (stub.wrappedMethod) { + stub.wrappedMethod.call(wrappedThis, ...args) + } + } finally { + if (numCalls < callCount) { + numCalls += 1 + if (numCalls === callCount) { + resolve() + } + } } - wasCalled() }) return stubHasBeenCalled } + +module.exports = waitUntilCalled diff --git a/test/stub/provider.js b/test/stub/provider.js index 40fd95258..f9bc72977 100644 --- a/test/stub/provider.js +++ b/test/stub/provider.js @@ -1,4 +1,4 @@ -import JsonRpcEngine from 'json-rpc-engine' +import { JsonRpcEngine } from 'json-rpc-engine' import scaffoldMiddleware from 'eth-json-rpc-middleware/scaffold' import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware' import GanacheCore from 'ganache-core' diff --git a/test/unit-global/frozenPromise.js b/test/unit-global/frozenPromise.js index 6583e1edf..1a1ca18b5 100644 --- a/test/unit-global/frozenPromise.js +++ b/test/unit-global/frozenPromise.js @@ -1,6 +1,8 @@ -import '../../app/scripts/lib/freezeGlobals' - -import assert from 'assert' +// Should occur before anything else +import './globalPatch' +import 'ses/dist/lockdown.cjs' +import '../../app/scripts/runLockdown' +import assert from 'assert' /* eslint-disable-line import/first,import/order */ describe('Promise global is immutable', function () { it('throws when reassinging promise (syntax 1)', function () { diff --git a/test/unit-global/globalPatch.js b/test/unit-global/globalPatch.js new file mode 100644 index 000000000..89d392454 --- /dev/null +++ b/test/unit-global/globalPatch.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/unambiguous,node/no-unsupported-features/es-builtins +global.globalThis = global diff --git a/test/unit/app/controllers/detect-tokens-test.js b/test/unit/app/controllers/detect-tokens-test.js index 8f3a5a52c..82be8808a 100644 --- a/test/unit/app/controllers/detect-tokens-test.js +++ b/test/unit/app/controllers/detect-tokens-test.js @@ -1,7 +1,7 @@ import assert from 'assert' import sinon from 'sinon' import ObservableStore from 'obs-store' -import contracts from 'eth-contract-metadata' +import contracts from '@metamask/contract-metadata' import BigNumber from 'bignumber.js' import DetectTokensController from '../../../../app/scripts/controllers/detect-tokens' diff --git a/test/unit/app/controllers/metamask-controller-test.js b/test/unit/app/controllers/metamask-controller-test.js index 09b8ffac7..99bd3f957 100644 --- a/test/unit/app/controllers/metamask-controller-test.js +++ b/test/unit/app/controllers/metamask-controller-test.js @@ -108,6 +108,7 @@ describe('MetaMaskController', function () { }, }, initState: cloneDeep(firstTimeState), + initLangCode: 'en_US', platform: { showTransactionNotification: () => undefined, getVersion: () => 'foo', @@ -799,7 +800,7 @@ describe('MetaMaskController', function () { it('checks the default currentLocale', function () { const preferenceCurrentLocale = metamaskController.preferencesController.store.getState() .currentLocale - assert.equal(preferenceCurrentLocale, undefined) + assert.equal(preferenceCurrentLocale, 'en_US') }) it('sets current locale in preferences controller', function () { diff --git a/test/unit/app/controllers/metametrics-test.js b/test/unit/app/controllers/metametrics-test.js new file mode 100644 index 000000000..d43f48f4f --- /dev/null +++ b/test/unit/app/controllers/metametrics-test.js @@ -0,0 +1,546 @@ +import { strict as assert } from 'assert' +import sinon from 'sinon' +import MetaMetricsController from '../../../../app/scripts/controllers/metametrics' +import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../../app/scripts/lib/enums' +import { createSegmentMock } from '../../../../app/scripts/lib/segment' +import { + METAMETRICS_ANONYMOUS_ID, + METAMETRICS_BACKGROUND_PAGE_OBJECT, +} from '../../../../shared/constants/metametrics' +import waitUntilCalled from '../../../lib/wait-until-called' + +const segment = createSegmentMock(2, 10000) +const segmentLegacy = createSegmentMock(2, 10000) + +const VERSION = '0.0.1-test' +const NETWORK = 'Mainnet' +const FAKE_CHAIN_ID = '0x1338' +const LOCALE = 'en_US' +const TEST_META_METRICS_ID = '0xabc' + +const DEFAULT_TEST_CONTEXT = { + app: { name: 'MetaMask Extension', version: VERSION }, + page: METAMETRICS_BACKGROUND_PAGE_OBJECT, + referrer: undefined, + userAgent: window.navigator.userAgent, +} + +const DEFAULT_SHARED_PROPERTIES = { + chain_id: FAKE_CHAIN_ID, + locale: LOCALE.replace('_', '-'), + network: NETWORK, + environment_type: 'background', +} + +const DEFAULT_EVENT_PROPERTIES = { + category: 'Unit Test', + revenue: undefined, + value: undefined, + currency: undefined, + ...DEFAULT_SHARED_PROPERTIES, +} + +const DEFAULT_PAGE_PROPERTIES = { + ...DEFAULT_SHARED_PROPERTIES, +} + +function getMockNetworkController( + chainId = FAKE_CHAIN_ID, + provider = { type: NETWORK }, +) { + let networkStore = { chainId, provider } + const on = sinon.stub().withArgs('networkDidChange') + const updateState = (newState) => { + networkStore = { ...networkStore, ...newState } + on.getCall(0).args[1]() + } + return { + store: { + getState: () => networkStore, + updateState, + }, + getCurrentChainId: () => networkStore.chainId, + getNetworkIdentifier: () => networkStore.provider.type, + on, + } +} + +function getMockPreferencesStore({ currentLocale = LOCALE } = {}) { + let preferencesStore = { + currentLocale, + } + const subscribe = sinon.stub() + const updateState = (newState) => { + preferencesStore = { ...preferencesStore, ...newState } + subscribe.getCall(0).args[0](preferencesStore) + } + return { + getState: sinon.stub().returns(preferencesStore), + updateState, + subscribe, + } +} + +function getMetaMetricsController({ + participateInMetaMetrics = true, + metaMetricsId = TEST_META_METRICS_ID, + metaMetricsSendCount = 0, + preferencesStore = getMockPreferencesStore(), + networkController = getMockNetworkController(), +} = {}) { + return new MetaMetricsController({ + segment, + segmentLegacy, + getNetworkIdentifier: networkController.getNetworkIdentifier.bind( + networkController, + ), + getCurrentChainId: networkController.getCurrentChainId.bind( + networkController, + ), + onNetworkDidChange: networkController.on.bind( + networkController, + 'networkDidChange', + ), + preferencesStore, + version: '0.0.1', + environment: 'test', + initState: { + participateInMetaMetrics, + metaMetricsId, + metaMetricsSendCount, + }, + }) +} +describe('MetaMetricsController', function () { + describe('constructor', function () { + it('should properly initialize', function () { + const metaMetricsController = getMetaMetricsController() + assert.strictEqual(metaMetricsController.version, VERSION) + assert.strictEqual(metaMetricsController.network, NETWORK) + assert.strictEqual(metaMetricsController.chainId, FAKE_CHAIN_ID) + assert.strictEqual( + metaMetricsController.state.participateInMetaMetrics, + true, + ) + assert.strictEqual( + metaMetricsController.state.metaMetricsId, + TEST_META_METRICS_ID, + ) + assert.strictEqual(metaMetricsController.locale, LOCALE.replace('_', '-')) + }) + + it('should update when network changes', function () { + const networkController = getMockNetworkController() + const metaMetricsController = getMetaMetricsController({ + networkController, + }) + assert.strictEqual(metaMetricsController.network, NETWORK) + networkController.store.updateState({ + provider: { + type: 'NEW_NETWORK', + }, + chainId: '0xaab', + }) + assert.strictEqual(metaMetricsController.network, 'NEW_NETWORK') + assert.strictEqual(metaMetricsController.chainId, '0xaab') + }) + + it('should update when preferences changes', function () { + const preferencesStore = getMockPreferencesStore() + const metaMetricsController = getMetaMetricsController({ + preferencesStore, + }) + assert.strictEqual(metaMetricsController.network, NETWORK) + preferencesStore.updateState({ + currentLocale: 'en_UK', + }) + assert.strictEqual(metaMetricsController.locale, 'en-UK') + }) + }) + + describe('generateMetaMetricsId', function () { + it('should generate an 0x prefixed hex string', function () { + const metaMetricsController = getMetaMetricsController() + assert.equal( + metaMetricsController.generateMetaMetricsId().startsWith('0x'), + true, + ) + }) + }) + + describe('setParticipateInMetaMetrics', function () { + it('should update the value of participateInMetaMetrics', function () { + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: null, + metaMetricsId: null, + }) + assert.equal(metaMetricsController.state.participateInMetaMetrics, null) + metaMetricsController.setParticipateInMetaMetrics(true) + assert.equal(metaMetricsController.state.participateInMetaMetrics, true) + metaMetricsController.setParticipateInMetaMetrics(false) + assert.equal(metaMetricsController.state.participateInMetaMetrics, false) + }) + it('should generate and update the metaMetricsId when set to true', function () { + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: null, + metaMetricsId: null, + }) + assert.equal(metaMetricsController.state.metaMetricsId, null) + metaMetricsController.setParticipateInMetaMetrics(true) + assert.equal(typeof metaMetricsController.state.metaMetricsId, 'string') + }) + it('should nullify the metaMetricsId when set to false', function () { + const metaMetricsController = getMetaMetricsController() + metaMetricsController.setParticipateInMetaMetrics(false) + assert.equal(metaMetricsController.state.metaMetricsId, null) + }) + }) + + describe('setMetaMetricsSendCount', function () { + it('should update the send count in state', function () { + const metaMetricsController = getMetaMetricsController() + metaMetricsController.setMetaMetricsSendCount(1) + assert.equal(metaMetricsController.state.metaMetricsSendCount, 1) + }) + }) + + describe('trackEvent', function () { + it('should not track an event if user is not participating in metametrics', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: false, + }) + mock.expects('track').never() + metaMetricsController.trackEvent({ + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }) + mock.verify() + }) + + it('should track an event if user has not opted in, but isOptIn is true', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: false, + }) + mock + .expects('track') + .once() + .withArgs({ + event: 'Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }, + { isOptIn: true }, + ) + mock.verify() + }) + + it('should track an event during optin and allow for metaMetricsId override', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: false, + }) + mock + .expects('track') + .once() + .withArgs({ + event: 'Fake Event', + userId: 'TESTID', + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }, + { isOptIn: true, metaMetricsId: 'TESTID' }, + ) + mock.verify() + }) + + it('should track a legacy event', function () { + const mock = sinon.mock(segmentLegacy) + const metaMetricsController = getMetaMetricsController() + mock + .expects('track') + .once() + .withArgs({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }, + { matomoEvent: true }, + ) + mock.verify() + }) + + it('should track a non legacy event', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController() + mock + .expects('track') + .once() + .withArgs({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent({ + event: 'Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }) + mock.verify() + }) + + it('should use anonymousId when metametrics send count is not trackable in send flow', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + metaMetricsSendCount: 1, + }) + mock + .expects('track') + .once() + .withArgs({ + event: 'Send Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent({ + event: 'Send Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }) + mock.verify() + }) + + it('should use user metametrics id when metametrics send count is trackable in send flow', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController() + mock + .expects('track') + .once() + .withArgs({ + event: 'Send Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + test: 1, + ...DEFAULT_EVENT_PROPERTIES, + }, + }) + metaMetricsController.trackEvent( + { + event: 'Send Fake Event', + category: 'Unit Test', + properties: { + test: 1, + }, + }, + { metaMetricsSendCount: 0 }, + ) + mock.verify() + }) + + it('should immediately flush queue if flushImmediately set to true', async function () { + const metaMetricsController = getMetaMetricsController() + const flushStub = sinon.stub(segment, 'flush') + const flushCalled = waitUntilCalled(flushStub, segment) + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + }, + { flushImmediately: true }, + ) + assert.doesNotReject(flushCalled) + }) + + it('should throw if event or category not provided', function () { + const metaMetricsController = getMetaMetricsController() + assert.rejects( + () => metaMetricsController.trackEvent({ event: 'test' }), + /Must specify event and category\./u, + 'must specify category', + ) + + assert.rejects( + () => metaMetricsController.trackEvent({ category: 'test' }), + /Must specify event and category\./u, + 'must specify event', + ) + }) + + it('should throw if provided sensitiveProperties, when excludeMetaMetricsId is true', function () { + const metaMetricsController = getMetaMetricsController() + assert.rejects( + () => + metaMetricsController.trackEvent( + { + event: 'Fake Event', + category: 'Unit Test', + sensitiveProperties: { foo: 'bar' }, + }, + { excludeMetaMetricsId: true }, + ), + /sensitiveProperties was specified in an event payload that also set the excludeMetaMetricsId flag/u, + ) + }) + + it('should track sensitiveProperties in a separate, anonymous event', function () { + const metaMetricsController = getMetaMetricsController() + const spy = sinon.spy(segment, 'track') + metaMetricsController.trackEvent({ + event: 'Fake Event', + category: 'Unit Test', + sensitiveProperties: { foo: 'bar' }, + }) + assert.ok(spy.calledTwice) + assert.ok( + spy.calledWith({ + event: 'Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + foo: 'bar', + ...DEFAULT_EVENT_PROPERTIES, + }, + }), + ) + assert.ok( + spy.calledWith({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: DEFAULT_EVENT_PROPERTIES, + }), + ) + }) + }) + + describe('trackPage', function () { + it('should track a page view', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController() + mock + .expects('page') + .once() + .withArgs({ + name: 'home', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + params: null, + ...DEFAULT_PAGE_PROPERTIES, + }, + }) + metaMetricsController.trackPage({ + name: 'home', + params: null, + environmentType: ENVIRONMENT_TYPE_BACKGROUND, + page: METAMETRICS_BACKGROUND_PAGE_OBJECT, + }) + mock.verify() + }) + + it('should not track a page view if user is not participating in metametrics', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + participateInMetaMetrics: false, + }) + mock.expects('page').never() + metaMetricsController.trackPage({ + name: 'home', + params: null, + environmentType: ENVIRONMENT_TYPE_BACKGROUND, + page: METAMETRICS_BACKGROUND_PAGE_OBJECT, + }) + mock.verify() + }) + + it('should track a page view if isOptInPath is true and user not yet opted in', function () { + const mock = sinon.mock(segment) + const metaMetricsController = getMetaMetricsController({ + preferencesStore: getMockPreferencesStore({ + participateInMetaMetrics: null, + }), + }) + mock + .expects('page') + .once() + .withArgs({ + name: 'home', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + params: null, + ...DEFAULT_PAGE_PROPERTIES, + }, + }) + metaMetricsController.trackPage( + { + name: 'home', + params: null, + environmentType: ENVIRONMENT_TYPE_BACKGROUND, + page: METAMETRICS_BACKGROUND_PAGE_OBJECT, + }, + { isOptInPath: true }, + ) + mock.verify() + }) + }) + + afterEach(function () { + // flush the queues manually after each test + segment.flush() + segmentLegacy.flush() + sinon.restore() + }) +}) diff --git a/test/unit/app/controllers/permissions/permissions-controller-test.js b/test/unit/app/controllers/permissions/permissions-controller-test.js index 5e593f114..5f79bb443 100644 --- a/test/unit/app/controllers/permissions/permissions-controller-test.js +++ b/test/unit/app/controllers/permissions/permissions-controller-test.js @@ -1290,12 +1290,6 @@ describe('permissions controller', function () { }, 'should not throw') assert.equal(typeof middleware, 'function', 'should return function') - - assert.equal( - middleware.name, - 'engineAsMiddleware', - 'function name should be "engineAsMiddleware"', - ) }) it('should create a middleware with extensionId', function () { @@ -1311,12 +1305,6 @@ describe('permissions controller', function () { assert.equal(typeof middleware, 'function', 'should return function') - assert.equal( - middleware.name, - 'engineAsMiddleware', - 'function name should be "engineAsMiddleware"', - ) - const metadataStore = permController.store.getState()[METADATA_STORE_KEY] assert.deepEqual( diff --git a/test/unit/app/controllers/preferences-controller-test.js b/test/unit/app/controllers/preferences-controller-test.js index e041bb582..6a831c3e7 100644 --- a/test/unit/app/controllers/preferences-controller-test.js +++ b/test/unit/app/controllers/preferences-controller-test.js @@ -2,7 +2,6 @@ import assert from 'assert' import ObservableStore from 'obs-store' import sinon from 'sinon' import PreferencesController from '../../../../app/scripts/controllers/preferences' -import { addInternalMethodPrefix } from '../../../../app/scripts/controllers/permissions' describe('preferences controller', function () { let preferencesController @@ -405,53 +404,41 @@ describe('preferences controller', function () { }) describe('on watchAsset', function () { - let stubHandleWatchAssetERC20, asy, req, res + let req, stubHandleWatchAssetERC20 const sandbox = sinon.createSandbox() beforeEach(function () { - req = { params: {} } - res = {} - asy = { next: sandbox.spy(), end: sandbox.spy() } + req = { method: 'wallet_watchAsset', params: {} } stubHandleWatchAssetERC20 = sandbox.stub( preferencesController, '_handleWatchAssetERC20', ) }) + after(function () { sandbox.restore() }) - it('shouldn not do anything if method not corresponds', async function () { - req.method = 'metamask' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) - sandbox.assert.notCalled(asy.end) - sandbox.assert.called(asy.next) + it('should error if passed no type', async function () { + await assert.rejects( + () => preferencesController.requestWatchAsset(req), + { message: 'Asset of type "undefined" not supported.' }, + 'should have errored', + ) }) - it('should do something if method is supported', async function () { - req.method = 'metamask_watchAsset' + + it('should error if method is not supported', async function () { req.params.type = 'someasset' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) - sandbox.assert.called(asy.end) - sandbox.assert.notCalled(asy.next) - req.method = addInternalMethodPrefix('watchAsset') - req.params.type = 'someasset' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) - sandbox.assert.calledTwice(asy.end) - sandbox.assert.notCalled(asy.next) + await assert.rejects( + () => preferencesController.requestWatchAsset(req), + { message: 'Asset of type "someasset" not supported.' }, + 'should have errored', + ) }) - it('should through error if method is supported but asset type is not', async function () { - req.method = 'metamask_watchAsset' - req.params.type = 'someasset' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) - sandbox.assert.called(asy.end) - sandbox.assert.notCalled(stubHandleWatchAssetERC20) - sandbox.assert.notCalled(asy.next) - assert.deepEqual(res, {}) - }) - it('should trigger handle add asset if type supported', async function () { - req.method = 'metamask_watchAsset' + + it('should handle ERC20 type', async function () { req.params.type = 'ERC20' - await preferencesController.requestWatchAsset(req, res, asy.next, asy.end) + await preferencesController.requestWatchAsset(req) sandbox.assert.called(stubHandleWatchAssetERC20) }) }) @@ -527,7 +514,7 @@ describe('preferences controller', function () { assert.doesNotThrow(() => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: 0, }), @@ -539,7 +526,7 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', decimals: 0, }), 'missing symbol should fail', @@ -547,7 +534,7 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', }), 'missing decimals should fail', @@ -555,7 +542,7 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABCDEFGHI', decimals: 0, }), @@ -564,7 +551,7 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: -1, }), @@ -573,14 +560,14 @@ describe('preferences controller', function () { assert.throws( () => validate({ - rawAddress: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', + address: '0xd26114cd6EE289AccF82350c8d8487fedB8A0C07', symbol: 'ABC', decimals: 38, }), 'decimals > 36 should fail', ) assert.throws( - () => validate({ rawAddress: '0x123', symbol: 'ABC', decimals: 0 }), + () => validate({ address: '0x123', symbol: 'ABC', decimals: 0 }), 'invalid address should fail', ) }) diff --git a/test/unit/migrations/049-test.js b/test/unit/migrations/049-test.js new file mode 100644 index 000000000..f720a4723 --- /dev/null +++ b/test/unit/migrations/049-test.js @@ -0,0 +1,132 @@ +import assert from 'assert' +import migration49 from '../../../app/scripts/migrations/049' + +describe('migration #49', function () { + it('should update the version metadata', async function () { + const oldStorage = { + meta: { + version: 48, + }, + data: {}, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.meta, { + version: 49, + }) + }) + + it('should move metaMetricsId to MetaMetricsController', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + metaMetricsId: '0xaab', + bar: 'baz', + }, + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + PreferencesController: { + bar: 'baz', + }, + MetaMetricsController: { + metaMetricsId: '0xaab', + }, + foo: 'bar', + }) + }) + + it('should move participateInMetaMetrics to MetaMetricsController', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + participateInMetaMetrics: false, + bar: 'baz', + }, + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + PreferencesController: { + bar: 'baz', + }, + MetaMetricsController: { + participateInMetaMetrics: false, + }, + foo: 'bar', + }) + }) + + it('should move metaMetricsSendCount to MetaMetricsController', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + metaMetricsSendCount: 1, + bar: 'baz', + }, + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + PreferencesController: { + bar: 'baz', + }, + MetaMetricsController: { + metaMetricsSendCount: 1, + }, + foo: 'bar', + }) + }) + + it('should move all metaMetrics fields to MetaMetricsController', async function () { + const oldStorage = { + meta: {}, + data: { + PreferencesController: { + metaMetricsSendCount: 1, + metaMetricsId: '0xaab', + participateInMetaMetrics: true, + bar: 'baz', + }, + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + PreferencesController: { + bar: 'baz', + }, + MetaMetricsController: { + metaMetricsSendCount: 1, + metaMetricsId: '0xaab', + participateInMetaMetrics: true, + }, + foo: 'bar', + }) + }) + + it('should do nothing if no PreferencesController key', async function () { + const oldStorage = { + meta: {}, + data: { + foo: 'bar', + }, + } + + const newStorage = await migration49.migrate(oldStorage) + assert.deepStrictEqual(newStorage.data, { + foo: 'bar', + }) + }) +}) diff --git a/test/unit/migrations/050-test.js b/test/unit/migrations/050-test.js new file mode 100644 index 000000000..fea2f1b06 --- /dev/null +++ b/test/unit/migrations/050-test.js @@ -0,0 +1,89 @@ +import { strict as assert } from 'assert' +import sinon from 'sinon' +import migration50 from '../../../app/scripts/migrations/050' + +const LEGACY_LOCAL_STORAGE_KEYS = [ + 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', + 'METASWAP_GAS_PRICE_ESTIMATES', + 'cachedFetch', + 'BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', + 'BASIC_PRICE_ESTIMATES', + 'BASIC_GAS_AND_TIME_API_ESTIMATES', + 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', + 'GAS_API_ESTIMATES_LAST_RETRIEVED', + 'GAS_API_ESTIMATES', +] + +describe('migration #50', function () { + let mockLocalStorageRemoveItem + + beforeEach(function () { + mockLocalStorageRemoveItem = sinon.stub(window.localStorage, 'removeItem') + }) + + afterEach(function () { + sinon.restore() + }) + + it('should update the version metadata', async function () { + const oldStorage = { + meta: { + version: 49, + }, + data: {}, + } + + const newStorage = await migration50.migrate(oldStorage) + assert.deepEqual(newStorage.meta, { + version: 50, + }) + }) + + it('should call window.localStorage.removeItem for each legacy key', async function () { + const oldStorage = { + meta: { + version: 49, + }, + data: {}, + } + + await migration50.migrate(oldStorage) + assert.equal(mockLocalStorageRemoveItem.callCount, 9) + assert.equal( + mockLocalStorageRemoveItem.getCall(0).args[0], + LEGACY_LOCAL_STORAGE_KEYS[0], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(1).args[0], + LEGACY_LOCAL_STORAGE_KEYS[1], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(2).args[0], + LEGACY_LOCAL_STORAGE_KEYS[2], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(3).args[0], + LEGACY_LOCAL_STORAGE_KEYS[3], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(4).args[0], + LEGACY_LOCAL_STORAGE_KEYS[4], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(5).args[0], + LEGACY_LOCAL_STORAGE_KEYS[5], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(6).args[0], + LEGACY_LOCAL_STORAGE_KEYS[6], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(7).args[0], + LEGACY_LOCAL_STORAGE_KEYS[7], + ) + assert.equal( + mockLocalStorageRemoveItem.getCall(8).args[0], + LEGACY_LOCAL_STORAGE_KEYS[8], + ) + }) +}) diff --git a/test/unit/ui/app/actions.spec.js b/test/unit/ui/app/actions.spec.js index d487d825e..09ae2acba 100644 --- a/test/unit/ui/app/actions.spec.js +++ b/test/unit/ui/app/actions.spec.js @@ -54,6 +54,7 @@ describe('Actions', function () { return Promise.resolve(this.object) }, }, + initLangCode: 'en_US', initState: cloneDeep(firstTimeState), infuraProjectId: 'foo', }) diff --git a/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js b/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js index 4c65e3b70..5b329d1ac 100644 --- a/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js +++ b/ui/app/components/app/account-list-item/tests/account-list-item-component.test.js @@ -45,23 +45,23 @@ describe('AccountListItem Component', function () { }) it('should render a div with the passed className', function () { - assert.equal(wrapper.find('.mockClassName').length, 1) + assert.strictEqual(wrapper.find('.mockClassName').length, 1) assert(wrapper.find('.mockClassName').is('div')) assert(wrapper.find('.mockClassName').hasClass('account-list-item')) }) it('should call handleClick with the expected props when the root div is clicked', function () { const { onClick } = wrapper.find('.mockClassName').props() - assert.equal(propsMethodSpies.handleClick.callCount, 0) + assert.strictEqual(propsMethodSpies.handleClick.callCount, 0) onClick() - assert.equal(propsMethodSpies.handleClick.callCount, 1) - assert.deepEqual(propsMethodSpies.handleClick.getCall(0).args, [ + assert.strictEqual(propsMethodSpies.handleClick.callCount, 1) + assert.deepStrictEqual(propsMethodSpies.handleClick.getCall(0).args, [ { address: 'mockAddress', name: 'mockName', balance: 'mockBalance' }, ]) }) it('should have a top row div', function () { - assert.equal( + assert.strictEqual( wrapper.find('.mockClassName > .account-list-item__top-row').length, 1, ) @@ -74,16 +74,19 @@ describe('AccountListItem Component', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', ) - assert.equal(topRow.find(Identicon).length, 1) - assert.equal(topRow.find('.account-list-item__account-name').length, 1) - assert.equal(topRow.find('.account-list-item__icon').length, 1) + assert.strictEqual(topRow.find(Identicon).length, 1) + assert.strictEqual( + topRow.find('.account-list-item__account-name').length, + 1, + ) + assert.strictEqual(topRow.find('.account-list-item__icon').length, 1) }) it('should show the account name if it exists', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', ) - assert.equal( + assert.strictEqual( topRow.find('.account-list-item__account-name').text(), 'mockName', ) @@ -94,7 +97,7 @@ describe('AccountListItem Component', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', ) - assert.equal( + assert.strictEqual( topRow.find('.account-list-item__account-name').text(), 'addressButNoName', ) @@ -115,25 +118,27 @@ describe('AccountListItem Component', function () { const topRow = wrapper.find( '.mockClassName > .account-list-item__top-row', ) - assert.equal(topRow.find('.account-list-item__icon').length, 0) + assert.strictEqual(topRow.find('.account-list-item__icon').length, 0) }) it('should render the account address as a checksumAddress if displayAddress is true and name is provided', function () { wrapper.setProps({ displayAddress: true }) - assert.equal( + assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 1, ) - assert.equal( + assert.strictEqual( wrapper.find('.account-list-item__account-address').text(), 'mockCheckSumAddress', ) - assert.deepEqual(checksumAddressStub.getCall(0).args, ['mockAddress']) + assert.deepStrictEqual(checksumAddressStub.getCall(0).args, [ + 'mockAddress', + ]) }) it('should not render the account address as a checksumAddress if displayAddress is false', function () { wrapper.setProps({ displayAddress: false }) - assert.equal( + assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 0, ) @@ -141,7 +146,7 @@ describe('AccountListItem Component', function () { it('should not render the account address as a checksumAddress if name is not provided', function () { wrapper.setProps({ account: { address: 'someAddressButNoName' } }) - assert.equal( + assert.strictEqual( wrapper.find('.account-list-item__account-address').length, 0, ) diff --git a/ui/app/components/app/account-menu/tests/account-menu.test.js b/ui/app/components/app/account-menu/tests/account-menu.test.js index 70dba281f..eb35b1c3b 100644 --- a/ui/app/components/app/account-menu/tests/account-menu.test.js +++ b/ui/app/components/app/account-menu/tests/account-menu.test.js @@ -74,14 +74,14 @@ describe('Account Menu', function () { describe('Render Content', function () { it('returns account name from identities', function () { const accountName = wrapper.find('.account-menu__name') - assert.equal(accountName.length, 2) + assert.strictEqual(accountName.length, 2) }) it('renders user preference currency display balance from account balance', function () { const accountBalance = wrapper.find( '.currency-display-component.account-menu__balance', ) - assert.equal(accountBalance.length, 2) + assert.strictEqual(accountBalance.length, 2) }) it('simulate click', function () { @@ -91,12 +91,15 @@ describe('Account Menu', function () { click.first().simulate('click') assert(props.showAccountDetail.calledOnce) - assert.equal(props.showAccountDetail.getCall(0).args[0], '0xAddress') + assert.strictEqual( + props.showAccountDetail.getCall(0).args[0], + '0xAddress', + ) }) it('render imported account label', function () { const importedAccount = wrapper.find('.keyring-label.allcaps') - assert.equal(importedAccount.text(), 'imported') + assert.strictEqual(importedAccount.text(), 'imported') }) }) @@ -105,13 +108,13 @@ describe('Account Menu', function () { it('logout', function () { logout = wrapper.find('.account-menu__lock-button') - assert.equal(logout.length, 1) + assert.strictEqual(logout.length, 1) }) it('simulate click', function () { logout.simulate('click') assert(props.lockMetamask.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/') + assert.strictEqual(props.history.push.getCall(0).args[0], '/') }) }) @@ -120,13 +123,13 @@ describe('Account Menu', function () { it('renders create account item', function () { createAccount = wrapper.find({ text: 'createAccount' }) - assert.equal(createAccount.length, 1) + assert.strictEqual(createAccount.length, 1) }) it('calls toggle menu and push new-account route to history', function () { createAccount.simulate('click') assert(props.toggleAccountMenu.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/new-account') + assert.strictEqual(props.history.push.getCall(0).args[0], '/new-account') }) }) @@ -135,7 +138,7 @@ describe('Account Menu', function () { it('renders import account item', function () { importAccount = wrapper.find({ text: 'importAccount' }) - assert.equal(importAccount.length, 1) + assert.strictEqual(importAccount.length, 1) }) it('calls toggle menu and push /new-account/import route to history', function () { @@ -150,13 +153,13 @@ describe('Account Menu', function () { it('renders import account item', function () { connectHardwareWallet = wrapper.find({ text: 'connectHardwareWallet' }) - assert.equal(connectHardwareWallet.length, 1) + assert.strictEqual(connectHardwareWallet.length, 1) }) it('calls toggle menu and push /new-account/connect route to history', function () { connectHardwareWallet.simulate('click') assert(props.toggleAccountMenu.calledOnce) - assert.equal( + assert.strictEqual( props.history.push.getCall(0).args[0], '/new-account/connect', ) @@ -168,13 +171,16 @@ describe('Account Menu', function () { it('renders import account item', function () { infoHelp = wrapper.find({ text: 'infoHelp' }) - assert.equal(infoHelp.length, 1) + assert.strictEqual(infoHelp.length, 1) }) it('calls toggle menu and push /new-account/connect route to history', function () { infoHelp.simulate('click') assert(props.toggleAccountMenu.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/settings/about-us') + assert.strictEqual( + props.history.push.getCall(0).args[0], + '/settings/about-us', + ) }) }) @@ -183,13 +189,13 @@ describe('Account Menu', function () { it('renders import account item', function () { settings = wrapper.find({ text: 'settings' }) - assert.equal(settings.length, 1) + assert.strictEqual(settings.length, 1) }) it('calls toggle menu and push /new-account/connect route to history', function () { settings.simulate('click') assert(props.toggleAccountMenu.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/settings') + assert.strictEqual(props.history.push.getCall(0).args[0], '/settings') }) }) }) diff --git a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js b/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js index fff6504bb..d16ec36c0 100644 --- a/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js +++ b/ui/app/components/app/alerts/unconnected-account-alert/tests/unconnected-account-alert.test.js @@ -115,9 +115,9 @@ describe('Unconnected Account Alert', function () { const dontShowCheckbox = getByRole('checkbox') - assert.equal(dontShowCheckbox.checked, false) + assert.strictEqual(dontShowCheckbox.checked, false) fireEvent.click(dontShowCheckbox) - assert.equal(dontShowCheckbox.checked, true) + assert.strictEqual(dontShowCheckbox.checked, true) }) it('clicks dismiss button and calls dismissAlert action', function () { @@ -128,7 +128,10 @@ describe('Unconnected Account Alert', function () { const dismissButton = getByText(/dismiss/u) fireEvent.click(dismissButton) - assert.equal(store.getActions()[0].type, 'unconnectedAccount/dismissAlert') + assert.strictEqual( + store.getActions()[0].type, + 'unconnectedAccount/dismissAlert', + ) }) it('clicks Dont Show checkbox and dismiss to call disable alert request action', async function () { @@ -148,11 +151,11 @@ describe('Unconnected Account Alert', function () { fireEvent.click(dismissButton) setImmediate(() => { - assert.equal( + assert.strictEqual( store.getActions()[0].type, 'unconnectedAccount/disableAlertRequested', ) - assert.equal( + assert.strictEqual( store.getActions()[1].type, 'unconnectedAccount/disableAlertSucceeded', ) diff --git a/ui/app/components/app/app-header/tests/app-header.test.js b/ui/app/components/app/app-header/tests/app-header.test.js index 0bb9ed9df..7a1b43ee7 100644 --- a/ui/app/components/app/app-header/tests/app-header.test.js +++ b/ui/app/components/app/app-header/tests/app-header.test.js @@ -43,7 +43,7 @@ describe('App Header', function () { const appLogo = wrapper.find(MetaFoxLogo) appLogo.simulate('click') assert(props.history.push.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/') + assert.strictEqual(props.history.push.getCall(0).args[0], '/') }) }) @@ -74,7 +74,7 @@ describe('App Header', function () { it('hides network indicator', function () { wrapper.setProps({ hideNetworkIndicator: true }) const network = wrapper.find({ network: 'test' }) - assert.equal(network.length, 0) + assert.strictEqual(network.length, 0) }) }) diff --git a/ui/app/components/app/asset-list-item/asset-list-item.js b/ui/app/components/app/asset-list-item/asset-list-item.js index 274f0576b..b5164e39c 100644 --- a/ui/app/components/app/asset-list-item/asset-list-item.js +++ b/ui/app/components/app/asset-list-item/asset-list-item.js @@ -113,6 +113,7 @@ const AssetListItem = ({ diameter={32} address={tokenAddress} image={tokenImage} + alt={`${primary} ${tokenSymbol}`} /> } midContent={midContent} diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js index add78407c..ed6ac21f8 100644 --- a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js @@ -29,11 +29,11 @@ describe('Confirm Detail Row Component', function () { }) it('should render a div with a confirm-detail-row class', function () { - assert.equal(wrapper.find('div.confirm-detail-row').length, 1) + assert.strictEqual(wrapper.find('div.confirm-detail-row').length, 1) }) it('should render the label as a child of the confirm-detail-row__label', function () { - assert.equal( + assert.strictEqual( wrapper .find('.confirm-detail-row > .confirm-detail-row__label') .childAt(0) @@ -43,7 +43,7 @@ describe('Confirm Detail Row Component', function () { }) it('should render the headerText as a child of the confirm-detail-row__header-text', function () { - assert.equal( + assert.strictEqual( wrapper .find( '.confirm-detail-row__details > .confirm-detail-row__header-text', @@ -55,7 +55,7 @@ describe('Confirm Detail Row Component', function () { }) it('should render the primaryText as a child of the confirm-detail-row__primary', function () { - assert.equal( + assert.strictEqual( wrapper .find('.confirm-detail-row__details > .confirm-detail-row__primary') .childAt(0) @@ -65,7 +65,7 @@ describe('Confirm Detail Row Component', function () { }) it('should render the ethText as a child of the confirm-detail-row__secondary', function () { - assert.equal( + assert.strictEqual( wrapper .find('.confirm-detail-row__details > .confirm-detail-row__secondary') .childAt(0) @@ -75,14 +75,14 @@ describe('Confirm Detail Row Component', function () { }) it('should set the fiatTextColor on confirm-detail-row__primary', function () { - assert.equal( + assert.strictEqual( wrapper.find('.confirm-detail-row__primary').props().style.color, 'mockColor', ) }) it('should assure the confirm-detail-row__header-text classname is correct', function () { - assert.equal( + assert.strictEqual( wrapper.find('.confirm-detail-row__header-text').props().className, 'confirm-detail-row__header-text mockHeaderClass', ) diff --git a/ui/app/components/app/dropdowns/tests/dropdown.test.js b/ui/app/components/app/dropdowns/tests/dropdown.test.js index e362104ba..7ceb8227c 100644 --- a/ui/app/components/app/dropdowns/tests/dropdown.test.js +++ b/ui/app/components/app/dropdowns/tests/dropdown.test.js @@ -20,16 +20,16 @@ describe('Dropdown', function () { }) it('renders li with dropdown-menu-item class', function () { - assert.equal(wrapper.find('li.dropdown-menu-item').length, 1) + assert.strictEqual(wrapper.find('li.dropdown-menu-item').length, 1) }) it('adds style based on props passed', function () { - assert.equal(wrapper.prop('style').test, 'style') + assert.strictEqual(wrapper.prop('style').test, 'style') }) it('simulates click event and calls onClick and closeMenu', function () { wrapper.prop('onClick')() - assert.equal(onClickSpy.callCount, 1) - assert.equal(closeMenuSpy.callCount, 1) + assert.strictEqual(onClickSpy.callCount, 1) + assert.strictEqual(closeMenuSpy.callCount, 1) }) }) diff --git a/ui/app/components/app/dropdowns/tests/network-dropdown-icon.test.js b/ui/app/components/app/dropdowns/tests/network-dropdown-icon.test.js index f0370b148..01210b49d 100644 --- a/ui/app/components/app/dropdowns/tests/network-dropdown-icon.test.js +++ b/ui/app/components/app/dropdowns/tests/network-dropdown-icon.test.js @@ -14,9 +14,9 @@ describe('Network Dropdown Icon', function () { />, ) const styleProp = wrapper.find('.menu-icon-circle').children().prop('style') - assert.equal(styleProp.background, 'red') - assert.equal(styleProp.border, 'none') - assert.equal(styleProp.height, '12px') - assert.equal(styleProp.width, '12px') + assert.strictEqual(styleProp.background, 'red') + assert.strictEqual(styleProp.border, 'none') + assert.strictEqual(styleProp.height, '12px') + assert.strictEqual(styleProp.width, '12px') }) }) diff --git a/ui/app/components/app/dropdowns/tests/network-dropdown.test.js b/ui/app/components/app/dropdowns/tests/network-dropdown.test.js index 09bec2615..2df87f956 100644 --- a/ui/app/components/app/dropdowns/tests/network-dropdown.test.js +++ b/ui/app/components/app/dropdowns/tests/network-dropdown.test.js @@ -31,11 +31,11 @@ describe('Network Dropdown', function () { }) it('checks for network droppo class', function () { - assert.equal(wrapper.find('.network-droppo').length, 1) + assert.strictEqual(wrapper.find('.network-droppo').length, 1) }) it('renders only one child when networkDropdown is false in state', function () { - assert.equal(wrapper.children().length, 1) + assert.strictEqual(wrapper.children().length, 1) }) }) @@ -62,53 +62,53 @@ describe('Network Dropdown', function () { }) it('renders 8 DropDownMenuItems ', function () { - assert.equal(wrapper.find(DropdownMenuItem).length, 8) + assert.strictEqual(wrapper.find(DropdownMenuItem).length, 8) }) it('checks background color for first NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(0).prop('backgroundColor'), '#29B6AF', ) // Ethereum Mainnet Teal }) it('checks background color for second NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(1).prop('backgroundColor'), '#ff4a8d', ) // Ropsten Red }) it('checks background color for third NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(2).prop('backgroundColor'), '#7057ff', ) // Kovan Purple }) it('checks background color for fourth NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(3).prop('backgroundColor'), '#f6c343', ) // Rinkeby Yellow }) it('checks background color for fifth NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(4).prop('backgroundColor'), '#3099f2', ) // Goerli Blue }) it('checks background color for sixth NetworkDropdownIcon', function () { - assert.equal( + assert.strictEqual( wrapper.find(NetworkDropdownIcon).at(5).prop('backgroundColor'), '#d6d9dc', ) // "Custom network grey" }) it('checks dropdown for frequestRPCList from state', function () { - assert.equal( + assert.strictEqual( wrapper.find(DropdownMenuItem).at(6).text(), '✓http://localhost:7545', ) diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js index 161237c90..8c17f4d52 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js @@ -40,7 +40,7 @@ describe('Advanced Gas Inputs', function () { wrapper.find('input').at(0).simulate('change', event) clock.tick(499) - assert.equal(props.updateCustomGasPrice.callCount, 0) + assert.strictEqual(props.updateCustomGasPrice.callCount, 0) }) it('simulates onChange on gas price after debounce', function () { @@ -49,8 +49,8 @@ describe('Advanced Gas Inputs', function () { wrapper.find('input').at(0).simulate('change', event) clock.tick(500) - assert.equal(props.updateCustomGasPrice.calledOnce, true) - assert.equal(props.updateCustomGasPrice.calledWith(1), true) + assert.strictEqual(props.updateCustomGasPrice.calledOnce, true) + assert.strictEqual(props.updateCustomGasPrice.calledWith(1), true) }) it('wont update gasLimit in props before debounce', function () { @@ -59,7 +59,7 @@ describe('Advanced Gas Inputs', function () { wrapper.find('input').at(1).simulate('change', event) clock.tick(499) - assert.equal(props.updateCustomGasLimit.callCount, 0) + assert.strictEqual(props.updateCustomGasLimit.callCount, 0) }) it('simulates onChange on gas limit after debounce', function () { @@ -68,8 +68,8 @@ describe('Advanced Gas Inputs', function () { wrapper.find('input').at(1).simulate('change', event) clock.tick(500) - assert.equal(props.updateCustomGasLimit.calledOnce, true) - assert.equal(props.updateCustomGasLimit.calledWith(21000), true) + assert.strictEqual(props.updateCustomGasLimit.calledOnce, true) + assert.strictEqual(props.updateCustomGasLimit.calledWith(21000), true) }) it('errors when insufficientBalance under gas price and gas limit', function () { @@ -77,10 +77,10 @@ describe('Advanced Gas Inputs', function () { const renderError = wrapper.find( '.advanced-gas-inputs__gas-edit-row__error-text', ) - assert.equal(renderError.length, 2) + assert.strictEqual(renderError.length, 2) - assert.equal(renderError.at(0).text(), 'insufficientBalance') - assert.equal(renderError.at(1).text(), 'insufficientBalance') + assert.strictEqual(renderError.at(0).text(), 'insufficientBalance') + assert.strictEqual(renderError.at(1).text(), 'insufficientBalance') }) it('errors zero gas price / speed up', function () { @@ -89,10 +89,10 @@ describe('Advanced Gas Inputs', function () { const renderError = wrapper.find( '.advanced-gas-inputs__gas-edit-row__error-text', ) - assert.equal(renderError.length, 2) + assert.strictEqual(renderError.length, 2) - assert.equal(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError') - assert.equal(renderError.at(1).text(), 'gasLimitTooLowWithDynamicFee') + assert.strictEqual(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError') + assert.strictEqual(renderError.at(1).text(), 'gasLimitTooLowWithDynamicFee') }) it('warns when custom gas price is too low', function () { @@ -101,8 +101,8 @@ describe('Advanced Gas Inputs', function () { const renderWarning = wrapper.find( '.advanced-gas-inputs__gas-edit-row__warning-text', ) - assert.equal(renderWarning.length, 1) + assert.strictEqual(renderWarning.length, 1) - assert.equal(renderWarning.text(), 'gasPriceExtremelyLow') + assert.strictEqual(renderWarning.text(), 'gasPriceExtremelyLow') }) }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index c79122aa2..8f2ddbc6c 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -1,8 +1,5 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { decGWEIToHexWEI } from '../../../../../helpers/utils/conversions.util' -import Loading from '../../../../ui/loading-screen' -import GasPriceChart from '../../gas-price-chart' import AdvancedGasInputs from '../../advanced-gas-inputs' export default class AdvancedTabContent extends Component { @@ -15,65 +12,46 @@ export default class AdvancedTabContent extends Component { updateCustomGasLimit: PropTypes.func, customModalGasPriceInHex: PropTypes.string, customModalGasLimitInHex: PropTypes.string, - gasEstimatesLoading: PropTypes.bool, - millisecondsRemaining: PropTypes.number, transactionFee: PropTypes.string, - timeRemaining: PropTypes.string, - gasChartProps: PropTypes.object, insufficientBalance: PropTypes.bool, customPriceIsSafe: PropTypes.bool, isSpeedUp: PropTypes.bool, - isEthereumNetwork: PropTypes.bool, customGasLimitMessage: PropTypes.string, minimumGasLimit: PropTypes.number, } - renderDataSummary(transactionFee, timeRemaining) { + renderDataSummary(transactionFee) { return (
{this.context.t('newTransactionFee')} - ~{this.context.t('transactionTime')}
{transactionFee}
-
- {timeRemaining} -
) } - onGasChartUpdate = (price) => { - const { updateCustomGasPrice } = this.props - updateCustomGasPrice(decGWEIToHexWEI(price)) - } - render() { - const { t } = this.context const { updateCustomGasPrice, updateCustomGasLimit, - timeRemaining, customModalGasPriceInHex, customModalGasLimitInHex, insufficientBalance, - gasChartProps, - gasEstimatesLoading, customPriceIsSafe, isSpeedUp, transactionFee, - isEthereumNetwork, customGasLimitMessage, minimumGasLimit, } = this.props return (
- {this.renderDataSummary(transactionFee, timeRemaining)} + {this.renderDataSummary(transactionFee)}
- {isEthereumNetwork ? ( -
-
- {t('liveGasPricePredictions')} -
- {gasEstimatesLoading ? ( - - ) : ( - - )} -
- {t('slower')} - {t('faster')} -
-
- ) : ( -
- {t('chartOnlyAvailableEth')} -
- )}
) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index d6b21e04c..0371d1d14 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -2,8 +2,7 @@ display: flex; flex-flow: column; - &__transaction-data-summary, - &__fee-chart-title { + &__transaction-data-summary { padding-left: 24px; padding-right: 24px; } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 283240cef..b33dcadee 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -4,9 +4,6 @@ import sinon from 'sinon' import shallow from '../../../../../../../lib/shallow-with-context' import AdvancedTabContent from '../advanced-tab-content.component' -import GasPriceChart from '../../../gas-price-chart' -import Loading from '../../../../../ui/loading-screen' - describe('AdvancedTabContent Component', function () { let wrapper @@ -23,12 +20,10 @@ describe('AdvancedTabContent Component', function () { updateCustomGasLimit={propsMethodSpies.updateCustomGasLimit} customModalGasPriceInHex="11" customModalGasLimitInHex="23456" - timeRemaining="21500" transactionFee="$0.25" insufficientBalance={false} customPriceIsSafe isSpeedUp={false} - isEthereumNetwork />, ) }) @@ -42,68 +37,22 @@ describe('AdvancedTabContent Component', function () { assert(wrapper.hasClass('advanced-tab')) }) - it('should render the expected four children of the advanced-tab div', function () { + it('should render the expected child of the advanced-tab div', function () { const advancedTabChildren = wrapper.children() - assert.equal(advancedTabChildren.length, 2) + assert.strictEqual(advancedTabChildren.length, 2) assert( advancedTabChildren .at(0) .hasClass('advanced-tab__transaction-data-summary'), ) - assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart')) - - const feeChartDiv = advancedTabChildren.at(1) - - assert( - feeChartDiv - .childAt(1) - .childAt(0) - .hasClass('advanced-tab__fee-chart__title'), - ) - assert(feeChartDiv.childAt(1).childAt(1).is(GasPriceChart)) - assert( - feeChartDiv - .childAt(1) - .childAt(2) - .hasClass('advanced-tab__fee-chart__speed-buttons'), - ) - }) - - it('should render a loading component instead of the chart if gasEstimatesLoading is true', function () { - wrapper.setProps({ gasEstimatesLoading: true }) - const advancedTabChildren = wrapper.children() - assert.equal(advancedTabChildren.length, 2) - - assert( - advancedTabChildren - .at(0) - .hasClass('advanced-tab__transaction-data-summary'), - ) - assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart')) - - const feeChartDiv = advancedTabChildren.at(1) - - assert( - feeChartDiv - .childAt(1) - .childAt(0) - .hasClass('advanced-tab__fee-chart__title'), - ) - assert(feeChartDiv.childAt(1).childAt(1).is(Loading)) - assert( - feeChartDiv - .childAt(1) - .childAt(2) - .hasClass('advanced-tab__fee-chart__speed-buttons'), - ) }) it('should call renderDataSummary with the expected params', function () { const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall( 0, ).args - assert.deepEqual(renderDataSummaryArgs, ['$0.25', '21500']) + assert.deepStrictEqual(renderDataSummaryArgs, ['$0.25']) }) }) @@ -112,7 +61,7 @@ describe('AdvancedTabContent Component', function () { beforeEach(function () { dataSummary = shallow( - wrapper.instance().renderDataSummary('mockTotalFee', 'mockMsRemaining'), + wrapper.instance().renderDataSummary('mockTotalFee'), ) }) @@ -125,8 +74,10 @@ describe('AdvancedTabContent Component', function () { assert( titlesNode.hasClass('advanced-tab__transaction-data-summary__titles'), ) - assert.equal(titlesNode.children().at(0).text(), 'newTransactionFee') - assert.equal(titlesNode.children().at(1).text(), '~transactionTime') + assert.strictEqual( + titlesNode.children().at(0).text(), + 'newTransactionFee', + ) }) it('should render the data', function () { @@ -134,14 +85,7 @@ describe('AdvancedTabContent Component', function () { assert( dataNode.hasClass('advanced-tab__transaction-data-summary__container'), ) - assert.equal(dataNode.children().at(0).text(), 'mockTotalFee') - assert( - dataNode - .children() - .at(1) - .hasClass('advanced-tab__transaction-data-summary__time-remaining'), - ) - assert.equal(dataNode.children().at(1).text(), 'mockMsRemaining') + assert.strictEqual(dataNode.children().at(0).text(), 'mockTotalFee') }) }) }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js index 2c28fc556..ae0829db0 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js @@ -60,7 +60,7 @@ describe('BasicTabContent Component', function () { }) it('should render a GasPriceButtonGroup compenent', function () { - assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 1) }) it('should pass correct props to GasPriceButtonGroup', function () { @@ -72,22 +72,22 @@ describe('BasicTabContent Component', function () { noButtonActiveByDefault, showCheck, } = wrapper.find(GasPriceButtonGroup).props() - assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) - assert.equal( + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 1) + assert.strictEqual( buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading, ) - assert.equal(className, mockGasPriceButtonGroupProps.className) - assert.equal( + assert.strictEqual(className, mockGasPriceButtonGroupProps.className) + assert.strictEqual( noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault, ) - assert.equal(showCheck, mockGasPriceButtonGroupProps.showCheck) - assert.deepEqual( + assert.strictEqual(showCheck, mockGasPriceButtonGroupProps.showCheck) + assert.deepStrictEqual( gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo, ) - assert.equal( + assert.strictEqual( JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection), ) @@ -101,8 +101,8 @@ describe('BasicTabContent Component', function () { }, }) - assert.equal(wrapper.find(GasPriceButtonGroup).length, 0) - assert.equal(wrapper.find(Loading).length, 1) + assert.strictEqual(wrapper.find(GasPriceButtonGroup).length, 0) + assert.strictEqual(wrapper.find(Loading).length, 1) }) }) }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 4fe7ad979..05810f07f 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -16,13 +16,9 @@ export default class GasModalPageContainer extends Component { hideBasic: PropTypes.bool, updateCustomGasPrice: PropTypes.func, updateCustomGasLimit: PropTypes.func, - currentTimeEstimate: PropTypes.string, insufficientBalance: PropTypes.bool, - fetchBasicGasAndTimeEstimates: PropTypes.func, - fetchGasEstimates: PropTypes.func, + fetchBasicGasEstimates: PropTypes.func, gasPriceButtonGroupProps: PropTypes.object, - gasChartProps: PropTypes.object, - gasEstimatesLoading: PropTypes.bool, infoRowProps: PropTypes.shape({ originalTotalFiat: PropTypes.string, originalTotalEth: PropTypes.string, @@ -35,24 +31,14 @@ export default class GasModalPageContainer extends Component { customModalGasPriceInHex: PropTypes.string, customModalGasLimitInHex: PropTypes.string, cancelAndClose: PropTypes.func, - blockTime: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), customPriceIsSafe: PropTypes.bool, isSpeedUp: PropTypes.bool, isRetry: PropTypes.bool, disableSave: PropTypes.bool, - isEthereumNetwork: PropTypes.bool, } componentDidMount() { - const promise = this.props.hideBasic - ? Promise.resolve(this.props.blockTime) - : this.props - .fetchBasicGasAndTimeEstimates() - .then((basicEstimates) => basicEstimates.blockTime) - - promise.then((blockTime) => { - this.props.fetchGasEstimates(blockTime) - }) + this.props.fetchBasicGasEstimates() } renderBasicTabContent(gasPriceButtonGroupProps) { @@ -67,15 +53,11 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit, customModalGasPriceInHex, customModalGasLimitInHex, - gasChartProps, - currentTimeEstimate, insufficientBalance, - gasEstimatesLoading, customPriceIsSafe, isSpeedUp, isRetry, infoRowProps: { transactionFee }, - isEthereumNetwork, } = this.props return ( @@ -84,15 +66,11 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit={updateCustomGasLimit} customModalGasPriceInHex={customModalGasPriceInHex} customModalGasLimitInHex={customModalGasLimitInHex} - timeRemaining={currentTimeEstimate} transactionFee={transactionFee} - gasChartProps={gasChartProps} insufficientBalance={insufficientBalance} - gasEstimatesLoading={gasEstimatesLoading} customPriceIsSafe={customPriceIsSafe} isSpeedUp={isSpeedUp} isRetry={isRetry} - isEthereumNetwork={isEthereumNetwork} /> ) } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index e383d1bac..bdf987c8a 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -1,5 +1,4 @@ import { connect } from 'react-redux' -import { captureException } from '@sentry/browser' import { addHexPrefix } from '../../../../../../app/scripts/lib/util' import { hideModal, @@ -16,8 +15,7 @@ import { setCustomGasPrice, setCustomGasLimit, resetCustomData, - fetchGasEstimates, - fetchBasicGasAndTimeEstimates, + fetchBasicGasEstimates, } from '../../../../ducks/gas/gas.duck' import { hideGasButtonGroup, @@ -29,21 +27,16 @@ import { getCurrentEthBalance, getIsMainnet, getSendToken, - isEthereumNetwork, getPreferences, getBasicGasEstimateLoadingStatus, - getGasEstimatesLoadingStatus, getCustomGasLimit, getCustomGasPrice, getDefaultActiveButtonIndex, - getEstimatedGasPrices, - getEstimatedGasTimes, getRenderableBasicEstimateData, - getBasicGasEstimateBlockTime, isCustomPriceSafe, getTokenBalance, getSendMaxModeState, - getFastPriceEstimateInHexWEI, + getAveragePriceEstimateInHexWEI, } from '../../../../selectors' import { @@ -53,7 +46,6 @@ import { getValueFromWeiHex, sumHexWEIsToRenderableFiat, } from '../../../../helpers/utils/conversions.util' -import { getRenderableTimeEstimate } from '../../../../helpers/utils/gas-time-estimates.util' import { formatETHFee } from '../../../../helpers/utils/formatters' import { calcGasTotal, @@ -73,7 +65,6 @@ const mapStateToProps = (state, ownProps) => { ({ id }) => id === (transaction.id || txData.id), ) const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) - const gasEstimatesLoading = getGasEstimatesLoadingStatus(state) const sendToken = getSendToken(state) // a "default" txParams is used during the send flow, since the transaction doesn't exist yet in that case @@ -81,7 +72,7 @@ const mapStateToProps = (state, ownProps) => { ? selectedTransaction.txParams : { gas: send.gasLimit || '0x5208', - gasPrice: send.gasPrice || getFastPriceEstimateInHexWEI(state, true), + gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state, true), value: sendToken ? '0x0' : send.amount, } @@ -113,8 +104,6 @@ const mapStateToProps = (state, ownProps) => { const maxModeOn = getSendMaxModeState(state) - const gasPrices = getEstimatedGasPrices(state) - const estimatedTimes = getEstimatedGasTimes(state) const balance = getCurrentEthBalance(state) const { showFiatInTestnets } = getPreferences(state) @@ -142,17 +131,6 @@ const mapStateToProps = (state, ownProps) => { conversionRate, }) - let currentTimeEstimate = '' - try { - currentTimeEstimate = getRenderableTimeEstimate( - customGasPrice, - gasPrices, - estimatedTimes, - ) - } catch (error) { - captureException(error) - } - return { hideBasic, isConfirm: isConfirm(state), @@ -162,8 +140,6 @@ const mapStateToProps = (state, ownProps) => { customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), customGasTotal, newTotalFiat, - currentTimeEstimate, - blockTime: getBasicGasEstimateBlockTime(state), customPriceIsSafe: isCustomPriceSafe(state), maxModeOn, gasPriceButtonGroupProps: { @@ -174,13 +150,6 @@ const mapStateToProps = (state, ownProps) => { ), gasButtonInfo, }, - gasChartProps: { - currentPrice: customGasPrice, - gasPrices, - estimatedTimes, - gasPricesMax: gasPrices[gasPrices.length - 1], - estimatedTimesMax: estimatedTimes[0], - }, infoRowProps: { originalTotalFiat: sumHexWEIsToRenderableFiat( [value, customGasTotal], @@ -198,9 +167,7 @@ const mapStateToProps = (state, ownProps) => { isRetry: transaction.status === TRANSACTION_STATUSES.FAILED, txId: transaction.id, insufficientBalance, - gasEstimatesLoading, isMainnet, - isEthereumNetwork: isEthereumNetwork(state), sendToken, balance, tokenBalance: getTokenBalance(state), @@ -239,9 +206,7 @@ const mapDispatchToProps = (dispatch) => { }, hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), hideSidebar: () => dispatch(hideSidebar()), - fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), - fetchBasicGasAndTimeEstimates: () => - dispatch(fetchBasicGasAndTimeEstimates()), + fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), setGasTotal: (total) => dispatch(setGasTotal(total)), setAmountToMax: (maxAmountDataObject) => { dispatch(updateSendErrors({ amount: null })) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index b3c9f98f5..8ae08274c 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -3,23 +3,21 @@ import React from 'react' import sinon from 'sinon' import shallow from '../../../../../../lib/shallow-with-context' import GasModalPageContainer from '../gas-modal-page-container.component' -import timeout from '../../../../../../lib/test-timeout' import PageContainer from '../../../../ui/page-container' import { Tab } from '../../../../ui/tabs' const mockBasicGasEstimates = { - blockTime: 'mockBlockTime', + average: '20', } const propsMethodSpies = { cancelAndClose: sinon.spy(), onSubmit: sinon.spy(), - fetchBasicGasAndTimeEstimates: sinon + fetchBasicGasEstimates: sinon .stub() .returns(Promise.resolve(mockBasicGasEstimates)), - fetchGasEstimates: sinon.spy(), } const mockGasPriceButtonGroupProps = { @@ -70,17 +68,11 @@ describe('GasModalPageContainer Component', function () { 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} - customGasPrice={21} - customGasLimit={54321} gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} infoRowProps={mockInfoRowProps} - currentTimeEstimate="1 min 31 sec" customGasPriceInHex="mockCustomGasPriceInHex" customGasLimitInHex="mockCustomGasLimitInHex" insufficientBalance={false} @@ -94,54 +86,40 @@ describe('GasModalPageContainer Component', function () { }) describe('componentDidMount', function () { - it('should call props.fetchBasicGasAndTimeEstimates', function () { - propsMethodSpies.fetchBasicGasAndTimeEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchBasicGasAndTimeEstimates.callCount, 0) + it('should call props.fetchBasicGasEstimates', function () { + propsMethodSpies.fetchBasicGasEstimates.resetHistory() + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) wrapper.instance().componentDidMount() - assert.equal(propsMethodSpies.fetchBasicGasAndTimeEstimates.callCount, 1) - }) - - it('should call props.fetchGasEstimates with the block time returned by fetchBasicGasAndTimeEstimates', async function () { - propsMethodSpies.fetchGasEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 0) - wrapper.instance().componentDidMount() - await timeout(250) - assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1) - assert.equal( - propsMethodSpies.fetchGasEstimates.getCall(0).args[0], - 'mockBlockTime', - ) + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) }) }) describe('render', function () { it('should render a PageContainer compenent', function () { - assert.equal(wrapper.find(PageContainer).length, 1) + assert.strictEqual(wrapper.find(PageContainer).length, 1) }) it('should pass correct props to PageContainer', function () { const { title, subtitle, disabled } = wrapper.find(PageContainer).props() - assert.equal(title, 'customGas') - assert.equal(subtitle, 'customGasSubTitle') - assert.equal(disabled, false) + assert.strictEqual(title, 'customGas') + assert.strictEqual(subtitle, 'customGasSubTitle') + assert.strictEqual(disabled, false) }) it('should pass the correct onCancel and onClose methods to PageContainer', function () { const { onCancel, onClose } = wrapper.find(PageContainer).props() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 0) + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 0) onCancel() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 1) + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 1) onClose() - assert.equal(propsMethodSpies.cancelAndClose.callCount, 2) + assert.strictEqual(propsMethodSpies.cancelAndClose.callCount, 2) }) it('should pass the correct renderTabs property to PageContainer', function () { sinon.stub(GP, 'renderTabs').returns('mockTabs') const renderTabsWrapperTester = shallow( , { context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, @@ -149,7 +127,7 @@ describe('GasModalPageContainer Component', function () { const { tabsComponent } = renderTabsWrapperTester .find(PageContainer) .props() - assert.equal(tabsComponent, 'mockTabs') + assert.strictEqual(tabsComponent, 'mockTabs') GasModalPageContainer.prototype.renderTabs.restore() }) }) @@ -170,32 +148,38 @@ describe('GasModalPageContainer Component', function () { it('should render a Tabs component with "Basic" and "Advanced" tabs', function () { const renderTabsResult = wrapper.instance().renderTabs() const renderedTabs = shallow(renderTabsResult) - assert.equal(renderedTabs.props().className, 'tabs') + assert.strictEqual(renderedTabs.props().className, 'tabs') const tabs = renderedTabs.find(Tab) - assert.equal(tabs.length, 2) + assert.strictEqual(tabs.length, 2) - assert.equal(tabs.at(0).props().name, 'basic') - assert.equal(tabs.at(1).props().name, 'advanced') + assert.strictEqual(tabs.at(0).props().name, 'basic') + assert.strictEqual(tabs.at(1).props().name, 'advanced') - assert.equal(tabs.at(0).childAt(0).props().className, 'gas-modal-content') - assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content') + assert.strictEqual( + tabs.at(0).childAt(0).props().className, + 'gas-modal-content', + ) + assert.strictEqual( + tabs.at(1).childAt(0).props().className, + 'gas-modal-content', + ) }) it('should call renderInfoRows with the expected props', function () { - assert.equal(GP.renderInfoRows.callCount, 0) + assert.strictEqual(GP.renderInfoRows.callCount, 0) wrapper.instance().renderTabs() - assert.equal(GP.renderInfoRows.callCount, 2) + assert.strictEqual(GP.renderInfoRows.callCount, 2) - assert.deepEqual(GP.renderInfoRows.getCall(0).args, [ + assert.deepStrictEqual(GP.renderInfoRows.getCall(0).args, [ 'mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', 'mockTransactionFee', ]) - assert.deepEqual(GP.renderInfoRows.getCall(1).args, [ + assert.deepStrictEqual(GP.renderInfoRows.getCall(1).args, [ 'mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', @@ -208,17 +192,11 @@ describe('GasModalPageContainer Component', function () { 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} - customGasPrice={21} - customGasLimit={54321} gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} infoRowProps={mockInfoRowProps} - currentTimeEstimate="1 min 31 sec" customGasPriceInHex="mockCustomGasPriceInHex" customGasLimitInHex="mockCustomGasLimitInHex" insufficientBalance={false} @@ -230,8 +208,8 @@ describe('GasModalPageContainer Component', function () { const renderedTabs = shallow(renderTabsResult) const tabs = renderedTabs.find(Tab) - assert.equal(tabs.length, 1) - assert.equal(tabs.at(0).props().name, 'advanced') + assert.strictEqual(tabs.length, 1) + assert.strictEqual(tabs.at(0).props().name, 'advanced') }) }) @@ -241,7 +219,7 @@ describe('GasModalPageContainer Component', function () { .instance() .renderBasicTabContent(mockGasPriceButtonGroupProps) - assert.deepEqual( + assert.deepStrictEqual( renderBasicTabContentResult.props.gasPriceButtonGroupProps, mockGasPriceButtonGroupProps, ) @@ -265,7 +243,7 @@ describe('GasModalPageContainer Component', function () { assert(renderedInfoRowsContainer.childAt(0).hasClass(baseClassName)) const renderedInfoRows = renderedInfoRowsContainer.childAt(0).children() - assert.equal(renderedInfoRows.length, 4) + assert.strictEqual(renderedInfoRows.length, 4) assert(renderedInfoRows.at(0).hasClass(`${baseClassName}__send-info`)) assert( renderedInfoRows.at(1).hasClass(`${baseClassName}__transaction-info`), @@ -275,13 +253,19 @@ describe('GasModalPageContainer Component', function () { renderedInfoRows.at(3).hasClass(`${baseClassName}__fiat-total-info`), ) - assert.equal(renderedInfoRows.at(0).text(), 'sendAmount mockSendAmount') - assert.equal( + assert.strictEqual( + renderedInfoRows.at(0).text(), + 'sendAmount mockSendAmount', + ) + assert.strictEqual( renderedInfoRows.at(1).text(), 'transactionFee mockTransactionFee', ) - assert.equal(renderedInfoRows.at(2).text(), 'newTotal mockNewTotalEth') - assert.equal(renderedInfoRows.at(3).text(), 'mockNewTotalFiat') + assert.strictEqual( + renderedInfoRows.at(2).text(), + 'newTotal mockNewTotalEth', + ) + assert.strictEqual(renderedInfoRows.at(3).text(), 'mockNewTotalFiat') }) }) }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 49687ee89..81934468c 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -104,7 +104,6 @@ describe('gas-modal-page-container container', function () { limit: 'aaaaaaaa', price: 'ffffffff', }, - gasEstimatesLoading: false, priceAndTimeEstimates: [ { gasprice: 3, expectedTime: 31 }, { gasprice: 4, expectedTime: 62 }, @@ -127,27 +126,17 @@ describe('gas-modal-page-container container', function () { isConfirm: true, customGasPrice: 4.294967295, customGasLimit: 2863311530, - currentTimeEstimate: '~1 min 11 sec', newTotalFiat: '637.41', - blockTime: 12, conversionRate: 50, customModalGasLimitInHex: 'aaaaaaaa', customModalGasPriceInHex: 'ffffffff', customGasTotal: 'aaaaaaa955555556', customPriceIsSafe: true, - gasChartProps: { - currentPrice: 4.294967295, - estimatedTimes: [31, 62, 93, 124], - estimatedTimesMax: 31, - gasPrices: [3, 4, 5, 6], - gasPricesMax: 6, - }, gasPriceButtonGroupProps: { buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, - gasEstimatesLoading: false, hideBasic: true, infoRowProps: { originalTotalFiat: '637.41', @@ -161,7 +150,6 @@ describe('gas-modal-page-container container', function () { isSpeedUp: false, isRetry: false, txId: 34, - isEthereumNetwork: true, isMainnet: true, maxModeOn: false, sendToken: null, diff --git a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.component.js b/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.component.js deleted file mode 100644 index e01001ebf..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.component.js +++ /dev/null @@ -1,123 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import * as d3 from 'd3' -import { - generateChart, - getCoordinateData, - handleChartUpdate, - hideDataUI, - setTickPosition, - handleMouseMove, -} from './gas-price-chart.utils' - -export default class GasPriceChart extends Component { - static contextTypes = { - t: PropTypes.func, - } - - static propTypes = { - gasPrices: PropTypes.array, - estimatedTimes: PropTypes.array, - gasPricesMax: PropTypes.number, - estimatedTimesMax: PropTypes.number, - currentPrice: PropTypes.number, - updateCustomGasPrice: PropTypes.func, - } - - renderChart() { - const { - currentPrice, - gasPrices, - estimatedTimes, - gasPricesMax, - estimatedTimesMax, - updateCustomGasPrice, - } = this.props - const chart = generateChart( - gasPrices, - estimatedTimes, - gasPricesMax, - estimatedTimesMax, - this.context.t, - ) - setTimeout(function () { - setTickPosition('y', 0, -5, 8) - setTickPosition('y', 1, -3, -5) - setTickPosition('x', 0, 3) - setTickPosition('x', 1, 3, -8) - - const { x: domainX } = getCoordinateData('.domain') - const { x: yAxisX } = getCoordinateData('.c3-axis-y-label') - const { x: tickX } = getCoordinateData('.c3-axis-x .tick') - - d3.select('.c3-axis-x .tick').attr( - 'transform', - `translate(${(domainX - tickX) / 2}, 0)`, - ) - d3.select('.c3-axis-x-label').attr('transform', 'translate(0,-15)') - d3.select('.c3-axis-y-label').attr( - 'transform', - `translate(${domainX - yAxisX - 12}, 2) rotate(-90)`, - ) - d3.select('.c3-xgrid-focus line').attr('y2', 98) - - d3.select('.c3-chart').on('mouseout', () => { - hideDataUI(chart, '#overlayed-circle') - }) - - d3.select('.c3-chart').on('click', () => { - const { x: newGasPrice } = d3.select('#overlayed-circle').datum() - updateCustomGasPrice(newGasPrice) - }) - - const { x: chartXStart, width: chartWidth } = getCoordinateData( - '.c3-areas-data1', - ) - - handleChartUpdate({ - chart, - gasPrices, - newPrice: currentPrice, - cssId: '#set-circle', - }) - - d3.select('.c3-chart').on('mousemove', function () { - handleMouseMove({ - xMousePos: d3.event.clientX, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, - chart, - }) - }) - }, 0) - - this.chart = chart - } - - componentDidUpdate(prevProps) { - const { gasPrices, currentPrice: newPrice } = this.props - - if (prevProps.currentPrice !== newPrice) { - handleChartUpdate({ - chart: this.chart, - gasPrices, - newPrice, - cssId: '#set-circle', - }) - } - } - - componentDidMount() { - this.renderChart() - } - - render() { - return ( -
-
-
- ) - } -} diff --git a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js deleted file mode 100644 index 6fa809686..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ /dev/null @@ -1,422 +0,0 @@ -import * as d3 from 'd3' -import c3 from 'c3' -import { - extrapolateY, - getAdjacentGasPrices, - newBigSigDig, - bigNumMinus, - bigNumDiv, -} from '../../../../helpers/utils/gas-time-estimates.util' - -export function handleMouseMove({ - xMousePos, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, - chart, -}) { - const { currentPosValue, newTimeEstimate } = getNewXandTimeEstimate({ - xMousePos, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, - }) - - if (currentPosValue === null && newTimeEstimate === null) { - hideDataUI(chart, '#overlayed-circle') - return - } - - const indexOfNewCircle = estimatedTimes.length + 1 - const dataUIObj = generateDataUIObj( - currentPosValue, - indexOfNewCircle, - newTimeEstimate, - ) - - chart.internal.overlayPoint(dataUIObj, indexOfNewCircle) - chart.internal.showTooltip( - [dataUIObj], - d3.select('.c3-areas-data1')._groups[0], - ) - chart.internal.showXGridFocus([dataUIObj]) -} - -export function getCoordinateData(selector) { - const node = d3.select(selector).node() - return node ? node.getBoundingClientRect() : {} -} - -export function generateDataUIObj(x, index, value) { - return { - x, - value, - index, - id: 'data1', - name: 'data1', - } -} - -export function handleChartUpdate({ chart, gasPrices, newPrice, cssId }) { - const { - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: newPrice }) - - if (closestLowerValue && closestHigherValue) { - setSelectedCircle({ - chart, - newPrice, - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - }) - } else { - hideDataUI(chart, cssId) - } -} - -export function getNewXandTimeEstimate({ - xMousePos, - chartXStart, - chartWidth, - gasPrices, - estimatedTimes, -}) { - const chartMouseXPos = bigNumMinus(xMousePos, chartXStart) - const posPercentile = bigNumDiv(chartMouseXPos, chartWidth) - - const currentPosValue = bigNumMinus( - gasPrices[gasPrices.length - 1], - gasPrices[0], - ) - .times(newBigSigDig(posPercentile)) - .plus(newBigSigDig(gasPrices[0])) - .toNumber() - - const { - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: currentPosValue }) - - return !closestHigherValue || !closestLowerValue - ? { - currentPosValue: null, - newTimeEstimate: null, - } - : { - currentPosValue, - newTimeEstimate: extrapolateY({ - higherY: estimatedTimes[closestHigherValueIndex], - lowerY: estimatedTimes[closestLowerValueIndex], - higherX: closestHigherValue, - lowerX: closestLowerValue, - xForExtrapolation: currentPosValue, - }), - } -} - -export function hideDataUI(chart, dataNodeId) { - const overLayedCircle = d3.select(dataNodeId) - if (!overLayedCircle.empty()) { - overLayedCircle.remove() - } - d3.select('.c3-tooltip-container').style('display', 'none !important') - chart.internal.hideXGridFocus() -} - -export function setTickPosition(axis, n, newPosition, secondNewPosition) { - const positionToShift = axis === 'y' ? 'x' : 'y' - const secondPositionToShift = axis === 'y' ? 'y' : 'x' - d3.select('#chart') - .select(`.c3-axis-${axis}`) - .selectAll('.tick') - .filter((_, i) => i === n) - .select('text') - .attr(positionToShift, 0) - .select('tspan') - .attr(positionToShift, newPosition) - .attr(secondPositionToShift, secondNewPosition || 0) - .style('visibility', 'visible') -} - -/* eslint-disable @babel/no-invalid-this */ -export function appendOrUpdateCircle({ - data, - itemIndex, - cx, - cy, - cssId, - appendOnly, -}) { - const circle = this.main - .select(`.c3-selected-circles${this.getTargetSelectorSuffix(data.id)}`) - .selectAll(`.c3-selected-circle-${itemIndex}`) - - if (appendOnly || circle.empty()) { - circle - .data([data]) - .enter() - .append('circle') - .attr('class', () => this.generateClass('c3-selected-circle', itemIndex)) - .attr('id', cssId) - .attr('cx', cx) - .attr('cy', cy) - .attr('stroke', () => this.color(data)) - .attr('r', 6) - } else { - circle.data([data]).attr('cx', cx).attr('cy', cy) - } -} -/* eslint-enable @babel/no-invalid-this */ - -export function setSelectedCircle({ - chart, - newPrice, - closestLowerValueIndex, - closestLowerValue, - closestHigherValueIndex, - closestHigherValue, -}) { - const numberOfValues = chart.internal.data.xs.data1.length - - const { x: lowerX, y: lowerY } = getCoordinateData( - `.c3-circle-${closestLowerValueIndex}`, - ) - let { x: higherX, y: higherY } = getCoordinateData( - `.c3-circle-${closestHigherValueIndex}`, - ) - let count = closestHigherValueIndex + 1 - - if (lowerX && higherX) { - while (lowerX === higherX) { - higherX = getCoordinateData(`.c3-circle-${count}`).x - higherY = getCoordinateData(`.c3-circle-${count}`).y - count += 1 - } - } - - const currentX = bigNumMinus(higherX, lowerX) - .times(bigNumMinus(newPrice, closestLowerValue)) - .div(bigNumMinus(closestHigherValue, closestLowerValue)) - .plus(newBigSigDig(lowerX)) - - const newTimeEstimate = extrapolateY({ - higherY, - lowerY, - higherX, - lowerX, - xForExtrapolation: currentX, - }) - - chart.internal.selectPoint( - generateDataUIObj(currentX.toNumber(), numberOfValues, newTimeEstimate), - numberOfValues, - ) -} - -export function generateChart( - gasPrices, - estimatedTimes, - gasPricesMax, - estimatedTimesMax, -) { - const gasPricesMaxPadded = gasPricesMax + 1 - const chart = c3.generate({ - size: { - height: 165, - }, - transition: { - duration: 0, - }, - padding: { left: 20, right: 15, top: 6, bottom: 10 }, - data: { - x: 'x', - columns: [ - ['x', ...gasPrices], - ['data1', ...estimatedTimes], - ], - types: { - data1: 'area', - }, - selection: { - enabled: false, - }, - }, - color: { - data1: '#259de5', - }, - axis: { - x: { - min: gasPrices[0], - max: gasPricesMax, - tick: { - values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMax)], - outer: false, - format(val) { - return `${val} GWEI` - }, - }, - padding: { left: gasPricesMax / 50, right: gasPricesMax / 50 }, - label: { - text: 'Gas Price ($)', - position: 'outer-center', - }, - }, - y: { - padding: { top: 7, bottom: 7 }, - tick: { - values: [ - Math.floor(estimatedTimesMax * 0.05), - Math.ceil(estimatedTimesMax * 0.97), - ], - outer: false, - }, - label: { - text: 'Confirmation time (sec)', - position: 'outer-middle', - }, - min: 0, - }, - }, - legend: { - show: false, - }, - grid: { - x: {}, - lines: { - front: false, - }, - }, - point: { - focus: { - expand: { - enabled: false, - r: 3.5, - }, - }, - }, - tooltip: { - format: { - title: (v) => v.toPrecision(4), - }, - contents(d) { - const titleFormat = this.config.tooltip_format_title - let text - d.forEach((el) => { - if (el && (el.value || el.value === 0) && !text) { - text = `` - } - }) - return `${text}
${titleFormat( - el.x, - )}
` - }, - position() { - if (d3.select('#overlayed-circle').empty()) { - return { top: -100, left: -100 } - } - - const { - x: circleX, - y: circleY, - width: circleWidth, - } = getCoordinateData('#overlayed-circle') - const { x: chartXStart, y: chartYStart } = getCoordinateData( - '.c3-chart', - ) - - // TODO: Confirm the below constants work with all data sets and screen sizes - const flipTooltip = circleY - circleWidth < chartYStart + 5 - - d3.select('.tooltip-arrow').style( - 'margin-top', - flipTooltip ? '-16px' : '4px', - ) - - return { - top: bigNumMinus(circleY, chartYStart) - .minus(19) - .plus(flipTooltip ? circleWidth + 38 : 0) - .toNumber(), - left: bigNumMinus(circleX, chartXStart) - .plus(newBigSigDig(circleWidth)) - .minus(bigNumDiv(gasPricesMaxPadded, 50)) - .toNumber(), - } - }, - show: true, - }, - }) - - chart.internal.selectPoint = function (data, itemIndex = data.index || 0) { - const { x: chartXStart, y: chartYStart } = getCoordinateData( - '.c3-areas-data1', - ) - - d3.select('#set-circle').remove() - - appendOrUpdateCircle.bind(this)({ - data, - itemIndex, - cx: () => bigNumMinus(data.x, chartXStart).plus(11).toNumber(), - cy: () => bigNumMinus(data.value, chartYStart).plus(10).toNumber(), - cssId: 'set-circle', - appendOnly: true, - }) - } - - chart.internal.overlayPoint = function (data, itemIndex) { - appendOrUpdateCircle.bind(this)({ - data, - itemIndex, - cx: this.circleX.bind(this), - cy: this.circleY.bind(this), - cssId: 'overlayed-circle', - }) - } - - chart.internal.showTooltip = function (selectedData, element) { - const dataToShow = selectedData.filter( - (d) => d && (d.value || d.value === 0), - ) - - if (dataToShow.length) { - this.tooltip - .html( - this.config.tooltip_contents.call( - this, - selectedData, - this.axis.getXAxisTickFormat(), - this.getYFormat(), - this.color, - ), - ) - .style('display', 'flex') - - // Get tooltip dimensions - const tWidth = this.tooltip.property('offsetWidth') - const tHeight = this.tooltip.property('offsetHeight') - const position = this.config.tooltip_position.call( - this, - dataToShow, - tWidth, - tHeight, - element, - ) - // Set tooltip - this.tooltip - .style('top', `${position.top}px`) - .style('left', `${position.left}px`) - } - } - - return chart -} diff --git a/ui/app/components/app/gas-customization/gas-price-chart/index.js b/ui/app/components/app/gas-customization/gas-price-chart/index.js deleted file mode 100644 index 9895acb62..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './gas-price-chart.component' diff --git a/ui/app/components/app/gas-customization/gas-price-chart/index.scss b/ui/app/components/app/gas-customization/gas-price-chart/index.scss deleted file mode 100644 index 8d204e9ec..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/index.scss +++ /dev/null @@ -1,134 +0,0 @@ -.gas-price-chart { - display: flex; - position: relative; - justify-content: center; - - &__root { - max-height: 154px; - max-width: 391px; - position: relative; - overflow: hidden; - - @media screen and (max-width: $break-small) { - max-width: 326px; - } - } - - .tick text, - .c3-axis-x-label, - .c3-axis-y-label { - @include H9; - - line-height: normal; - font-weight: bold; - text-align: center; - fill: #9a9ca6 !important; - } - - .c3-tooltip-container { - display: flex; - justify-content: center !important; - align-items: flex-end !important; - } - - .custom-tooltip { - background: rgba(0, 0, 0, 1); - box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); - border-radius: 3px; - opacity: 1 !important; - height: 21px; - z-index: 1; - } - - .tooltip-arrow { - background: black; - box-shadow: 0 4px 4px rgba(0, 0, 0, 0.5); - -webkit-transform: rotate(45deg); - transform: rotate(45deg); - opacity: 1 !important; - width: 9px; - height: 9px; - margin-top: 4px; - } - - .custom-tooltip th { - @include H8; - - font-weight: 500; - text-align: center; - padding: 3px; - color: #fff; - } - - .c3-circle { - visibility: hidden; - } - - .c3-selected-circle, - .c3-circle._expanded_ { - fill: #fff !important; - stroke-width: 2.4px !important; - stroke: #2d9fd9 !important; - - /* visibility: visible; */ - } - - #set-circle { - fill: #313a5e !important; - stroke: #313a5e !important; - } - - .c3-axis-x-label, - .c3-axis-y-label { - font-weight: normal; - } - - .tick text tspan { - visibility: hidden; - } - - .c3-circle { - fill: #2d9fd9 !important; - } - - .c3-line-data1 { - stroke: #2d9fd9 !important; - background: rgba(0, 0, 0, 0) !important; - color: rgba(0, 0, 0, 0) !important; - } - - .c3 path { - fill: none; - } - - .c3 path.c3-area-data1 { - opacity: 1; - fill: #e9edf1 !important; - } - - .c3-xgrid-line line { - stroke: #b8b8b8 !important; - } - - .c3-xgrid-focus { - stroke: #aaa; - } - - .c3-axis-x .domain { - fill: none; - stroke: none; - } - - .c3-axis-y .domain { - fill: none; - stroke: #c8ccd6; - } - - .c3-event-rect { - cursor: pointer; - } -} - -#chart { - background: #f8f9fb; -} diff --git a/ui/app/components/app/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js b/ui/app/components/app/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js deleted file mode 100644 index 6256b8734..000000000 --- a/ui/app/components/app/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js +++ /dev/null @@ -1,258 +0,0 @@ -import assert from 'assert' -import React from 'react' -import proxyquire from 'proxyquire' -import sinon from 'sinon' -import * as d3 from 'd3' -import shallow from '../../../../../../lib/shallow-with-context' - -function timeout(time) { - return new Promise((resolve) => { - setTimeout(resolve, time) - }) -} - -describe('GasPriceChart Component', function () { - let GasPriceChart - let gasPriceChartUtilsSpies - let propsMethodSpies - let selectReturnSpies - let testProps - let wrapper - - beforeEach(function () { - propsMethodSpies = { - updateCustomGasPrice: sinon.spy(), - } - - selectReturnSpies = { - empty: sinon.spy(), - remove: sinon.spy(), - style: sinon.spy(), - select: d3.select, - attr: sinon.spy(), - on: sinon.spy(), - datum: sinon.stub().returns({ x: 'mockX' }), - } - - const mockSelectReturn = { - ...d3.select('div'), - node: () => ({ - getBoundingClientRect: () => ({ x: 123, y: 321, width: 400 }), - }), - ...selectReturnSpies, - } - - gasPriceChartUtilsSpies = { - appendOrUpdateCircle: sinon.spy(), - generateChart: sinon.stub().returns({ mockChart: true }), - generateDataUIObj: sinon.spy(), - getAdjacentGasPrices: sinon.spy(), - getCoordinateData: sinon - .stub() - .returns({ x: 'mockCoordinateX', width: 'mockWidth' }), - getNewXandTimeEstimate: sinon.spy(), - handleChartUpdate: sinon.spy(), - hideDataUI: sinon.spy(), - setSelectedCircle: sinon.spy(), - setTickPosition: sinon.spy(), - handleMouseMove: sinon.spy(), - } - - testProps = { - gasPrices: [1.5, 2.5, 4, 8], - estimatedTimes: [100, 80, 40, 10], - gasPricesMax: 9, - estimatedTimesMax: 100, - currentPrice: 6, - updateCustomGasPrice: propsMethodSpies.updateCustomGasPrice, - } - - GasPriceChart = proxyquire('../gas-price-chart.component.js', { - './gas-price-chart.utils.js': gasPriceChartUtilsSpies, - d3: { - ...d3, - select(...args) { - const result = d3.select(...args) - return result.empty() ? mockSelectReturn : result - }, - event: { - clientX: 'mockClientX', - }, - }, - }).default - sinon.spy(GasPriceChart.prototype, 'renderChart') - - wrapper = shallow() - }) - - afterEach(function () { - sinon.restore() - }) - - describe('render()', function () { - it('should render', function () { - assert(wrapper.hasClass('gas-price-chart')) - }) - - it('should render the chart div', function () { - assert(wrapper.childAt(0).hasClass('gas-price-chart__root')) - assert.equal(wrapper.childAt(0).props().id, 'chart') - }) - }) - - describe('componentDidMount', function () { - it('should call this.renderChart', function () { - assert(GasPriceChart.prototype.renderChart.callCount, 1) - wrapper.instance().componentDidMount() - assert(GasPriceChart.prototype.renderChart.callCount, 2) - }) - }) - - describe('componentDidUpdate', function () { - it('should call handleChartUpdate if props.currentPrice has changed', function () { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 7 }) - assert.equal(gasPriceChartUtilsSpies.handleChartUpdate.callCount, 1) - }) - - it('should call handleChartUpdate with the correct props', function () { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 7 }) - assert.deepEqual( - gasPriceChartUtilsSpies.handleChartUpdate.getCall(0).args, - [ - { - chart: { mockChart: true }, - gasPrices: [1.5, 2.5, 4, 8], - newPrice: 6, - cssId: '#set-circle', - }, - ], - ) - }) - - it('should not call handleChartUpdate if props.currentPrice has not changed', function () { - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().componentDidUpdate({ currentPrice: 6 }) - assert.equal(gasPriceChartUtilsSpies.handleChartUpdate.callCount, 0) - }) - }) - - describe('renderChart', function () { - it('should call setTickPosition 4 times, with the expected props', async function () { - await timeout(0) - gasPriceChartUtilsSpies.setTickPosition.resetHistory() - assert.equal(gasPriceChartUtilsSpies.setTickPosition.callCount, 0) - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.equal(gasPriceChartUtilsSpies.setTickPosition.callCount, 4) - assert.deepEqual( - gasPriceChartUtilsSpies.setTickPosition.getCall(0).args, - ['y', 0, -5, 8], - ) - assert.deepEqual( - gasPriceChartUtilsSpies.setTickPosition.getCall(1).args, - ['y', 1, -3, -5], - ) - assert.deepEqual( - gasPriceChartUtilsSpies.setTickPosition.getCall(2).args, - ['x', 0, 3], - ) - assert.deepEqual( - gasPriceChartUtilsSpies.setTickPosition.getCall(3).args, - ['x', 1, 3, -8], - ) - }) - - it('should call handleChartUpdate with the correct props', async function () { - await timeout(0) - gasPriceChartUtilsSpies.handleChartUpdate.resetHistory() - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.deepEqual( - gasPriceChartUtilsSpies.handleChartUpdate.getCall(0).args, - [ - { - chart: { mockChart: true }, - gasPrices: [1.5, 2.5, 4, 8], - newPrice: 6, - cssId: '#set-circle', - }, - ], - ) - }) - - it('should add three events to the chart', async function () { - await timeout(0) - selectReturnSpies.on.resetHistory() - assert.equal(selectReturnSpies.on.callCount, 0) - wrapper.instance().renderChart(testProps) - await timeout(0) - assert.equal(selectReturnSpies.on.callCount, 3) - - const firstOnEventArgs = selectReturnSpies.on.getCall(0).args - assert.equal(firstOnEventArgs[0], 'mouseout') - const secondOnEventArgs = selectReturnSpies.on.getCall(1).args - assert.equal(secondOnEventArgs[0], 'click') - const thirdOnEventArgs = selectReturnSpies.on.getCall(2).args - assert.equal(thirdOnEventArgs[0], 'mousemove') - }) - - it('should hide the data UI on mouseout', async function () { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - gasPriceChartUtilsSpies.hideDataUI.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(0).args - assert.equal(gasPriceChartUtilsSpies.hideDataUI.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(gasPriceChartUtilsSpies.hideDataUI.callCount, 1) - assert.deepEqual(gasPriceChartUtilsSpies.hideDataUI.getCall(0).args, [ - { mockChart: true }, - '#overlayed-circle', - ]) - }) - - it('should updateCustomGasPrice on click', async function () { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - propsMethodSpies.updateCustomGasPrice.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(1).args - assert.equal(propsMethodSpies.updateCustomGasPrice.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(propsMethodSpies.updateCustomGasPrice.callCount, 1) - assert.equal( - propsMethodSpies.updateCustomGasPrice.getCall(0).args[0], - 'mockX', - ) - }) - - it('should handle mousemove', async function () { - await timeout(0) - selectReturnSpies.on.resetHistory() - wrapper.instance().renderChart(testProps) - gasPriceChartUtilsSpies.handleMouseMove.resetHistory() - await timeout(0) - const mouseoutEventArgs = selectReturnSpies.on.getCall(2).args - assert.equal(gasPriceChartUtilsSpies.handleMouseMove.callCount, 0) - mouseoutEventArgs[1]() - assert.equal(gasPriceChartUtilsSpies.handleMouseMove.callCount, 1) - assert.deepEqual( - gasPriceChartUtilsSpies.handleMouseMove.getCall(0).args, - [ - { - xMousePos: 'mockClientX', - chartXStart: 'mockCoordinateX', - chartWidth: 'mockWidth', - gasPrices: testProps.gasPrices, - estimatedTimes: testProps.estimatedTimes, - chart: { mockChart: true }, - }, - ], - ) - }) - }) -}) diff --git a/ui/app/components/app/gas-customization/index.scss b/ui/app/components/app/gas-customization/index.scss index 06a9d7820..fa8954bab 100644 --- a/ui/app/components/app/gas-customization/index.scss +++ b/ui/app/components/app/gas-customization/index.scss @@ -1,4 +1,3 @@ @import './gas-slider/index'; @import './gas-modal-page-container/index'; -@import './gas-price-chart/index'; @import './advanced-gas-inputs/index'; diff --git a/ui/app/components/app/info-box/tests/info-box.test.js b/ui/app/components/app/info-box/tests/info-box.test.js index 031ac62f4..82f019e01 100644 --- a/ui/app/components/app/info-box/tests/info-box.test.js +++ b/ui/app/components/app/info-box/tests/info-box.test.js @@ -20,12 +20,12 @@ describe('InfoBox', function () { it('renders title from props', function () { const title = wrapper.find('.info-box__title') - assert.equal(title.text(), props.title) + assert.strictEqual(title.text(), props.title) }) it('renders description from props', function () { const description = wrapper.find('.info-box__description') - assert.equal(description.text(), props.description) + assert.strictEqual(description.text(), props.description) }) it('closes info box', function () { diff --git a/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js b/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js index de40a39bd..8056563f6 100644 --- a/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js +++ b/ui/app/components/app/modal/modal-content/tests/modal-content.component.test.js @@ -7,17 +7,20 @@ describe('ModalContent Component', function () { it('should render a title', function () { const wrapper = shallow() - assert.equal(wrapper.find('.modal-content__title').length, 1) - assert.equal(wrapper.find('.modal-content__title').text(), 'Modal Title') - assert.equal(wrapper.find('.modal-content__description').length, 0) + assert.strictEqual(wrapper.find('.modal-content__title').length, 1) + assert.strictEqual( + wrapper.find('.modal-content__title').text(), + 'Modal Title', + ) + assert.strictEqual(wrapper.find('.modal-content__description').length, 0) }) it('should render a description', function () { const wrapper = shallow() - assert.equal(wrapper.find('.modal-content__title').length, 0) - assert.equal(wrapper.find('.modal-content__description').length, 1) - assert.equal( + assert.strictEqual(wrapper.find('.modal-content__title').length, 0) + assert.strictEqual(wrapper.find('.modal-content__description').length, 1) + assert.strictEqual( wrapper.find('.modal-content__description').text(), 'Modal Description', ) @@ -28,10 +31,13 @@ describe('ModalContent Component', function () { , ) - assert.equal(wrapper.find('.modal-content__title').length, 1) - assert.equal(wrapper.find('.modal-content__title').text(), 'Modal Title') - assert.equal(wrapper.find('.modal-content__description').length, 1) - assert.equal( + assert.strictEqual(wrapper.find('.modal-content__title').length, 1) + assert.strictEqual( + wrapper.find('.modal-content__title').text(), + 'Modal Title', + ) + assert.strictEqual(wrapper.find('.modal-content__description').length, 1) + assert.strictEqual( wrapper.find('.modal-content__description').text(), 'Modal Description', ) diff --git a/ui/app/components/app/modal/tests/modal.component.test.js b/ui/app/components/app/modal/tests/modal.component.test.js index fe55b61bd..a0ad195ae 100644 --- a/ui/app/components/app/modal/tests/modal.component.test.js +++ b/ui/app/components/app/modal/tests/modal.component.test.js @@ -9,10 +9,10 @@ describe('Modal Component', function () { it('should render a modal with a submit button', function () { const wrapper = shallow() - assert.equal(wrapper.find('.modal-container').length, 1) + assert.strictEqual(wrapper.find('.modal-container').length, 1) const buttons = wrapper.find(Button) - assert.equal(buttons.length, 1) - assert.equal(buttons.at(0).props().type, 'secondary') + assert.strictEqual(buttons.length, 1) + assert.strictEqual(buttons.at(0).props().type, 'secondary') }) it('should render a modal with a cancel and a submit button', function () { @@ -28,21 +28,21 @@ describe('Modal Component', function () { ) const buttons = wrapper.find(Button) - assert.equal(buttons.length, 2) + assert.strictEqual(buttons.length, 2) const cancelButton = buttons.at(0) const submitButton = buttons.at(1) - assert.equal(cancelButton.props().type, 'default') - assert.equal(cancelButton.props().children, 'Cancel') - assert.equal(handleCancel.callCount, 0) + assert.strictEqual(cancelButton.props().type, 'default') + assert.strictEqual(cancelButton.props().children, 'Cancel') + assert.strictEqual(handleCancel.callCount, 0) cancelButton.simulate('click') - assert.equal(handleCancel.callCount, 1) + assert.strictEqual(handleCancel.callCount, 1) - assert.equal(submitButton.props().type, 'secondary') - assert.equal(submitButton.props().children, 'Submit') - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(submitButton.props().type, 'secondary') + assert.strictEqual(submitButton.props().children, 'Submit') + assert.strictEqual(handleSubmit.callCount, 0) submitButton.simulate('click') - assert.equal(handleSubmit.callCount, 1) + assert.strictEqual(handleSubmit.callCount, 1) }) it('should render a modal with different button types', function () { @@ -58,9 +58,9 @@ describe('Modal Component', function () { ) const buttons = wrapper.find(Button) - assert.equal(buttons.length, 2) - assert.equal(buttons.at(0).props().type, 'secondary') - assert.equal(buttons.at(1).props().type, 'confirm') + assert.strictEqual(buttons.length, 2) + assert.strictEqual(buttons.at(0).props().type, 'secondary') + assert.strictEqual(buttons.at(1).props().type, 'confirm') }) it('should render a modal with children', function () { @@ -93,15 +93,15 @@ describe('Modal Component', function () { ) assert.ok(wrapper.find('.modal-container__header')) - assert.equal( + assert.strictEqual( wrapper.find('.modal-container__header-text').text(), 'My Header', ) - assert.equal(handleCancel.callCount, 0) - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(handleCancel.callCount, 0) + assert.strictEqual(handleSubmit.callCount, 0) wrapper.find('.modal-container__header-close').simulate('click') - assert.equal(handleCancel.callCount, 1) - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(handleCancel.callCount, 1) + assert.strictEqual(handleSubmit.callCount, 0) }) it('should disable the submit button if submitDisabled is true', function () { @@ -120,17 +120,17 @@ describe('Modal Component', function () { ) const buttons = wrapper.find(Button) - assert.equal(buttons.length, 2) + assert.strictEqual(buttons.length, 2) const cancelButton = buttons.at(0) const submitButton = buttons.at(1) - assert.equal(handleCancel.callCount, 0) + assert.strictEqual(handleCancel.callCount, 0) cancelButton.simulate('click') - assert.equal(handleCancel.callCount, 1) + assert.strictEqual(handleCancel.callCount, 1) - assert.equal(submitButton.props().disabled, true) - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(submitButton.props().disabled, true) + assert.strictEqual(handleSubmit.callCount, 0) submitButton.simulate('click') - assert.equal(handleSubmit.callCount, 0) + assert.strictEqual(handleSubmit.callCount, 0) }) }) diff --git a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js index 12b1bae06..c10971110 100644 --- a/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js +++ b/ui/app/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/tests/cancel-transaction-gas-fee.component.test.js @@ -9,18 +9,18 @@ describe('CancelTransactionGasFee Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) + assert.strictEqual(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) const ethDisplay = wrapper.find(UserPreferencedCurrencyDisplay).at(0) const fiatDisplay = wrapper.find(UserPreferencedCurrencyDisplay).at(1) - assert.equal(ethDisplay.props().value, '0x3b9aca00') - assert.equal( + assert.strictEqual(ethDisplay.props().value, '0x3b9aca00') + assert.strictEqual( ethDisplay.props().className, 'cancel-transaction-gas-fee__eth', ) - assert.equal(fiatDisplay.props().value, '0x3b9aca00') - assert.equal( + assert.strictEqual(fiatDisplay.props().value, '0x3b9aca00') + assert.strictEqual( fiatDisplay.props().className, 'cancel-transaction-gas-fee__fiat', ) diff --git a/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js b/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js index 411cc8b27..64e08944a 100644 --- a/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js +++ b/ui/app/components/app/modals/cancel-transaction/tests/cancel-transaction.component.test.js @@ -15,17 +15,17 @@ describe('CancelTransaction Component', function () { }) assert.ok(wrapper) - assert.equal(wrapper.find(Modal).length, 1) - assert.equal(wrapper.find(CancelTransactionGasFee).length, 1) - assert.equal( + assert.strictEqual(wrapper.find(Modal).length, 1) + assert.strictEqual(wrapper.find(CancelTransactionGasFee).length, 1) + assert.strictEqual( wrapper.find(CancelTransactionGasFee).props().value, '0x1319718a5000', ) - assert.equal( + assert.strictEqual( wrapper.find('.cancel-transaction__title').text(), 'cancellationGasFee', ) - assert.equal( + assert.strictEqual( wrapper.find('.cancel-transaction__description').text(), 'attemptToCancelDescription', ) @@ -47,19 +47,19 @@ describe('CancelTransaction Component', function () { { context: { t } }, ) - assert.equal(wrapper.find(Modal).length, 1) + assert.strictEqual(wrapper.find(Modal).length, 1) const modalProps = wrapper.find(Modal).props() - assert.equal(modalProps.headerText, 'attemptToCancel') - assert.equal(modalProps.submitText, 'yesLetsTry') - assert.equal(modalProps.cancelText, 'nevermind') + assert.strictEqual(modalProps.headerText, 'attemptToCancel') + assert.strictEqual(modalProps.submitText, 'yesLetsTry') + assert.strictEqual(modalProps.cancelText, 'nevermind') - assert.equal(createCancelTransactionSpy.callCount, 0) - assert.equal(hideModalSpy.callCount, 0) + assert.strictEqual(createCancelTransactionSpy.callCount, 0) + assert.strictEqual(hideModalSpy.callCount, 0) await modalProps.onSubmit() - assert.equal(createCancelTransactionSpy.callCount, 1) - assert.equal(hideModalSpy.callCount, 1) + assert.strictEqual(createCancelTransactionSpy.callCount, 1) + assert.strictEqual(hideModalSpy.callCount, 1) modalProps.onCancel() - assert.equal(hideModalSpy.callCount, 2) + assert.strictEqual(hideModalSpy.callCount, 2) }) }) diff --git a/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js b/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js index 86329ec88..7d06ef459 100644 --- a/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js +++ b/ui/app/components/app/modals/confirm-delete-network/tests/confirm-delete-network.test.js @@ -30,7 +30,7 @@ describe('Confirm Delete Network', function () { it('renders delete network modal title', function () { const modalTitle = wrapper.find('.modal-content__title') - assert.equal(modalTitle.text(), 'deleteNetwork') + assert.strictEqual(modalTitle.text(), 'deleteNetwork') }) it('clicks cancel to hide modal', function () { diff --git a/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js b/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js index 5f239e665..e50b87308 100644 --- a/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js +++ b/ui/app/components/app/modals/confirm-remove-account/tests/confirm-remove-account.test.js @@ -61,7 +61,10 @@ describe('Confirm Remove Account', function () { remove.simulate('click') assert(props.removeAccount.calledOnce) - assert.equal(props.removeAccount.getCall(0).args[0], props.identity.address) + assert.strictEqual( + props.removeAccount.getCall(0).args[0], + props.identity.address, + ) setImmediate(() => { assert(props.hideModal.calledOnce) diff --git a/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js b/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js index ec113f108..5b9f4798d 100644 --- a/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js +++ b/ui/app/components/app/modals/metametrics-opt-in-modal/tests/metametrics-opt-in-modal.test.js @@ -34,7 +34,10 @@ describe('MetaMetrics Opt In', function () { setImmediate(() => { assert(props.setParticipateInMetaMetrics.calledOnce) - assert.equal(props.setParticipateInMetaMetrics.getCall(0).args[0], false) + assert.strictEqual( + props.setParticipateInMetaMetrics.getCall(0).args[0], + false, + ) assert(props.hideModal.calledOnce) done() }) @@ -48,7 +51,10 @@ describe('MetaMetrics Opt In', function () { setImmediate(() => { assert(props.setParticipateInMetaMetrics.calledOnce) - assert.equal(props.setParticipateInMetaMetrics.getCall(0).args[0], true) + assert.strictEqual( + props.setParticipateInMetaMetrics.getCall(0).args[0], + true, + ) assert(props.hideModal.calledOnce) done() }) diff --git a/ui/app/components/app/modals/tests/account-details-modal.test.js b/ui/app/components/app/modals/tests/account-details-modal.test.js index 55b8b1b0a..62da1c56e 100644 --- a/ui/app/components/app/modals/tests/account-details-modal.test.js +++ b/ui/app/components/app/modals/tests/account-details-modal.test.js @@ -46,7 +46,7 @@ describe('Account Details Modal', function () { accountLabel.simulate('submit', 'New Label') assert(props.setAccountLabel.calledOnce) - assert.equal(props.setAccountLabel.getCall(0).args[1], 'New Label') + assert.strictEqual(props.setAccountLabel.getCall(0).args[1], 'New Label') }) it('opens new tab when view block explorer is clicked', function () { @@ -72,7 +72,7 @@ describe('Account Details Modal', function () { const modalButton = wrapper.find('.account-details-modal__button') const blockExplorerLink = modalButton.first() - assert.equal( + assert.strictEqual( blockExplorerLink.html(), '', ) diff --git a/ui/app/components/app/selected-account/tests/selected-account-component.test.js b/ui/app/components/app/selected-account/tests/selected-account-component.test.js index d0a608f3e..fcb924c25 100644 --- a/ui/app/components/app/selected-account/tests/selected-account-component.test.js +++ b/ui/app/components/app/selected-account/tests/selected-account-component.test.js @@ -15,10 +15,13 @@ describe('SelectedAccount Component', function () { { context: { t: () => undefined } }, ) // Checksummed version of address is displayed - assert.equal( + assert.strictEqual( wrapper.find('.selected-account__address').text(), '0x1B82...5C9D', ) - assert.equal(wrapper.find('.selected-account__name').text(), 'testName') + assert.strictEqual( + wrapper.find('.selected-account__name').text(), + 'testName', + ) }) }) diff --git a/ui/app/components/app/sidebars/sidebar-content.scss b/ui/app/components/app/sidebars/sidebar-content.scss index 91222fdbc..d8bb0a5d0 100644 --- a/ui/app/components/app/sidebars/sidebar-content.scss +++ b/ui/app/components/app/sidebars/sidebar-content.scss @@ -23,14 +23,6 @@ } } - .gas-price-chart { - margin-left: 10px; - - &__root { - max-height: 160px !important; - } - } - .page-container__bottom { display: flex; flex-direction: column; diff --git a/ui/app/components/app/sidebars/tests/sidebars-component.test.js b/ui/app/components/app/sidebars/tests/sidebars-component.test.js index 22a7cbc2c..87d9377c0 100644 --- a/ui/app/components/app/sidebars/tests/sidebars-component.test.js +++ b/ui/app/components/app/sidebars/tests/sidebars-component.test.js @@ -41,9 +41,9 @@ describe('Sidebar Component', function () { }) it('should pass the correct onClick function to the element', function () { - assert.equal(propsMethodSpies.hideSidebar.callCount, 0) + assert.strictEqual(propsMethodSpies.hideSidebar.callCount, 0) renderOverlay.props().onClick() - assert.equal(propsMethodSpies.hideSidebar.callCount, 1) + assert.strictEqual(propsMethodSpies.hideSidebar.callCount, 1) }) }) @@ -64,26 +64,26 @@ describe('Sidebar Component', function () { it('should not render with an unrecognized type', function () { wrapper.setProps({ type: 'foobar' }) renderSidebarContent = wrapper.instance().renderSidebarContent() - assert.equal(renderSidebarContent, undefined) + assert.strictEqual(renderSidebarContent, null) }) }) describe('render', function () { it('should render a div with one child', function () { assert(wrapper.is('div')) - assert.equal(wrapper.children().length, 1) + assert.strictEqual(wrapper.children().length, 1) }) it('should render the ReactCSSTransitionGroup without any children', function () { assert(wrapper.children().at(0).is(ReactCSSTransitionGroup)) - assert.equal(wrapper.children().at(0).children().length, 0) + assert.strictEqual(wrapper.children().at(0).children().length, 0) }) it('should render sidebar content and the overlay if sidebarOpen is true', function () { wrapper.setProps({ sidebarOpen: true }) - assert.equal(wrapper.children().length, 2) + assert.strictEqual(wrapper.children().length, 2) assert(wrapper.children().at(1).hasClass('sidebar-overlay')) - assert.equal(wrapper.children().at(0).children().length, 1) + assert.strictEqual(wrapper.children().at(0).children().length, 1) assert(wrapper.children().at(0).children().at(0).hasClass('sidebar-left')) assert( wrapper diff --git a/ui/app/components/app/signature-request/tests/signature-request.test.js b/ui/app/components/app/signature-request/tests/signature-request.test.js index 331abac04..8966c014e 100644 --- a/ui/app/components/app/signature-request/tests/signature-request.test.js +++ b/ui/app/components/app/signature-request/tests/signature-request.test.js @@ -23,7 +23,7 @@ describe('Signature Request Component', function () { ) assert(wrapper.is('div')) - assert.equal(wrapper.length, 1) + assert.strictEqual(wrapper.length, 1) assert(wrapper.hasClass('signature-request')) }) }) diff --git a/ui/app/components/app/token-cell/token-cell.test.js b/ui/app/components/app/token-cell/token-cell.test.js index 1e876cfb3..08b4e545d 100644 --- a/ui/app/components/app/token-cell/token-cell.test.js +++ b/ui/app/components/app/token-cell/token-cell.test.js @@ -64,20 +64,32 @@ describe('Token Cell', function () { }) it('renders Identicon with props from token cell', function () { - assert.equal(wrapper.find(Identicon).prop('address'), '0xAnotherToken') - assert.equal(wrapper.find(Identicon).prop('image'), './test-image') + assert.strictEqual( + wrapper.find(Identicon).prop('address'), + '0xAnotherToken', + ) + assert.strictEqual(wrapper.find(Identicon).prop('image'), './test-image') }) it('renders token balance', function () { - assert.equal(wrapper.find('.asset-list-item__token-value').text(), '5.000') + assert.strictEqual( + wrapper.find('.asset-list-item__token-value').text(), + '5.000', + ) }) it('renders token symbol', function () { - assert.equal(wrapper.find('.asset-list-item__token-symbol').text(), 'TEST') + assert.strictEqual( + wrapper.find('.asset-list-item__token-symbol').text(), + 'TEST', + ) }) it('renders converted fiat amount', function () { - assert.equal(wrapper.find('.list-item__subheading').text(), '$0.52 USD') + assert.strictEqual( + wrapper.find('.list-item__subheading').text(), + '$0.52 USD', + ) }) it('calls onClick when clicked', function () { diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js index ec5cbb3df..d07f98764 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.component.test.js @@ -109,7 +109,7 @@ describe('TransactionActivityLog Component', function () { assert.ok(wrapper.hasClass('transaction-activity-log')) assert.ok(wrapper.hasClass('test-class')) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-activity-log__action-link').length, 2, ) @@ -166,7 +166,7 @@ describe('TransactionActivityLog Component', function () { assert.ok(wrapper.hasClass('transaction-activity-log')) assert.ok(wrapper.hasClass('test-class')) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-activity-log__action-link').length, 0, ) diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js index b756a5962..f54f2ce94 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.container.test.js @@ -22,7 +22,7 @@ describe('TransactionActivityLog container', function () { }, } - assert.deepEqual(mapStateToProps(mockState), { + assert.deepStrictEqual(mapStateToProps(mockState), { conversionRate: 280.45, nativeCurrency: 'ETH', }) diff --git a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js index 5b9ab0662..8b03326db 100644 --- a/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js +++ b/ui/app/components/app/transaction-activity-log/tests/transaction-activity-log.util.test.js @@ -11,7 +11,7 @@ import { describe('TransactionActivityLog utils', function () { describe('combineTransactionHistories', function () { it('should return no activities for an empty list of transactions', function () { - assert.deepEqual(combineTransactionHistories([]), []) + assert.deepStrictEqual(combineTransactionHistories([]), []) }) it('should return activities for an array of transactions', function () { @@ -217,7 +217,10 @@ describe('TransactionActivityLog utils', function () { }, ] - assert.deepEqual(combineTransactionHistories(transactions), expected) + assert.deepStrictEqual( + combineTransactionHistories(transactions), + expected, + ) }) }) @@ -237,7 +240,7 @@ describe('TransactionActivityLog utils', function () { }, } - assert.deepEqual(getActivities(transaction), []) + assert.deepStrictEqual(getActivities(transaction), []) }) it("should return activities for a transaction's history", function () { @@ -412,7 +415,7 @@ describe('TransactionActivityLog utils', function () { }, ] - assert.deepEqual(getActivities(transaction, true), expectedResult) + assert.deepStrictEqual(getActivities(transaction, true), expectedResult) }) }) }) diff --git a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js index e3083e504..db5ebef70 100644 --- a/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js +++ b/ui/app/components/app/transaction-breakdown/transaction-breakdown-row/tests/transaction-breakdown-row.component.test.js @@ -14,11 +14,11 @@ describe('TransactionBreakdownRow Component', function () { ) assert.ok(wrapper.hasClass('transaction-breakdown-row')) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-breakdown-row__title').text(), 'test', ) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-breakdown-row__value').text(), 'Test', ) @@ -33,7 +33,7 @@ describe('TransactionBreakdownRow Component', function () { ) assert.ok(wrapper.hasClass('transaction-breakdown-row')) - assert.equal( + assert.strictEqual( wrapper.find('.transaction-breakdown-row__title').text(), 'test', ) diff --git a/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js b/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js index 9d1e8c18b..5027cc05b 100644 --- a/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js +++ b/ui/app/components/app/transaction-list-item-details/tests/transaction-list-item-details.component.test.js @@ -44,10 +44,10 @@ describe('TransactionListItemDetails Component', function () { ) const child = wrapper.childAt(0) assert.ok(child.hasClass('transaction-list-item-details')) - assert.equal(child.find(Button).length, 2) - assert.equal(child.find(SenderToRecipient).length, 1) - assert.equal(child.find(TransactionBreakdown).length, 1) - assert.equal(child.find(TransactionActivityLog).length, 1) + assert.strictEqual(child.find(Button).length, 2) + assert.strictEqual(child.find(SenderToRecipient).length, 1) + assert.strictEqual(child.find(TransactionBreakdown).length, 1) + assert.strictEqual(child.find(TransactionActivityLog).length, 1) }) it('should render a retry button', function () { @@ -90,7 +90,7 @@ describe('TransactionListItemDetails Component', function () { const child = wrapper.childAt(0) assert.ok(child.hasClass('transaction-list-item-details')) - assert.equal(child.find(Button).length, 3) + assert.strictEqual(child.find(Button).length, 3) }) it('should disable the Copy Tx ID and View In Etherscan buttons when tx hash is missing', function () { diff --git a/ui/app/components/app/transaction-list-item/transaction-list-item.component.js b/ui/app/components/app/transaction-list-item/transaction-list-item.component.js index 9c472c11f..64a617cda 100644 --- a/ui/app/components/app/transaction-list-item/transaction-list-item.component.js +++ b/ui/app/components/app/transaction-list-item/transaction-list-item.component.js @@ -4,7 +4,6 @@ import classnames from 'classnames' import { useHistory } from 'react-router-dom' import ListItem from '../../ui/list-item' import { useTransactionDisplayData } from '../../../hooks/useTransactionDisplayData' -import Preloader from '../../ui/icon/preloader' import { useI18nContext } from '../../../hooks/useI18nContext' import { useCancelTransaction } from '../../../hooks/useCancelTransaction' import { useRetryTransaction } from '../../../hooks/useRetryTransaction' @@ -15,8 +14,6 @@ import { CONFIRM_TRANSACTION_ROUTE } from '../../../helpers/constants/routes' import { useShouldShowSpeedUp } from '../../../hooks/useShouldShowSpeedUp' import TransactionStatus from '../transaction-status/transaction-status.component' import TransactionIcon from '../transaction-icon' -import { useTransactionTimeRemaining } from '../../../hooks/useTransactionTimeRemaining' -import IconWithLabel from '../../ui/icon-with-label' import { TRANSACTION_GROUP_CATEGORIES, TRANSACTION_STATUSES, @@ -33,7 +30,7 @@ export default function TransactionListItem({ const { initialTransaction: { id }, - primaryTransaction: { err, gasPrice, status, submittedTime }, + primaryTransaction: { err, status }, } = transactionGroup const [cancelEnabled, cancelTransaction] = useCancelTransaction( transactionGroup, @@ -56,16 +53,8 @@ export default function TransactionListItem({ displayedStatusKey, isPending, senderAddress, - isSubmitted, } = useTransactionDisplayData(transactionGroup) - const timeRemaining = useTransactionTimeRemaining( - isSubmitted, - isEarliestNonce, - submittedTime, - gasPrice, - ) - const isSignatureReq = category === TRANSACTION_GROUP_CATEGORIES.SIGNATURE_REQUEST const isApproval = category === TRANSACTION_GROUP_CATEGORIES.APPROVAL @@ -143,16 +132,6 @@ export default function TransactionListItem({ onClick={toggleShowDetails} className={className} title={title} - titleIcon={ - !isUnapproved && - isPending && - isEarliestNonce && ( - } - label={timeRemaining} - /> - ) - } icon={ } diff --git a/ui/app/components/app/transaction-list/transaction-list.component.js b/ui/app/components/app/transaction-list/transaction-list.component.js index cfb70244f..31f690740 100644 --- a/ui/app/components/app/transaction-list/transaction-list.component.js +++ b/ui/app/components/app/transaction-list/transaction-list.component.js @@ -1,12 +1,10 @@ -import React, { useMemo, useEffect, useRef, useState, useCallback } from 'react' +import React, { useMemo, useState, useCallback } from 'react' import PropTypes from 'prop-types' -import { useSelector, useDispatch } from 'react-redux' +import { useSelector } from 'react-redux' import { nonceSortedCompletedTransactionsSelector, nonceSortedPendingTransactionsSelector, } from '../../../selectors/transactions' -import { getFeatureFlags } from '../../../selectors/selectors' -import * as actions from '../../../ducks/gas/gas.duck' import { useI18nContext } from '../../../hooks/useI18nContext' import TransactionListItem from '../transaction-list-item' import Button from '../../ui/button' @@ -63,16 +61,12 @@ export default function TransactionList({ const [limit, setLimit] = useState(PAGE_INCREMENT) const t = useI18nContext() - const dispatch = useDispatch() const unfilteredPendingTransactions = useSelector( nonceSortedPendingTransactionsSelector, ) const unfilteredCompletedTransactions = useSelector( nonceSortedCompletedTransactionsSelector, ) - const { transactionTime: transactionTimeFeatureActive } = useSelector( - getFeatureFlags, - ) const pendingTransactions = useMemo( () => @@ -93,55 +87,6 @@ export default function TransactionList({ [hideTokenTransactions, tokenAddress, unfilteredCompletedTransactions], ) - const { fetchGasEstimates, fetchBasicGasAndTimeEstimates } = useMemo( - () => ({ - fetchGasEstimates: (blockTime) => - dispatch(actions.fetchGasEstimates(blockTime)), - fetchBasicGasAndTimeEstimates: () => - dispatch(actions.fetchBasicGasAndTimeEstimates()), - }), - [dispatch], - ) - - // keep track of previous values from state. - // loaded is used here to determine if our effect has ran at least once. - const prevState = useRef({ - loaded: false, - pendingTransactions, - transactionTimeFeatureActive, - }) - - useEffect(() => { - const { loaded } = prevState.current - const pendingTransactionAdded = - pendingTransactions.length > 0 && - prevState.current.pendingTransactions.length === 0 - const transactionTimeFeatureWasActivated = - !prevState.current.transactionTimeFeatureActive && - transactionTimeFeatureActive - if ( - transactionTimeFeatureActive && - pendingTransactions.length > 0 && - (loaded === false || - transactionTimeFeatureWasActivated || - pendingTransactionAdded) - ) { - fetchBasicGasAndTimeEstimates().then(({ blockTime }) => - fetchGasEstimates(blockTime), - ) - } - prevState.current = { - loaded: true, - pendingTransactions, - transactionTimeFeatureActive, - } - }, [ - fetchGasEstimates, - fetchBasicGasAndTimeEstimates, - transactionTimeFeatureActive, - pendingTransactions, - ]) - const viewMore = useCallback( () => setLimit((prev) => prev + PAGE_INCREMENT), [], diff --git a/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js b/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js index d468d8d5f..016d4d5a9 100644 --- a/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js +++ b/ui/app/components/app/transaction-status/tests/transaction-status.component.test.js @@ -17,7 +17,7 @@ describe('TransactionStatus Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.text(), 'June 1') + assert.strictEqual(wrapper.text(), 'June 1') }) it('should render PENDING properly when status is APPROVED', function () { @@ -30,8 +30,8 @@ describe('TransactionStatus Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.text(), 'PENDING') - assert.equal(wrapper.find(Tooltip).props().title, 'test-title') + assert.strictEqual(wrapper.text(), 'PENDING') + assert.strictEqual(wrapper.find(Tooltip).props().title, 'test-title') }) it('should render PENDING properly', function () { @@ -40,7 +40,7 @@ describe('TransactionStatus Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.text(), 'PENDING') + assert.strictEqual(wrapper.text(), 'PENDING') }) it('should render QUEUED properly', function () { @@ -51,7 +51,7 @@ describe('TransactionStatus Component', function () { wrapper.find('.transaction-status--queued').length, 'queued className not found', ) - assert.equal(wrapper.text(), 'QUEUED') + assert.strictEqual(wrapper.text(), 'QUEUED') }) it('should render UNAPPROVED properly', function () { @@ -62,7 +62,7 @@ describe('TransactionStatus Component', function () { wrapper.find('.transaction-status--unapproved').length, 'unapproved className not found', ) - assert.equal(wrapper.text(), 'UNAPPROVED') + assert.strictEqual(wrapper.text(), 'UNAPPROVED') }) after(function () { diff --git a/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js b/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js index 41b8ac862..4c2533de5 100644 --- a/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js +++ b/ui/app/components/app/user-preferenced-currency-display/tests/user-preferenced-currency-display.component.test.js @@ -19,7 +19,7 @@ describe('UserPreferencedCurrencyDisplay Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find(CurrencyDisplay).length, 1) + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) }) it('should pass all props to the CurrencyDisplay child component', function () { @@ -28,10 +28,10 @@ describe('UserPreferencedCurrencyDisplay Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find(CurrencyDisplay).length, 1) - assert.equal(wrapper.find(CurrencyDisplay).props().prop1, true) - assert.equal(wrapper.find(CurrencyDisplay).props().prop2, 'test') - assert.equal(wrapper.find(CurrencyDisplay).props().prop3, 1) + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop1, true) + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop2, 'test') + assert.strictEqual(wrapper.find(CurrencyDisplay).props().prop3, 1) }) afterEach(function () { sinon.restore() diff --git a/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js b/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js index 208b93197..8496d7ca1 100644 --- a/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js +++ b/ui/app/components/app/user-preferenced-currency-display/user-preferenced-currency-display.component.js @@ -19,7 +19,6 @@ export default function UserPreferencedCurrencyDisplay({ fiatNumberOfDecimals, numberOfDecimals: propsNumberOfDecimals, }) - const prefixComponent = useMemo(() => { return ( currency === ETH && diff --git a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js index 63b9d42a5..30052e039 100644 --- a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js +++ b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js @@ -10,7 +10,7 @@ describe('UserPreferencedCurrencyInput Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find(CurrencyInput).length, 1) + assert.strictEqual(wrapper.find(CurrencyInput).length, 1) }) it('should render useFiat for CurrencyInput based on preferences.useNativeCurrencyAsPrimaryCurrency', function () { @@ -19,10 +19,10 @@ describe('UserPreferencedCurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find(CurrencyInput).length, 1) - assert.equal(wrapper.find(CurrencyInput).props().useFiat, false) + assert.strictEqual(wrapper.find(CurrencyInput).length, 1) + assert.strictEqual(wrapper.find(CurrencyInput).props().useFiat, false) wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }) - assert.equal(wrapper.find(CurrencyInput).props().useFiat, true) + assert.strictEqual(wrapper.find(CurrencyInput).props().useFiat, true) }) }) }) diff --git a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js index 84c67f453..a687d469d 100644 --- a/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js +++ b/ui/app/components/app/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js @@ -23,7 +23,7 @@ describe('UserPreferencedCurrencyInput container', function () { }, } - assert.deepEqual(mapStateToProps(mockState), { + assert.deepStrictEqual(mapStateToProps(mockState), { useNativeCurrencyAsPrimaryCurrency: true, }) }) diff --git a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js index ce882f6e5..dcc5b6874 100644 --- a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js +++ b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js @@ -12,7 +12,7 @@ describe('UserPreferencedCurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find(TokenInput).length, 1) + assert.strictEqual(wrapper.find(TokenInput).length, 1) }) it('should render showFiat for TokenInput based on preferences.useNativeCurrencyAsPrimaryCurrency', function () { @@ -24,10 +24,10 @@ describe('UserPreferencedCurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find(TokenInput).length, 1) - assert.equal(wrapper.find(TokenInput).props().showFiat, false) + assert.strictEqual(wrapper.find(TokenInput).length, 1) + assert.strictEqual(wrapper.find(TokenInput).props().showFiat, false) wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }) - assert.equal(wrapper.find(TokenInput).props().showFiat, true) + assert.strictEqual(wrapper.find(TokenInput).props().showFiat, true) }) }) }) diff --git a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js index f7bef30e4..8011f4885 100644 --- a/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js +++ b/ui/app/components/app/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js @@ -23,7 +23,7 @@ describe('UserPreferencedTokenInput container', function () { }, } - assert.deepEqual(mapStateToProps(mockState), { + assert.deepStrictEqual(mapStateToProps(mockState), { useNativeCurrencyAsPrimaryCurrency: true, }) }) diff --git a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js b/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js index f49935770..733d81241 100644 --- a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js +++ b/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js @@ -20,11 +20,11 @@ describe('AccountMismatchWarning', function () { }) it('renders nothing when the addresses match', function () { const wrapper = shallow() - assert.equal(wrapper.find(InfoIcon).length, 0) + assert.strictEqual(wrapper.find(InfoIcon).length, 0) }) it('renders a warning info icon when addresses do not match', function () { const wrapper = shallow() - assert.equal(wrapper.find(InfoIcon).length, 1) + assert.strictEqual(wrapper.find(InfoIcon).length, 1) }) after(function () { sinon.restore() diff --git a/ui/app/components/ui/alert/tests/alert.test.js b/ui/app/components/ui/alert/tests/alert.test.js index f69a59b06..c8d36528b 100644 --- a/ui/app/components/ui/alert/tests/alert.test.js +++ b/ui/app/components/ui/alert/tests/alert.test.js @@ -13,7 +13,7 @@ describe('Alert', function () { it('renders nothing with no visible boolean in state', function () { const alert = wrapper.find('.global-alert') - assert.equal(alert.length, 0) + assert.strictEqual(alert.length, 0) }) it('renders when visible in state is true, and message', function () { @@ -22,10 +22,10 @@ describe('Alert', function () { wrapper.setState({ visible: true, msg: errorMessage }) const alert = wrapper.find('.global-alert') - assert.equal(alert.length, 1) + assert.strictEqual(alert.length, 1) const errorText = wrapper.find('.msg') - assert.equal(errorText.text(), errorMessage) + assert.strictEqual(errorText.text(), errorMessage) }) it('calls component method when componentWillReceiveProps is called', function () { diff --git a/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js b/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js index cbbbfd8e2..9d9abbdc6 100644 --- a/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js +++ b/ui/app/components/ui/breadcrumbs/tests/breadcrumbs.component.test.js @@ -8,17 +8,17 @@ describe('Breadcrumbs Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find('.breadcrumbs').length, 1) - assert.equal(wrapper.find('.breadcrumb').length, 3) - assert.equal( + assert.strictEqual(wrapper.find('.breadcrumbs').length, 1) + assert.strictEqual(wrapper.find('.breadcrumb').length, 3) + assert.strictEqual( wrapper.find('.breadcrumb').at(0).props().style.backgroundColor, '#FFFFFF', ) - assert.equal( + assert.strictEqual( wrapper.find('.breadcrumb').at(1).props().style.backgroundColor, '#D8D8D8', ) - assert.equal( + assert.strictEqual( wrapper.find('.breadcrumb').at(2).props().style.backgroundColor, '#FFFFFF', ) diff --git a/ui/app/components/ui/button-group/button-group.stories.js b/ui/app/components/ui/button-group/button-group.stories.js index 38c538092..d9cbdf3d5 100644 --- a/ui/app/components/ui/button-group/button-group.stories.js +++ b/ui/app/components/ui/button-group/button-group.stories.js @@ -1,7 +1,7 @@ import React from 'react' import { action } from '@storybook/addon-actions' import classnames from 'classnames' -import { text, boolean } from '@storybook/addon-knobs/react' +import { text, boolean } from '@storybook/addon-knobs' import Button from '../button' import ButtonGroup from '.' diff --git a/ui/app/components/ui/button-group/tests/button-group-component.test.js b/ui/app/components/ui/button-group/tests/button-group-component.test.js index 28f54cf57..e64c866fa 100644 --- a/ui/app/components/ui/button-group/tests/button-group-component.test.js +++ b/ui/app/components/ui/button-group/tests/button-group-component.test.js @@ -49,77 +49,80 @@ describe('ButtonGroup Component', function () { describe('componentDidUpdate', function () { it('should set the activeButtonIndex to the updated newActiveButtonIndex', function () { - assert.equal(wrapper.state('activeButtonIndex'), 1) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1) wrapper.setProps({ newActiveButtonIndex: 2 }) - assert.equal(wrapper.state('activeButtonIndex'), 2) + assert.strictEqual(wrapper.state('activeButtonIndex'), 2) }) it('should not set the activeButtonIndex to an updated newActiveButtonIndex that is not a number', function () { - assert.equal(wrapper.state('activeButtonIndex'), 1) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1) wrapper.setProps({ newActiveButtonIndex: null }) - assert.equal(wrapper.state('activeButtonIndex'), 1) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1) }) }) describe('handleButtonClick', function () { it('should set the activeButtonIndex', function () { - assert.equal(wrapper.state('activeButtonIndex'), 1) + assert.strictEqual(wrapper.state('activeButtonIndex'), 1) wrapper.instance().handleButtonClick(2) - assert.equal(wrapper.state('activeButtonIndex'), 2) + assert.strictEqual(wrapper.state('activeButtonIndex'), 2) }) }) describe('renderButtons', function () { it('should render a button for each child', function () { const childButtons = wrapper.find('.button-group__button') - assert.equal(childButtons.length, 3) + assert.strictEqual(childButtons.length, 3) }) it('should render the correct button with an active state', function () { const childButtons = wrapper.find('.button-group__button') const activeChildButton = wrapper.find('.button-group__button--active') - assert.deepEqual(childButtons.get(1), activeChildButton.get(0)) + assert.deepStrictEqual(childButtons.get(1), activeChildButton.get(0)) }) it("should call handleButtonClick and the respective button's onClick method when a button is clicked", function () { - assert.equal(ButtonGroup.prototype.handleButtonClick.callCount, 0) - assert.equal(childButtonSpies.onClick.callCount, 0) + assert.strictEqual(ButtonGroup.prototype.handleButtonClick.callCount, 0) + assert.strictEqual(childButtonSpies.onClick.callCount, 0) const childButtons = wrapper.find('.button-group__button') childButtons.at(0).props().onClick() childButtons.at(1).props().onClick() childButtons.at(2).props().onClick() - assert.equal(ButtonGroup.prototype.handleButtonClick.callCount, 3) - assert.equal(childButtonSpies.onClick.callCount, 3) + assert.strictEqual(ButtonGroup.prototype.handleButtonClick.callCount, 3) + assert.strictEqual(childButtonSpies.onClick.callCount, 3) }) it('should render all child buttons as disabled if props.disabled is true', function () { const childButtons = wrapper.find('.button-group__button') childButtons.forEach((button) => { - assert.equal(button.props().disabled, undefined) + assert.strictEqual(button.props().disabled, undefined) }) wrapper.setProps({ disabled: true }) const disabledChildButtons = wrapper.find('[disabled=true]') - assert.equal(disabledChildButtons.length, 3) + assert.strictEqual(disabledChildButtons.length, 3) }) it('should render the children of the button', function () { const mockClass = wrapper.find('.mockClass') - assert.equal(mockClass.length, 1) + assert.strictEqual(mockClass.length, 1) }) }) describe('render', function () { it('should render a div with the expected class and style', function () { - assert.equal(wrapper.find('div').at(0).props().className, 'someClassName') - assert.deepEqual(wrapper.find('div').at(0).props().style, { + assert.strictEqual( + wrapper.find('div').at(0).props().className, + 'someClassName', + ) + assert.deepStrictEqual(wrapper.find('div').at(0).props().style, { color: 'red', }) }) it('should call renderButtons when rendering', function () { - assert.equal(ButtonGroup.prototype.renderButtons.callCount, 1) + assert.strictEqual(ButtonGroup.prototype.renderButtons.callCount, 1) wrapper.instance().render() - assert.equal(ButtonGroup.prototype.renderButtons.callCount, 2) + assert.strictEqual(ButtonGroup.prototype.renderButtons.callCount, 2) }) }) }) diff --git a/ui/app/components/ui/button/button.stories.js b/ui/app/components/ui/button/button.stories.js index 25fc853de..d07b02e31 100644 --- a/ui/app/components/ui/button/button.stories.js +++ b/ui/app/components/ui/button/button.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { text, boolean } from '@storybook/addon-knobs/react' +import { text, boolean } from '@storybook/addon-knobs' import Button from '.' export default { diff --git a/ui/app/components/ui/card/tests/card.component.test.js b/ui/app/components/ui/card/tests/card.component.test.js index 4fc92252a..efd05e727 100644 --- a/ui/app/components/ui/card/tests/card.component.test.js +++ b/ui/app/components/ui/card/tests/card.component.test.js @@ -14,9 +14,9 @@ describe('Card Component', function () { assert.ok(wrapper.hasClass('card-test-class')) const title = wrapper.find('.card__title') assert.ok(title) - assert.equal(title.text(), 'Test') + assert.strictEqual(title.text(), 'Test') const child = wrapper.find('.child-test-class') assert.ok(child) - assert.equal(child.text(), 'Child') + assert.strictEqual(child.text(), 'Child') }) }) diff --git a/ui/app/components/ui/check-box/check-box.stories.js b/ui/app/components/ui/check-box/check-box.stories.js index 20647f780..2fb7cdae7 100644 --- a/ui/app/components/ui/check-box/check-box.stories.js +++ b/ui/app/components/ui/check-box/check-box.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { boolean, select, text } from '@storybook/addon-knobs/react' +import { boolean, select, text } from '@storybook/addon-knobs' import CheckBox, { CHECKED, INDETERMINATE, diff --git a/ui/app/components/ui/currency-display/tests/currency-display.component.test.js b/ui/app/components/ui/currency-display/tests/currency-display.component.test.js index 9e023aef3..8fd0bb4ba 100644 --- a/ui/app/components/ui/currency-display/tests/currency-display.component.test.js +++ b/ui/app/components/ui/currency-display/tests/currency-display.component.test.js @@ -24,7 +24,7 @@ describe('CurrencyDisplay Component', function () { ) assert.ok(wrapper.hasClass('currency-display')) - assert.equal(wrapper.text(), '$123.45') + assert.strictEqual(wrapper.text(), '$123.45') }) it('should render text with a prefix', function () { @@ -38,7 +38,7 @@ describe('CurrencyDisplay Component', function () { ) assert.ok(wrapper.hasClass('currency-display')) - assert.equal(wrapper.text(), '-$123.45') + assert.strictEqual(wrapper.text(), '-$123.45') }) afterEach(function () { sinon.restore() diff --git a/ui/app/components/ui/currency-input/tests/currency-input.component.test.js b/ui/app/components/ui/currency-input/tests/currency-input.component.test.js index d4d88be02..e6e05a33b 100644 --- a/ui/app/components/ui/currency-input/tests/currency-input.component.test.js +++ b/ui/app/components/ui/currency-input/tests/currency-input.component.test.js @@ -15,7 +15,7 @@ describe('CurrencyInput Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find(UnitInput).length, 1) + assert.strictEqual(wrapper.find(UnitInput).length, 1) }) it('should render properly with a suffix', function () { @@ -39,9 +39,9 @@ describe('CurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH') - assert.equal(wrapper.find(CurrencyDisplay).length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) }) it('should render properly with an ETH value', function () { @@ -69,12 +69,15 @@ describe('CurrencyInput Component', function () { assert.ok(wrapper) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'de0b6b3a7640000') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual( + currencyInputInstance.state.hexValue, + 'de0b6b3a7640000', + ) + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, 1) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', ) @@ -106,12 +109,12 @@ describe('CurrencyInput Component', function () { assert.ok(wrapper) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'f602f2234d0ea') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'USD') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'USD') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, 1) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', ) @@ -148,12 +151,15 @@ describe('CurrencyInput Component', function () { assert.ok(wrapper) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 0.004328) - assert.equal(currencyInputInstance.state.hexValue, 'f602f2234d0ea') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH') - assert.equal(wrapper.find('.unit-input__input').props().value, '0.004328') - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 0.004328) + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') + assert.strictEqual( + wrapper.find('.unit-input__input').props().value, + 0.004328, + ) + assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'noConversionRateAvailable_t', ) @@ -191,28 +197,31 @@ describe('CurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 0) - assert.equal(currencyInputInstance.state.hexValue, undefined) - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 0) + assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000')) - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', ) - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'de0b6b3a7640000') + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual( + currencyInputInstance.state.hexValue, + 'de0b6b3a7640000', + ) }) it('should call onChange on input changes with the hex value for fiat', function () { @@ -238,25 +247,28 @@ describe('CurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 0) - assert.equal(currencyInputInstance.state.hexValue, undefined) - assert.equal(wrapper.find('.currency-display-component').text(), '0ETH') + assert.strictEqual(currencyInputInstance.state.decimalValue, 0) + assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + assert.strictEqual( + wrapper.find('.currency-display-component').text(), + '0ETH', + ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('f602f2234d0ea')) - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', ) - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'f602f2234d0ea') + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual(currencyInputInstance.state.hexValue, 'f602f2234d0ea') }) it('should change the state and pass in a new decimalValue when props.value changes', function () { @@ -283,15 +295,18 @@ describe('CurrencyInput Component', function () { assert.ok(wrapper) const currencyInputInstance = wrapper.find(CurrencyInput).dive() - assert.equal(currencyInputInstance.state('decimalValue'), 0) - assert.equal(currencyInputInstance.state('hexValue'), undefined) - assert.equal(currencyInputInstance.find(UnitInput).props().value, 0) + assert.strictEqual(currencyInputInstance.state('decimalValue'), 0) + assert.strictEqual(currencyInputInstance.state('hexValue'), undefined) + assert.strictEqual(currencyInputInstance.find(UnitInput).props().value, 0) currencyInputInstance.setProps({ value: '1ec05e43e72400' }) currencyInputInstance.update() - assert.equal(currencyInputInstance.state('decimalValue'), 2) - assert.equal(currencyInputInstance.state('hexValue'), '1ec05e43e72400') - assert.equal(currencyInputInstance.find(UnitInput).props().value, 2) + assert.strictEqual(currencyInputInstance.state('decimalValue'), 2) + assert.strictEqual( + currencyInputInstance.state('hexValue'), + '1ec05e43e72400', + ) + assert.strictEqual(currencyInputInstance.find(UnitInput).props().value, 2) }) it('should swap selected currency when swap icon is clicked', function () { @@ -317,32 +332,35 @@ describe('CurrencyInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const currencyInputInstance = wrapper.find(CurrencyInput).at(0).instance() - assert.equal(currencyInputInstance.state.decimalValue, 0) - assert.equal(currencyInputInstance.state.hexValue, undefined) - assert.equal( + assert.strictEqual(currencyInputInstance.state.decimalValue, 0) + assert.strictEqual(currencyInputInstance.state.hexValue, undefined) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('de0b6b3a7640000')) - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$231.06USD', ) - assert.equal(currencyInputInstance.state.decimalValue, 1) - assert.equal(currencyInputInstance.state.hexValue, 'de0b6b3a7640000') + assert.strictEqual(currencyInputInstance.state.decimalValue, 1) + assert.strictEqual( + currencyInputInstance.state.hexValue, + 'de0b6b3a7640000', + ) const swap = wrapper.find('.currency-input__swap-component') swap.simulate('click') - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '0.004328ETH', ) diff --git a/ui/app/components/ui/currency-input/tests/currency-input.container.test.js b/ui/app/components/ui/currency-input/tests/currency-input.container.test.js index 3dac9add0..1ce9eb559 100644 --- a/ui/app/components/ui/currency-input/tests/currency-input.container.test.js +++ b/ui/app/components/ui/currency-input/tests/currency-input.container.test.js @@ -131,7 +131,7 @@ describe('CurrencyInput container', function () { tests.forEach(({ mockState, expected, comment }) => { it(comment, function () { - return assert.deepEqual(mapStateToProps(mockState), expected) + return assert.deepStrictEqual(mapStateToProps(mockState), expected) }) }) }) @@ -189,7 +189,7 @@ describe('CurrencyInput container', function () { comment, }) => { it(comment, function () { - assert.deepEqual( + assert.deepStrictEqual( mergeProps(stateProps, dispatchProps, ownProps), expected, ) diff --git a/ui/app/components/ui/dropdown/dropdown.stories.js b/ui/app/components/ui/dropdown/dropdown.stories.js index e5771623f..b46358def 100644 --- a/ui/app/components/ui/dropdown/dropdown.stories.js +++ b/ui/app/components/ui/dropdown/dropdown.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { boolean, select, text } from '@storybook/addon-knobs/react' +import { boolean, select, text } from '@storybook/addon-knobs' import Dropdown from '.' export default { diff --git a/ui/app/components/ui/error-message/tests/error-message.component.test.js b/ui/app/components/ui/error-message/tests/error-message.component.test.js index 5bf05d876..884fe6565 100644 --- a/ui/app/components/ui/error-message/tests/error-message.component.test.js +++ b/ui/app/components/ui/error-message/tests/error-message.component.test.js @@ -12,9 +12,9 @@ describe('ErrorMessage Component', function () { }) assert.ok(wrapper) - assert.equal(wrapper.find('.error-message').length, 1) - assert.equal(wrapper.find('.error-message__icon').length, 1) - assert.equal( + assert.strictEqual(wrapper.find('.error-message').length, 1) + assert.strictEqual(wrapper.find('.error-message__icon').length, 1) + assert.strictEqual( wrapper.find('.error-message__text').text(), 'ALERT: This is an error.', ) @@ -26,9 +26,9 @@ describe('ErrorMessage Component', function () { }) assert.ok(wrapper) - assert.equal(wrapper.find('.error-message').length, 1) - assert.equal(wrapper.find('.error-message__icon').length, 1) - assert.equal( + assert.strictEqual(wrapper.find('.error-message').length, 1) + assert.strictEqual(wrapper.find('.error-message__icon').length, 1) + assert.strictEqual( wrapper.find('.error-message__text').text(), 'ALERT: translate testKey', ) diff --git a/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js b/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js index 3d8086630..cb75bfd63 100644 --- a/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js +++ b/ui/app/components/ui/hex-to-decimal/tests/hex-to-decimal.component.test.js @@ -10,7 +10,7 @@ describe('HexToDecimal Component', function () { ) assert.ok(wrapper.hasClass('hex-to-decimal')) - assert.equal(wrapper.text(), '12345') + assert.strictEqual(wrapper.text(), '12345') }) it('should render an unprefixed hex as a decimal with a className', function () { @@ -19,6 +19,6 @@ describe('HexToDecimal Component', function () { ) assert.ok(wrapper.hasClass('hex-to-decimal')) - assert.equal(wrapper.text(), '6789') + assert.strictEqual(wrapper.text(), '6789') }) }) diff --git a/ui/app/components/ui/icon/icon.stories.js b/ui/app/components/ui/icon/icon.stories.js index a737b77c9..11209a32a 100644 --- a/ui/app/components/ui/icon/icon.stories.js +++ b/ui/app/components/ui/icon/icon.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { color, number } from '@storybook/addon-knobs/react' +import { color, number } from '@storybook/addon-knobs' import Approve from './approve-icon.component' import Copy from './copy-icon.component' import Interaction from './interaction-icon.component' diff --git a/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js b/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js index 390ef02a3..05d201e22 100644 --- a/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js +++ b/ui/app/components/ui/identicon/blockieIdenticon/blockieIdenticon.component.js @@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from 'react' import PropTypes from 'prop-types' import { renderIcon } from '@download/blockies' -const BlockieIdenticon = ({ address, diameter }) => { +const BlockieIdenticon = ({ address, diameter, alt }) => { const [dataUrl, setDataUrl] = useState(null) const canvasRef = useRef(null) @@ -19,7 +19,7 @@ const BlockieIdenticon = ({ address, diameter }) => { return ( <> - + {alt ) } @@ -27,6 +27,7 @@ const BlockieIdenticon = ({ address, diameter }) => { BlockieIdenticon.propTypes = { address: PropTypes.string.isRequired, diameter: PropTypes.number.isRequired, + alt: PropTypes.string, } export default BlockieIdenticon diff --git a/ui/app/components/ui/identicon/identicon.component.js b/ui/app/components/ui/identicon/identicon.component.js index 840108f60..09a731eca 100644 --- a/ui/app/components/ui/identicon/identicon.component.js +++ b/ui/app/components/ui/identicon/identicon.component.js @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { checksumAddress } from '../../../helpers/utils/util' import Jazzicon from '../jazzicon' @@ -21,6 +21,7 @@ export default class Identicon extends PureComponent { diameter: PropTypes.number, image: PropTypes.string, useBlockie: PropTypes.bool, + alt: PropTypes.string, } static defaultProps = { @@ -30,23 +31,24 @@ export default class Identicon extends PureComponent { diameter: 46, image: undefined, useBlockie: false, + alt: '', } renderImage() { - const { className, diameter, image } = this.props + const { className, diameter, image, alt } = this.props return ( ) } renderJazzicon() { - const { address, className, diameter } = this.props + const { address, className, diameter, alt } = this.props return ( ) } renderBlockie() { - const { address, className, diameter } = this.props + const { address, className, diameter, alt } = this.props return (
- +
) } @@ -79,6 +82,7 @@ export default class Identicon extends PureComponent { diameter, useBlockie, addBorder, + alt, } = this.props if (image) { @@ -88,10 +92,7 @@ export default class Identicon extends PureComponent { if (address) { const checksummedAddress = checksumAddress(address) - if ( - contractMap[checksummedAddress] && - contractMap[checksummedAddress].logo - ) { + if (contractMap[checksummedAddress]?.logo) { return this.renderJazzicon() } @@ -109,7 +110,7 @@ export default class Identicon extends PureComponent { className={classnames('identicon__eth-logo', className)} src="./images/eth_logo.svg" style={getStyles(diameter)} - alt="" + alt={alt} /> ) } diff --git a/ui/app/components/ui/identicon/identicon.stories.js b/ui/app/components/ui/identicon/identicon.stories.js index fec2e2f2c..0dbefe0ff 100644 --- a/ui/app/components/ui/identicon/identicon.stories.js +++ b/ui/app/components/ui/identicon/identicon.stories.js @@ -1,6 +1,5 @@ import React from 'react' -import { text, boolean } from '@storybook/addon-knobs/react' -import { number } from '@storybook/addon-knobs' +import { text, boolean, number } from '@storybook/addon-knobs' import Identicon from './identicon.component' export default { title: 'Identicon' } diff --git a/ui/app/components/ui/identicon/tests/identicon.component.test.js b/ui/app/components/ui/identicon/tests/identicon.component.test.js index f07fb2d96..c938657ab 100644 --- a/ui/app/components/ui/identicon/tests/identicon.component.test.js +++ b/ui/app/components/ui/identicon/tests/identicon.component.test.js @@ -19,7 +19,7 @@ describe('Identicon', function () { it('renders default eth_logo identicon with no props', function () { const wrapper = mount() - assert.equal( + assert.strictEqual( wrapper.find('img.identicon__eth-logo').prop('src'), './images/eth_logo.svg', ) @@ -30,11 +30,11 @@ describe('Identicon', function () { , ) - assert.equal( + assert.strictEqual( wrapper.find('img.test-image').prop('className'), 'identicon test-image', ) - assert.equal(wrapper.find('img.test-image').prop('src'), 'test-image') + assert.strictEqual(wrapper.find('img.test-image').prop('src'), 'test-image') }) it('renders div with address prop', function () { @@ -42,7 +42,7 @@ describe('Identicon', function () { , ) - assert.equal( + assert.strictEqual( wrapper.find('div.test-address').prop('className'), 'identicon test-address', ) diff --git a/ui/app/components/ui/info-tooltip/info-tooltip.stories.js b/ui/app/components/ui/info-tooltip/info-tooltip.stories.js index 5d79ef92a..dfe44e2cf 100644 --- a/ui/app/components/ui/info-tooltip/info-tooltip.stories.js +++ b/ui/app/components/ui/info-tooltip/info-tooltip.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import InfoTooltip from './info-tooltip' export default { diff --git a/ui/app/components/ui/list-item/list-item.stories.js b/ui/app/components/ui/list-item/list-item.stories.js index 80a979b5b..ce9f3d4af 100644 --- a/ui/app/components/ui/list-item/list-item.stories.js +++ b/ui/app/components/ui/list-item/list-item.stories.js @@ -1,6 +1,6 @@ import React from 'react' import PropTypes from 'prop-types' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import Send from '../icon/send-icon.component' import Interaction from '../icon/interaction-icon.component' import Approve from '../icon/approve-icon.component' diff --git a/ui/app/components/ui/list-item/tests/list-item.test.js b/ui/app/components/ui/list-item/tests/list-item.test.js index 94d42ea3c..6f9e132cd 100644 --- a/ui/app/components/ui/list-item/tests/list-item.test.js +++ b/ui/app/components/ui/list-item/tests/list-item.test.js @@ -35,13 +35,13 @@ describe('ListItem', function () { ) }) it('includes the data-testid', function () { - assert.equal(wrapper.props()['data-testid'], 'test-id') + assert.strictEqual(wrapper.props()['data-testid'], 'test-id') }) it(`renders "${TITLE}" title`, function () { - assert.equal(wrapper.find('.list-item__heading h2').text(), TITLE) + assert.strictEqual(wrapper.find('.list-item__heading h2').text(), TITLE) }) it(`renders "I am a list item" subtitle`, function () { - assert.equal( + assert.strictEqual( wrapper.find('.list-item__subheading').text(), 'I am a list item', ) @@ -50,19 +50,19 @@ describe('ListItem', function () { assert(wrapper.props().className.includes(CLASSNAME)) }) it('renders content on the right side of the list item', function () { - assert.equal( + assert.strictEqual( wrapper.find('.list-item__right-content p').text(), 'Content rendered to the right', ) }) it('renders content in the middle of the list item', function () { - assert.equal( + assert.strictEqual( wrapper.find('.list-item__mid-content p').text(), 'Content rendered in the middle', ) }) it('renders list item actions', function () { - assert.equal( + assert.strictEqual( wrapper.find('.list-item__actions button').text(), 'I am a button', ) @@ -75,7 +75,7 @@ describe('ListItem', function () { }) it('handles click action and fires onClick', function () { wrapper.simulate('click') - assert.equal(clickHandler.callCount, 1) + assert.strictEqual(clickHandler.callCount, 1) }) after(function () { diff --git a/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js b/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js index ab2fd753b..5ea89c620 100644 --- a/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js +++ b/ui/app/components/ui/metafox-logo/tests/metafox-logo.component.test.js @@ -7,11 +7,11 @@ describe('MetaFoxLogo', function () { it('sets icon height and width to 42 by default', function () { const wrapper = mount() - assert.equal( + assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('width'), 42, ) - assert.equal( + assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('height'), 42, ) @@ -20,13 +20,13 @@ describe('MetaFoxLogo', function () { it('does not set icon height and width when unsetIconHeight is true', function () { const wrapper = mount() - assert.equal( + assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('width'), - null, + undefined, ) - assert.equal( + assert.strictEqual( wrapper.find('img.app-header__metafox-logo--icon').prop('height'), - null, + undefined, ) }) }) diff --git a/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js b/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js index ff41417a3..4fd9b039c 100644 --- a/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js +++ b/ui/app/components/ui/page-container/page-container-footer/tests/page-container-footer.component.test.js @@ -24,7 +24,7 @@ describe('Page Footer', function () { }) it('renders page container footer', function () { - assert.equal(wrapper.find('.page-container__footer').length, 1) + assert.strictEqual(wrapper.find('.page-container__footer').length, 1) }) it('should render a secondary footer inside page-container__footer when given children', function () { @@ -35,23 +35,26 @@ describe('Page Footer', function () { { context: { t: sinon.spy((k) => `[${k}]`) } }, ) - assert.equal(wrapper.find('.page-container__footer-secondary').length, 1) + assert.strictEqual( + wrapper.find('.page-container__footer-secondary').length, + 1, + ) }) it('renders two button components', function () { - assert.equal(wrapper.find(Button).length, 2) + assert.strictEqual(wrapper.find(Button).length, 2) }) describe('Cancel Button', function () { it('has button type of default', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').first().prop('type'), 'default', ) }) it('has children text of Cancel', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').first().prop('children'), 'Cancel', ) @@ -59,27 +62,27 @@ describe('Page Footer', function () { it('should call cancel when click is simulated', function () { wrapper.find('.page-container__footer-button').first().prop('onClick')() - assert.equal(onCancel.callCount, 1) + assert.strictEqual(onCancel.callCount, 1) }) }) describe('Submit Button', function () { it('assigns button type based on props', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('type'), 'Test Type', ) }) it('has disabled prop', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('disabled'), false, ) }) it('has children text when submitText prop exists', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__footer-button').last().prop('children'), 'Submit', ) @@ -87,7 +90,7 @@ describe('Page Footer', function () { it('should call submit when click is simulated', function () { wrapper.find('.page-container__footer-button').last().prop('onClick')() - assert.equal(onSubmit.callCount, 1) + assert.strictEqual(onSubmit.callCount, 1) }) }) }) diff --git a/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js b/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js index ab035c641..c686e3490 100644 --- a/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js +++ b/ui/app/components/ui/page-container/page-container-header/tests/page-container-header.component.test.js @@ -27,12 +27,15 @@ describe('Page Container Header', function () { describe('Render Header Row', function () { it('renders back button', function () { - assert.equal(wrapper.find('.page-container__back-button').length, 1) - assert.equal(wrapper.find('.page-container__back-button').text(), 'Back') + assert.strictEqual(wrapper.find('.page-container__back-button').length, 1) + assert.strictEqual( + wrapper.find('.page-container__back-button').text(), + 'Back', + ) }) it('ensures style prop', function () { - assert.equal( + assert.strictEqual( wrapper.find('.page-container__back-button').props().style, style, ) @@ -40,7 +43,7 @@ describe('Page Container Header', function () { it('should call back button when click is simulated', function () { wrapper.find('.page-container__back-button').prop('onClick')() - assert.equal(onBackButtonClick.callCount, 1) + assert.strictEqual(onBackButtonClick.callCount, 1) }) }) @@ -57,29 +60,29 @@ describe('Page Container Header', function () { }) it('renders page container', function () { - assert.equal(header.length, 1) - assert.equal(headerRow.length, 1) - assert.equal(pageTitle.length, 1) - assert.equal(pageSubtitle.length, 1) - assert.equal(pageClose.length, 1) - assert.equal(pageTab.length, 1) + assert.strictEqual(header.length, 1) + assert.strictEqual(headerRow.length, 1) + assert.strictEqual(pageTitle.length, 1) + assert.strictEqual(pageSubtitle.length, 1) + assert.strictEqual(pageClose.length, 1) + assert.strictEqual(pageTab.length, 1) }) it('renders title', function () { - assert.equal(pageTitle.text(), 'Test Title') + assert.strictEqual(pageTitle.text(), 'Test Title') }) it('renders subtitle', function () { - assert.equal(pageSubtitle.text(), 'Test Subtitle') + assert.strictEqual(pageSubtitle.text(), 'Test Subtitle') }) it('renders tabs', function () { - assert.equal(pageTab.text(), 'Test Tab') + assert.strictEqual(pageTab.text(), 'Test Tab') }) it('should call close when click is simulated', function () { pageClose.prop('onClick')() - assert.equal(onClose.callCount, 1) + assert.strictEqual(onClose.callCount, 1) }) }) }) diff --git a/ui/app/components/ui/popover/popover.stories.js b/ui/app/components/ui/popover/popover.stories.js index f81aa69e2..be713f0dc 100644 --- a/ui/app/components/ui/popover/popover.stories.js +++ b/ui/app/components/ui/popover/popover.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import { action } from '@storybook/addon-actions' import Popover from './popover.component' diff --git a/ui/app/components/ui/tabs/tabs.stories.js b/ui/app/components/ui/tabs/tabs.stories.js index f69d38103..1cdc9044c 100644 --- a/ui/app/components/ui/tabs/tabs.stories.js +++ b/ui/app/components/ui/tabs/tabs.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import Tab from './tab/tab.component' import Tabs from './tabs.component' diff --git a/ui/app/components/ui/token-input/tests/token-input.component.test.js b/ui/app/components/ui/token-input/tests/token-input.component.test.js index 52668a1cc..e6542b3e2 100644 --- a/ui/app/components/ui/token-input/tests/token-input.component.test.js +++ b/ui/app/components/ui/token-input/tests/token-input.component.test.js @@ -41,13 +41,13 @@ describe('TokenInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal( + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual( wrapper.find('.currency-input__conversion-component').length, 1, ) - assert.equal( + assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'translate noConversionRateAvailable', ) @@ -82,9 +82,9 @@ describe('TokenInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal(wrapper.find(CurrencyDisplay).length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual(wrapper.find(CurrencyDisplay).length, 1) }) it('should render properly with a token value for ETH', function () { @@ -112,12 +112,15 @@ describe('TokenInput Component', function () { assert.ok(wrapper) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal(wrapper.find('.currency-display-component').text(), '2ETH') + assert.strictEqual(tokenInputInstance.state.decimalValue, '1') + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.strictEqual( + wrapper.find('.currency-display-component').text(), + '2ETH', + ) }) it('should render properly with a token value for fiat', function () { @@ -146,12 +149,12 @@ describe('TokenInput Component', function () { assert.ok(wrapper) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal( + assert.strictEqual(tokenInputInstance.state.decimalValue, '1') + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$462.12USD', ) @@ -190,12 +193,12 @@ describe('TokenInput Component', function () { assert.ok(wrapper) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ABC') - assert.equal(wrapper.find('.unit-input__input').props().value, '1') - assert.equal( + assert.strictEqual(tokenInputInstance.state.decimalValue, '1') + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ABC') + assert.strictEqual(wrapper.find('.unit-input__input').props().value, '1') + assert.strictEqual( wrapper.find('.currency-input__conversion-component').text(), 'translate noConversionRateAvailable', ) @@ -234,22 +237,28 @@ describe('TokenInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 0) - assert.equal(tokenInputInstance.state.hexValue, undefined) - assert.equal(wrapper.find('.currency-display-component').text(), '0ETH') + assert.strictEqual(tokenInputInstance.state.decimalValue, 0) + assert.strictEqual(tokenInputInstance.state.hexValue, undefined) + assert.strictEqual( + wrapper.find('.currency-display-component').text(), + '0ETH', + ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('2710')) - assert.equal(wrapper.find('.currency-display-component').text(), '2ETH') - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual( + wrapper.find('.currency-display-component').text(), + '2ETH', + ) + assert.strictEqual(tokenInputInstance.state.decimalValue, 1) + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') }) it('should call onChange on input changes with the hex value for fiat', function () { @@ -276,28 +285,28 @@ describe('TokenInput Component', function () { ) assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) - assert.equal(handleBlurSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) + assert.strictEqual(handleBlurSpy.callCount, 0) const tokenInputInstance = wrapper.find(TokenInput).at(0).instance() - assert.equal(tokenInputInstance.state.decimalValue, 0) - assert.equal(tokenInputInstance.state.hexValue, undefined) - assert.equal( + assert.strictEqual(tokenInputInstance.state.decimalValue, 0) + assert.strictEqual(tokenInputInstance.state.hexValue, undefined) + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$0.00USD', ) const input = wrapper.find('input') - assert.equal(input.props().value, 0) + assert.strictEqual(input.props().value, 0) input.simulate('change', { target: { value: 1 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith('2710')) - assert.equal( + assert.strictEqual( wrapper.find('.currency-display-component').text(), '$462.12USD', ) - assert.equal(tokenInputInstance.state.decimalValue, 1) - assert.equal(tokenInputInstance.state.hexValue, '2710') + assert.strictEqual(tokenInputInstance.state.decimalValue, 1) + assert.strictEqual(tokenInputInstance.state.hexValue, '2710') }) it('should change the state and pass in a new decimalValue when props.value changes', function () { @@ -325,15 +334,15 @@ describe('TokenInput Component', function () { assert.ok(wrapper) const tokenInputInstance = wrapper.find(TokenInput).dive() - assert.equal(tokenInputInstance.state('decimalValue'), 0) - assert.equal(tokenInputInstance.state('hexValue'), undefined) - assert.equal(tokenInputInstance.find(UnitInput).props().value, 0) + assert.strictEqual(tokenInputInstance.state('decimalValue'), 0) + assert.strictEqual(tokenInputInstance.state('hexValue'), undefined) + assert.strictEqual(tokenInputInstance.find(UnitInput).props().value, 0) tokenInputInstance.setProps({ value: '2710' }) tokenInputInstance.update() - assert.equal(tokenInputInstance.state('decimalValue'), 1) - assert.equal(tokenInputInstance.state('hexValue'), '2710') - assert.equal(tokenInputInstance.find(UnitInput).props().value, 1) + assert.strictEqual(tokenInputInstance.state('decimalValue'), '1') + assert.strictEqual(tokenInputInstance.state('hexValue'), '2710') + assert.strictEqual(tokenInputInstance.find(UnitInput).props().value, '1') }) }) }) diff --git a/ui/app/components/ui/unit-input/tests/unit-input.component.test.js b/ui/app/components/ui/unit-input/tests/unit-input.component.test.js index c759f496f..47fdfafde 100644 --- a/ui/app/components/ui/unit-input/tests/unit-input.component.test.js +++ b/ui/app/components/ui/unit-input/tests/unit-input.component.test.js @@ -10,15 +10,15 @@ describe('UnitInput Component', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 0) + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 0) }) it('should render properly with a suffix', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input__suffix').length, 1) - assert.equal(wrapper.find('.unit-input__suffix').text(), 'ETH') + assert.strictEqual(wrapper.find('.unit-input__suffix').length, 1) + assert.strictEqual(wrapper.find('.unit-input__suffix').text(), 'ETH') }) it('should render properly with a child component', function () { @@ -29,15 +29,15 @@ describe('UnitInput Component', function () { ) assert.ok(wrapper) - assert.equal(wrapper.find('.testing').length, 1) - assert.equal(wrapper.find('.testing').text(), 'TESTCOMPONENT') + assert.strictEqual(wrapper.find('.testing').length, 1) + assert.strictEqual(wrapper.find('.testing').text(), 'TESTCOMPONENT') }) it('should render with an error class when props.error === true', function () { const wrapper = shallow() assert.ok(wrapper) - assert.equal(wrapper.find('.unit-input--error').length, 1) + assert.strictEqual(wrapper.find('.unit-input--error').length, 1) }) }) @@ -57,43 +57,43 @@ describe('UnitInput Component', function () { const handleFocusSpy = sinon.spy(wrapper.instance(), 'handleFocus') wrapper.instance().forceUpdate() wrapper.update() - assert.equal(handleFocusSpy.callCount, 0) + assert.strictEqual(handleFocusSpy.callCount, 0) wrapper.find('.unit-input').simulate('click') - assert.equal(handleFocusSpy.callCount, 1) + assert.strictEqual(handleFocusSpy.callCount, 1) }) it('should call onChange on input changes with the value', function () { const wrapper = mount() assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) const input = wrapper.find('input') input.simulate('change', { target: { value: 123 } }) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith(123)) - assert.equal(wrapper.state('value'), 123) + assert.strictEqual(wrapper.state('value'), 123) }) it('should set the component state value with props.value', function () { const wrapper = mount() assert.ok(wrapper) - assert.equal(wrapper.state('value'), 123) + assert.strictEqual(wrapper.state('value'), 123) }) it('should update the component state value with props.value', function () { const wrapper = mount() assert.ok(wrapper) - assert.equal(handleChangeSpy.callCount, 0) + assert.strictEqual(handleChangeSpy.callCount, 0) const input = wrapper.find('input') input.simulate('change', { target: { value: 123 } }) - assert.equal(wrapper.state('value'), 123) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(wrapper.state('value'), 123) + assert.strictEqual(handleChangeSpy.callCount, 1) assert.ok(handleChangeSpy.calledWith(123)) wrapper.setProps({ value: 456 }) - assert.equal(wrapper.state('value'), 456) - assert.equal(handleChangeSpy.callCount, 1) + assert.strictEqual(wrapper.state('value'), 456) + assert.strictEqual(handleChangeSpy.callCount, 1) }) }) }) diff --git a/ui/app/contexts/metametrics.js b/ui/app/contexts/metametrics.js index 835f0caea..80d383a54 100644 --- a/ui/app/contexts/metametrics.js +++ b/ui/app/contexts/metametrics.js @@ -4,7 +4,6 @@ import React, { useEffect, useCallback, useState, - useMemo, } from 'react' import { useSelector } from 'react-redux' import PropTypes from 'prop-types' @@ -12,17 +11,14 @@ import { useHistory } from 'react-router-dom' import { captureException } from '@sentry/browser' import { - getCurrentNetworkId, getAccountType, getNumberOfAccounts, getNumberOfTokens, - getCurrentChainId, } from '../selectors/selectors' import { getSendToken } from '../selectors/send' import { txDataSelector } from '../selectors/confirm-transaction' import { getEnvironmentType } from '../../../app/scripts/lib/util' -import { getTrackMetaMetricsEvent } from '../../../shared/modules/metametrics' -import { getCurrentLocale } from '../ducks/metamask/metamask' +import { trackMetaMetricsEvent } from '../store/actions' export const MetaMetricsContext = createContext(() => { captureException( @@ -34,20 +30,10 @@ export const MetaMetricsContext = createContext(() => { export function MetaMetricsProvider({ children }) { const txData = useSelector(txDataSelector) || {} - const network = useSelector(getCurrentNetworkId) const environmentType = getEnvironmentType() - const chainId = useSelector(getCurrentChainId) - const locale = useSelector(getCurrentLocale) const activeCurrency = useSelector(getSendToken)?.symbol const accountType = useSelector(getAccountType) const confirmTransactionOrigin = txData.origin - const metaMetricsId = useSelector((state) => state.metamask.metaMetricsId) - const participateInMetaMetrics = useSelector( - (state) => state.metamask.participateInMetaMetrics, - ) - const metaMetricsSendCount = useSelector( - (state) => state.metamask.metaMetricsSendCount, - ) const numberOfTokens = useSelector(getNumberOfTokens) const numberOfAccounts = useSelector(getNumberOfAccounts) const history = useHistory() @@ -69,75 +55,58 @@ export function MetaMetricsProvider({ children }) { return unlisten }, [history]) - /** - * track a metametrics event - * - * @param {import('../../../shared/modules/metametrics').MetaMetricsEventPayload} payload - payload for event - * @returns undefined - */ - const trackEvent = useMemo(() => { - const referrer = confirmTransactionOrigin - ? { url: confirmTransactionOrigin } - : undefined - const page = { - path: currentPath, - } - return getTrackMetaMetricsEvent(global.platform.getVersion(), () => ({ - context: { - referrer, - page, - }, - environmentType, - locale: locale.replace('_', '-'), - network, - chainId, - participateInMetaMetrics, - metaMetricsId, - metaMetricsSendCount, - })) - }, [ - network, - chainId, - locale, - environmentType, - participateInMetaMetrics, - currentPath, - confirmTransactionOrigin, - metaMetricsId, - metaMetricsSendCount, - ]) - const metricsEvent = useCallback( (config = {}, overrides = {}) => { const { eventOpts = {} } = config - - return trackEvent({ - event: eventOpts.name, - category: eventOpts.category, - isOptIn: config.isOptIn, - excludeMetaMetricsId: - eventOpts.excludeMetaMetricsId ?? - overrides.excludeMetaMetricsId ?? - false, - metaMetricsId: config.metaMetricsId, - matomoEvent: true, - properties: { - action: eventOpts.action, - number_of_tokens: numberOfTokens, - number_of_accounts: numberOfAccounts, - active_currency: activeCurrency, - account_type: accountType, - is_new_visit: config.is_new_visit, - // the properties coming from this key will not match our standards for - // snake_case on properties, and they may be redundant and/or not in the - // proper location (origin not as a referrer, for example). This is a temporary - // solution to not lose data, and the entire event system will be reworked in - // forthcoming PRs to deprecate the old Matomo events in favor of the new schema. - ...config.customVariables, + const referrer = confirmTransactionOrigin + ? { url: confirmTransactionOrigin } + : undefined + const page = { + path: currentPath, + } + return trackMetaMetricsEvent( + { + event: eventOpts.name, + category: eventOpts.category, + properties: { + action: eventOpts.action, + number_of_tokens: numberOfTokens, + number_of_accounts: numberOfAccounts, + active_currency: activeCurrency, + account_type: accountType, + is_new_visit: config.is_new_visit, + // the properties coming from this key will not match our standards for + // snake_case on properties, and they may be redundant and/or not in the + // proper location (origin not as a referrer, for example). This is a temporary + // solution to not lose data, and the entire event system will be reworked in + // forthcoming PRs to deprecate the old Matomo events in favor of the new schema. + ...config.customVariables, + }, + page, + referrer, + environmentType, }, - }) + { + isOptIn: config.isOptIn, + excludeMetaMetricsId: + eventOpts.excludeMetaMetricsId ?? + overrides.excludeMetaMetricsId ?? + false, + metaMetricsId: config.metaMetricsId, + matomoEvent: true, + flushImmediately: config.flushImmediately, + }, + ) }, - [accountType, activeCurrency, numberOfTokens, numberOfAccounts, trackEvent], + [ + accountType, + currentPath, + confirmTransactionOrigin, + activeCurrency, + numberOfTokens, + numberOfAccounts, + environmentType, + ], ) return ( diff --git a/ui/app/contexts/metametrics.new.js b/ui/app/contexts/metametrics.new.js index f8596b796..ca39df100 100644 --- a/ui/app/contexts/metametrics.new.js +++ b/ui/app/contexts/metametrics.new.js @@ -4,33 +4,46 @@ * metrics system. This file implements Segment analytics tracking. */ import React, { - useRef, Component, createContext, useEffect, - useMemo, + useRef, + useCallback, } from 'react' import { useSelector } from 'react-redux' import PropTypes from 'prop-types' -import { useLocation, matchPath, useRouteMatch } from 'react-router-dom' +import { matchPath, useLocation, useRouteMatch } from 'react-router-dom' import { captureException, captureMessage } from '@sentry/browser' import { omit } from 'lodash' - import { getEnvironmentType } from '../../../app/scripts/lib/util' import { PATH_NAME_MAP } from '../helpers/constants/routes' -import { getCurrentLocale } from '../ducks/metamask/metamask' -import { - getCurrentChainId, - getMetricsNetworkIdentifier, - txDataSelector, -} from '../selectors' -import { - getTrackMetaMetricsEvent, - METAMETRICS_ANONYMOUS_ID, - segment, -} from '../../../shared/modules/metametrics' +import { txDataSelector } from '../selectors' +import { trackMetaMetricsEvent, trackMetaMetricsPage } from '../store/actions' + +// type imports +/** + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventPayload} MetaMetricsEventPayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageObject} MetaMetricsPageObject + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsReferrerObject} MetaMetricsReferrerObject + */ + +// types +/** + * @typedef {Omit} UIMetricsEventPayload + */ +/** + * @typedef {( + * payload: UIMetricsEventPayload, + * options: MetaMetricsEventOptions + * ) => Promise} UITrackEventMethod + */ + +/** + * @type {React.Context} + */ export const MetaMetricsContext = createContext(() => { captureException( Error( @@ -41,6 +54,14 @@ export const MetaMetricsContext = createContext(() => { const PATHS_TO_CHECK = Object.keys(PATH_NAME_MAP) +/** + * Returns the current page if it matches out route map, as well as the origin + * if there is a confirmation that was triggered by a dapp + * @returns {{ + * page?: MetaMetricsPageObject + * referrer?: MetaMetricsReferrerObject + * }} + */ function useSegmentContext() { const match = useRouteMatch({ path: PATHS_TO_CHECK, @@ -71,45 +92,25 @@ function useSegmentContext() { } export function MetaMetricsProvider({ children }) { - const metaMetricsId = useSelector((state) => state.metamask.metaMetricsId) - const participateInMetaMetrics = useSelector( - (state) => state.metamask.participateInMetaMetrics, - ) - const metaMetricsSendCount = useSelector( - (state) => state.metamask.metaMetricsSendCount, - ) - const locale = useSelector(getCurrentLocale) const location = useLocation() const context = useSegmentContext() - const network = useSelector(getMetricsNetworkIdentifier) - const chainId = useSelector(getCurrentChainId) /** - * track a metametrics event - * - * @param {import('../../../shared/modules/metametrics').MetaMetricsEventPayload} payload - payload for event - * @returns undefined + * @type {UITrackEventMethod} */ - const trackEvent = useMemo(() => { - return getTrackMetaMetricsEvent(global.platform.getVersion(), () => ({ - context, - locale: locale.replace('_', '-'), - environmentType: getEnvironmentType(), - chainId, - network, - participateInMetaMetrics, - metaMetricsId, - metaMetricsSendCount, - })) - }, [ - network, - participateInMetaMetrics, - locale, - metaMetricsId, - metaMetricsSendCount, - chainId, - context, - ]) + const trackEvent = useCallback( + (payload, options) => { + trackMetaMetricsEvent( + { + ...payload, + environmentType: getEnvironmentType(), + ...context, + }, + options, + ) + }, + [context], + ) // Used to prevent double tracking page calls const previousMatch = useRef() @@ -122,68 +123,52 @@ export function MetaMetricsProvider({ children }) { */ useEffect(() => { const environmentType = getEnvironmentType() - if ( - (participateInMetaMetrics === null && - location.pathname.startsWith('/initialize')) || - participateInMetaMetrics - ) { - // Events that happen during initialization before the user opts into - // MetaMetrics will be anonymous - const idTrait = metaMetricsId ? 'userId' : 'anonymousId' - const idValue = metaMetricsId ?? METAMETRICS_ANONYMOUS_ID - const match = matchPath(location.pathname, { - path: PATHS_TO_CHECK, - exact: true, - strict: true, + const match = matchPath(location.pathname, { + path: PATHS_TO_CHECK, + exact: true, + strict: true, + }) + // Start by checking for a missing match route. If this falls through to + // the else if, then we know we have a matched route for tracking. + if (!match) { + captureMessage(`Segment page tracking found unmatched route`, { + extra: { + previousMatch, + currentPath: location.pathname, + }, }) - // Start by checking for a missing match route. If this falls through to - // the else if, then we know we have a matched route for tracking. - if (!match) { - captureMessage(`Segment page tracking found unmatched route`, { - extra: { - previousMatch, - currentPath: location.pathname, - }, - }) - } else if ( - previousMatch.current !== match.path && - !( - environmentType === 'notification' && - match.path === '/' && - previousMatch.current === undefined - ) - ) { - // When a notification window is open by a Dapp we do not want to track - // the initial home route load that can sometimes happen. To handle - // this we keep track of the previousMatch, and we skip the event track - // in the event that we are dealing with the initial load of the - // homepage - const { path, params } = match - const name = PATH_NAME_MAP[path] - segment.page({ - [idTrait]: idValue, + } else if ( + previousMatch.current !== match.path && + !( + environmentType === 'notification' && + match.path === '/' && + previousMatch.current === undefined + ) + ) { + // When a notification window is open by a Dapp we do not want to track + // the initial home route load that can sometimes happen. To handle + // this we keep track of the previousMatch, and we skip the event track + // in the event that we are dealing with the initial load of the + // homepage + const { path, params } = match + const name = PATH_NAME_MAP[path] + trackMetaMetricsPage( + { name, - properties: { - // We do not want to send addresses or accounts in any events - // Some routes include these as params. - params: omit(params, ['account', 'address']), - locale: locale.replace('_', '-'), - network, - environment_type: environmentType, - }, - context, - }) - } - previousMatch.current = match?.path + // We do not want to send addresses or accounts in any events + // Some routes include these as params. + params: omit(params, ['account', 'address']), + environmentType, + page: context.page, + referrer: context.referrer, + }, + { + isOptInPath: location.pathname.startsWith('/initialize'), + }, + ) } - }, [ - location, - locale, - context, - network, - metaMetricsId, - participateInMetaMetrics, - ]) + previousMatch.current = match?.path + }, [location, context]) return ( diff --git a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js index 4d2d56544..f5edaa67f 100644 --- a/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js +++ b/ui/app/ducks/confirm-transaction/confirm-transaction.duck.test.js @@ -83,11 +83,14 @@ describe('Confirm Transaction Duck', function () { } it('should initialize state', function () { - assert.deepEqual(ConfirmTransactionReducer(undefined, {}), initialState) + assert.deepStrictEqual( + ConfirmTransactionReducer(undefined, {}), + initialState, + ) }) it('should return state unchanged if it does not match a dispatched actions type', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: 'someOtherAction', value: 'someValue', @@ -97,7 +100,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set txData when receiving a UPDATE_TX_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TX_DATA, payload: { @@ -115,7 +118,7 @@ describe('Confirm Transaction Duck', function () { }) it('should clear txData when receiving a CLEAR_TX_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: CLEAR_TX_DATA, }), @@ -127,7 +130,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set tokenData when receiving a UPDATE_TOKEN_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TOKEN_DATA, payload: { @@ -145,7 +148,7 @@ describe('Confirm Transaction Duck', function () { }) it('should clear tokenData when receiving a CLEAR_TOKEN_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: CLEAR_TOKEN_DATA, }), @@ -157,7 +160,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set methodData when receiving a UPDATE_METHOD_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_METHOD_DATA, payload: { @@ -175,7 +178,7 @@ describe('Confirm Transaction Duck', function () { }) it('should clear methodData when receiving a CLEAR_METHOD_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: CLEAR_METHOD_DATA, }), @@ -187,7 +190,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update transaction amounts when receiving an UPDATE_TRANSACTION_AMOUNTS action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TRANSACTION_AMOUNTS, payload: { @@ -206,7 +209,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update transaction fees when receiving an UPDATE_TRANSACTION_FEES action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TRANSACTION_FEES, payload: { @@ -225,7 +228,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update transaction totals when receiving an UPDATE_TRANSACTION_TOTALS action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TRANSACTION_TOTALS, payload: { @@ -244,7 +247,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update tokenProps when receiving an UPDATE_TOKEN_PROPS action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TOKEN_PROPS, payload: { @@ -263,7 +266,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update nonce when receiving an UPDATE_NONCE action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_NONCE, payload: '0x1', @@ -276,7 +279,7 @@ describe('Confirm Transaction Duck', function () { }) it('should update nonce when receiving an UPDATE_TO_SMART_CONTRACT action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: UPDATE_TO_SMART_CONTRACT, payload: true, @@ -289,7 +292,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set fetchingData to true when receiving a FETCH_DATA_START action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: FETCH_DATA_START, }), @@ -301,7 +304,7 @@ describe('Confirm Transaction Duck', function () { }) it('should set fetchingData to false when receiving a FETCH_DATA_END action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer( { fetchingData: true }, { type: FETCH_DATA_END }, @@ -311,7 +314,7 @@ describe('Confirm Transaction Duck', function () { }) it('should clear confirmTransaction when receiving a FETCH_DATA_END action', function () { - assert.deepEqual( + assert.deepStrictEqual( ConfirmTransactionReducer(mockState, { type: CLEAR_CONFIRM_TRANSACTION, }), @@ -328,7 +331,7 @@ describe('Confirm Transaction Duck', function () { payload: txData, } - assert.deepEqual(actions.updateTxData(txData), expectedAction) + assert.deepStrictEqual(actions.updateTxData(txData), expectedAction) }) it('should create an action to clear txData', function () { @@ -336,7 +339,7 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_TX_DATA, } - assert.deepEqual(actions.clearTxData(), expectedAction) + assert.deepStrictEqual(actions.clearTxData(), expectedAction) }) it('should create an action to update tokenData', function () { @@ -346,7 +349,7 @@ describe('Confirm Transaction Duck', function () { payload: tokenData, } - assert.deepEqual(actions.updateTokenData(tokenData), expectedAction) + assert.deepStrictEqual(actions.updateTokenData(tokenData), expectedAction) }) it('should create an action to clear tokenData', function () { @@ -354,7 +357,7 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_TOKEN_DATA, } - assert.deepEqual(actions.clearTokenData(), expectedAction) + assert.deepStrictEqual(actions.clearTokenData(), expectedAction) }) it('should create an action to update methodData', function () { @@ -364,7 +367,10 @@ describe('Confirm Transaction Duck', function () { payload: methodData, } - assert.deepEqual(actions.updateMethodData(methodData), expectedAction) + assert.deepStrictEqual( + actions.updateMethodData(methodData), + expectedAction, + ) }) it('should create an action to clear methodData', function () { @@ -372,7 +378,7 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_METHOD_DATA, } - assert.deepEqual(actions.clearMethodData(), expectedAction) + assert.deepStrictEqual(actions.clearMethodData(), expectedAction) }) it('should create an action to update transaction amounts', function () { @@ -382,7 +388,7 @@ describe('Confirm Transaction Duck', function () { payload: transactionAmounts, } - assert.deepEqual( + assert.deepStrictEqual( actions.updateTransactionAmounts(transactionAmounts), expectedAction, ) @@ -395,7 +401,7 @@ describe('Confirm Transaction Duck', function () { payload: transactionFees, } - assert.deepEqual( + assert.deepStrictEqual( actions.updateTransactionFees(transactionFees), expectedAction, ) @@ -408,7 +414,7 @@ describe('Confirm Transaction Duck', function () { payload: transactionTotals, } - assert.deepEqual( + assert.deepStrictEqual( actions.updateTransactionTotals(transactionTotals), expectedAction, ) @@ -424,7 +430,10 @@ describe('Confirm Transaction Duck', function () { payload: tokenProps, } - assert.deepEqual(actions.updateTokenProps(tokenProps), expectedAction) + assert.deepStrictEqual( + actions.updateTokenProps(tokenProps), + expectedAction, + ) }) it('should create an action to update nonce', function () { @@ -434,7 +443,7 @@ describe('Confirm Transaction Duck', function () { payload: nonce, } - assert.deepEqual(actions.updateNonce(nonce), expectedAction) + assert.deepStrictEqual(actions.updateNonce(nonce), expectedAction) }) it('should create an action to set fetchingData to true', function () { @@ -442,7 +451,7 @@ describe('Confirm Transaction Duck', function () { type: FETCH_DATA_START, } - assert.deepEqual(actions.setFetchingData(true), expectedAction) + assert.deepStrictEqual(actions.setFetchingData(true), expectedAction) }) it('should create an action to set fetchingData to false', function () { @@ -450,7 +459,7 @@ describe('Confirm Transaction Duck', function () { type: FETCH_DATA_END, } - assert.deepEqual(actions.setFetchingData(false), expectedAction) + assert.deepStrictEqual(actions.setFetchingData(false), expectedAction) }) it('should create an action to clear confirmTransaction', function () { @@ -458,7 +467,7 @@ describe('Confirm Transaction Duck', function () { type: CLEAR_CONFIRM_TRANSACTION, } - assert.deepEqual(actions.clearConfirmTransaction(), expectedAction) + assert.deepStrictEqual(actions.clearConfirmTransaction(), expectedAction) }) }) @@ -526,9 +535,9 @@ describe('Confirm Transaction Duck', function () { ) const storeActions = store.getActions() - assert.equal(storeActions.length, expectedActions.length) + assert.strictEqual(storeActions.length, expectedActions.length) storeActions.forEach((action, index) => - assert.equal(action.type, expectedActions[index]), + assert.strictEqual(action.type, expectedActions[index]), ) }) @@ -592,9 +601,9 @@ describe('Confirm Transaction Duck', function () { store.dispatch(actions.updateTxDataAndCalculate(txData)) const storeActions = store.getActions() - assert.equal(storeActions.length, expectedActions.length) + assert.strictEqual(storeActions.length, expectedActions.length) storeActions.forEach((action, index) => - assert.equal(action.type, expectedActions[index]), + assert.strictEqual(action.type, expectedActions[index]), ) }) @@ -638,10 +647,10 @@ describe('Confirm Transaction Duck', function () { store.dispatch(actions.setTransactionToConfirm(2603411941761054)) const storeActions = store.getActions() - assert.equal(storeActions.length, expectedActions.length) + assert.strictEqual(storeActions.length, expectedActions.length) storeActions.forEach((action, index) => - assert.equal(action.type, expectedActions[index]), + assert.strictEqual(action.type, expectedActions[index]), ) }) }) diff --git a/ui/app/ducks/gas/gas-duck.test.js b/ui/app/ducks/gas/gas-duck.test.js index 6db54d12a..519741f25 100644 --- a/ui/app/ducks/gas/gas-duck.test.js +++ b/ui/app/ducks/gas/gas-duck.test.js @@ -2,10 +2,10 @@ import assert from 'assert' import sinon from 'sinon' import proxyquire from 'proxyquire' -const fakeLocalStorage = {} +const fakeStorage = {} const GasDuck = proxyquire('./gas.duck.js', { - '../../../lib/local-storage-helpers': fakeLocalStorage, + '../../../lib/storage-helpers': fakeStorage, }) const { @@ -14,143 +14,22 @@ const { setBasicGasEstimateData, setCustomGasPrice, setCustomGasLimit, - setCustomGasTotal, - setCustomGasErrors, resetCustomGasState, - fetchBasicGasAndTimeEstimates, fetchBasicGasEstimates, - gasEstimatesLoadingStarted, - gasEstimatesLoadingFinished, - setPricesAndTimeEstimates, - fetchGasEstimates, - setApiEstimatesLastRetrieved, } = GasDuck const GasReducer = GasDuck.default describe('Gas Duck', function () { let tempFetch let tempDateNow - const mockEthGasApiResponse = { - average: 20, - avgWait: 'mockAvgWait', - block_time: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 30, - fastest: 40, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 10, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - standard: 20, + const mockGasPriceApiResponse = { + SafeGasPrice: 10, + ProposeGasPrice: 20, + FastGasPrice: 30, } - const mockPredictTableResponse = [ - { - expectedTime: 400, - expectedWait: 40, - gasprice: 0.25, - somethingElse: 'foobar', - }, - { - expectedTime: 200, - expectedWait: 20, - gasprice: 0.5, - somethingElse: 'foobar', - }, - { - expectedTime: 100, - expectedWait: 10, - gasprice: 1, - somethingElse: 'foobar', - }, - { - expectedTime: 75, - expectedWait: 7.5, - gasprice: 1.5, - somethingElse: 'foobar', - }, - { expectedTime: 50, expectedWait: 5, gasprice: 2, somethingElse: 'foobar' }, - { - expectedTime: 35, - expectedWait: 4.5, - gasprice: 3, - somethingElse: 'foobar', - }, - { - expectedTime: 34, - expectedWait: 4.4, - gasprice: 3.1, - somethingElse: 'foobar', - }, - { - expectedTime: 25, - expectedWait: 4.2, - gasprice: 3.5, - somethingElse: 'foobar', - }, - { expectedTime: 20, expectedWait: 4, gasprice: 4, somethingElse: 'foobar' }, - { - expectedTime: 19, - expectedWait: 3.9, - gasprice: 4.1, - somethingElse: 'foobar', - }, - { expectedTime: 15, expectedWait: 3, gasprice: 7, somethingElse: 'foobar' }, - { - expectedTime: 14, - expectedWait: 2.9, - gasprice: 7.1, - somethingElse: 'foobar', - }, - { - expectedTime: 12, - expectedWait: 2.5, - gasprice: 8, - somethingElse: 'foobar', - }, - { - expectedTime: 10, - expectedWait: 2, - gasprice: 10, - somethingElse: 'foobar', - }, - { - expectedTime: 9, - expectedWait: 1.9, - gasprice: 10.1, - somethingElse: 'foobar', - }, - { expectedTime: 5, expectedWait: 1, gasprice: 15, somethingElse: 'foobar' }, - { - expectedTime: 4, - expectedWait: 0.9, - gasprice: 15.1, - somethingElse: 'foobar', - }, - { - expectedTime: 2, - expectedWait: 0.8, - gasprice: 17, - somethingElse: 'foobar', - }, - { - expectedTime: 1.1, - expectedWait: 0.6, - gasprice: 19.9, - somethingElse: 'foobar', - }, - { - expectedTime: 1, - expectedWait: 0.5, - gasprice: 20, - somethingElse: 'foobar', - }, - ] - const fakeFetch = (url) => + const fakeFetch = () => new Promise((resolve) => { - const dataToResolve = url.match(/ethgasAPI/u) - ? mockEthGasApiResponse - : mockPredictTableResponse + const dataToResolve = mockGasPriceApiResponse resolve({ json: () => Promise.resolve(dataToResolve), }) @@ -160,8 +39,8 @@ describe('Gas Duck', function () { tempFetch = window.fetch tempDateNow = global.Date.now - fakeLocalStorage.loadLocalStorageData = sinon.stub() - fakeLocalStorage.saveLocalStorageData = sinon.spy() + fakeStorage.getStorageItem = sinon.stub() + fakeStorage.setStorageItem = sinon.spy() window.fetch = sinon.stub().callsFake(fakeFetch) global.Date.now = () => 2000000 }) @@ -183,55 +62,30 @@ describe('Gas Duck', function () { }, basicEstimates: { average: null, - fastestWait: null, - fastWait: null, fast: null, - safeLowWait: null, - blockNum: null, - avgWait: null, - blockTime: null, - speed: null, - fastest: null, safeLow: null, }, basicEstimateIsLoading: true, - errors: {}, - gasEstimatesLoading: true, - priceAndTimeEstimates: [], - priceAndTimeEstimatesLastRetrieved: 0, - basicPriceAndTimeEstimatesLastRetrieved: 0, basicPriceEstimatesLastRetrieved: 0, } const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' - const GAS_ESTIMATE_LOADING_FINISHED = - 'metamask/gas/GAS_ESTIMATE_LOADING_FINISHED' - const GAS_ESTIMATE_LOADING_STARTED = - 'metamask/gas/GAS_ESTIMATE_LOADING_STARTED' const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' - const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS' const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' - const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' - const SET_PRICE_AND_TIME_ESTIMATES = - 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES' - const SET_API_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED' - const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED' const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' describe('GasReducer()', function () { it('should initialize state', function () { - assert.deepEqual(GasReducer(undefined, {}), initState) + assert.deepStrictEqual(GasReducer(undefined, {}), initState) }) it('should return state unchanged if it does not match a dispatched actions type', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: 'someOtherAction', value: 'someValue', @@ -241,35 +95,21 @@ describe('Gas Duck', function () { }) it('should set basicEstimateIsLoading to true when receiving a BASIC_GAS_ESTIMATE_LOADING_STARTED action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }), { basicEstimateIsLoading: true, ...mockState }, ) }) it('should set basicEstimateIsLoading to false when receiving a BASIC_GAS_ESTIMATE_LOADING_FINISHED action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }), { basicEstimateIsLoading: false, ...mockState }, ) }) - it('should set gasEstimatesLoading to true when receiving a GAS_ESTIMATE_LOADING_STARTED action', function () { - assert.deepEqual( - GasReducer(mockState, { type: GAS_ESTIMATE_LOADING_STARTED }), - { gasEstimatesLoading: true, ...mockState }, - ) - }) - - it('should set gasEstimatesLoading to false when receiving a GAS_ESTIMATE_LOADING_FINISHED action', function () { - assert.deepEqual( - GasReducer(mockState, { type: GAS_ESTIMATE_LOADING_FINISHED }), - { gasEstimatesLoading: false, ...mockState }, - ) - }) - it('should set basicEstimates when receiving a SET_BASIC_GAS_ESTIMATE_DATA action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { someProp: 'someData123' }, @@ -278,18 +118,8 @@ describe('Gas Duck', function () { ) }) - it('should set priceAndTimeEstimates when receiving a SET_PRICE_AND_TIME_ESTIMATES action', function () { - assert.deepEqual( - GasReducer(mockState, { - type: SET_PRICE_AND_TIME_ESTIMATES, - value: { someProp: 'someData123' }, - }), - { priceAndTimeEstimates: { someProp: 'someData123' }, ...mockState }, - ) - }) - it('should set customData.price when receiving a SET_CUSTOM_GAS_PRICE action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: SET_CUSTOM_GAS_PRICE, value: 4321, @@ -299,7 +129,7 @@ describe('Gas Duck', function () { }) it('should set customData.limit when receiving a SET_CUSTOM_GAS_LIMIT action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: SET_CUSTOM_GAS_LIMIT, value: 9876, @@ -308,51 +138,8 @@ describe('Gas Duck', function () { ) }) - it('should set customData.total when receiving a SET_CUSTOM_GAS_TOTAL action', function () { - assert.deepEqual( - GasReducer(mockState, { - type: SET_CUSTOM_GAS_TOTAL, - value: 10000, - }), - { customData: { total: 10000 }, ...mockState }, - ) - }) - - it('should set priceAndTimeEstimatesLastRetrieved when receiving a SET_API_ESTIMATES_LAST_RETRIEVED action', function () { - assert.deepEqual( - GasReducer(mockState, { - type: SET_API_ESTIMATES_LAST_RETRIEVED, - value: 1500000000000, - }), - { priceAndTimeEstimatesLastRetrieved: 1500000000000, ...mockState }, - ) - }) - - it('should set priceAndTimeEstimatesLastRetrieved when receiving a SET_BASIC_API_ESTIMATES_LAST_RETRIEVED action', function () { - assert.deepEqual( - GasReducer(mockState, { - type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, - value: 1700000000000, - }), - { - basicPriceAndTimeEstimatesLastRetrieved: 1700000000000, - ...mockState, - }, - ) - }) - - it('should set errors when receiving a SET_CUSTOM_GAS_ERRORS action', function () { - assert.deepEqual( - GasReducer(mockState, { - type: SET_CUSTOM_GAS_ERRORS, - value: { someError: 'error_error' }, - }), - { errors: { someError: 'error_error' }, ...mockState }, - ) - }) - it('should return the initial state in response to a RESET_CUSTOM_GAS_STATE action', function () { - assert.deepEqual( + assert.deepStrictEqual( GasReducer(mockState, { type: RESET_CUSTOM_GAS_STATE }), initState, ) @@ -361,7 +148,7 @@ describe('Gas Duck', function () { describe('basicGasEstimatesLoadingStarted', function () { it('should create the correct action', function () { - assert.deepEqual(basicGasEstimatesLoadingStarted(), { + assert.deepStrictEqual(basicGasEstimatesLoadingStarted(), { type: BASIC_GAS_ESTIMATE_LOADING_STARTED, }) }) @@ -369,7 +156,7 @@ describe('Gas Duck', function () { describe('basicGasEstimatesLoadingFinished', function () { it('should create the correct action', function () { - assert.deepEqual(basicGasEstimatesLoadingFinished(), { + assert.deepStrictEqual(basicGasEstimatesLoadingFinished(), { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED, }) }) @@ -382,394 +169,106 @@ describe('Gas Duck', function () { await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState, basicPriceAEstimatesLastRetrieved: 1000000 }, })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, ]) assert.ok( window.fetch .getCall(0) - .args[0].startsWith('https://ethgasstation.info/json/ethgasAPI.json'), - 'should fetch ETH Gas Station', + .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), + 'should fetch metaswap /gasPrices', ) - assert.deepEqual(mockDistpatch.getCall(1).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { - average: 2, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 3, - fastest: 4, - safeLow: 1, + average: 20, + fast: 30, + safeLow: 10, }, }, ]) - assert.deepEqual(mockDistpatch.getCall(3).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(3).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, ]) }) - it('should fetch recently retrieved estimates from local storage', async function () { + it('should fetch recently retrieved estimates from storage', async function () { const mockDistpatch = sinon.spy() - fakeLocalStorage.loadLocalStorageData + fakeStorage.getStorageItem .withArgs('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') .returns(2000000 - 1) // one second ago from "now" - fakeLocalStorage.loadLocalStorageData - .withArgs('BASIC_PRICE_ESTIMATES') - .returns({ - average: 25, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 35, - fastest: 45, - safeLow: 15, - }) + fakeStorage.getStorageItem.withArgs('BASIC_PRICE_ESTIMATES').returns({ + average: 25, + fast: 35, + safeLow: 15, + }) await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, ]) assert.ok(window.fetch.notCalled) - assert.deepEqual(mockDistpatch.getCall(1).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { average: 25, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', fast: 35, - fastest: 45, safeLow: 15, }, }, ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, ]) }) - it('should fallback to network if retrieving estimates from local storage fails', async function () { + it('should fallback to network if retrieving estimates from storage fails', async function () { const mockDistpatch = sinon.spy() - fakeLocalStorage.loadLocalStorageData + fakeStorage.getStorageItem .withArgs('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') .returns(2000000 - 1) // one second ago from "now" await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: { ...initState }, })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(0).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, ]) assert.ok( window.fetch .getCall(0) - .args[0].startsWith('https://ethgasstation.info/json/ethgasAPI.json'), - 'should fetch ETH Gas Station', + .args[0].startsWith('https://api.metaswap.codefi.network/gasPrices'), + 'should fetch metaswap /gasPrices', ) - assert.deepEqual(mockDistpatch.getCall(1).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(1).args, [ { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(2).args, [ { type: SET_BASIC_GAS_ESTIMATE_DATA, value: { - average: 2, - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 3, - fastest: 4, - safeLow: 1, + safeLow: 10, + average: 20, + fast: 30, }, }, ]) - assert.deepEqual(mockDistpatch.getCall(3).args, [ + assert.deepStrictEqual(mockDistpatch.getCall(3).args, [ { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, ]) }) }) - describe('fetchBasicGasAndTimeEstimates', function () { - it('should call fetch with the expected params', async function () { - const mockDistpatch = sinon.spy() - - await fetchBasicGasAndTimeEstimates()(mockDistpatch, () => ({ - gas: { - ...initState, - basicPriceAndTimeEstimatesLastRetrieved: 1000000, - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok( - window.fetch - .getCall(0) - .args[0].startsWith('https://ethgasstation.info/json/ethgasAPI.json'), - 'should fetch ETH Gas Station', - ) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]) - - assert.deepEqual(mockDistpatch.getCall(2).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - average: 2, - avgWait: 'mockAvgWait', - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 3, - fastest: 4, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 1, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - }, - }, - ]) - assert.deepEqual(mockDistpatch.getCall(3).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - - it('should fetch recently retrieved estimates from local storage', async function () { - const mockDistpatch = sinon.spy() - fakeLocalStorage.loadLocalStorageData - .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') - .returns(2000000 - 1) // one second ago from "now" - fakeLocalStorage.loadLocalStorageData - .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES') - .returns({ - average: 5, - avgWait: 'mockAvgWait', - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 6, - fastest: 7, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 1, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - }) - - await fetchBasicGasAndTimeEstimates()(mockDistpatch, () => ({ - gas: { - ...initState, - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok(window.fetch.notCalled) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - average: 5, - avgWait: 'mockAvgWait', - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 6, - fastest: 7, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 1, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - }, - }, - ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - - it('should fallback to network if retrieving estimates from local storage fails', async function () { - const mockDistpatch = sinon.spy() - fakeLocalStorage.loadLocalStorageData - .withArgs('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') - .returns(2000000 - 1) // one second ago from "now" - - await fetchBasicGasAndTimeEstimates()(mockDistpatch, () => ({ - gas: { - ...initState, - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok( - window.fetch - .getCall(0) - .args[0].startsWith('https://ethgasstation.info/json/ethgasAPI.json'), - 'should fetch ETH Gas Station', - ) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]) - - assert.deepEqual(mockDistpatch.getCall(2).args, [ - { - type: SET_BASIC_GAS_ESTIMATE_DATA, - value: { - average: 2, - avgWait: 'mockAvgWait', - blockTime: 'mockBlock_time', - blockNum: 'mockBlockNum', - fast: 3, - fastest: 4, - fastestWait: 'mockFastestWait', - fastWait: 'mockFastWait', - safeLow: 1, - safeLowWait: 'mockSafeLowWait', - speed: 'mockSpeed', - }, - }, - ]) - assert.deepEqual(mockDistpatch.getCall(3).args, [ - { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - }) - - describe('fetchGasEstimates', function () { - it('should call fetch with the expected params', async function () { - const mockDistpatch = sinon.spy() - - await fetchGasEstimates(5)(mockDistpatch, () => ({ - gas: { - ...initState, - priceAndTimeEstimatesLastRetrieved: 1000000, - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.ok( - window.fetch - .getCall(0) - .args[0].startsWith( - 'https://ethgasstation.info/json/predictTable.json', - ), - 'should fetch ETH Gas Station', - ) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { type: SET_API_ESTIMATES_LAST_RETRIEVED, value: 2000000 }, - ]) - - const { - type: thirdDispatchCallType, - value: priceAndTimeEstimateResult, - } = mockDistpatch.getCall(2).args[0] - assert.equal(thirdDispatchCallType, SET_PRICE_AND_TIME_ESTIMATES) - assert( - priceAndTimeEstimateResult.length < - mockPredictTableResponse.length * 3 - 2, - ) - assert(!priceAndTimeEstimateResult.find((d) => d.expectedTime > 100)) - assert( - !priceAndTimeEstimateResult.find( - (d, _, a) => a[a + 1] && d.expectedTime > a[a + 1].expectedTime, - ), - ) - assert( - !priceAndTimeEstimateResult.find( - (d, _, a) => a[a + 1] && d.gasprice > a[a + 1].gasprice, - ), - ) - - assert.deepEqual(mockDistpatch.getCall(3).args, [ - { type: GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - - it('should not call fetch if the estimates were retrieved < 75000 ms ago', async function () { - const mockDistpatch = sinon.spy() - - await fetchGasEstimates(5)(mockDistpatch, () => ({ - gas: { - ...initState, - priceAndTimeEstimatesLastRetrieved: Date.now(), - priceAndTimeEstimates: [ - { - expectedTime: '10', - expectedWait: 2, - gasprice: 50, - }, - ], - }, - metamask: { provider: { type: 'ropsten' } }, - })) - assert.deepEqual(mockDistpatch.getCall(0).args, [ - { type: GAS_ESTIMATE_LOADING_STARTED }, - ]) - assert.equal(window.fetch.callCount, 0) - - assert.deepEqual(mockDistpatch.getCall(1).args, [ - { - type: SET_PRICE_AND_TIME_ESTIMATES, - value: [ - { - expectedTime: '10', - expectedWait: 2, - gasprice: 50, - }, - ], - }, - ]) - assert.deepEqual(mockDistpatch.getCall(2).args, [ - { type: GAS_ESTIMATE_LOADING_FINISHED }, - ]) - }) - }) - - describe('gasEstimatesLoadingStarted', function () { - it('should create the correct action', function () { - assert.deepEqual(gasEstimatesLoadingStarted(), { - type: GAS_ESTIMATE_LOADING_STARTED, - }) - }) - }) - - describe('gasEstimatesLoadingFinished', function () { - it('should create the correct action', function () { - assert.deepEqual(gasEstimatesLoadingFinished(), { - type: GAS_ESTIMATE_LOADING_FINISHED, - }) - }) - }) - - describe('setPricesAndTimeEstimates', function () { - it('should create the correct action', function () { - assert.deepEqual( - setPricesAndTimeEstimates('mockPricesAndTimeEstimates'), - { - type: SET_PRICE_AND_TIME_ESTIMATES, - value: 'mockPricesAndTimeEstimates', - }, - ) - }) - }) - describe('setBasicGasEstimateData', function () { it('should create the correct action', function () { - assert.deepEqual(setBasicGasEstimateData('mockBasicEstimatData'), { + assert.deepStrictEqual(setBasicGasEstimateData('mockBasicEstimatData'), { type: SET_BASIC_GAS_ESTIMATE_DATA, value: 'mockBasicEstimatData', }) @@ -778,7 +277,7 @@ describe('Gas Duck', function () { describe('setCustomGasPrice', function () { it('should create the correct action', function () { - assert.deepEqual(setCustomGasPrice('mockCustomGasPrice'), { + assert.deepStrictEqual(setCustomGasPrice('mockCustomGasPrice'), { type: SET_CUSTOM_GAS_PRICE, value: 'mockCustomGasPrice', }) @@ -787,43 +286,18 @@ describe('Gas Duck', function () { describe('setCustomGasLimit', function () { it('should create the correct action', function () { - assert.deepEqual(setCustomGasLimit('mockCustomGasLimit'), { + assert.deepStrictEqual(setCustomGasLimit('mockCustomGasLimit'), { type: SET_CUSTOM_GAS_LIMIT, value: 'mockCustomGasLimit', }) }) }) - describe('setCustomGasTotal', function () { - it('should create the correct action', function () { - assert.deepEqual(setCustomGasTotal('mockCustomGasTotal'), { - type: SET_CUSTOM_GAS_TOTAL, - value: 'mockCustomGasTotal', - }) - }) - }) - - describe('setCustomGasErrors', function () { - it('should create the correct action', function () { - assert.deepEqual(setCustomGasErrors('mockErrorObject'), { - type: SET_CUSTOM_GAS_ERRORS, - value: 'mockErrorObject', - }) - }) - }) - - describe('setApiEstimatesLastRetrieved', function () { - it('should create the correct action', function () { - assert.deepEqual(setApiEstimatesLastRetrieved(1234), { - type: SET_API_ESTIMATES_LAST_RETRIEVED, - value: 1234, - }) - }) - }) - describe('resetCustomGasState', function () { it('should create the correct action', function () { - assert.deepEqual(resetCustomGasState(), { type: RESET_CUSTOM_GAS_STATE }) + assert.deepStrictEqual(resetCustomGasState(), { + type: RESET_CUSTOM_GAS_STATE, + }) }) }) }) diff --git a/ui/app/ducks/gas/gas.duck.js b/ui/app/ducks/gas/gas.duck.js index 5a937e744..83b15ecf1 100644 --- a/ui/app/ducks/gas/gas.duck.js +++ b/ui/app/ducks/gas/gas.duck.js @@ -1,32 +1,19 @@ -import { uniqBy, cloneDeep, flatten } from 'lodash' +import { cloneDeep } from 'lodash' import BigNumber from 'bignumber.js' -import { - loadLocalStorageData, - saveLocalStorageData, -} from '../../../lib/local-storage-helpers' +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' + import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util' -import { isEthereumNetwork } from '../../selectors' // Actions const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' -const GAS_ESTIMATE_LOADING_FINISHED = - 'metamask/gas/GAS_ESTIMATE_LOADING_FINISHED' -const GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/GAS_ESTIMATE_LOADING_STARTED' const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA' const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' -const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS' const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' -const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' -const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES' -const SET_API_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED' -const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = - 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED' const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' @@ -36,25 +23,12 @@ const initState = { limit: null, }, basicEstimates: { - average: null, - fastestWait: null, - fastWait: null, - fast: null, - safeLowWait: null, - blockNum: null, - avgWait: null, - blockTime: null, - speed: null, - fastest: null, safeLow: null, + average: null, + fast: null, }, basicEstimateIsLoading: true, - gasEstimatesLoading: true, - priceAndTimeEstimates: [], - priceAndTimeEstimatesLastRetrieved: 0, - basicPriceAndTimeEstimatesLastRetrieved: 0, basicPriceEstimatesLastRetrieved: 0, - errors: {}, } // Reducer @@ -70,16 +44,6 @@ export default function reducer(state = initState, action) { ...state, basicEstimateIsLoading: false, } - case GAS_ESTIMATE_LOADING_STARTED: - return { - ...state, - gasEstimatesLoading: true, - } - case GAS_ESTIMATE_LOADING_FINISHED: - return { - ...state, - gasEstimatesLoading: false, - } case SET_BASIC_GAS_ESTIMATE_DATA: return { ...state, @@ -101,37 +65,6 @@ export default function reducer(state = initState, action) { limit: action.value, }, } - case SET_CUSTOM_GAS_TOTAL: - return { - ...state, - customData: { - ...state.customData, - total: action.value, - }, - } - case SET_PRICE_AND_TIME_ESTIMATES: - return { - ...state, - priceAndTimeEstimates: action.value, - } - case SET_CUSTOM_GAS_ERRORS: - return { - ...state, - errors: { - ...state.errors, - ...action.value, - }, - } - case SET_API_ESTIMATES_LAST_RETRIEVED: - return { - ...state, - priceAndTimeEstimatesLastRetrieved: action.value, - } - case SET_BASIC_API_ESTIMATES_LAST_RETRIEVED: - return { - ...state, - basicPriceAndTimeEstimatesLastRetrieved: action.value, - } case SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED: return { ...state, @@ -162,41 +95,11 @@ export function basicGasEstimatesLoadingFinished() { } } -export function gasEstimatesLoadingStarted() { - return { - type: GAS_ESTIMATE_LOADING_STARTED, - } -} - -export function gasEstimatesLoadingFinished() { - return { - type: GAS_ESTIMATE_LOADING_FINISHED, - } -} - -async function queryEthGasStationBasic() { - const apiKey = process.env.ETH_GAS_STATION_API_KEY - ? `?api-key=${process.env.ETH_GAS_STATION_API_KEY}` - : '' - const url = `https://ethgasstation.info/json/ethgasAPI.json${apiKey}` +async function basicGasPriceQuery() { + const url = `https://api.metaswap.codefi.network/gasPrices` return await window.fetch(url, { headers: {}, - referrer: 'http://ethgasstation.info/json/', - referrerPolicy: 'no-referrer-when-downgrade', - body: null, - method: 'GET', - mode: 'cors', - }) -} - -async function queryEthGasStationPredictionTable() { - const apiKey = process.env.ETH_GAS_STATION_API_KEY - ? `?api-key=${process.env.ETH_GAS_STATION_API_KEY}` - : '' - const url = `https://ethgasstation.info/json/predictTable.json${apiKey}` - return await window.fetch(url, { - headers: {}, - referrer: 'http://ethgasstation.info/json/', + referrer: 'https://api.metaswap.codefi.network/gasPrices', referrerPolicy: 'no-referrer-when-downgrade', body: null, method: 'GET', @@ -209,7 +112,7 @@ export function fetchBasicGasEstimates() { const { basicPriceEstimatesLastRetrieved } = getState().gas const timeLastRetrieved = basicPriceEstimatesLastRetrieved || - loadLocalStorageData('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') || + (await getStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED')) || 0 dispatch(basicGasEstimatesLoadingStarted()) @@ -218,7 +121,7 @@ export function fetchBasicGasEstimates() { if (Date.now() - timeLastRetrieved > 75000) { basicEstimates = await fetchExternalBasicGasEstimates(dispatch) } else { - const cachedBasicEstimates = loadLocalStorageData('BASIC_PRICE_ESTIMATES') + const cachedBasicEstimates = await getStorageItem('BASIC_PRICE_ESTIMATES') basicEstimates = cachedBasicEstimates || (await fetchExternalBasicGasEstimates(dispatch)) } @@ -231,299 +134,36 @@ export function fetchBasicGasEstimates() { } async function fetchExternalBasicGasEstimates(dispatch) { - const response = await queryEthGasStationBasic() + const response = await basicGasPriceQuery() - const { - safeLow: safeLowTimes10, - average: averageTimes10, - fast: fastTimes10, - fastest: fastestTimes10, - block_time: blockTime, - blockNum, - } = await response.json() + const { SafeGasPrice, ProposeGasPrice, FastGasPrice } = await response.json() - const [average, fast, fastest, safeLow] = [ - averageTimes10, - fastTimes10, - fastestTimes10, - safeLowTimes10, - ].map((price) => new BigNumber(price).div(10).toNumber()) + const [safeLow, average, fast] = [ + SafeGasPrice, + ProposeGasPrice, + FastGasPrice, + ].map((price) => new BigNumber(price, 10).toNumber()) const basicEstimates = { safeLow, average, fast, - fastest, - blockTime, - blockNum, } const timeRetrieved = Date.now() - saveLocalStorageData(basicEstimates, 'BASIC_PRICE_ESTIMATES') - saveLocalStorageData(timeRetrieved, 'BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') + await Promise.all([ + setStorageItem('BASIC_PRICE_ESTIMATES', basicEstimates), + setStorageItem('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED', timeRetrieved), + ]) dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved)) return basicEstimates } -export function fetchBasicGasAndTimeEstimates() { - return async (dispatch, getState) => { - const { basicPriceAndTimeEstimatesLastRetrieved } = getState().gas - const timeLastRetrieved = - basicPriceAndTimeEstimatesLastRetrieved || - loadLocalStorageData('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') || - 0 - - dispatch(basicGasEstimatesLoadingStarted()) - - let basicEstimates - if (Date.now() - timeLastRetrieved > 75000) { - basicEstimates = await fetchExternalBasicGasAndTimeEstimates(dispatch) - } else { - const cachedBasicEstimates = loadLocalStorageData( - 'BASIC_GAS_AND_TIME_API_ESTIMATES', - ) - basicEstimates = - cachedBasicEstimates || - (await fetchExternalBasicGasAndTimeEstimates(dispatch)) - } - - dispatch(setBasicGasEstimateData(basicEstimates)) - dispatch(basicGasEstimatesLoadingFinished()) - return basicEstimates - } -} - -async function fetchExternalBasicGasAndTimeEstimates(dispatch) { - const response = await queryEthGasStationBasic() - - const { - average: averageTimes10, - avgWait, - block_time: blockTime, - blockNum, - fast: fastTimes10, - fastest: fastestTimes10, - fastestWait, - fastWait, - safeLow: safeLowTimes10, - safeLowWait, - speed, - } = await response.json() - const [average, fast, fastest, safeLow] = [ - averageTimes10, - fastTimes10, - fastestTimes10, - safeLowTimes10, - ].map((price) => new BigNumber(price).div(10).toNumber()) - - const basicEstimates = { - average, - avgWait, - blockTime, - blockNum, - fast, - fastest, - fastestWait, - fastWait, - safeLow, - safeLowWait, - speed, - } - - const timeRetrieved = Date.now() - saveLocalStorageData(basicEstimates, 'BASIC_GAS_AND_TIME_API_ESTIMATES') - saveLocalStorageData( - timeRetrieved, - 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED', - ) - dispatch(setBasicApiEstimatesLastRetrieved(timeRetrieved)) - - return basicEstimates -} - -function extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) { - /* eslint-disable no-param-reassign */ - higherY = new BigNumber(higherY, 10) - lowerY = new BigNumber(lowerY, 10) - higherX = new BigNumber(higherX, 10) - lowerX = new BigNumber(lowerX, 10) - xForExtrapolation = new BigNumber(xForExtrapolation, 10) - /* eslint-enable no-param-reassign */ - const slope = higherY.minus(lowerY).div(higherX.minus(lowerX)) - const newTimeEstimate = slope - .times(higherX.minus(xForExtrapolation)) - .minus(higherY) - .negated() - - return Number(newTimeEstimate.toPrecision(10)) -} - -function getRandomArbitrary(minStr, maxStr) { - const min = new BigNumber(minStr, 10) - const max = new BigNumber(maxStr, 10) - const random = new BigNumber(String(Math.random()), 10) - return new BigNumber(random.times(max.minus(min)).plus(min)).toPrecision(10) -} - -function calcMedian(list) { - const medianPos = - (Math.floor(list.length / 2) + Math.ceil(list.length / 2)) / 2 - return medianPos === Math.floor(medianPos) - ? (list[medianPos - 1] + list[medianPos]) / 2 - : list[Math.floor(medianPos)] -} - -function quartiles(data) { - const lowerHalf = data.slice(0, Math.floor(data.length / 2)) - const upperHalf = data.slice( - Math.floor(data.length / 2) + (data.length % 2 === 0 ? 0 : 1), - ) - const median = calcMedian(data) - const lowerQuartile = calcMedian(lowerHalf) - const upperQuartile = calcMedian(upperHalf) - return { - median, - lowerQuartile, - upperQuartile, - } -} - -function inliersByIQR(data, prop) { - const { lowerQuartile, upperQuartile } = quartiles( - data.map((d) => (prop ? d[prop] : d)), - ) - const IQR = upperQuartile - lowerQuartile - const lowerBound = lowerQuartile - 1.5 * IQR - const upperBound = upperQuartile + 1.5 * IQR - return data.filter((d) => { - const value = prop ? d[prop] : d - return value >= lowerBound && value <= upperBound - }) -} - -export function fetchGasEstimates(blockTime) { - return (dispatch, getState) => { - const state = getState() - - if (!isEthereumNetwork(state)) { - return Promise.resolve(null) - } - - const { - priceAndTimeEstimatesLastRetrieved, - priceAndTimeEstimates, - } = state.gas - const timeLastRetrieved = - priceAndTimeEstimatesLastRetrieved || - loadLocalStorageData('GAS_API_ESTIMATES_LAST_RETRIEVED') || - 0 - - dispatch(gasEstimatesLoadingStarted()) - - const promiseToFetch = - Date.now() - timeLastRetrieved > 75000 - ? queryEthGasStationPredictionTable() - .then((r) => r.json()) - .then((r) => { - const estimatedPricesAndTimes = r.map( - ({ expectedTime, expectedWait, gasprice }) => ({ - expectedTime, - expectedWait, - gasprice, - }), - ) - const estimatedTimeWithUniquePrices = uniqBy( - estimatedPricesAndTimes, - ({ expectedTime }) => expectedTime, - ) - - const withSupplementalTimeEstimates = flatten( - estimatedTimeWithUniquePrices.map( - ({ expectedWait, gasprice }, i, arr) => { - const next = arr[i + 1] - if (!next) { - return [{ expectedWait, gasprice }] - } - const supplementalPrice = getRandomArbitrary( - gasprice, - next.gasprice, - ) - const supplementalTime = extrapolateY({ - higherY: next.expectedWait, - lowerY: expectedWait, - higherX: next.gasprice, - lowerX: gasprice, - xForExtrapolation: supplementalPrice, - }) - const supplementalPrice2 = getRandomArbitrary( - supplementalPrice, - next.gasprice, - ) - const supplementalTime2 = extrapolateY({ - higherY: next.expectedWait, - lowerY: supplementalTime, - higherX: next.gasprice, - lowerX: supplementalPrice, - xForExtrapolation: supplementalPrice2, - }) - return [ - { expectedWait, gasprice }, - { - expectedWait: supplementalTime, - gasprice: supplementalPrice, - }, - { - expectedWait: supplementalTime2, - gasprice: supplementalPrice2, - }, - ] - }, - ), - ) - const withOutliersRemoved = inliersByIQR( - withSupplementalTimeEstimates.slice(0).reverse(), - 'expectedWait', - ).reverse() - const timeMappedToSeconds = withOutliersRemoved.map( - ({ expectedWait, gasprice }) => { - const expectedTime = new BigNumber(expectedWait) - .times(Number(blockTime), 10) - .toNumber() - return { - expectedTime, - gasprice: new BigNumber(gasprice, 10).toNumber(), - } - }, - ) - - const timeRetrieved = Date.now() - dispatch(setApiEstimatesLastRetrieved(timeRetrieved)) - saveLocalStorageData( - timeRetrieved, - 'GAS_API_ESTIMATES_LAST_RETRIEVED', - ) - saveLocalStorageData(timeMappedToSeconds, 'GAS_API_ESTIMATES') - - return timeMappedToSeconds - }) - : Promise.resolve( - priceAndTimeEstimates.length - ? priceAndTimeEstimates - : loadLocalStorageData('GAS_API_ESTIMATES'), - ) - - return promiseToFetch.then((estimates) => { - dispatch(setPricesAndTimeEstimates(estimates)) - dispatch(gasEstimatesLoadingFinished()) - }) - } -} - export function setCustomGasPriceForRetry(newPrice) { - return (dispatch) => { + return async (dispatch) => { if (newPrice === '0x0') { - const { fast } = loadLocalStorageData('BASIC_PRICE_ESTIMATES') + const { fast } = await getStorageItem('BASIC_PRICE_ESTIMATES') dispatch(setCustomGasPrice(decGWEIToHexWEI(fast))) } else { dispatch(setCustomGasPrice(newPrice)) @@ -538,13 +178,6 @@ export function setBasicGasEstimateData(basicGasEstimateData) { } } -export function setPricesAndTimeEstimates(estimatedPricesAndTimes) { - return { - type: SET_PRICE_AND_TIME_ESTIMATES, - value: estimatedPricesAndTimes, - } -} - export function setCustomGasPrice(newPrice) { return { type: SET_CUSTOM_GAS_PRICE, @@ -559,34 +192,6 @@ export function setCustomGasLimit(newLimit) { } } -export function setCustomGasTotal(newTotal) { - return { - type: SET_CUSTOM_GAS_TOTAL, - value: newTotal, - } -} - -export function setCustomGasErrors(newErrors) { - return { - type: SET_CUSTOM_GAS_ERRORS, - value: newErrors, - } -} - -export function setApiEstimatesLastRetrieved(retrievalTime) { - return { - type: SET_API_ESTIMATES_LAST_RETRIEVED, - value: retrievalTime, - } -} - -export function setBasicApiEstimatesLastRetrieved(retrievalTime) { - return { - type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, - value: retrievalTime, - } -} - export function setBasicPriceEstimatesLastRetrieved(retrievalTime) { return { type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, diff --git a/ui/app/ducks/send/send-duck.test.js b/ui/app/ducks/send/send-duck.test.js index 3c7ca415a..2d123fb01 100644 --- a/ui/app/ducks/send/send-duck.test.js +++ b/ui/app/ducks/send/send-duck.test.js @@ -26,11 +26,11 @@ describe('Send Duck', function () { describe('SendReducer()', function () { it('should initialize state', function () { - assert.deepEqual(SendReducer(undefined, {}), initState) + assert.deepStrictEqual(SendReducer(undefined, {}), initState) }) it('should return state unchanged if it does not match a dispatched actions type', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: 'someOtherAction', value: 'someValue', @@ -40,7 +40,7 @@ describe('Send Duck', function () { }) it('should set toDropdownOpen to true when receiving a OPEN_TO_DROPDOWN action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: OPEN_TO_DROPDOWN, }), @@ -49,7 +49,7 @@ describe('Send Duck', function () { }) it('should set toDropdownOpen to false when receiving a CLOSE_TO_DROPDOWN action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: CLOSE_TO_DROPDOWN, }), @@ -58,7 +58,7 @@ describe('Send Duck', function () { }) it('should set gasButtonGroupShown to true when receiving a SHOW_GAS_BUTTON_GROUP action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer( { ...mockState, gasButtonGroupShown: false }, { type: SHOW_GAS_BUTTON_GROUP }, @@ -68,7 +68,7 @@ describe('Send Duck', function () { }) it('should set gasButtonGroupShown to false when receiving a HIDE_GAS_BUTTON_GROUP action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: HIDE_GAS_BUTTON_GROUP }), { gasButtonGroupShown: false, ...mockState }, ) @@ -81,7 +81,7 @@ describe('Send Duck', function () { someError: false, }, } - assert.deepEqual( + assert.deepStrictEqual( SendReducer(modifiedMockState, { type: UPDATE_SEND_ERRORS, value: { someOtherError: true }, @@ -97,7 +97,7 @@ describe('Send Duck', function () { }) it('should return the initial state in response to a RESET_SEND_STATE action', function () { - assert.deepEqual( + assert.deepStrictEqual( SendReducer(mockState, { type: RESET_SEND_STATE, }), @@ -107,23 +107,27 @@ describe('Send Duck', function () { }) describe('openToDropdown', function () { - assert.deepEqual(openToDropdown(), { type: OPEN_TO_DROPDOWN }) + assert.deepStrictEqual(openToDropdown(), { type: OPEN_TO_DROPDOWN }) }) describe('closeToDropdown', function () { - assert.deepEqual(closeToDropdown(), { type: CLOSE_TO_DROPDOWN }) + assert.deepStrictEqual(closeToDropdown(), { type: CLOSE_TO_DROPDOWN }) }) describe('showGasButtonGroup', function () { - assert.deepEqual(showGasButtonGroup(), { type: SHOW_GAS_BUTTON_GROUP }) + assert.deepStrictEqual(showGasButtonGroup(), { + type: SHOW_GAS_BUTTON_GROUP, + }) }) describe('hideGasButtonGroup', function () { - assert.deepEqual(hideGasButtonGroup(), { type: HIDE_GAS_BUTTON_GROUP }) + assert.deepStrictEqual(hideGasButtonGroup(), { + type: HIDE_GAS_BUTTON_GROUP, + }) }) describe('updateSendErrors', function () { - assert.deepEqual(updateSendErrors('mockErrorObject'), { + assert.deepStrictEqual(updateSendErrors('mockErrorObject'), { type: UPDATE_SEND_ERRORS, value: 'mockErrorObject', }) diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index 998648b35..7f4c5df96 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -2,10 +2,8 @@ import { createSlice } from '@reduxjs/toolkit' import BigNumber from 'bignumber.js' import log from 'loglevel' -import { - loadLocalStorageData, - saveLocalStorageData, -} from '../../../lib/local-storage-helpers' +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' + import { addToken, addUnapprovedTransaction, @@ -469,12 +467,7 @@ export const fetchQuotesAndSetQuoteState = ( metaMetricsEvent({ event: 'Quotes Requested', category: 'swaps', - }) - metaMetricsEvent({ - event: 'Quotes Requested', - category: 'swaps', - excludeMetaMetricsId: true, - properties: { + sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), token_to: toTokenSymbol, @@ -520,12 +513,7 @@ export const fetchQuotesAndSetQuoteState = ( metaMetricsEvent({ event: 'No Quotes Available', category: 'swaps', - }) - metaMetricsEvent({ - event: 'No Quotes Available', - category: 'swaps', - excludeMetaMetricsId: true, - properties: { + sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), token_to: toTokenSymbol, @@ -541,12 +529,7 @@ export const fetchQuotesAndSetQuoteState = ( metaMetricsEvent({ event: 'Quotes Received', category: 'swaps', - }) - metaMetricsEvent({ - event: 'Quotes Received', - category: 'swaps', - excludeMetaMetricsId: true, - properties: { + sensitiveProperties: { token_from: fromTokenSymbol, token_from_amount: String(inputValue), token_to: toTokenSymbol, @@ -673,16 +656,10 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { median_metamask_fee: usedQuote.savings?.medianMetaMaskFee, } - const metaMetricsConfig = { + metaMetricsEvent({ event: 'Swap Started', category: 'swaps', - } - - metaMetricsEvent({ ...metaMetricsConfig }) - metaMetricsEvent({ - ...metaMetricsConfig, - excludeMetaMetricsId: true, - properties: swapMetaData, + sensitiveProperties: swapMetaData, }) let finalApproveTxMeta @@ -754,7 +731,7 @@ export function fetchMetaSwapsGasPriceEstimates() { ) const timeLastRetrieved = priceEstimatesLastRetrieved || - loadLocalStorageData('METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED') || + (await getStorageItem('METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED')) || 0 dispatch(swapGasPriceEstimatesFetchStarted()) @@ -764,7 +741,7 @@ export function fetchMetaSwapsGasPriceEstimates() { if (Date.now() - timeLastRetrieved > 30000) { priceEstimates = await fetchSwapsGasPrices() } else { - const cachedPriceEstimates = loadLocalStorageData( + const cachedPriceEstimates = await getStorageItem( 'METASWAP_GAS_PRICE_ESTIMATES', ) priceEstimates = cachedPriceEstimates || (await fetchSwapsGasPrices()) @@ -795,11 +772,13 @@ export function fetchMetaSwapsGasPriceEstimates() { const timeRetrieved = Date.now() - saveLocalStorageData(priceEstimates, 'METASWAP_GAS_PRICE_ESTIMATES') - saveLocalStorageData( - timeRetrieved, - 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', - ) + await Promise.all([ + setStorageItem('METASWAP_GAS_PRICE_ESTIMATES', priceEstimates), + setStorageItem( + 'METASWAP_GAS_PRICE_ESTIMATES_LAST_RETRIEVED', + timeRetrieved, + ), + ]) dispatch( swapGasPriceEstimatesFetchCompleted({ diff --git a/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js b/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js index df1b20cb4..06f95129a 100644 --- a/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js +++ b/ui/app/helpers/higher-order-components/with-modal-props/tests/with-modal-props.test.js @@ -27,12 +27,12 @@ describe('withModalProps', function () { assert.ok(wrapper) const testComponent = wrapper.find(TestComponent).at(0) - assert.equal(testComponent.length, 1) - assert.equal(testComponent.find('.test').text(), 'Testing') + assert.strictEqual(testComponent.length, 1) + assert.strictEqual(testComponent.find('.test').text(), 'Testing') const testComponentProps = testComponent.props() - assert.equal(testComponentProps.prop1, 'prop1') - assert.equal(testComponentProps.prop2, 2) - assert.equal(testComponentProps.prop3, true) - assert.equal(typeof testComponentProps.hideModal, 'function') + assert.strictEqual(testComponentProps.prop1, 'prop1') + assert.strictEqual(testComponentProps.prop2, 2) + assert.strictEqual(testComponentProps.prop3, true) + assert.strictEqual(typeof testComponentProps.hideModal, 'function') }) }) diff --git a/ui/app/helpers/utils/common.util.test.js b/ui/app/helpers/utils/common.util.test.js index cd2d71b03..2e083322d 100644 --- a/ui/app/helpers/utils/common.util.test.js +++ b/ui/app/helpers/utils/common.util.test.js @@ -20,7 +20,7 @@ describe('Common utils', function () { ] tests.forEach(({ test, expected }) => { - assert.equal(utils.camelCaseToCapitalize(test), expected) + assert.strictEqual(utils.camelCaseToCapitalize(test), expected) }) }) }) diff --git a/ui/app/helpers/utils/confirm-tx.util.test.js b/ui/app/helpers/utils/confirm-tx.util.test.js index 0db49ef89..a05090648 100644 --- a/ui/app/helpers/utils/confirm-tx.util.test.js +++ b/ui/app/helpers/utils/confirm-tx.util.test.js @@ -5,43 +5,43 @@ describe('Confirm Transaction utils', function () { describe('increaseLastGasPrice', function () { it('should increase the gasPrice by 10%', function () { const increasedGasPrice = utils.increaseLastGasPrice('0xa') - assert.equal(increasedGasPrice, '0xb') + assert.strictEqual(increasedGasPrice, '0xb') }) it('should prefix the result with 0x', function () { const increasedGasPrice = utils.increaseLastGasPrice('a') - assert.equal(increasedGasPrice, '0xb') + assert.strictEqual(increasedGasPrice, '0xb') }) }) describe('hexGreaterThan', function () { it('should return true if the first value is greater than the second value', function () { - assert.equal(utils.hexGreaterThan('0xb', '0xa'), true) + assert.strictEqual(utils.hexGreaterThan('0xb', '0xa'), true) }) it('should return false if the first value is less than the second value', function () { - assert.equal(utils.hexGreaterThan('0xa', '0xb'), false) + assert.strictEqual(utils.hexGreaterThan('0xa', '0xb'), false) }) it('should return false if the first value is equal to the second value', function () { - assert.equal(utils.hexGreaterThan('0xa', '0xa'), false) + assert.strictEqual(utils.hexGreaterThan('0xa', '0xa'), false) }) it('should correctly compare prefixed and non-prefixed hex values', function () { - assert.equal(utils.hexGreaterThan('0xb', 'a'), true) + assert.strictEqual(utils.hexGreaterThan('0xb', 'a'), true) }) }) describe('getHexGasTotal', function () { it('should multiply the hex gasLimit and hex gasPrice values together', function () { - assert.equal( + assert.strictEqual( utils.getHexGasTotal({ gasLimit: '0x5208', gasPrice: '0x3b9aca00' }), '0x1319718a5000', ) }) it('should prefix the result with 0x', function () { - assert.equal( + assert.strictEqual( utils.getHexGasTotal({ gasLimit: '5208', gasPrice: '3b9aca00' }), '0x1319718a5000', ) @@ -50,11 +50,11 @@ describe('Confirm Transaction utils', function () { describe('addEth', function () { it('should add two values together rounding to 6 decimal places', function () { - assert.equal(utils.addEth('0.12345678', '0'), '0.123457') + assert.strictEqual(utils.addEth('0.12345678', '0'), '0.123457') }) it('should add any number of values together rounding to 6 decimal places', function () { - assert.equal( + assert.strictEqual( utils.addEth( '0.1', '0.02', @@ -71,11 +71,11 @@ describe('Confirm Transaction utils', function () { describe('addFiat', function () { it('should add two values together rounding to 2 decimal places', function () { - assert.equal(utils.addFiat('0.12345678', '0'), '0.12') + assert.strictEqual(utils.addFiat('0.12345678', '0'), '0.12') }) it('should add any number of values together rounding to 2 decimal places', function () { - assert.equal( + assert.strictEqual( utils.addFiat( '0.1', '0.02', @@ -99,7 +99,7 @@ describe('Confirm Transaction utils', function () { numberOfDecimals: 6, }) - assert.equal(ethTransactionAmount, '1') + assert.strictEqual(ethTransactionAmount, '1') }) it('should get the transaction amount in fiat', function () { @@ -110,7 +110,7 @@ describe('Confirm Transaction utils', function () { numberOfDecimals: 2, }) - assert.equal(fiatTransactionAmount, '468.58') + assert.strictEqual(fiatTransactionAmount, '468.58') }) }) @@ -123,7 +123,7 @@ describe('Confirm Transaction utils', function () { numberOfDecimals: 6, }) - assert.equal(ethTransactionFee, '0.000021') + assert.strictEqual(ethTransactionFee, '0.000021') }) it('should get the transaction fee in fiat', function () { @@ -134,14 +134,14 @@ describe('Confirm Transaction utils', function () { numberOfDecimals: 2, }) - assert.equal(fiatTransactionFee, '0.01') + assert.strictEqual(fiatTransactionFee, '0.01') }) }) describe('formatCurrency', function () { it('should format USD values', function () { const value = utils.formatCurrency('123.45', 'usd') - assert.equal(value, '$123.45') + assert.strictEqual(value, '$123.45') }) }) }) diff --git a/ui/app/helpers/utils/conversion-util.test.js b/ui/app/helpers/utils/conversion-util.test.js index 34a7a5308..5e05f6727 100644 --- a/ui/app/helpers/utils/conversion-util.test.js +++ b/ui/app/helpers/utils/conversion-util.test.js @@ -9,7 +9,7 @@ describe('conversion utils', function () { aBase: 10, bBase: 10, }) - assert.equal(result.toNumber(), 12) + assert.strictEqual(result.toNumber(), 12) }) it('add decimals', function () { @@ -17,7 +17,7 @@ describe('conversion utils', function () { aBase: 10, bBase: 10, }) - assert.equal(result.toNumber(), 3.2) + assert.strictEqual(result.toNumber(), 3.2) }) it('add repeating decimals', function () { @@ -25,7 +25,7 @@ describe('conversion utils', function () { aBase: 10, bBase: 10, }) - assert.equal(result.toNumber(), 0.4444444444444444) + assert.strictEqual(result.toNumber(), 0.4444444444444444) }) }) @@ -47,14 +47,14 @@ describe('conversion utils', function () { assert(conv2 instanceof BigNumber, 'conversion 2 should be a BigNumber') }) it('Converts from dec to hex', function () { - assert.equal( + assert.strictEqual( conversionUtil('1000000000000000000', { fromNumericBase: 'dec', toNumericBase: 'hex', }), 'de0b6b3a7640000', ) - assert.equal( + assert.strictEqual( conversionUtil('1500000000000000000', { fromNumericBase: 'dec', toNumericBase: 'hex', @@ -63,79 +63,79 @@ describe('conversion utils', function () { ) }) it('Converts hex formatted numbers to dec', function () { - assert.equal( + assert.strictEqual( conversionUtil('0xde0b6b3a7640000', { fromNumericBase: 'hex', toNumericBase: 'dec', }), - 1000000000000000000, + '1000000000000000000', ) - assert.equal( + assert.strictEqual( conversionUtil('0x14d1120d7b160000', { fromNumericBase: 'hex', toNumericBase: 'dec', }), - 1500000000000000000, + '1500000000000000000', ) }) it('Converts WEI to ETH', function () { - assert.equal( + assert.strictEqual( conversionUtil('0xde0b6b3a7640000', { fromNumericBase: 'hex', toNumericBase: 'dec', fromDenomination: 'WEI', toDenomination: 'ETH', }), - 1, + '1', ) - assert.equal( + assert.strictEqual( conversionUtil('0x14d1120d7b160000', { fromNumericBase: 'hex', toNumericBase: 'dec', fromDenomination: 'WEI', toDenomination: 'ETH', }), - 1.5, + '1.5', ) }) it('Converts ETH to WEI', function () { - assert.equal( + assert.strictEqual( conversionUtil('1', { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'WEI', - }), + }).toNumber(), 1000000000000000000, ) - assert.equal( + assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'WEI', - }), + }).toNumber(), 1500000000000000000, ) }) it('Converts ETH to GWEI', function () { - assert.equal( + assert.strictEqual( conversionUtil('1', { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'GWEI', - }), + }).toNumber(), 1000000000, ) - assert.equal( + assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', fromDenomination: 'ETH', toDenomination: 'GWEI', - }), + }).toNumber(), 1500000000, ) }) it('Converts ETH to USD', function () { - assert.equal( + assert.strictEqual( conversionUtil('1', { fromNumericBase: 'dec', toNumericBase: 'dec', @@ -143,9 +143,9 @@ describe('conversion utils', function () { conversionRate: 468.58, numberOfDecimals: 2, }), - 468.58, + '468.58', ) - assert.equal( + assert.strictEqual( conversionUtil('1.5', { fromNumericBase: 'dec', toNumericBase: 'dec', @@ -153,11 +153,11 @@ describe('conversion utils', function () { conversionRate: 468.58, numberOfDecimals: 2, }), - 702.87, + '702.87', ) }) it('Converts USD to ETH', function () { - assert.equal( + assert.strictEqual( conversionUtil('468.58', { fromNumericBase: 'dec', toNumericBase: 'dec', @@ -166,9 +166,9 @@ describe('conversion utils', function () { numberOfDecimals: 2, invertConversionRate: true, }), - 1, + '1', ) - assert.equal( + assert.strictEqual( conversionUtil('702.87', { fromNumericBase: 'dec', toNumericBase: 'dec', @@ -177,7 +177,7 @@ describe('conversion utils', function () { numberOfDecimals: 2, invertConversionRate: true, }), - 1.5, + '1.5', ) }) }) diff --git a/ui/app/helpers/utils/conversions.util.test.js b/ui/app/helpers/utils/conversions.util.test.js index 5a32ceff4..6ae58ca83 100644 --- a/ui/app/helpers/utils/conversions.util.test.js +++ b/ui/app/helpers/utils/conversions.util.test.js @@ -10,34 +10,34 @@ describe('conversion utils', function () { fromCurrency: ETH, fromDenomination: ETH, }) - assert.equal(weiValue, '0') + assert.strictEqual(weiValue, '0') }) }) describe('decETHToDecWEI', function () { it('should correctly convert 1 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('1') - assert.equal(weiValue, '1000000000000000000') + assert.strictEqual(weiValue, '1000000000000000000') }) it('should correctly convert 0.000000000000000001 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('0.000000000000000001') - assert.equal(weiValue, '1') + assert.strictEqual(weiValue, '1') }) it('should correctly convert 1000000.000000000000000001 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('1000000.000000000000000001') - assert.equal(weiValue, '1000000000000000000000001') + assert.strictEqual(weiValue, '1000000000000000000000001') }) it('should correctly convert 9876.543210 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('9876.543210') - assert.equal(weiValue, '9876543210000000000000') + assert.strictEqual(weiValue, '9876543210000000000000') }) it('should correctly convert 1.0000000000000000 ETH to WEI', function () { const weiValue = utils.decETHToDecWEI('1.0000000000000000') - assert.equal(weiValue, '1000000000000000000') + assert.strictEqual(weiValue, '1000000000000000000') }) }) }) diff --git a/ui/app/helpers/utils/fetch-with-cache.js b/ui/app/helpers/utils/fetch-with-cache.js index c04d54086..351ee4ab9 100644 --- a/ui/app/helpers/utils/fetch-with-cache.js +++ b/ui/app/helpers/utils/fetch-with-cache.js @@ -1,7 +1,4 @@ -import { - loadLocalStorageData, - saveLocalStorageData, -} from '../../../lib/local-storage-helpers' +import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' import fetchWithTimeout from '../../../../app/scripts/lib/fetch-with-timeout' const fetchWithCache = async ( @@ -27,7 +24,7 @@ const fetchWithCache = async ( } const currentTime = Date.now() - const cachedFetch = loadLocalStorageData('cachedFetch') || {} + const cachedFetch = (await getStorageItem('cachedFetch')) || {} const { cachedResponse, cachedTime } = cachedFetch[url] || {} if (cachedResponse && currentTime - cachedTime < cacheRefreshTime) { return cachedResponse @@ -52,7 +49,7 @@ const fetchWithCache = async ( cachedTime: currentTime, } cachedFetch[url] = cacheEntry - saveLocalStorageData(cachedFetch, 'cachedFetch') + await setStorageItem('cachedFetch', cachedFetch) return responseJson } diff --git a/ui/app/helpers/utils/fetch-with-cache.test.js b/ui/app/helpers/utils/fetch-with-cache.test.js index c5981abd9..43336a85e 100644 --- a/ui/app/helpers/utils/fetch-with-cache.test.js +++ b/ui/app/helpers/utils/fetch-with-cache.test.js @@ -3,15 +3,15 @@ import nock from 'nock' import sinon from 'sinon' import proxyquire from 'proxyquire' -const fakeLocalStorageHelpers = {} +const fakeStorage = {} const fetchWithCache = proxyquire('./fetch-with-cache', { - '../../../lib/local-storage-helpers': fakeLocalStorageHelpers, + '../../../lib/storage-helpers': fakeStorage, }).default describe('Fetch with cache', function () { beforeEach(function () { - fakeLocalStorageHelpers.loadLocalStorageData = sinon.stub() - fakeLocalStorageHelpers.saveLocalStorageData = sinon.stub() + fakeStorage.getStorageItem = sinon.stub() + fakeStorage.setStorageItem = sinon.stub() }) afterEach(function () { sinon.restore() @@ -26,7 +26,7 @@ describe('Fetch with cache', function () { const response = await fetchWithCache( 'https://fetchwithcache.metamask.io/price', ) - assert.deepEqual(response, { + assert.deepStrictEqual(response, { average: 1, }) }) @@ -36,7 +36,7 @@ describe('Fetch with cache', function () { .get('/price') .reply(200, '{"average": 2}') - fakeLocalStorageHelpers.loadLocalStorageData.returns({ + fakeStorage.getStorageItem.returns({ 'https://fetchwithcache.metamask.io/price': { cachedResponse: { average: 1 }, cachedTime: Date.now(), @@ -46,7 +46,7 @@ describe('Fetch with cache', function () { const response = await fetchWithCache( 'https://fetchwithcache.metamask.io/price', ) - assert.deepEqual(response, { + assert.deepStrictEqual(response, { average: 1, }) }) @@ -56,7 +56,7 @@ describe('Fetch with cache', function () { .get('/price') .reply(200, '{"average": 3}') - fakeLocalStorageHelpers.loadLocalStorageData.returns({ + fakeStorage.getStorageItem.returns({ 'https://fetchwithcache.metamask.io/cached': { cachedResponse: { average: 1 }, cachedTime: Date.now() - 1000, @@ -68,7 +68,7 @@ describe('Fetch with cache', function () { {}, { cacheRefreshTime: 123 }, ) - assert.deepEqual(response, { + assert.deepStrictEqual(response, { average: 3, }) }) diff --git a/ui/app/helpers/utils/gas-time-estimates.util.js b/ui/app/helpers/utils/gas-time-estimates.util.js deleted file mode 100644 index 7757f69ff..000000000 --- a/ui/app/helpers/utils/gas-time-estimates.util.js +++ /dev/null @@ -1,125 +0,0 @@ -import BigNumber from 'bignumber.js' - -export function newBigSigDig(n) { - return new BigNumber(new BigNumber(String(n)).toPrecision(15)) -} - -const createOp = (a, b, op) => newBigSigDig(a)[op](newBigSigDig(b)) - -export function bigNumMinus(a = 0, b = 0) { - return createOp(a, b, 'minus') -} - -export function bigNumDiv(a = 0, b = 1) { - return createOp(a, b, 'div') -} - -export function extrapolateY({ - higherY = 0, - lowerY = 0, - higherX = 0, - lowerX = 0, - xForExtrapolation = 0, -}) { - const slope = bigNumMinus(higherY, lowerY).div(bigNumMinus(higherX, lowerX)) - const newTimeEstimate = slope - .times(bigNumMinus(higherX, xForExtrapolation)) - .minus(newBigSigDig(higherY)) - .negated() - - return newTimeEstimate.toNumber() -} - -export function getAdjacentGasPrices({ gasPrices, priceToPosition }) { - const closestLowerValueIndex = gasPrices.findIndex( - (e, i, a) => e <= priceToPosition && a[i + 1] >= priceToPosition, - ) - const closestHigherValueIndex = gasPrices.findIndex( - (e) => e > priceToPosition, - ) - return { - closestLowerValueIndex, - closestHigherValueIndex, - closestHigherValue: gasPrices[closestHigherValueIndex], - closestLowerValue: gasPrices[closestLowerValueIndex], - } -} - -export function formatTimeEstimate(totalSeconds, greaterThanMax, lessThanMin) { - const minutes = Math.floor(totalSeconds / 60) - const seconds = Math.floor(totalSeconds % 60) - - if (!minutes && !seconds) { - return '...' - } - - let symbol = '~' - if (greaterThanMax) { - symbol = '< ' - } else if (lessThanMin) { - symbol = '> ' - } - - const formattedMin = `${minutes ? `${minutes} min` : ''}` - const formattedSec = `${seconds ? `${seconds} sec` : ''}` - const formattedCombined = - formattedMin && formattedSec - ? `${symbol}${formattedMin} ${formattedSec}` - : symbol + (formattedMin || formattedSec) - - return formattedCombined -} - -export function getRawTimeEstimateData( - currentGasPrice, - gasPrices, - estimatedTimes, -) { - const minGasPrice = gasPrices[0] - const maxGasPrice = gasPrices[gasPrices.length - 1] - let priceForEstimation = currentGasPrice - if (currentGasPrice < minGasPrice) { - priceForEstimation = minGasPrice - } else if (currentGasPrice > maxGasPrice) { - priceForEstimation = maxGasPrice - } - - const { - closestLowerValueIndex, - closestHigherValueIndex, - closestHigherValue, - closestLowerValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: priceForEstimation }) - - const newTimeEstimate = extrapolateY({ - higherY: estimatedTimes[closestHigherValueIndex], - lowerY: estimatedTimes[closestLowerValueIndex], - higherX: closestHigherValue, - lowerX: closestLowerValue, - xForExtrapolation: priceForEstimation, - }) - - return { - newTimeEstimate, - minGasPrice, - maxGasPrice, - } -} - -export function getRenderableTimeEstimate( - currentGasPrice, - gasPrices, - estimatedTimes, -) { - const { newTimeEstimate, minGasPrice, maxGasPrice } = getRawTimeEstimateData( - currentGasPrice, - gasPrices, - estimatedTimes, - ) - - return formatTimeEstimate( - newTimeEstimate, - currentGasPrice > maxGasPrice, - currentGasPrice < minGasPrice, - ) -} diff --git a/ui/app/helpers/utils/i18n-helper.test.js b/ui/app/helpers/utils/i18n-helper.test.js index 3c0cca220..1c908f7f3 100644 --- a/ui/app/helpers/utils/i18n-helper.test.js +++ b/ui/app/helpers/utils/i18n-helper.test.js @@ -100,12 +100,12 @@ describe('i18n helper', function () { describe('getMessage', function () { it('should return the exact message paired with key if there are no substitutions', function () { const result = t(TEST_KEY_1) - assert.equal(result, 'This is a simple message.') + assert.strictEqual(result, 'This is a simple message.') }) it('should return the correct message when a single non-react substitution is made', function () { const result = t(TEST_KEY_2, [TEST_SUBSTITUTION_1]) - assert.equal( + assert.strictEqual( result, `This is a message with a single non-react substitution ${TEST_SUBSTITUTION_1}.`, ) @@ -113,7 +113,7 @@ describe('i18n helper', function () { it('should return the correct message when two non-react substitutions are made', function () { const result = t(TEST_KEY_3, [TEST_SUBSTITUTION_1, TEST_SUBSTITUTION_2]) - assert.equal( + assert.strictEqual( result, `This is a message with two non-react substitutions ${TEST_SUBSTITUTION_1} and ${TEST_SUBSTITUTION_2}.`, ) @@ -127,7 +127,7 @@ describe('i18n helper', function () { TEST_SUBSTITUTION_4, TEST_SUBSTITUTION_5, ]) - assert.equal( + assert.strictEqual( result, `${TEST_SUBSTITUTION_1} - ${TEST_SUBSTITUTION_2} - ${TEST_SUBSTITUTION_3} - ${TEST_SUBSTITUTION_4} - ${TEST_SUBSTITUTION_5}`, ) @@ -135,17 +135,17 @@ describe('i18n helper', function () { it('should correctly render falsey substitutions', function () { const result = t(TEST_KEY_4, [0, -0, '', false, NaN]) - assert.equal(result, '0 - 0 - - false - NaN') + assert.strictEqual(result, '0 - 0 - - false - NaN') }) it('should render nothing for "null" and "undefined" substitutions', function () { const result = t(TEST_KEY_5, [null, TEST_SUBSTITUTION_2]) - assert.equal(result, ` - ${TEST_SUBSTITUTION_2} - `) + assert.strictEqual(result, ` - ${TEST_SUBSTITUTION_2} - `) }) it('should return the correct message when a single react substitution is made', function () { const result = t(TEST_KEY_6, [TEST_SUBSTITUTION_6]) - assert.equal( + assert.strictEqual( shallow(result).html(), ' Testing a react substitution
TEST_SUBSTITUTION_1
.
', ) @@ -156,7 +156,7 @@ describe('i18n helper', function () { TEST_SUBSTITUTION_7_1, TEST_SUBSTITUTION_7_2, ]) - assert.equal( + assert.strictEqual( shallow(result).html(), ' Testing a react substitution
TEST_SUBSTITUTION_1
and another
TEST_SUBSTITUTION_2
.
', ) @@ -169,7 +169,7 @@ describe('i18n helper', function () { TEST_SUBSTITUTION_2, TEST_SUBSTITUTION_8_2, ]) - assert.equal( + assert.strictEqual( shallow(result).html(), ' Testing a mix TEST_SUBSTITUTION_1 of react substitutions
TEST_SUBSTITUTION_3
and string substitutions TEST_SUBSTITUTION_2 +
TEST_SUBSTITUTION_4
.
', ) diff --git a/ui/app/helpers/utils/token-util.js b/ui/app/helpers/utils/token-util.js index fa581f910..e8965edb3 100644 --- a/ui/app/helpers/utils/token-util.js +++ b/ui/app/helpers/utils/token-util.js @@ -1,6 +1,6 @@ import log from 'loglevel' import BigNumber from 'bignumber.js' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import * as util from './util' import { conversionUtil, multiplyCurrencies } from './conversion-util' import { formatCurrency } from './confirm-tx.util' diff --git a/ui/app/helpers/utils/transactions.util.test.js b/ui/app/helpers/utils/transactions.util.test.js index 80de38846..9079028dd 100644 --- a/ui/app/helpers/utils/transactions.util.test.js +++ b/ui/app/helpers/utils/transactions.util.test.js @@ -14,11 +14,11 @@ describe('Transactions utils', function () { ) assert.ok(tokenData) const { name, args } = tokenData - assert.equal(name, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER) + assert.strictEqual(name, TRANSACTION_CATEGORIES.TOKEN_METHOD_TRANSFER) const to = args._to const value = args._value.toString() - assert.equal(to, '0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706') - assert.equal(value, '20000') + assert.strictEqual(to, '0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706') + assert.strictEqual(value, '20000') }) it('should not throw errors when called without arguments', function () { @@ -56,7 +56,7 @@ describe('Transactions utils', function () { ] tests.forEach(({ transaction, expected }) => { - assert.equal(utils.getStatusKey(transaction), expected) + assert.strictEqual(utils.getStatusKey(transaction), expected) }) }) }) @@ -96,7 +96,7 @@ describe('Transactions utils', function () { ] tests.forEach(({ expected, networkId, hash, rpcPrefs }) => { - assert.equal( + assert.strictEqual( utils.getBlockExplorerUrlForTx(networkId, hash, rpcPrefs), expected, ) diff --git a/ui/app/helpers/utils/util.test.js b/ui/app/helpers/utils/util.test.js index 15c8e722f..9f319c362 100644 --- a/ui/app/helpers/utils/util.test.js +++ b/ui/app/helpers/utils/util.test.js @@ -12,25 +12,25 @@ describe('util', function () { it('should render 0.01 eth correctly', function () { const input = '0x2386F26FC10000' const output = util.parseBalance(input) - assert.deepEqual(output, ['0', '01']) + assert.deepStrictEqual(output, ['0', '01']) }) it('should render 12.023 eth correctly', function () { const input = 'A6DA46CCA6858000' const output = util.parseBalance(input) - assert.deepEqual(output, ['12', '023']) + assert.deepStrictEqual(output, ['12', '023']) }) it('should render 0.0000000342422 eth correctly', function () { const input = '0x7F8FE81C0' const output = util.parseBalance(input) - assert.deepEqual(output, ['0', '0000000342422']) + assert.deepStrictEqual(output, ['0', '0000000342422']) }) it('should render 0 eth correctly', function () { const input = '0x0' const output = util.parseBalance(input) - assert.deepEqual(output, ['0', '0']) + assert.deepStrictEqual(output, ['0', '0']) }) }) @@ -38,13 +38,13 @@ describe('util', function () { it('should add case-sensitive checksum', function () { const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825' const result = util.addressSummary(address) - assert.equal(result, '0xFDEa65C8...b825') + assert.strictEqual(result, '0xFDEa65C8...b825') }) it('should accept arguments for firstseg, lastseg, and keepPrefix', function () { const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825' const result = util.addressSummary(address, 4, 4, false) - assert.equal(result, 'FDEa...b825') + assert.strictEqual(result, 'FDEa...b825') }) }) @@ -89,7 +89,7 @@ describe('util', function () { const address = '0x5Fda30Bb72B8Dfe20e48A00dFc108d0915BE9Bb0' const result = util.isValidAddress(address) const hashed = ethUtil.toChecksumAddress(address.toLowerCase()) - assert.equal(hashed, address, 'example is hashed correctly') + assert.strictEqual(hashed, address, 'example is hashed correctly') assert.ok(result, 'is valid by our check') }) }) @@ -155,30 +155,30 @@ describe('util', function () { describe('#numericBalance', function () { it('should return a BN 0 if given nothing', function () { const result = util.numericBalance() - assert.equal(result.toString(10), 0) + assert.strictEqual(result.toString(10), '0') }) it('should work with hex prefix', function () { const result = util.numericBalance('0x012') - assert.equal(result.toString(10), '18') + assert.strictEqual(result.toString(10), '18') }) it('should work with no hex prefix', function () { const result = util.numericBalance('012') - assert.equal(result.toString(10), '18') + assert.strictEqual(result.toString(10), '18') }) }) describe('#formatBalance', function () { it('should return None when given nothing', function () { const result = util.formatBalance() - assert.equal(result, 'None', 'should return "None"') + assert.strictEqual(result, 'None', 'should return "None"') }) it('should return 1.0000 ETH', function () { const input = new ethUtil.BN(ethInWei, 10).toJSON() const result = util.formatBalance(input, 4) - assert.equal(result, '1.0000 ETH') + assert.strictEqual(result, '1.0000 ETH') }) it('should return 0.500 ETH', function () { @@ -186,29 +186,29 @@ describe('util', function () { .div(new ethUtil.BN('2', 10)) .toJSON() const result = util.formatBalance(input, 3) - assert.equal(result, '0.500 ETH') + assert.strictEqual(result, '0.500 ETH') }) it('should display specified decimal points', function () { const input = '0x128dfa6a90b28000' const result = util.formatBalance(input, 2) - assert.equal(result, '1.33 ETH') + assert.strictEqual(result, '1.33 ETH') }) it('should default to 3 decimal points', function () { const input = '0x128dfa6a90b28000' const result = util.formatBalance(input) - assert.equal(result, '1.337 ETH') + assert.strictEqual(result, '1.337 ETH') }) it('should show 2 significant digits for tiny balances', function () { const input = '0x1230fa6a90b28' const result = util.formatBalance(input) - assert.equal(result, '0.00032 ETH') + assert.strictEqual(result, '0.00032 ETH') }) it('should not parse the balance and return value with 2 decimal points with ETH at the end', function () { const value = '1.2456789' const needsParse = false const result = util.formatBalance(value, 2, needsParse) - assert.equal(result, '1.24 ETH') + assert.strictEqual(result, '1.24 ETH') }) }) @@ -235,7 +235,7 @@ describe('util', function () { Object.keys(valueTable).forEach((currency) => { const value = new ethUtil.BN(valueTable[currency], 10) const output = util.normalizeToWei(value, currency) - assert.equal( + assert.strictEqual( output.toString(10), valueTable.wei, `value of ${output.toString( @@ -250,25 +250,25 @@ describe('util', function () { it('should convert decimal eth to pure wei BN', function () { const input = '1.23456789' const output = util.normalizeEthStringToWei(input) - assert.equal(output.toString(10), '1234567890000000000') + assert.strictEqual(output.toString(10), '1234567890000000000') }) it('should convert 1 to expected wei', function () { const input = '1' const output = util.normalizeEthStringToWei(input) - assert.equal(output.toString(10), ethInWei) + assert.strictEqual(output.toString(10), ethInWei) }) it('should account for overflow numbers gracefully by dropping extra precision.', function () { const input = '1.11111111111111111111' const output = util.normalizeEthStringToWei(input) - assert.equal(output.toString(10), '1111111111111111111') + assert.strictEqual(output.toString(10), '1111111111111111111') }) it('should not truncate very exact wei values that do not have extra precision.', function () { const input = '1.100000000000000001' const output = util.normalizeEthStringToWei(input) - assert.equal(output.toString(10), '1100000000000000001') + assert.strictEqual(output.toString(10), '1100000000000000001') }) }) @@ -277,17 +277,17 @@ describe('util', function () { const input = 0.0002 const output = util.normalizeNumberToWei(input, 'ether') const str = output.toString(10) - assert.equal(str, '200000000000000') + assert.strictEqual(str, '200000000000000') }) it('should convert a kwei number to the appropriate equivalent wei', function () { const result = util.normalizeNumberToWei(1.111, 'kwei') - assert.equal(result.toString(10), '1111', 'accepts decimals') + assert.strictEqual(result.toString(10), '1111', 'accepts decimals') }) it('should convert a ether number to the appropriate equivalent wei', function () { const result = util.normalizeNumberToWei(1.111, 'ether') - assert.equal( + assert.strictEqual( result.toString(10), '1111000000000000000', 'accepts decimals', @@ -408,14 +408,17 @@ describe('util', function () { testData.forEach(({ args, result }) => { it(`should return ${result} when passed number ${args[0]} and precision ${args[1]}`, function () { - assert.equal(util.toPrecisionWithoutTrailingZeros(...args), result) + assert.strictEqual( + util.toPrecisionWithoutTrailingZeros(...args), + result, + ) }) }) }) describe('addHexPrefixToObjectValues()', function () { it('should return a new object with the same properties with a 0x prefix', function () { - assert.deepEqual( + assert.deepStrictEqual( util.addHexPrefixToObjectValues({ prop1: '0x123', prop2: '456', diff --git a/ui/app/hooks/tests/useCancelTransaction.test.js b/ui/app/hooks/tests/useCancelTransaction.test.js index 903e861d0..0d3d590f3 100644 --- a/ui/app/hooks/tests/useCancelTransaction.test.js +++ b/ui/app/hooks/tests/useCancelTransaction.test.js @@ -44,18 +44,18 @@ describe('useCancelTransaction', function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ) - assert.equal(result.current[0], false) + assert.strictEqual(result.current[0], false) }) it(`should return a function that kicks off cancellation for id ${transactionId}`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ) - assert.equal(typeof result.current[1], 'function') + assert.strictEqual(typeof result.current[1], 'function') result.current[1]({ preventDefault: () => undefined, stopPropagation: () => undefined, }) - assert.equal( + assert.strictEqual( dispatch.calledWith( showModal({ name: 'CANCEL_TRANSACTION', @@ -96,18 +96,18 @@ describe('useCancelTransaction', function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ) - assert.equal(result.current[0], true) + assert.strictEqual(result.current[0], true) }) it(`should return a function that kicks off cancellation for id ${transactionId}`, function () { const { result } = renderHook(() => useCancelTransaction(transactionGroup), ) - assert.equal(typeof result.current[1], 'function') + assert.strictEqual(typeof result.current[1], 'function') result.current[1]({ preventDefault: () => undefined, stopPropagation: () => undefined, }) - assert.equal( + assert.strictEqual( dispatch.calledWith( showModal({ name: 'CANCEL_TRANSACTION', diff --git a/ui/app/hooks/tests/useCurrencyDisplay.test.js b/ui/app/hooks/tests/useCurrencyDisplay.test.js index bacaa6ff0..4b90e9a79 100644 --- a/ui/app/hooks/tests/useCurrencyDisplay.test.js +++ b/ui/app/hooks/tests/useCurrencyDisplay.test.js @@ -117,13 +117,13 @@ describe('useCurrencyDisplay', function () { const [displayValue, parts] = hookReturn.result.current stub.restore() it(`should return ${result.displayValue} as displayValue`, function () { - assert.equal(displayValue, result.displayValue) + assert.strictEqual(displayValue, result.displayValue) }) it(`should return ${result.value} as value`, function () { - assert.equal(parts.value, result.value) + assert.strictEqual(parts.value, result.value) }) it(`should return ${result.suffix} as suffix`, function () { - assert.equal(parts.suffix, result.suffix) + assert.strictEqual(parts.suffix, result.suffix) }) }) }) diff --git a/ui/app/hooks/tests/useRetryTransaction.test.js b/ui/app/hooks/tests/useRetryTransaction.test.js index d1e1fb541..91d99026d 100644 --- a/ui/app/hooks/tests/useRetryTransaction.test.js +++ b/ui/app/hooks/tests/useRetryTransaction.test.js @@ -43,7 +43,7 @@ describe('useRetryTransaction', function () { ) const retry = result.current retry(event) - assert.equal(trackEvent.calledOnce, true) + assert.strictEqual(trackEvent.calledOnce, true) }) it('retryTransaction function should show retry sidebar', async function () { @@ -52,9 +52,7 @@ describe('useRetryTransaction', function () { ) const retry = result.current await retry(event) - const calls = dispatch.getCalls() - assert.equal(calls.length, 5) - assert.equal( + assert.strictEqual( dispatch.calledWith( showSidebar({ transitionName: 'sidebar-left', diff --git a/ui/app/hooks/tests/useTokenData.test.js b/ui/app/hooks/tests/useTokenData.test.js index 373c84eb5..ec473300d 100644 --- a/ui/app/hooks/tests/useTokenData.test.js +++ b/ui/app/hooks/tests/useTokenData.test.js @@ -53,14 +53,14 @@ describe('useTokenData', function () { it(testTitle, function () { const { result } = renderHook(() => useTokenData(test.data)) if (test.tokenData) { - assert.equal(result.current.name, test.tokenData.name) - assert.equal( + assert.strictEqual(result.current.name, test.tokenData.name) + assert.strictEqual( result.current.args[0].toLowerCase(), test.tokenData.args[0], ) assert.ok(test.tokenData.args[1].eq(result.current.args[1])) } else { - assert.equal(result.current, test.tokenData) + assert.strictEqual(result.current, test.tokenData) } }) }) diff --git a/ui/app/hooks/tests/useTokenDisplayValue.test.js b/ui/app/hooks/tests/useTokenDisplayValue.test.js index e9ba328bd..bc77bd6c7 100644 --- a/ui/app/hooks/tests/useTokenDisplayValue.test.js +++ b/ui/app/hooks/tests/useTokenDisplayValue.test.js @@ -130,7 +130,7 @@ describe('useTokenDisplayValue', function () { useTokenDisplayValue(`${idx}-fakestring`, test.token), ) sinon.restore() - assert.equal(result.current, test.displayValue) + assert.strictEqual(result.current, test.displayValue) }) }) }) diff --git a/ui/app/hooks/tests/useTransactionDisplayData.test.js b/ui/app/hooks/tests/useTransactionDisplayData.test.js index cb7784620..00b2f5bb8 100644 --- a/ui/app/hooks/tests/useTransactionDisplayData.test.js +++ b/ui/app/hooks/tests/useTransactionDisplayData.test.js @@ -178,35 +178,38 @@ describe('useTransactionDisplayData', function () { () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.title, expected.title) + assert.strictEqual(result.current.title, expected.title) }) it(`should return a subtitle of ${expected.subtitle}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.subtitle, expected.subtitle) + assert.strictEqual(result.current.subtitle, expected.subtitle) }) it(`should return a category of ${expected.category}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.category, expected.category) + assert.strictEqual(result.current.category, expected.category) }) it(`should return a primaryCurrency of ${expected.primaryCurrency}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.primaryCurrency, expected.primaryCurrency) + assert.strictEqual( + result.current.primaryCurrency, + expected.primaryCurrency, + ) }) it(`should return a secondaryCurrency of ${expected.secondaryCurrency}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal( + assert.strictEqual( result.current.secondaryCurrency, expected.secondaryCurrency, ) @@ -216,7 +219,7 @@ describe('useTransactionDisplayData', function () { () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal( + assert.strictEqual( result.current.displayedStatusKey, expected.displayedStatusKey, ) @@ -226,14 +229,17 @@ describe('useTransactionDisplayData', function () { () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.recipientAddress, expected.recipientAddress) + assert.strictEqual( + result.current.recipientAddress, + expected.recipientAddress, + ) }) it(`should return a senderAddress of ${expected.senderAddress}`, function () { const { result } = renderHookWithRouter( () => useTransactionDisplayData(transactionGroup), tokenAddress, ) - assert.equal(result.current.senderAddress, expected.senderAddress) + assert.strictEqual(result.current.senderAddress, expected.senderAddress) }) }) }) @@ -241,7 +247,7 @@ describe('useTransactionDisplayData', function () { const { result } = renderHookWithRouter(() => useTransactionDisplayData(transactions[0]), ) - assert.deepEqual(result.current, expectedResults[0]) + assert.deepStrictEqual(result.current, expectedResults[0]) }) after(function () { useSelector.restore() diff --git a/ui/app/hooks/tests/useUserPreferencedCurrency.test.js b/ui/app/hooks/tests/useUserPreferencedCurrency.test.js index 0b5534fdb..0386e6ec4 100644 --- a/ui/app/hooks/tests/useUserPreferencedCurrency.test.js +++ b/ui/app/hooks/tests/useUserPreferencedCurrency.test.js @@ -135,12 +135,12 @@ describe('useUserPreferencedCurrency', function () { it(`should return currency as ${ result.currency || 'not modified by user preferences' }`, function () { - assert.equal(hookResult.current.currency, result.currency) + assert.strictEqual(hookResult.current.currency, result.currency) }) it(`should return decimals as ${ result.numberOfDecimals || 'not modified by user preferences' }`, function () { - assert.equal( + assert.strictEqual( hookResult.current.numberOfDecimals, result.numberOfDecimals, ) diff --git a/ui/app/hooks/useMetricEvent.js b/ui/app/hooks/useMetricEvent.js index 352f95cc4..e428fc5d2 100644 --- a/ui/app/hooks/useMetricEvent.js +++ b/ui/app/hooks/useMetricEvent.js @@ -3,6 +3,12 @@ import { MetaMetricsContext } from '../contexts/metametrics' import { MetaMetricsContext as NewMetaMetricsContext } from '../contexts/metametrics.new' import { useEqualityCheck } from './useEqualityCheck' +// Type imports +/** + * @typedef {import('../contexts/metametrics.new').UIMetricsEventPayload} UIMetricsEventPayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions + */ + export function useMetricEvent(config = {}, overrides = {}) { const metricsEvent = useContext(MetaMetricsContext) const trackEvent = useCallback(() => metricsEvent(config, overrides), [ @@ -17,21 +23,18 @@ export function useMetricEvent(config = {}, overrides = {}) { * track a metametrics event using segment * e.g metricsEvent({ event: 'Unlocked MetaMask', category: 'Navigation' }) * - * @param {Object} config - configuration object for the event to track - * @param {string} config.event - event name to track - * @param {string} config.category - category to associate event to - * @param {boolean} [config.isOptIn] - happened during opt in/out workflow - * @param {Object} [config.properties] - object of custom values to track, snake_case - * @param {number} [config.revenue] - amount of currency that event creates in revenue for MetaMask - * @param {string} [config.currency] - ISO 4127 format currency for events with revenue, defaults to US dollars - * @param {number} [config.value] - Abstract "value" that this event has for MetaMask. - * @return {() => undefined} function to execute the tracking event + * @param {UIMetricsEventPayload} payload - payload of the event to track + * @param {MetaMetricsEventOptions} options - options for handling/routing event + * @return {() => Promise} function to execute the tracking event */ -export function useNewMetricEvent(config) { - const memoizedConfig = useEqualityCheck(config) +export function useNewMetricEvent(payload, options) { + const memoizedPayload = useEqualityCheck(payload) + const memoizedOptions = useEqualityCheck(options) const metricsEvent = useContext(NewMetaMetricsContext) - return useCallback(() => metricsEvent(memoizedConfig), [ + + return useCallback(() => metricsEvent(memoizedPayload, memoizedOptions), [ metricsEvent, - memoizedConfig, + memoizedPayload, + memoizedOptions, ]) } diff --git a/ui/app/hooks/useRetryTransaction.js b/ui/app/hooks/useRetryTransaction.js index c12000266..63bd6f283 100644 --- a/ui/app/hooks/useRetryTransaction.js +++ b/ui/app/hooks/useRetryTransaction.js @@ -2,8 +2,7 @@ import { useDispatch } from 'react-redux' import { useCallback } from 'react' import { showSidebar } from '../store/actions' import { - fetchBasicGasAndTimeEstimates, - fetchGasEstimates, + fetchBasicGasEstimates, setCustomGasPriceForRetry, setCustomGasLimit, } from '../ducks/gas/gas.duck' @@ -34,11 +33,10 @@ export function useRetryTransaction(transactionGroup) { event.stopPropagation() trackMetricsEvent() - const basicEstimates = await dispatch(fetchBasicGasAndTimeEstimates) - await dispatch(fetchGasEstimates(basicEstimates.blockTime)) + await dispatch(fetchBasicGasEstimates) const transaction = initialTransaction const increasedGasPrice = increaseLastGasPrice(gasPrice) - dispatch( + await dispatch( setCustomGasPriceForRetry( increasedGasPrice || transaction.txParams.gasPrice, ), diff --git a/ui/app/hooks/useTokensToSearch.js b/ui/app/hooks/useTokensToSearch.js index 0d9485e1b..8df33e55e 100644 --- a/ui/app/hooks/useTokensToSearch.js +++ b/ui/app/hooks/useTokensToSearch.js @@ -1,6 +1,6 @@ import { useMemo } from 'react' import { useSelector } from 'react-redux' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import BigNumber from 'bignumber.js' import { isEqual, shuffle } from 'lodash' import { checksumAddress } from '../helpers/utils/util' diff --git a/ui/app/hooks/useTransactionTimeRemaining.js b/ui/app/hooks/useTransactionTimeRemaining.js deleted file mode 100644 index 96deadf07..000000000 --- a/ui/app/hooks/useTransactionTimeRemaining.js +++ /dev/null @@ -1,126 +0,0 @@ -import { useSelector } from 'react-redux' -import { useRef, useEffect, useState, useMemo } from 'react' -import { isEqual } from 'lodash' -import { captureException } from '@sentry/browser' -import { hexWEIToDecGWEI } from '../helpers/utils/conversions.util' -import { - getEstimatedGasPrices, - getEstimatedGasTimes, - getFeatureFlags, - getIsMainnet, -} from '../selectors' -import { getRawTimeEstimateData } from '../helpers/utils/gas-time-estimates.util' -import { getCurrentLocale } from '../ducks/metamask/metamask' - -/** - * Calculate the number of minutes remaining until the transaction completes. - * @param {number} initialTimeEstimate - timestamp for the projected completion time - * @param {number} submittedTime - timestamp of when the tx was submitted - * @return {number} minutes remaining - */ -function calcTransactionTimeRemaining(initialTimeEstimate, submittedTime) { - const currentTime = new Date().getTime() - const timeElapsedSinceSubmission = (currentTime - submittedTime) / 1000 - const timeRemainingOnEstimate = - initialTimeEstimate - timeElapsedSinceSubmission - - const renderingTimeRemainingEstimate = Math.round( - timeRemainingOnEstimate / 60, - ) - return renderingTimeRemainingEstimate -} - -/** - * returns a string representing the number of minutes predicted for the transaction to be - * completed. Only returns this prediction if the transaction is the earliest pending - * transaction, and the feature flag for showing timing is enabled. - * @param {bool} isSubmitted - is the transaction currently in the 'submitted' state - * @param {bool} isEarliestNonce - is this transaction the earliest nonce in list - * @param {number} submittedTime - the timestamp for when the transaction was submitted - * @param {number} currentGasPrice - gas price to use for calculation of time - * @param {boolean} dontFormat - Whether the result should be be formatted, or just a number of minutes - * @returns {string | undefined} i18n formatted string if applicable - */ -export function useTransactionTimeRemaining( - isSubmitted, - isEarliestNonce, - submittedTime, - currentGasPrice, - forceAllow, - dontFormat, -) { - // the following two selectors return the result of mapping over an array, as such they - // will always be new objects and trigger effects. To avoid this, we use isEqual as the - // equalityFn to only update when the data is new. - const gasPrices = useSelector(getEstimatedGasPrices, isEqual) - const estimatedTimes = useSelector(getEstimatedGasTimes, isEqual) - const locale = useSelector(getCurrentLocale) - const isMainNet = useSelector(getIsMainnet) - const interval = useRef() - const [timeRemaining, setTimeRemaining] = useState(null) - const featureFlags = useSelector(getFeatureFlags) - const transactionTimeFeatureActive = featureFlags?.transactionTime - - const rtf = new Intl.RelativeTimeFormat(locale.replace('_', '-'), { - numeric: 'auto', - style: 'narrow', - }) - - // Memoize this value so it can be used as a dependency in the effect below - const initialTimeEstimate = useMemo(() => { - const customGasPrice = Number(hexWEIToDecGWEI(currentGasPrice)) - try { - const { newTimeEstimate } = getRawTimeEstimateData( - customGasPrice, - gasPrices, - estimatedTimes, - ) - return newTimeEstimate - } catch (error) { - captureException(error) - return NaN - } - }, [currentGasPrice, gasPrices, estimatedTimes]) - - useEffect(() => { - if ( - isMainNet && - (transactionTimeFeatureActive || forceAllow) && - isSubmitted && - isEarliestNonce && - !isNaN(initialTimeEstimate) - ) { - clearInterval(interval.current) - setTimeRemaining( - calcTransactionTimeRemaining(initialTimeEstimate, submittedTime), - ) - interval.current = setInterval(() => { - setTimeRemaining( - calcTransactionTimeRemaining(initialTimeEstimate, submittedTime), - ) - }, 10000) - return () => clearInterval(interval.current) - } - return undefined - }, [ - isMainNet, - transactionTimeFeatureActive, - isEarliestNonce, - submittedTime, - initialTimeEstimate, - forceAllow, - isSubmitted, - ]) - - // there are numerous checks to determine if time should be displayed. - // if any of the following are true, the timeRemaining will be null - // User is currently not on the mainnet - // User does not have the transactionTime feature flag enabled - // The transaction is not pending, or isn't the earliest nonce - if (timeRemaining && dontFormat) { - return timeRemaining - } else if (timeRemaining) { - return rtf.format(timeRemaining, 'minute') - } - return undefined -} diff --git a/ui/app/pages/add-token/tests/add-token.test.js b/ui/app/pages/add-token/tests/add-token.test.js index 300a6b019..697724dd7 100644 --- a/ui/app/pages/add-token/tests/add-token.test.js +++ b/ui/app/pages/add-token/tests/add-token.test.js @@ -49,7 +49,7 @@ describe('Add Token', function () { '.button.btn-secondary.page-container__footer-button', ) - assert.equal(nextButton.props().disabled, true) + assert.strictEqual(nextButton.props().disabled, true) }) it('edits token address', function () { @@ -58,7 +58,7 @@ describe('Add Token', function () { const customAddress = wrapper.find('input#custom-address') customAddress.simulate('change', event) - assert.equal( + assert.strictEqual( wrapper.find('AddToken').instance().state.customAddress, tokenAddress, ) @@ -70,7 +70,7 @@ describe('Add Token', function () { const customAddress = wrapper.find('#custom-symbol') customAddress.last().simulate('change', event) - assert.equal( + assert.strictEqual( wrapper.find('AddToken').instance().state.customSymbol, tokenSymbol, ) @@ -82,7 +82,7 @@ describe('Add Token', function () { const customAddress = wrapper.find('#custom-decimals') customAddress.last().simulate('change', event) - assert.equal( + assert.strictEqual( wrapper.find('AddToken').instance().state.customDecimals, tokenPrecision, ) @@ -96,7 +96,10 @@ describe('Add Token', function () { assert(props.setPendingTokens.calledOnce) assert(props.history.push.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/confirm-add-token') + assert.strictEqual( + props.history.push.getCall(0).args[0], + '/confirm-add-token', + ) }) it('cancels', function () { @@ -106,7 +109,7 @@ describe('Add Token', function () { cancelButton.simulate('click') assert(props.clearPendingTokens.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/') + assert.strictEqual(props.history.push.getCall(0).args[0], '/') }) }) }) diff --git a/ui/app/pages/add-token/token-search/token-search.component.js b/ui/app/pages/add-token/token-search/token-search.component.js index 8ef9d20af..8b889b057 100644 --- a/ui/app/pages/add-token/token-search/token-search.component.js +++ b/ui/app/pages/add-token/token-search/token-search.component.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import Fuse from 'fuse.js' import InputAdornment from '@material-ui/core/InputAdornment' import TextField from '../../../components/ui/text-field' diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js index 245df89ec..09cece00e 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux' import { compose } from 'redux' import { withRouter } from 'react-router-dom' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck' import { diff --git a/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js b/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js index 3add429b6..96ddc2ff4 100644 --- a/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js +++ b/ui/app/pages/confirm-transaction-base/tests/confirm-transaction-base.component.test.js @@ -4,11 +4,11 @@ import { getMethodName } from '../confirm-transaction-base.component' describe('ConfirmTransactionBase Component', function () { describe('getMethodName', function () { it('should get correct method names', function () { - assert.equal(getMethodName(undefined), '') - assert.equal(getMethodName({}), '') - assert.equal(getMethodName('confirm'), 'confirm') - assert.equal(getMethodName('balanceOf'), 'balance Of') - assert.equal( + assert.strictEqual(getMethodName(undefined), '') + assert.strictEqual(getMethodName({}), '') + assert.strictEqual(getMethodName('confirm'), 'confirm') + assert.strictEqual(getMethodName('balanceOf'), 'balance Of') + assert.strictEqual( getMethodName('ethToTokenSwapInput'), 'eth To Token Swap Input', ) diff --git a/ui/app/pages/confirm-transaction/confirm-transaction.component.js b/ui/app/pages/confirm-transaction/confirm-transaction.component.js index 92f073d9d..d794717ae 100644 --- a/ui/app/pages/confirm-transaction/confirm-transaction.component.js +++ b/ui/app/pages/confirm-transaction/confirm-transaction.component.js @@ -37,7 +37,7 @@ export default class ConfirmTransaction extends Component { send: PropTypes.object, setTransactionToConfirm: PropTypes.func, clearConfirmTransaction: PropTypes.func, - fetchBasicGasAndTimeEstimates: PropTypes.func, + fetchBasicGasEstimates: PropTypes.func, mostRecentOverviewPage: PropTypes.string.isRequired, transaction: PropTypes.object, getContractMethodData: PropTypes.func, @@ -54,7 +54,7 @@ export default class ConfirmTransaction extends Component { history, mostRecentOverviewPage, transaction: { txParams: { data, to } = {} } = {}, - fetchBasicGasAndTimeEstimates, + fetchBasicGasEstimates, getContractMethodData, transactionId, paramsTransactionId, @@ -67,7 +67,7 @@ export default class ConfirmTransaction extends Component { return } - fetchBasicGasAndTimeEstimates() + fetchBasicGasEstimates() getContractMethodData(data) if (isTokenMethodAction) { getTokenParams(to) diff --git a/ui/app/pages/confirm-transaction/confirm-transaction.container.js b/ui/app/pages/confirm-transaction/confirm-transaction.container.js index 61c4bc445..8dc56236d 100644 --- a/ui/app/pages/confirm-transaction/confirm-transaction.container.js +++ b/ui/app/pages/confirm-transaction/confirm-transaction.container.js @@ -6,7 +6,7 @@ import { clearConfirmTransaction, } from '../../ducks/confirm-transaction/confirm-transaction.duck' import { isTokenMethodAction } from '../../helpers/utils/transactions.util' -import { fetchBasicGasAndTimeEstimates } from '../../ducks/gas/gas.duck' +import { fetchBasicGasEstimates } from '../../ducks/gas/gas.duck' import { getContractMethodData, getTokenParams } from '../../store/actions' import { unconfirmedTransactionsListSelector } from '../../selectors' @@ -48,8 +48,7 @@ const mapDispatchToProps = (dispatch) => { dispatch(setTransactionToConfirm(transactionId)) }, clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), - fetchBasicGasAndTimeEstimates: () => - dispatch(fetchBasicGasAndTimeEstimates()), + fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), getContractMethodData: (data) => dispatch(getContractMethodData(data)), getTokenParams: (tokenAddress) => dispatch(getTokenParams(tokenAddress)), } diff --git a/ui/app/pages/create-account/tests/create-account.test.js b/ui/app/pages/create-account/tests/create-account.test.js index a99ffa47f..335d3c5ba 100644 --- a/ui/app/pages/create-account/tests/create-account.test.js +++ b/ui/app/pages/create-account/tests/create-account.test.js @@ -27,18 +27,24 @@ describe('Create Account Page', function () { it('clicks create account and routes to new-account path', function () { const createAccount = wrapper.find('.new-account__tabs__tab').at(0) createAccount.simulate('click') - assert.equal(props.history.push.getCall(0).args[0], '/new-account') + assert.strictEqual(props.history.push.getCall(0).args[0], '/new-account') }) it('clicks import account and routes to import new account path', function () { const importAccount = wrapper.find('.new-account__tabs__tab').at(1) importAccount.simulate('click') - assert.equal(props.history.push.getCall(0).args[0], '/new-account/import') + assert.strictEqual( + props.history.push.getCall(0).args[0], + '/new-account/import', + ) }) it('clicks connect HD Wallet and routes to connect new account path', function () { const connectHdWallet = wrapper.find('.new-account__tabs__tab').at(2) connectHdWallet.simulate('click') - assert.equal(props.history.push.getCall(0).args[0], '/new-account/connect') + assert.strictEqual( + props.history.push.getCall(0).args[0], + '/new-account/connect', + ) }) }) diff --git a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js index 2ec3b97dc..7aea35494 100644 --- a/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js +++ b/ui/app/pages/first-time-flow/create-password/import-with-seed-phrase/tests/import-with-seed-phrase.component.test.js @@ -20,7 +20,7 @@ describe('ImportWithSeedPhrase Component', function () { onSubmit: sinon.spy(), }) const textareaCount = root.find('.first-time-flow__textarea').length - assert.equal(textareaCount, 1, 'should render 12 seed phrases') + assert.strictEqual(textareaCount, 1, 'should render 12 seed phrases') }) describe('parseSeedPhrase', function () { @@ -31,7 +31,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz') + assert.deepStrictEqual(parseSeedPhrase('foo bar baz'), 'foo bar baz') }) it('should handle a mixed-case seed phrase', function () { @@ -41,7 +41,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase('FOO bAr baZ'), 'foo bar baz') + assert.deepStrictEqual(parseSeedPhrase('FOO bAr baZ'), 'foo bar baz') }) it('should handle an upper-case seed phrase', function () { @@ -51,7 +51,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase('FOO BAR BAZ'), 'foo bar baz') + assert.deepStrictEqual(parseSeedPhrase('FOO BAR BAZ'), 'foo bar baz') }) it('should trim extraneous whitespace from the given seed phrase', function () { @@ -61,7 +61,10 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase(' foo bar baz '), 'foo bar baz') + assert.deepStrictEqual( + parseSeedPhrase(' foo bar baz '), + 'foo bar baz', + ) }) it('should return an empty string when given a whitespace-only string', function () { @@ -71,7 +74,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase(' '), '') + assert.deepStrictEqual(parseSeedPhrase(' '), '') }) it('should return an empty string when given a string with only symbols', function () { @@ -81,7 +84,7 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase('$'), '') + assert.deepStrictEqual(parseSeedPhrase('$'), '') }) it('should return an empty string for both null and undefined', function () { @@ -91,8 +94,8 @@ describe('ImportWithSeedPhrase Component', function () { const { parseSeedPhrase } = root.instance() - assert.deepEqual(parseSeedPhrase(undefined), '') - assert.deepEqual(parseSeedPhrase(null), '') + assert.deepStrictEqual(parseSeedPhrase(undefined), '') + assert.deepStrictEqual(parseSeedPhrase(null), '') }) }) }) diff --git a/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js b/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js index ad7b0e7e1..aef4ef6a1 100644 --- a/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js +++ b/ui/app/pages/first-time-flow/end-of-flow/tests/end-of-flow.test.js @@ -20,7 +20,7 @@ describe('End of Flow Screen', function () { }) it('renders', function () { - assert.equal(wrapper.length, 1) + assert.strictEqual(wrapper.length, 1) }) it('should navigate to the default route on click', function (done) { diff --git a/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js b/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js index 3ec0d1a61..fa3b9788f 100644 --- a/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js +++ b/ui/app/pages/first-time-flow/first-time-flow-switch/tests/first-time-flow-switch.test.js @@ -21,7 +21,7 @@ describe('FirstTimeFlowSwitch', function () { const wrapper = mountWithRouter( , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_WELCOME_ROUTE } }).length, @@ -37,7 +37,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper.find('Lifecycle').find({ to: { pathname: DEFAULT_ROUTE } }) .length, 1, @@ -53,7 +53,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_END_OF_FLOW_ROUTE } }).length, @@ -70,7 +70,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_END_OF_FLOW_ROUTE } }).length, @@ -89,7 +89,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper.find('Lifecycle').find({ to: { pathname: LOCK_ROUTE } }).length, 1, ) @@ -107,7 +107,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_WELCOME_ROUTE } }).length, @@ -127,7 +127,7 @@ describe('FirstTimeFlowSwitch', function () { , ) - assert.equal( + assert.strictEqual( wrapper .find('Lifecycle') .find({ to: { pathname: INITIALIZE_UNLOCK_ROUTE } }).length, diff --git a/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js index b859457e8..2b34662ce 100644 --- a/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js +++ b/ui/app/pages/first-time-flow/metametrics-opt-in/metametrics-opt-in.component.js @@ -113,6 +113,7 @@ export default class MetaMetricsOptIn extends Component { name: 'Metrics Opt Out', }, isOptIn: true, + flushImmediately: true, }) } } finally { @@ -136,6 +137,7 @@ export default class MetaMetricsOptIn extends Component { name: 'Metrics Opt In', }, isOptIn: true, + flushImmediately: true, }), ) } @@ -148,6 +150,7 @@ export default class MetaMetricsOptIn extends Component { }, isOptIn: true, metaMetricsId, + flushImmediately: true, }), ) await Promise.all(metrics) diff --git a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js index 1c0950516..f0e561a4b 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js +++ b/ui/app/pages/first-time-flow/seed-phrase/reveal-seed-phrase/tests/reveal-seed-phrase.test.js @@ -30,18 +30,18 @@ describe('Reveal Seed Phrase', function () { it('seed phrase', function () { const seedPhrase = wrapper.find('.reveal-seed-phrase__secret-words--hidden') - assert.equal(seedPhrase.length, 1) - assert.equal(seedPhrase.text(), TEST_SEED) + assert.strictEqual(seedPhrase.length, 1) + assert.strictEqual(seedPhrase.text(), TEST_SEED) }) it('clicks to reveal', function () { const reveal = wrapper.find('.reveal-seed-phrase__secret-blocker') - assert.equal(wrapper.state().isShowingSeedPhrase, false) + assert.strictEqual(wrapper.state().isShowingSeedPhrase, false) reveal.simulate('click') - assert.equal(wrapper.state().isShowingSeedPhrase, true) + assert.strictEqual(wrapper.state().isShowingSeedPhrase, true) const showSeed = wrapper.find('.reveal-seed-phrase__secret-words') - assert.equal(showSeed.length, 1) + assert.strictEqual(showSeed.length, 1) }) }) diff --git a/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js b/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js index a5a0d1c91..1be3b70d7 100644 --- a/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js +++ b/ui/app/pages/first-time-flow/seed-phrase/tests/confirm-seed-phrase-component.test.js @@ -19,7 +19,7 @@ describe('ConfirmSeedPhrase Component', function () { seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬', }) - assert.equal( + assert.strictEqual( root.find('.confirm-seed-phrase__seed-word--sorted').length, 12, 'should render 12 seed phrases', @@ -46,7 +46,7 @@ describe('ConfirmSeedPhrase Component', function () { seeds.at(1).simulate('click') seeds.at(2).simulate('click') - assert.deepEqual( + assert.deepStrictEqual( root.state().selectedSeedIndices, [0, 1, 2], 'should add seed phrase to selected on click', @@ -57,7 +57,7 @@ describe('ConfirmSeedPhrase Component', function () { root.update() root.state() root.find('.confirm-seed-phrase__seed-word--sorted').at(1).simulate('click') - assert.deepEqual( + assert.deepStrictEqual( root.state().selectedSeedIndices, [0, 2], 'should remove seed phrase from selected when click again', @@ -94,9 +94,9 @@ describe('ConfirmSeedPhrase Component', function () { '.confirm-seed-phrase__selected-seed-words__pending-seed', ) - assert.equal(pendingSeeds.at(0).props().seedIndex, 2) - assert.equal(pendingSeeds.at(1).props().seedIndex, 0) - assert.equal(pendingSeeds.at(2).props().seedIndex, 1) + assert.strictEqual(pendingSeeds.at(0).props().seedIndex, 2) + assert.strictEqual(pendingSeeds.at(1).props().seedIndex, 0) + assert.strictEqual(pendingSeeds.at(2).props().seedIndex, 1) }) it('should insert seed in place on drop', function () { @@ -126,8 +126,8 @@ describe('ConfirmSeedPhrase Component', function () { root.update() - assert.deepEqual(root.state().selectedSeedIndices, [2, 0, 1]) - assert.deepEqual(root.state().pendingSeedIndices, [2, 0, 1]) + assert.deepStrictEqual(root.state().selectedSeedIndices, [2, 0, 1]) + assert.deepStrictEqual(root.state().pendingSeedIndices, [2, 0, 1]) }) it('should submit correctly', async function () { @@ -174,7 +174,7 @@ describe('ConfirmSeedPhrase Component', function () { await new Promise((resolve) => setTimeout(resolve, 100)) - assert.deepEqual(metricsEventSpy.args[0][0], { + assert.deepStrictEqual(metricsEventSpy.args[0][0], { eventOpts: { category: 'Onboarding', action: 'Seed Phrase Setup', @@ -182,6 +182,6 @@ describe('ConfirmSeedPhrase Component', function () { }, }) assert(initialize3BoxSpy.calledOnce) - assert.equal(pushSpy.args[0][0], '/initialize/end-of-flow') + assert.strictEqual(pushSpy.args[0][0], '/initialize/end-of-flow') }) }) diff --git a/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js b/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js index d8abdd135..447c20602 100644 --- a/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js +++ b/ui/app/pages/first-time-flow/select-action/tests/select-action.test.js @@ -31,7 +31,7 @@ describe('Selection Action', function () { importWalletButton.simulate('click') assert(props.setFirstTimeFlowType.calledOnce) - assert.equal(props.setFirstTimeFlowType.getCall(0).args[0], 'import') + assert.strictEqual(props.setFirstTimeFlowType.getCall(0).args[0], 'import') assert(props.history.push.calledOnce) }) @@ -42,7 +42,7 @@ describe('Selection Action', function () { createWalletButton.simulate('click') assert(props.setFirstTimeFlowType.calledOnce) - assert.equal(props.setFirstTimeFlowType.getCall(0).args[0], 'create') + assert.strictEqual(props.setFirstTimeFlowType.getCall(0).args[0], 'create') assert(props.history.push.calledOnce) }) }) diff --git a/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js b/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js index 67df69c14..4c35d8c0d 100644 --- a/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js +++ b/ui/app/pages/first-time-flow/welcome/tests/welcome.test.js @@ -32,7 +32,7 @@ describe('Welcome', function () { '.btn-primary.first-time-flow__button', ) getStartedButton.simulate('click') - assert.equal( + assert.strictEqual( props.history.push.getCall(0).args[0], '/initialize/select-action', ) @@ -56,7 +56,7 @@ describe('Welcome', function () { '.btn-primary.first-time-flow__button', ) getStartedButton.simulate('click') - assert.equal( + assert.strictEqual( props.history.push.getCall(0).args[0], '/initialize/create-password', ) diff --git a/ui/app/pages/lock/tests/lock.test.js b/ui/app/pages/lock/tests/lock.test.js index 92a46af6e..688fe062a 100644 --- a/ui/app/pages/lock/tests/lock.test.js +++ b/ui/app/pages/lock/tests/lock.test.js @@ -15,7 +15,7 @@ describe('Lock', function () { mountWithRouter() - assert.equal(props.history.replace.getCall(0).args[0], '/') + assert.strictEqual(props.history.replace.getCall(0).args[0], '/') }) it('locks and pushes history with default route when isUnlocked true', function (done) { @@ -33,7 +33,7 @@ describe('Lock', function () { assert(props.lockMetamask.calledOnce) setImmediate(() => { - assert.equal(props.history.push.getCall(0).args[0], '/') + assert.strictEqual(props.history.push.getCall(0).args[0], '/') done() }) }) diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.js index dc6283b83..47b64f774 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.js @@ -1,5 +1,5 @@ import ethUtil from 'ethereumjs-util' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { REQUIRED_ERROR, INVALID_RECIPIENT_ADDRESS_ERROR, diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js index 40f3b6a9c..fddaf3da7 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-component.test.js @@ -68,25 +68,28 @@ describe('AddRecipient Component', function () { describe('selectRecipient', function () { it('should call updateSendTo', function () { - assert.equal(propsMethodSpies.updateSendTo.callCount, 0) + assert.strictEqual(propsMethodSpies.updateSendTo.callCount, 0) instance.selectRecipient('mockTo2', 'mockNickname') - assert.equal(propsMethodSpies.updateSendTo.callCount, 1) - assert.deepEqual(propsMethodSpies.updateSendTo.getCall(0).args, [ + assert.strictEqual(propsMethodSpies.updateSendTo.callCount, 1) + assert.deepStrictEqual(propsMethodSpies.updateSendTo.getCall(0).args, [ 'mockTo2', 'mockNickname', ]) }) it('should call updateGas if there is no to error', function () { - assert.equal(propsMethodSpies.updateGas.callCount, 0) + assert.strictEqual(propsMethodSpies.updateGas.callCount, 0) instance.selectRecipient(false) - assert.equal(propsMethodSpies.updateGas.callCount, 1) + assert.strictEqual(propsMethodSpies.updateGas.callCount, 1) }) }) describe('render', function () { it('should render a component', function () { - assert.equal(wrapper.find('.send__select-recipient-wrapper').length, 1) + assert.strictEqual( + wrapper.find('.send__select-recipient-wrapper').length, + 1, + ) }) it('should render no content if there are no recents, transfers, and contacts', function () { @@ -95,11 +98,11 @@ describe('AddRecipient Component', function () { addressBook: [], }) - assert.equal( + assert.strictEqual( wrapper.find('.send__select-recipient-wrapper__list__link').length, 0, ) - assert.equal( + assert.strictEqual( wrapper.find('.send__select-recipient-wrapper__group').length, 0, ) @@ -118,10 +121,10 @@ describe('AddRecipient Component', function () { const xferLink = wrapper.find( '.send__select-recipient-wrapper__list__link', ) - assert.equal(xferLink.length, 1) + assert.strictEqual(xferLink.length, 1) const groups = wrapper.find('RecipientGroup') - assert.equal( + assert.strictEqual( groups.shallow().find('.send__select-recipient-wrapper__group').length, 1, ) @@ -138,7 +141,7 @@ describe('AddRecipient Component', function () { const contactList = wrapper.find('ContactList') - assert.equal(contactList.length, 1) + assert.strictEqual(contactList.length, 1) }) it('should render contacts', function () { @@ -154,12 +157,12 @@ describe('AddRecipient Component', function () { const xferLink = wrapper.find( '.send__select-recipient-wrapper__list__link', ) - assert.equal(xferLink.length, 0) + assert.strictEqual(xferLink.length, 0) const groups = wrapper.find('ContactList') - assert.equal(groups.length, 1) + assert.strictEqual(groups.length, 1) - assert.equal( + assert.strictEqual( groups.find('.send__select-recipient-wrapper__group-item').length, 0, ) @@ -175,9 +178,9 @@ describe('AddRecipient Component', function () { const dialog = wrapper.find(Dialog) - assert.equal(dialog.props().type, 'error') - assert.equal(dialog.props().children, 'bad_t') - assert.equal(dialog.length, 1) + assert.strictEqual(dialog.props().type, 'error') + assert.strictEqual(dialog.props().children, 'bad_t') + assert.strictEqual(dialog.length, 1) }) it('should render error when query has ens does not resolve', function () { @@ -191,9 +194,9 @@ describe('AddRecipient Component', function () { const dialog = wrapper.find(Dialog) - assert.equal(dialog.props().type, 'error') - assert.equal(dialog.props().children, 'very bad') - assert.equal(dialog.length, 1) + assert.strictEqual(dialog.props().type, 'error') + assert.strictEqual(dialog.props().children, 'very bad') + assert.strictEqual(dialog.length, 1) }) it('should not render error when ens resolved', function () { @@ -205,7 +208,7 @@ describe('AddRecipient Component', function () { const dialog = wrapper.find(Dialog) - assert.equal(dialog.length, 0) + assert.strictEqual(dialog.length, 0) }) it('should not render error when query has results', function () { @@ -220,7 +223,7 @@ describe('AddRecipient Component', function () { const dialog = wrapper.find(Dialog) - assert.equal(dialog.length, 0) + assert.strictEqual(dialog.length, 0) }) }) }) diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js index b7502bf52..f488b2f4e 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js @@ -33,7 +33,7 @@ proxyquire('../add-recipient.container.js', { describe('add-recipient container', function () { describe('mapStateToProps()', function () { it('should map the correct properties to props', function () { - assert.deepEqual(mapStateToProps('mockState'), { + assert.deepStrictEqual(mapStateToProps('mockState'), { addressBook: [{ name: 'mockAddressBook:mockState' }], contacts: [{ name: 'mockAddressBook:mockState' }], ensResolution: 'mockSendEnsResolution:mockState', @@ -57,7 +57,7 @@ describe('add-recipient container', function () { mapDispatchToPropsObject.updateSendTo('mockTo', 'mockNickname') assert(dispatchSpy.calledOnce) assert(actionSpies.updateSendTo.calledOnce) - assert.deepEqual(actionSpies.updateSendTo.getCall(0).args, [ + assert.deepStrictEqual(actionSpies.updateSendTo.getCall(0).args, [ 'mockTo', 'mockNickname', ]) diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js index e0972b36c..bfd83cbd7 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-utils.test.js @@ -24,25 +24,25 @@ const { getToErrorObject, getToWarningObject } = toRowUtils describe('add-recipient utils', function () { describe('getToErrorObject()', function () { it('should return a required error if "to" is falsy', function () { - assert.deepEqual(getToErrorObject(null), { + assert.deepStrictEqual(getToErrorObject(null), { to: REQUIRED_ERROR, }) }) it('should return null if "to" is falsy and hexData is truthy', function () { - assert.deepEqual(getToErrorObject(null, true), { + assert.deepStrictEqual(getToErrorObject(null, true), { to: null, }) }) it('should return an invalid recipient error if "to" is truthy but invalid', function () { - assert.deepEqual(getToErrorObject('mockInvalidTo'), { + assert.deepStrictEqual(getToErrorObject('mockInvalidTo'), { to: INVALID_RECIPIENT_ADDRESS_ERROR, }) }) it('should return null if "to" is truthy and valid', function () { - assert.deepEqual(getToErrorObject('0xabc123'), { + assert.deepStrictEqual(getToErrorObject('0xabc123'), { to: null, }) }) @@ -50,7 +50,7 @@ describe('add-recipient utils', function () { describe('getToWarningObject()', function () { it('should return a known address recipient error if "to" is a token address', function () { - assert.deepEqual( + assert.deepStrictEqual( getToWarningObject('0xabc123', [{ address: '0xabc123' }], { address: '0xabc123', }), @@ -61,7 +61,7 @@ describe('add-recipient utils', function () { }) it('should null if "to" is a token address but sendToken is falsy', function () { - assert.deepEqual( + assert.deepStrictEqual( getToWarningObject('0xabc123', [{ address: '0xabc123' }]), { to: null, @@ -70,7 +70,7 @@ describe('add-recipient utils', function () { }) it('should return a known address recipient error if "to" is part of contract metadata', function () { - assert.deepEqual( + assert.deepStrictEqual( getToWarningObject( '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359', [{ address: '0xabc123' }], @@ -82,7 +82,7 @@ describe('add-recipient utils', function () { ) }) it('should null if "to" is part of contract metadata but sendToken is falsy', function () { - assert.deepEqual( + assert.deepStrictEqual( getToWarningObject( '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359', [{ address: '0xabc123' }], diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js index f56aa6e12..fb040de64 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-component.test.js @@ -52,10 +52,10 @@ describe('AmountMaxButton Component', function () { describe('setMaxAmount', function () { it('should call setAmountToMax with the correct params', function () { - assert.equal(propsMethodSpies.setAmountToMax.callCount, 0) + assert.strictEqual(propsMethodSpies.setAmountToMax.callCount, 0) instance.setMaxAmount() - assert.equal(propsMethodSpies.setAmountToMax.callCount, 1) - assert.deepEqual(propsMethodSpies.setAmountToMax.getCall(0).args, [ + assert.strictEqual(propsMethodSpies.setAmountToMax.callCount, 1) + assert.deepStrictEqual(propsMethodSpies.setAmountToMax.getCall(0).args, [ { balance: 'mockBalance', gasTotal: 'mockGasTotal', @@ -74,17 +74,19 @@ describe('AmountMaxButton Component', function () { it('should call setMaxModeTo and setMaxAmount when the checkbox is checked', function () { const { onClick } = wrapper.find('.send-v2__amount-max').props() - assert.equal(AmountMaxButton.prototype.setMaxAmount.callCount, 0) - assert.equal(propsMethodSpies.setMaxModeTo.callCount, 0) + assert.strictEqual(AmountMaxButton.prototype.setMaxAmount.callCount, 0) + assert.strictEqual(propsMethodSpies.setMaxModeTo.callCount, 0) onClick(MOCK_EVENT) - assert.equal(AmountMaxButton.prototype.setMaxAmount.callCount, 1) - assert.equal(propsMethodSpies.setMaxModeTo.callCount, 1) - assert.deepEqual(propsMethodSpies.setMaxModeTo.getCall(0).args, [true]) + assert.strictEqual(AmountMaxButton.prototype.setMaxAmount.callCount, 1) + assert.strictEqual(propsMethodSpies.setMaxModeTo.callCount, 1) + assert.deepStrictEqual(propsMethodSpies.setMaxModeTo.getCall(0).args, [ + true, + ]) }) it('should render the expected text when maxModeOn is false', function () { wrapper.setProps({ maxModeOn: false }) - assert.equal(wrapper.find('.send-v2__amount-max').text(), 'max_t') + assert.strictEqual(wrapper.find('.send-v2__amount-max').text(), 'max_t') }) }) }) diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js index ac49eea81..ba5325a43 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-container.test.js @@ -39,7 +39,7 @@ proxyquire('../amount-max-button.container.js', { describe('amount-max-button container', function () { describe('mapStateToProps()', function () { it('should map the correct properties to props', function () { - assert.deepEqual(mapStateToProps('mockState'), { + assert.deepStrictEqual(mapStateToProps('mockState'), { balance: 'mockBalance:mockState', buttonDataLoading: 'mockButtonDataLoading:mockState', gasTotal: 'mockGasTotal:mockState', @@ -64,11 +64,14 @@ describe('amount-max-button container', function () { mapDispatchToPropsObject.setAmountToMax({ val: 11, foo: 'bar' }) assert(dispatchSpy.calledTwice) assert(duckActionSpies.updateSendErrors.calledOnce) - assert.deepEqual(duckActionSpies.updateSendErrors.getCall(0).args[0], { - amount: null, - }) + assert.deepStrictEqual( + duckActionSpies.updateSendErrors.getCall(0).args[0], + { + amount: null, + }, + ) assert(actionSpies.updateSendAmount.calledOnce) - assert.equal(actionSpies.updateSendAmount.getCall(0).args[0], 12) + assert.strictEqual(actionSpies.updateSendAmount.getCall(0).args[0], 12) }) }) @@ -76,7 +79,10 @@ describe('amount-max-button container', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.setMaxModeTo('mockVal') assert(dispatchSpy.calledOnce) - assert.equal(actionSpies.setMaxModeTo.getCall(0).args[0], 'mockVal') + assert.strictEqual( + actionSpies.setMaxModeTo.getCall(0).args[0], + 'mockVal', + ) }) }) }) diff --git a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js index d103525f3..c99f0449c 100644 --- a/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/amount-max-button/tests/amount-max-button-utils.test.js @@ -4,7 +4,7 @@ import { calcMaxAmount } from '../amount-max-button.utils' describe('amount-max-button utils', function () { describe('calcMaxAmount()', function () { it('should calculate the correct amount when no sendToken defined', function () { - assert.deepEqual( + assert.deepStrictEqual( calcMaxAmount({ balance: 'ffffff', gasTotal: 'ff', @@ -15,7 +15,7 @@ describe('amount-max-button utils', function () { }) it('should calculate the correct amount when a sendToken is defined', function () { - assert.deepEqual( + assert.deepStrictEqual( calcMaxAmount({ sendToken: { decimals: 10, diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js index 80e7b45a2..27c4b3bd9 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js @@ -16,7 +16,7 @@ describe('SendAmountRow Component', function () { propsMethodSpies: { updateSendAmountError }, } = shallowRenderSendAmountRow() - assert.equal(updateSendAmountError.callCount, 0) + assert.strictEqual(updateSendAmountError.callCount, 0) instance.validateAmount('someAmount') @@ -39,7 +39,7 @@ describe('SendAmountRow Component', function () { propsMethodSpies: { updateGasFeeError }, } = shallowRenderSendAmountRow() - assert.equal(updateGasFeeError.callCount, 0) + assert.strictEqual(updateGasFeeError.callCount, 0) instance.validateAmount('someAmount') @@ -64,11 +64,11 @@ describe('SendAmountRow Component', function () { wrapper.setProps({ sendToken: null }) - assert.equal(updateGasFeeError.callCount, 0) + assert.strictEqual(updateGasFeeError.callCount, 0) instance.validateAmount('someAmount') - assert.equal(updateGasFeeError.callCount, 0) + assert.strictEqual(updateGasFeeError.callCount, 0) }) }) @@ -79,7 +79,7 @@ describe('SendAmountRow Component', function () { propsMethodSpies: { setMaxModeTo }, } = shallowRenderSendAmountRow() - assert.equal(setMaxModeTo.callCount, 0) + assert.strictEqual(setMaxModeTo.callCount, 0) instance.updateAmount('someAmount') @@ -92,7 +92,7 @@ describe('SendAmountRow Component', function () { propsMethodSpies: { updateSendAmount }, } = shallowRenderSendAmountRow() - assert.equal(updateSendAmount.callCount, 0) + assert.strictEqual(updateSendAmount.callCount, 0) instance.updateAmount('someAmount') @@ -104,7 +104,7 @@ describe('SendAmountRow Component', function () { it('should render a SendRowWrapper component', function () { const { wrapper } = shallowRenderSendAmountRow() - assert.equal(wrapper.find(SendRowWrapper).length, 1) + assert.strictEqual(wrapper.find(SendRowWrapper).length, 1) }) it('should pass the correct props to SendRowWrapper', function () { @@ -113,9 +113,9 @@ describe('SendAmountRow Component', function () { .find(SendRowWrapper) .props() - assert.equal(errorType, 'amount') - assert.equal(label, 'amount_t:') - assert.equal(showError, false) + assert.strictEqual(errorType, 'amount') + assert.strictEqual(label, 'amount_t:') + assert.strictEqual(showError, false) }) it('should render an AmountMaxButton as the first child of the SendRowWrapper', function () { @@ -142,11 +142,11 @@ describe('SendAmountRow Component', function () { .childAt(1) .props() - assert.equal(error, false) - assert.equal(value, 'mockAmount') - assert.equal(updateGas.callCount, 0) - assert.equal(updateAmount.callCount, 0) - assert.equal(validateAmount.callCount, 0) + assert.strictEqual(error, false) + assert.strictEqual(value, 'mockAmount') + assert.strictEqual(updateGas.callCount, 0) + assert.strictEqual(updateAmount.callCount, 0) + assert.strictEqual(validateAmount.callCount, 0) onChange('mockNewAmount') diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js index 8b7dc5b8e..3137ef1b4 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-container.test.js @@ -50,7 +50,10 @@ describe('send-amount-row container', function () { mapDispatchToPropsObject.setMaxModeTo('mockBool') assert(dispatchSpy.calledOnce) assert(actionSpies.setMaxModeTo.calledOnce) - assert.equal(actionSpies.setMaxModeTo.getCall(0).args[0], 'mockBool') + assert.strictEqual( + actionSpies.setMaxModeTo.getCall(0).args[0], + 'mockBool', + ) }) }) @@ -59,7 +62,7 @@ describe('send-amount-row container', function () { mapDispatchToPropsObject.updateSendAmount('mockAmount') assert(dispatchSpy.calledOnce) assert(actionSpies.updateSendAmount.calledOnce) - assert.equal( + assert.strictEqual( actionSpies.updateSendAmount.getCall(0).args[0], 'mockAmount', ) @@ -71,10 +74,13 @@ describe('send-amount-row container', function () { mapDispatchToPropsObject.updateGasFeeError({ some: 'data' }) assert(dispatchSpy.calledOnce) assert(duckActionSpies.updateSendErrors.calledOnce) - assert.deepEqual(duckActionSpies.updateSendErrors.getCall(0).args[0], { - some: 'data', - mockGasFeeErrorChange: true, - }) + assert.deepStrictEqual( + duckActionSpies.updateSendErrors.getCall(0).args[0], + { + some: 'data', + mockGasFeeErrorChange: true, + }, + ) }) }) @@ -83,10 +89,13 @@ describe('send-amount-row container', function () { mapDispatchToPropsObject.updateSendAmountError({ some: 'data' }) assert(dispatchSpy.calledOnce) assert(duckActionSpies.updateSendErrors.calledOnce) - assert.deepEqual(duckActionSpies.updateSendErrors.getCall(0).args[0], { - some: 'data', - mockChange: true, - }) + assert.deepStrictEqual( + duckActionSpies.updateSendErrors.getCall(0).args[0], + { + some: 'data', + mockChange: true, + }, + ) }) }) }) diff --git a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js index 2dd085a38..817c324ea 100644 --- a/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/gas-fee-display/tests/gas-fee-display.component.test.js @@ -33,7 +33,7 @@ describe('GasFeeDisplay Component', function () { }) it('should render a CurrencyDisplay component', function () { - assert.equal(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) + assert.strictEqual(wrapper.find(UserPreferencedCurrencyDisplay).length, 2) }) it('should render the CurrencyDisplay with the correct props', function () { @@ -41,20 +41,20 @@ describe('GasFeeDisplay Component', function () { .find(UserPreferencedCurrencyDisplay) .at(0) .props() - assert.equal(type, 'PRIMARY') - assert.equal(value, 'mockGasTotal') + assert.strictEqual(type, 'PRIMARY') + assert.strictEqual(value, 'mockGasTotal') }) it('should render the reset button with the correct props', function () { const { onClick, className } = wrapper.find('button').props() - assert.equal(className, 'gas-fee-reset') - assert.equal(propsMethodSpies.onReset.callCount, 0) + assert.strictEqual(className, 'gas-fee-reset') + assert.strictEqual(propsMethodSpies.onReset.callCount, 0) onClick() - assert.equal(propsMethodSpies.onReset.callCount, 1) + assert.strictEqual(propsMethodSpies.onReset.callCount, 1) }) it('should render the reset button with the correct text', function () { - assert.equal(wrapper.find('button').text(), 'reset_t') + assert.strictEqual(wrapper.find('button').text(), 'reset_t') }) }) }) diff --git a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js b/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js index a80671c5f..926e9ae02 100644 --- a/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js +++ b/ui/app/pages/send/send-content/send-gas-row/tests/send-gas-row-component.test.js @@ -43,8 +43,8 @@ describe('SendGasRow Component', function () { }) it('should render a SendRowWrapper component', function () { - assert.equal(wrapper.name(), 'Fragment') - assert.equal(wrapper.at(0).find(SendRowWrapper).length, 1) + assert.strictEqual(wrapper.name(), 'Fragment') + assert.strictEqual(wrapper.at(0).find(SendRowWrapper).length, 1) }) it('should pass the correct props to SendRowWrapper', function () { @@ -53,9 +53,9 @@ describe('SendGasRow Component', function () { .first() .props() - assert.equal(label, 'transactionFee_t:') - assert.equal(showError, true) - assert.equal(errorType, 'gasFee') + assert.strictEqual(label, 'transactionFee_t:') + assert.strictEqual(showError, true) + assert.strictEqual(errorType, 'gasFee') }) it('should render a GasFeeDisplay as a child of the SendRowWrapper', function () { @@ -68,27 +68,27 @@ describe('SendGasRow Component', function () { .first() .childAt(0) .props() - assert.equal(gasLoadingError, false) - assert.equal(gasTotal, 'mockGasTotal') - assert.equal(propsMethodSpies.resetGasButtons.callCount, 0) + assert.strictEqual(gasLoadingError, false) + assert.strictEqual(gasTotal, 'mockGasTotal') + assert.strictEqual(propsMethodSpies.resetGasButtons.callCount, 0) onReset() - assert.equal(propsMethodSpies.resetGasButtons.callCount, 1) + assert.strictEqual(propsMethodSpies.resetGasButtons.callCount, 1) }) it('should render the GasPriceButtonGroup if gasButtonGroupShown is true', function () { wrapper.setProps({ gasButtonGroupShown: true }) const rendered = wrapper.find(SendRowWrapper).first().childAt(0) - assert.equal(wrapper.children().length, 2) + assert.strictEqual(wrapper.children().length, 2) const gasPriceButtonGroup = rendered.childAt(0) assert(gasPriceButtonGroup.is(GasPriceButtonGroup)) assert(gasPriceButtonGroup.hasClass('gas-price-button-group--small')) - assert.equal(gasPriceButtonGroup.props().showCheck, false) - assert.equal( + assert.strictEqual(gasPriceButtonGroup.props().showCheck, false) + assert.strictEqual( gasPriceButtonGroup.props().someGasPriceButtonGroupProp, 'foo', ) - assert.equal( + assert.strictEqual( gasPriceButtonGroup.props().anotherGasPriceButtonGroupProp, 'bar', ) @@ -97,14 +97,14 @@ describe('SendGasRow Component', function () { it('should render an advanced options button if gasButtonGroupShown is true', function () { wrapper.setProps({ gasButtonGroupShown: true }) const rendered = wrapper.find(SendRowWrapper).last() - assert.equal(wrapper.children().length, 2) + assert.strictEqual(wrapper.children().length, 2) const advancedOptionsButton = rendered.childAt(0) - assert.equal(advancedOptionsButton.text(), 'advancedOptions_t') + assert.strictEqual(advancedOptionsButton.text(), 'advancedOptions_t') - assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) + assert.strictEqual(propsMethodSpies.showCustomizeGasModal.callCount, 0) advancedOptionsButton.props().onClick() - assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) + assert.strictEqual(propsMethodSpies.showCustomizeGasModal.callCount, 1) }) }) }) diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js index 975b26748..41d318ffd 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-component.test.js @@ -18,16 +18,16 @@ describe('SendRowErrorMessage Component', function () { }) it('should render null if the passed errors do not contain an error of errorType', function () { - assert.equal(wrapper.find('.send-v2__error').length, 0) - assert.equal(wrapper.html(), null) + assert.strictEqual(wrapper.find('.send-v2__error').length, 0) + assert.strictEqual(wrapper.html(), null) }) it('should render an error message if the passed errors contain an error of errorType', function () { wrapper.setProps({ errors: { error1: 'abc', error2: 'def', error3: 'xyz' }, }) - assert.equal(wrapper.find('.send-v2__error').length, 1) - assert.equal(wrapper.find('.send-v2__error').text(), 'xyz_t') + assert.strictEqual(wrapper.find('.send-v2__error').length, 1) + assert.strictEqual(wrapper.find('.send-v2__error').text(), 'xyz_t') }) }) }) diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js index c85b50bfd..dd3a4da8f 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/tests/send-row-error-message-container.test.js @@ -16,7 +16,7 @@ proxyquire('../send-row-error-message.container.js', { describe('send-row-error-message container', function () { describe('mapStateToProps()', function () { it('should map the correct properties to props', function () { - assert.deepEqual( + assert.deepStrictEqual( mapStateToProps('mockState', { errorType: 'someType' }), { errors: 'mockErrors:mockState', diff --git a/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js b/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js index c2aa7c1f1..4a4b3189a 100644 --- a/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js +++ b/ui/app/pages/send/send-content/send-row-wrapper/tests/send-row-wrapper-component.test.js @@ -22,22 +22,22 @@ describe('SendContent Component', function () { }) it('should render a div with a send-v2__form-row class', function () { - assert.equal(wrapper.find('div.send-v2__form-row').length, 1) + assert.strictEqual(wrapper.find('div.send-v2__form-row').length, 1) }) it('should render two children of the root div, with send-v2_form label and field classes', function () { - assert.equal( + assert.strictEqual( wrapper.find('.send-v2__form-row > .send-v2__form-label').length, 1, ) - assert.equal( + assert.strictEqual( wrapper.find('.send-v2__form-row > .send-v2__form-field').length, 1, ) }) it('should render the label as a child of the send-v2__form-label', function () { - assert.equal( + assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-label') .childAt(0) @@ -47,7 +47,7 @@ describe('SendContent Component', function () { }) it('should render its first child as a child of the send-v2__form-field', function () { - assert.equal( + assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-field') .childAt(0) @@ -57,18 +57,18 @@ describe('SendContent Component', function () { }) it('should not render a SendRowErrorMessage if showError is false', function () { - assert.equal(wrapper.find(SendRowErrorMessage).length, 0) + assert.strictEqual(wrapper.find(SendRowErrorMessage).length, 0) }) it('should render a SendRowErrorMessage with and errorType props if showError is true', function () { wrapper.setProps({ showError: true }) - assert.equal(wrapper.find(SendRowErrorMessage).length, 1) + assert.strictEqual(wrapper.find(SendRowErrorMessage).length, 1) const expectedSendRowErrorMessage = wrapper .find('.send-v2__form-row > .send-v2__form-label') .childAt(1) assert(expectedSendRowErrorMessage.is(SendRowErrorMessage)) - assert.deepEqual(expectedSendRowErrorMessage.props(), { + assert.deepStrictEqual(expectedSendRowErrorMessage.props(), { errorType: 'mockErrorType', }) }) @@ -84,7 +84,7 @@ describe('SendContent Component', function () { Mock Form Field , ) - assert.equal( + assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-field') .childAt(0) @@ -104,7 +104,7 @@ describe('SendContent Component', function () { Mock Form Field , ) - assert.equal( + assert.strictEqual( wrapper .find('.send-v2__form-row > .send-v2__form-label') .childAt(1) diff --git a/ui/app/pages/send/send-content/tests/send-content-component.test.js b/ui/app/pages/send/send-content/tests/send-content-component.test.js index 30a9fba69..2628c516a 100644 --- a/ui/app/pages/send/send-content/tests/send-content-component.test.js +++ b/ui/app/pages/send/send-content/tests/send-content-component.test.js @@ -21,7 +21,7 @@ describe('SendContent Component', function () { describe('render', function () { it('should render a PageContainerContent component', function () { - assert.equal(wrapper.find(PageContainerContent).length, 1) + assert.strictEqual(wrapper.find(PageContainerContent).length, 1) }) it('should render a div with a .send-v2__form class as a child of PageContainerContent', function () { @@ -79,7 +79,7 @@ describe('SendContent Component', function () { PageContainerContentChild.childAt(3).is(SendGasRow), 'row[3] should be SendGasRow', ) - assert.equal(PageContainerContentChild.childAt(4).exists(), false) + assert.strictEqual(PageContainerContentChild.childAt(4).exists(), false) }) it('should not render the Dialog if contact has a name', function () { @@ -102,7 +102,7 @@ describe('SendContent Component', function () { PageContainerContentChild.childAt(2).is(SendGasRow), 'row[3] should be SendGasRow', ) - assert.equal(PageContainerContentChild.childAt(3).exists(), false) + assert.strictEqual(PageContainerContentChild.childAt(3).exists(), false) }) it('should not render the Dialog if it is an ownedAccount', function () { @@ -125,7 +125,7 @@ describe('SendContent Component', function () { PageContainerContentChild.childAt(2).is(SendGasRow), 'row[3] should be SendGasRow', ) - assert.equal(PageContainerContentChild.childAt(3).exists(), false) + assert.strictEqual(PageContainerContentChild.childAt(3).exists(), false) }) }) @@ -150,8 +150,8 @@ describe('SendContent Component', function () { const dialog = wrapper.find(Dialog).at(0) - assert.equal(dialog.props().type, 'warning') - assert.equal(dialog.props().children, 'watchout_t') - assert.equal(dialog.length, 1) + assert.strictEqual(dialog.props().type, 'warning') + assert.strictEqual(dialog.props().children, 'watchout_t') + assert.strictEqual(dialog.length, 1) }) }) diff --git a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js b/ui/app/pages/send/send-footer/tests/send-footer-component.test.js index 87a0e2d9a..d77b7fe87 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-component.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-component.test.js @@ -71,16 +71,16 @@ describe('SendFooter Component', function () { describe('onCancel', function () { it('should call clearSend', function () { - assert.equal(propsMethodSpies.clearSend.callCount, 0) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 0) wrapper.instance().onCancel() - assert.equal(propsMethodSpies.clearSend.callCount, 1) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 1) }) it('should call history.push', function () { - assert.equal(historySpies.push.callCount, 0) + assert.strictEqual(historySpies.push.callCount, 0) wrapper.instance().onCancel() - assert.equal(historySpies.push.callCount, 1) - assert.equal( + assert.strictEqual(historySpies.push.callCount, 1) + assert.strictEqual( historySpies.push.getCall(0).args[0], 'mostRecentOverviewPage', ) @@ -133,7 +133,7 @@ describe('SendFooter Component', function () { Object.entries(config).forEach(([description, obj]) => { it(description, function () { wrapper.setProps(obj) - assert.equal( + assert.strictEqual( wrapper.instance().formShouldBeDisabled(), obj.expectedResult, ) @@ -145,16 +145,16 @@ describe('SendFooter Component', function () { it('should call addToAddressBookIfNew with the correct params', function () { wrapper.instance().onSubmit(MOCK_EVENT) assert(propsMethodSpies.addToAddressBookIfNew.calledOnce) - assert.deepEqual(propsMethodSpies.addToAddressBookIfNew.getCall(0).args, [ - 'mockTo', - ['mockAccount'], - ]) + assert.deepStrictEqual( + propsMethodSpies.addToAddressBookIfNew.getCall(0).args, + ['mockTo', ['mockAccount']], + ) }) it('should call props.update if editingTransactionId is truthy', async function () { await wrapper.instance().onSubmit(MOCK_EVENT) assert(propsMethodSpies.update.calledOnce) - assert.deepEqual(propsMethodSpies.update.getCall(0).args[0], { + assert.deepStrictEqual(propsMethodSpies.update.getCall(0).args[0], { data: undefined, amount: 'mockAmount', editingTransactionId: 'mockEditingTransactionId', @@ -168,14 +168,14 @@ describe('SendFooter Component', function () { }) it('should not call props.sign if editingTransactionId is truthy', function () { - assert.equal(propsMethodSpies.sign.callCount, 0) + assert.strictEqual(propsMethodSpies.sign.callCount, 0) }) it('should call props.sign if editingTransactionId is falsy', async function () { wrapper.setProps({ editingTransactionId: null }) await wrapper.instance().onSubmit(MOCK_EVENT) assert(propsMethodSpies.sign.calledOnce) - assert.deepEqual(propsMethodSpies.sign.getCall(0).args[0], { + assert.deepStrictEqual(propsMethodSpies.sign.getCall(0).args[0], { data: undefined, amount: 'mockAmount', from: 'mockAddress', @@ -187,13 +187,13 @@ describe('SendFooter Component', function () { }) it('should not call props.update if editingTransactionId is falsy', function () { - assert.equal(propsMethodSpies.update.callCount, 0) + assert.strictEqual(propsMethodSpies.update.callCount, 0) }) it('should call history.push', async function () { await wrapper.instance().onSubmit(MOCK_EVENT) - assert.equal(historySpies.push.callCount, 1) - assert.equal( + assert.strictEqual(historySpies.push.callCount, 1) + assert.strictEqual( historySpies.push.getCall(0).args[0], CONFIRM_TRANSACTION_ROUTE, ) @@ -234,22 +234,22 @@ describe('SendFooter Component', function () { }) it('should render a PageContainerFooter component', function () { - assert.equal(wrapper.find(PageContainerFooter).length, 1) + assert.strictEqual(wrapper.find(PageContainerFooter).length, 1) }) it('should pass the correct props to PageContainerFooter', function () { const { onCancel, onSubmit, disabled } = wrapper .find(PageContainerFooter) .props() - assert.equal(disabled, true) + assert.strictEqual(disabled, true) - assert.equal(SendFooter.prototype.onSubmit.callCount, 0) + assert.strictEqual(SendFooter.prototype.onSubmit.callCount, 0) onSubmit(MOCK_EVENT) - assert.equal(SendFooter.prototype.onSubmit.callCount, 1) + assert.strictEqual(SendFooter.prototype.onSubmit.callCount, 1) - assert.equal(SendFooter.prototype.onCancel.callCount, 0) + assert.strictEqual(SendFooter.prototype.onCancel.callCount, 0) onCancel() - assert.equal(SendFooter.prototype.onCancel.callCount, 1) + assert.strictEqual(SendFooter.prototype.onCancel.callCount, 1) }) }) }) diff --git a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js b/ui/app/pages/send/send-footer/tests/send-footer-container.test.js index 74fe608c8..e037fe7cc 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-container.test.js @@ -82,18 +82,21 @@ describe('send-footer container', function () { gasPrice: 'mockGasPrice', }) assert(dispatchSpy.calledOnce) - assert.deepEqual(utilsStubs.constructTxParams.getCall(0).args[0], { - data: undefined, - sendToken: { - address: '0xabc', + assert.deepStrictEqual( + utilsStubs.constructTxParams.getCall(0).args[0], + { + data: undefined, + sendToken: { + address: '0xabc', + }, + to: 'mockTo', + amount: 'mockAmount', + from: 'mockFrom', + gas: 'mockGas', + gasPrice: 'mockGasPrice', }, - to: 'mockTo', - amount: 'mockAmount', - from: 'mockFrom', - gas: 'mockGas', - gasPrice: 'mockGasPrice', - }) - assert.deepEqual(actionSpies.signTokenTx.getCall(0).args, [ + ) + assert.deepStrictEqual(actionSpies.signTokenTx.getCall(0).args, [ '0xabc', 'mockTo', 'mockAmount', @@ -111,16 +114,19 @@ describe('send-footer container', function () { gasPrice: 'mockGasPrice', }) assert(dispatchSpy.calledOnce) - assert.deepEqual(utilsStubs.constructTxParams.getCall(0).args[0], { - data: undefined, - sendToken: undefined, - to: 'mockTo', - amount: 'mockAmount', - from: 'mockFrom', - gas: 'mockGas', - gasPrice: 'mockGasPrice', - }) - assert.deepEqual(actionSpies.signTx.getCall(0).args, [ + assert.deepStrictEqual( + utilsStubs.constructTxParams.getCall(0).args[0], + { + data: undefined, + sendToken: undefined, + to: 'mockTo', + amount: 'mockAmount', + from: 'mockFrom', + gas: 'mockGas', + gasPrice: 'mockGasPrice', + }, + ) + assert.deepStrictEqual(actionSpies.signTx.getCall(0).args, [ { value: 'mockAmount' }, ]) }) @@ -139,18 +145,21 @@ describe('send-footer container', function () { unapprovedTxs: 'mockUnapprovedTxs', }) assert(dispatchSpy.calledOnce) - assert.deepEqual(utilsStubs.constructUpdatedTx.getCall(0).args[0], { - data: undefined, - to: 'mockTo', - amount: 'mockAmount', - from: 'mockFrom', - gas: 'mockGas', - gasPrice: 'mockGasPrice', - editingTransactionId: 'mockEditingTransactionId', - sendToken: { address: 'mockAddress' }, - unapprovedTxs: 'mockUnapprovedTxs', - }) - assert.equal( + assert.deepStrictEqual( + utilsStubs.constructUpdatedTx.getCall(0).args[0], + { + data: undefined, + to: 'mockTo', + amount: 'mockAmount', + from: 'mockFrom', + gas: 'mockGas', + gasPrice: 'mockGasPrice', + editingTransactionId: 'mockEditingTransactionId', + sendToken: { address: 'mockAddress' }, + unapprovedTxs: 'mockUnapprovedTxs', + }, + ) + assert.strictEqual( actionSpies.updateTransaction.getCall(0).args[0], 'mockConstructedUpdatedTxParams', ) @@ -165,11 +174,11 @@ describe('send-footer container', function () { 'mockNickname', ) assert(dispatchSpy.calledOnce) - assert.equal( + assert.strictEqual( utilsStubs.addressIsNew.getCall(0).args[0], 'mockToAccounts', ) - assert.deepEqual(actionSpies.addToAddressBook.getCall(0).args, [ + assert.deepStrictEqual(actionSpies.addToAddressBook.getCall(0).args, [ '0xmockNewAddress', 'mockNickname', ]) diff --git a/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js b/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js index f462ff22f..52a84a993 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-utils.test.js @@ -19,7 +19,7 @@ const { addressIsNew, constructTxParams, constructUpdatedTx } = sendUtils describe('send-footer utils', function () { describe('addressIsNew()', function () { it('should return false if the address exists in toAccounts', function () { - assert.equal( + assert.strictEqual( addressIsNew( [{ address: '0xabc' }, { address: '0xdef' }, { address: '0xghi' }], '0xdef', @@ -29,7 +29,7 @@ describe('send-footer utils', function () { }) it('should return true if the address does not exists in toAccounts', function () { - assert.equal( + assert.strictEqual( addressIsNew( [{ address: '0xabc' }, { address: '0xdef' }, { address: '0xghi' }], '0xxyz', @@ -41,7 +41,7 @@ describe('send-footer utils', function () { describe('constructTxParams()', function () { it('should return a new txParams object with data if there data is given', function () { - assert.deepEqual( + assert.deepStrictEqual( constructTxParams({ data: 'someData', sendToken: undefined, @@ -63,7 +63,7 @@ describe('send-footer utils', function () { }) it('should return a new txParams object with value and to properties if there is no sendToken', function () { - assert.deepEqual( + assert.deepStrictEqual( constructTxParams({ sendToken: undefined, to: 'mockTo', @@ -84,7 +84,7 @@ describe('send-footer utils', function () { }) it('should return a new txParams object without a to property and a 0 value if there is a sendToken', function () { - assert.deepEqual( + assert.deepStrictEqual( constructTxParams({ sendToken: { address: '0x0' }, to: 'mockTo', @@ -124,7 +124,7 @@ describe('send-footer utils', function () { }, }, }) - assert.deepEqual(result, { + assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', txParams: { from: '0xmockFrom', @@ -159,7 +159,7 @@ describe('send-footer utils', function () { }, }) - assert.deepEqual(result, { + assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', txParams: { from: '0xmockFrom', @@ -191,7 +191,7 @@ describe('send-footer utils', function () { }, }) - assert.deepEqual(result, { + assert.deepStrictEqual(result, { unapprovedTxParam: 'someOtherParam', txParams: { from: '0xmockFrom', diff --git a/ui/app/pages/send/send-header/tests/send-header-component.test.js b/ui/app/pages/send/send-header/tests/send-header-component.test.js index e7abd308d..03168bed1 100644 --- a/ui/app/pages/send/send-header/tests/send-header-component.test.js +++ b/ui/app/pages/send/send-header/tests/send-header-component.test.js @@ -43,16 +43,16 @@ describe('SendHeader Component', function () { describe('onClose', function () { it('should call clearSend', function () { - assert.equal(propsMethodSpies.clearSend.callCount, 0) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 0) wrapper.instance().onClose() - assert.equal(propsMethodSpies.clearSend.callCount, 1) + assert.strictEqual(propsMethodSpies.clearSend.callCount, 1) }) it('should call history.push', function () { - assert.equal(historySpies.push.callCount, 0) + assert.strictEqual(historySpies.push.callCount, 0) wrapper.instance().onClose() - assert.equal(historySpies.push.callCount, 1) - assert.equal( + assert.strictEqual(historySpies.push.callCount, 1) + assert.strictEqual( historySpies.push.getCall(0).args[0], 'mostRecentOverviewPage', ) @@ -61,15 +61,15 @@ describe('SendHeader Component', function () { describe('render', function () { it('should render a PageContainerHeader component', function () { - assert.equal(wrapper.find(PageContainerHeader).length, 1) + assert.strictEqual(wrapper.find(PageContainerHeader).length, 1) }) it('should pass the correct props to PageContainerHeader', function () { const { onClose, title } = wrapper.find(PageContainerHeader).props() - assert.equal(title, 'mockTitleKey') - assert.equal(SendHeader.prototype.onClose.callCount, 0) + assert.strictEqual(title, 'mockTitleKey') + assert.strictEqual(SendHeader.prototype.onClose.callCount, 0) onClose() - assert.equal(SendHeader.prototype.onClose.callCount, 1) + assert.strictEqual(SendHeader.prototype.onClose.callCount, 1) }) }) }) diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js index 727c213af..4171f0611 100644 --- a/ui/app/pages/send/send.component.js +++ b/ui/app/pages/send/send.component.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' +import ethUtil from 'ethereumjs-util' import { debounce } from 'lodash' import { getAmountErrorObject, @@ -16,6 +17,7 @@ import AddRecipient from './send-content/add-recipient' import SendContent from './send-content' import SendFooter from './send-footer' import EnsInput from './send-content/add-recipient/ens-input' +import { INVALID_RECIPIENT_ADDRESS_ERROR } from './send.constants' export default class SendTransactionScreen extends Component { static propTypes = { @@ -162,12 +164,18 @@ export default class SendTransactionScreen extends Component { if (qrCodeData) { if (qrCodeData.type === 'address') { scannedAddress = qrCodeData.values.address.toLowerCase() - const currentAddress = prevTo?.toLowerCase() - if (currentAddress !== scannedAddress) { - updateSendTo(scannedAddress) - updateGas = true - // Clean up QR code data after handling + if (ethUtil.isValidAddress(scannedAddress)) { + const currentAddress = prevTo?.toLowerCase() + if (currentAddress !== scannedAddress) { + updateSendTo(scannedAddress) + updateGas = true + // Clean up QR code data after handling + qrCodeDetected(null) + } + } else { + scannedAddress = null qrCodeDetected(null) + this.setState({ toError: INVALID_RECIPIENT_ADDRESS_ERROR }) } } } diff --git a/ui/app/pages/send/tests/send-component.test.js b/ui/app/pages/send/tests/send-component.test.js index 4c5cd04e3..458082e7d 100644 --- a/ui/app/pages/send/tests/send-component.test.js +++ b/ui/app/pages/send/tests/send-component.test.js @@ -106,27 +106,27 @@ describe('Send Component', function () { describe('componentDidMount', function () { it('should call props.fetchBasicGasAndTimeEstimates', function () { propsMethodSpies.fetchBasicGasEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) wrapper.instance().componentDidMount() - assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) + assert.strictEqual(propsMethodSpies.fetchBasicGasEstimates.callCount, 1) }) it('should call this.updateGas', async function () { SendTransactionScreen.prototype.updateGas.resetHistory() propsMethodSpies.updateSendErrors.resetHistory() - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0) + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) wrapper.instance().componentDidMount() await timeout(250) - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1) + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 1) }) }) describe('componentWillUnmount', function () { it('should call this.props.resetSendState', function () { propsMethodSpies.resetSendState.resetHistory() - assert.equal(propsMethodSpies.resetSendState.callCount, 0) + assert.strictEqual(propsMethodSpies.resetSendState.callCount, 0) wrapper.instance().componentWillUnmount() - assert.equal(propsMethodSpies.resetSendState.callCount, 1) + assert.strictEqual(propsMethodSpies.resetSendState.callCount, 1) }) }) @@ -139,7 +139,7 @@ describe('Send Component', function () { }, }) assert(utilsMethodStubs.doesAmountErrorRequireUpdate.calledTwice) - assert.deepEqual( + assert.deepStrictEqual( utilsMethodStubs.doesAmountErrorRequireUpdate.getCall(0).args[0], { balance: 'mockBalance', @@ -164,7 +164,7 @@ describe('Send Component', function () { balance: 'mockBalance', }, }) - assert.equal(utilsMethodStubs.getAmountErrorObject.callCount, 0) + assert.strictEqual(utilsMethodStubs.getAmountErrorObject.callCount, 0) }) it('should call getAmountErrorObject if doesAmountErrorRequireUpdate returns true', function () { @@ -174,8 +174,8 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(utilsMethodStubs.getAmountErrorObject.callCount, 1) - assert.deepEqual( + assert.strictEqual(utilsMethodStubs.getAmountErrorObject.callCount, 1) + assert.deepStrictEqual( utilsMethodStubs.getAmountErrorObject.getCall(0).args[0], { amount: 'mockAmount', @@ -200,8 +200,8 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(utilsMethodStubs.getGasFeeErrorObject.callCount, 1) - assert.deepEqual( + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 1) + assert.deepStrictEqual( utilsMethodStubs.getGasFeeErrorObject.getCall(0).args[0], { balance: 'mockBalance', @@ -222,7 +222,7 @@ describe('Send Component', function () { wrapper.instance().componentDidUpdate({ from: { address: 'mockAddress', balance: 'mockBalance' }, }) - assert.equal(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) }) it('should not call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns true but sendToken is falsy', function () { @@ -233,7 +233,7 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) + assert.strictEqual(utilsMethodStubs.getGasFeeErrorObject.callCount, 0) }) it('should call updateSendErrors with the expected params if sendToken is falsy', function () { @@ -244,11 +244,14 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(propsMethodSpies.updateSendErrors.callCount, 1) - assert.deepEqual(propsMethodSpies.updateSendErrors.getCall(0).args[0], { - amount: 'mockAmountError', - gasFee: null, - }) + assert.strictEqual(propsMethodSpies.updateSendErrors.callCount, 1) + assert.deepStrictEqual( + propsMethodSpies.updateSendErrors.getCall(0).args[0], + { + amount: 'mockAmountError', + gasFee: null, + }, + ) }) it('should call updateSendErrors with the expected params if sendToken is truthy', function () { @@ -261,11 +264,14 @@ describe('Send Component', function () { balance: 'balanceChanged', }, }) - assert.equal(propsMethodSpies.updateSendErrors.callCount, 1) - assert.deepEqual(propsMethodSpies.updateSendErrors.getCall(0).args[0], { - amount: 'mockAmountError', - gasFee: 'mockGasFeeError', - }) + assert.strictEqual(propsMethodSpies.updateSendErrors.callCount, 1) + assert.deepStrictEqual( + propsMethodSpies.updateSendErrors.getCall(0).args[0], + { + amount: 'mockAmountError', + gasFee: 'mockGasFeeError', + }, + ) }) it('should not call updateSendTokenBalance or this.updateGas if network === prevNetwork', function () { @@ -278,8 +284,8 @@ describe('Send Component', function () { network: '3', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }) - assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 0) - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0) + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0) + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) }) it('should not call updateSendTokenBalance or this.updateGas if network === loading', function () { @@ -293,8 +299,8 @@ describe('Send Component', function () { network: '3', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }) - assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 0) - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0) + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 0) + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 0) }) it('should call updateSendTokenBalance and this.updateGas with the correct params', function () { @@ -307,8 +313,8 @@ describe('Send Component', function () { network: '2', sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset }) - assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 1) - assert.deepEqual( + assert.strictEqual(propsMethodSpies.updateSendTokenBalance.callCount, 1) + assert.deepStrictEqual( propsMethodSpies.updateSendTokenBalance.getCall(0).args[0], { sendToken: { @@ -320,8 +326,8 @@ describe('Send Component', function () { address: 'mockAddress', }, ) - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1) - assert.deepEqual( + assert.strictEqual(SendTransactionScreen.prototype.updateGas.callCount, 1) + assert.deepStrictEqual( SendTransactionScreen.prototype.updateGas.getCall(0).args, [], ) @@ -337,8 +343,11 @@ describe('Send Component', function () { network: '3', // Make sure not to hit updateGas when changing network sendToken: { address: 'newSelectedToken' }, }) - assert.equal(propsMethodSpies.updateToNicknameIfNecessary.callCount, 0) // Network did not change - assert.equal(propsMethodSpies.updateAndSetGasLimit.callCount, 1) + assert.strictEqual( + propsMethodSpies.updateToNicknameIfNecessary.callCount, + 0, + ) // Network did not change + assert.strictEqual(propsMethodSpies.updateAndSetGasLimit.callCount, 1) }) }) @@ -346,8 +355,8 @@ describe('Send Component', function () { it('should call updateAndSetGasLimit with the correct params if no to prop is passed', function () { propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.instance().updateGas() - assert.equal(propsMethodSpies.updateAndSetGasLimit.callCount, 1) - assert.deepEqual( + assert.strictEqual(propsMethodSpies.updateAndSetGasLimit.callCount, 1) + assert.deepStrictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0], { blockGasLimit: 'mockBlockGasLimit', @@ -371,7 +380,7 @@ describe('Send Component', function () { propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.setProps({ to: 'someAddress' }) wrapper.instance().updateGas() - assert.equal( + assert.strictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, 'someaddress', ) @@ -380,7 +389,7 @@ describe('Send Component', function () { it('should call updateAndSetGasLimit with to set to lowercase if passed', function () { propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.instance().updateGas({ to: '0xABC' }) - assert.equal( + assert.strictEqual( propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, '0xabc', ) @@ -389,22 +398,22 @@ describe('Send Component', function () { describe('render', function () { it('should render a page-container class', function () { - assert.equal(wrapper.find('.page-container').length, 1) + assert.strictEqual(wrapper.find('.page-container').length, 1) }) it('should render SendHeader and AddRecipient', function () { - assert.equal(wrapper.find(SendHeader).length, 1) - assert.equal(wrapper.find(AddRecipient).length, 1) + assert.strictEqual(wrapper.find(SendHeader).length, 1) + assert.strictEqual(wrapper.find(AddRecipient).length, 1) }) it('should pass the history prop to SendHeader and SendFooter', function () { wrapper.setProps({ to: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', }) - assert.equal(wrapper.find(SendHeader).length, 1) - assert.equal(wrapper.find(SendContent).length, 1) - assert.equal(wrapper.find(SendFooter).length, 1) - assert.deepEqual(wrapper.find(SendFooter).props(), { + assert.strictEqual(wrapper.find(SendHeader).length, 1) + assert.strictEqual(wrapper.find(SendContent).length, 1) + assert.strictEqual(wrapper.find(SendFooter).length, 1) + assert.deepStrictEqual(wrapper.find(SendFooter).props(), { history: { mockProp: 'history-abc' }, }) }) @@ -413,7 +422,7 @@ describe('Send Component', function () { wrapper.setProps({ to: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', }) - assert.equal(wrapper.find(SendContent).props().showHexData, true) + assert.strictEqual(wrapper.find(SendContent).props().showHexData, true) }) }) @@ -434,7 +443,7 @@ describe('Send Component', function () { '0x80F061544cC398520615B5d3e7A3BedD70cd4510', ) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', toError: null, @@ -449,7 +458,7 @@ describe('Send Component', function () { ) clock.tick(1001) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipient', @@ -465,7 +474,7 @@ describe('Send Component', function () { ) clock.tick(1001) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipientNotEthNetwork', @@ -481,7 +490,7 @@ describe('Send Component', function () { ) clock.tick(1001) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipientNotEthNetwork', @@ -489,7 +498,7 @@ describe('Send Component', function () { }) instance.onRecipientInputChange('') - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '', toError: '', @@ -505,7 +514,7 @@ describe('Send Component', function () { ) clock.tick(1001) - assert.deepEqual(instance.state, { + assert.deepStrictEqual(instance.state, { internalSearch: false, query: '0x13cb85823f78Cff38f0B0E90D3e975b8CB3AAd64', toError: null, diff --git a/ui/app/pages/send/tests/send-container.test.js b/ui/app/pages/send/tests/send-container.test.js index d6af26758..3a9f4a807 100644 --- a/ui/app/pages/send/tests/send-container.test.js +++ b/ui/app/pages/send/tests/send-container.test.js @@ -56,7 +56,7 @@ describe('send container', function () { it('should dispatch a setGasTotal action when editingTransactionId is truthy', function () { mapDispatchToPropsObject.updateAndSetGasLimit(mockProps) assert(dispatchSpy.calledOnce) - assert.equal(actionSpies.setGasTotal.getCall(0).args[0], '0x30x4') + assert.strictEqual(actionSpies.setGasTotal.getCall(0).args[0], '0x30x4') }) it('should dispatch an updateGasData action when editingTransactionId is falsy', function () { @@ -74,7 +74,7 @@ describe('send container', function () { editingTransactionId: false, }) assert(dispatchSpy.calledOnce) - assert.deepEqual(actionSpies.updateGasData.getCall(0).args[0], { + assert.deepStrictEqual(actionSpies.updateGasData.getCall(0).args[0], { gasPrice, selectedAddress, sendToken, @@ -96,7 +96,7 @@ describe('send container', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.updateSendTokenBalance({ ...mockProps }) assert(dispatchSpy.calledOnce) - assert.deepEqual( + assert.deepStrictEqual( actionSpies.updateSendTokenBalance.getCall(0).args[0], mockProps, ) @@ -107,7 +107,7 @@ describe('send container', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.updateSendErrors('mockError') assert(dispatchSpy.calledOnce) - assert.equal( + assert.strictEqual( duckActionSpies.updateSendErrors.getCall(0).args[0], 'mockError', ) @@ -118,7 +118,10 @@ describe('send container', function () { it('should dispatch an action', function () { mapDispatchToPropsObject.resetSendState() assert(dispatchSpy.calledOnce) - assert.equal(duckActionSpies.resetSendState.getCall(0).args.length, 0) + assert.strictEqual( + duckActionSpies.resetSendState.getCall(0).args.length, + 0, + ) }) }) }) diff --git a/ui/app/pages/send/tests/send-utils.test.js b/ui/app/pages/send/tests/send-utils.test.js index 9107dba46..853581e96 100644 --- a/ui/app/pages/send/tests/send-utils.test.js +++ b/ui/app/pages/send/tests/send-utils.test.js @@ -67,9 +67,9 @@ describe('send utils', function () { describe('calcGasTotal()', function () { it('should call multiplyCurrencies with the correct params and return the multiplyCurrencies return', function () { const result = calcGasTotal(12, 15) - assert.equal(result, '12x15') + assert.strictEqual(result, '12x15') const call_ = stubs.multiplyCurrencies.getCall(0).args - assert.deepEqual(call_, [ + assert.deepStrictEqual(call_, [ 12, 15, { @@ -112,14 +112,17 @@ describe('send utils', function () { } Object.entries(config).forEach(([description, obj]) => { it(description, function () { - assert.equal(doesAmountErrorRequireUpdate(obj), obj.expectedResult) + assert.strictEqual( + doesAmountErrorRequireUpdate(obj), + obj.expectedResult, + ) }) }) }) describe('generateTokenTransferData()', function () { it('should return undefined if not passed a send token', function () { - assert.equal( + assert.strictEqual( generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', @@ -136,14 +139,14 @@ describe('send utils', function () { amount: 'ab', sendToken: { address: '0x0' }, }) - assert.deepEqual(stubs.rawEncode.getCall(0).args, [ + assert.deepStrictEqual(stubs.rawEncode.getCall(0).args, [ ['address', 'uint256'], ['mockAddress', '0xab'], ]) }) it('should return encoded token transfer data', function () { - assert.equal( + assert.strictEqual( generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', @@ -189,7 +192,7 @@ describe('send utils', function () { } Object.entries(config).forEach(([description, obj]) => { it(description, function () { - assert.deepEqual(getAmountErrorObject(obj), obj.expectedResult) + assert.deepStrictEqual(getAmountErrorObject(obj), obj.expectedResult) }) }) }) @@ -213,14 +216,14 @@ describe('send utils', function () { } Object.entries(config).forEach(([description, obj]) => { it(description, function () { - assert.deepEqual(getGasFeeErrorObject(obj), obj.expectedResult) + assert.deepStrictEqual(getGasFeeErrorObject(obj), obj.expectedResult) }) }) }) describe('calcTokenBalance()', function () { it('should return the calculated token balance', function () { - assert.equal( + assert.strictEqual( calcTokenBalance({ sendToken: { address: '0x0', @@ -245,7 +248,7 @@ describe('send utils', function () { gasTotal: 17, primaryCurrency: 'ABC', }) - assert.deepEqual(stubs.addCurrencies.getCall(0).args, [ + assert.deepStrictEqual(stubs.addCurrencies.getCall(0).args, [ 15, 17, { @@ -254,7 +257,7 @@ describe('send utils', function () { toNumericBase: 'hex', }, ]) - assert.deepEqual(stubs.conversionGTE.getCall(0).args, [ + assert.deepStrictEqual(stubs.conversionGTE.getCall(0).args, [ { value: 100, fromNumericBase: 'hex', @@ -269,7 +272,7 @@ describe('send utils', function () { }, ]) - assert.equal(result, true) + assert.strictEqual(result, true) }) }) @@ -282,13 +285,13 @@ describe('send utils', function () { tokenBalance: 123, decimals: 10, }) - assert.deepEqual(stubs.conversionUtil.getCall(0).args, [ + assert.deepStrictEqual(stubs.conversionUtil.getCall(0).args, [ '0x10', { fromNumericBase: 'hex', }, ]) - assert.deepEqual(stubs.conversionGTE.getCall(0).args, [ + assert.deepStrictEqual(stubs.conversionGTE.getCall(0).args, [ { value: 123, fromNumericBase: 'hex', @@ -298,7 +301,7 @@ describe('send utils', function () { }, ]) - assert.equal(result, false) + assert.strictEqual(result, false) }) }) @@ -338,13 +341,16 @@ describe('send utils', function () { it('should call ethQuery.estimateGasForSend with the expected params', async function () { const result = await estimateGasForSend(baseMockParams) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual(baseMockParams.estimateGasMethod.getCall(0).args[0], { - gasPrice: undefined, - value: undefined, - ...baseExpectedCall, - }) - assert.equal(result, '0xabc16') + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepStrictEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + { + gasPrice: undefined, + value: undefined, + ...baseExpectedCall, + }, + ) + assert.strictEqual(result, '0xabc16') }) it('should call ethQuery.estimateGasForSend with the expected params when initialGasLimitHex is lower than the upperGasLimit', async function () { @@ -352,14 +358,17 @@ describe('send utils', function () { ...baseMockParams, blockGasLimit: '0xbcd', }) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual(baseMockParams.estimateGasMethod.getCall(0).args[0], { - gasPrice: undefined, - value: undefined, - ...baseExpectedCall, - gas: '0xbcdx0.95', - }) - assert.equal(result, '0xabc16x1.5') + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepStrictEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + { + gasPrice: undefined, + value: undefined, + ...baseExpectedCall, + gas: '0xbcdx0.95', + }, + ) + assert.strictEqual(result, '0xabc16x1.5') }) it('should call ethQuery.estimateGasForSend with a value of 0x0 and the expected data and to if passed a sendToken', async function () { @@ -368,55 +377,61 @@ describe('send utils', function () { sendToken: { address: 'mockAddress' }, ...baseMockParams, }) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual(baseMockParams.estimateGasMethod.getCall(0).args[0], { - ...baseExpectedCall, - gasPrice: undefined, - value: '0x0', - data: '0xa9059cbb104c', - to: 'mockAddress', - }) - assert.equal(result, '0xabc16') + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepStrictEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + { + ...baseExpectedCall, + gasPrice: undefined, + value: '0x0', + data: '0xa9059cbb104c', + to: 'mockAddress', + }, + ) + assert.strictEqual(result, '0xabc16') }) it('should call ethQuery.estimateGasForSend without a recipient if the recipient is empty and data passed', async function () { const data = 'mockData' const to = '' const result = await estimateGasForSend({ ...baseMockParams, data, to }) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual(baseMockParams.estimateGasMethod.getCall(0).args[0], { - gasPrice: undefined, - value: '0xff', - data, - from: baseExpectedCall.from, - gas: baseExpectedCall.gas, - }) - assert.equal(result, '0xabc16') + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepStrictEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + { + gasPrice: undefined, + value: '0xff', + data, + from: baseExpectedCall.from, + gas: baseExpectedCall.gas, + }, + ) + assert.strictEqual(result, '0xabc16') }) it(`should return ${SIMPLE_GAS_COST} if ethQuery.getCode does not return '0x'`, async function () { - assert.equal(baseMockParams.estimateGasMethod.callCount, 0) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) const result = await estimateGasForSend({ ...baseMockParams, to: '0x123', }) - assert.equal(result, SIMPLE_GAS_COST) + assert.strictEqual(result, SIMPLE_GAS_COST) }) it(`should return ${SIMPLE_GAS_COST} if not passed a sendToken or truthy to address`, async function () { - assert.equal(baseMockParams.estimateGasMethod.callCount, 0) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) const result = await estimateGasForSend({ ...baseMockParams, to: null }) - assert.equal(result, SIMPLE_GAS_COST) + assert.strictEqual(result, SIMPLE_GAS_COST) }) it(`should not return ${SIMPLE_GAS_COST} if passed a sendToken`, async function () { - assert.equal(baseMockParams.estimateGasMethod.callCount, 0) + assert.strictEqual(baseMockParams.estimateGasMethod.callCount, 0) const result = await estimateGasForSend({ ...baseMockParams, to: '0x123', sendToken: { address: '0x0' }, }) - assert.notEqual(result, SIMPLE_GAS_COST) + assert.notStrictEqual(result, SIMPLE_GAS_COST) }) it(`should return ${BASE_TOKEN_GAS_COST} if passed a sendToken but no to address`, async function () { @@ -425,7 +440,7 @@ describe('send utils', function () { to: null, sendToken: { address: '0x0' }, }) - assert.equal(result, BASE_TOKEN_GAS_COST) + assert.strictEqual(result, BASE_TOKEN_GAS_COST) }) it(`should return the adjusted blockGasLimit if it fails with a 'Transaction execution error.'`, async function () { @@ -433,7 +448,7 @@ describe('send utils', function () { ...baseMockParams, to: 'isContract willFailBecauseOf:Transaction execution error.', }) - assert.equal(result, '0x64x0.95') + assert.strictEqual(result, '0x64x0.95') }) it(`should return the adjusted blockGasLimit if it fails with a 'gas required exceeds allowance or always failing transaction.'`, async function () { @@ -442,7 +457,7 @@ describe('send utils', function () { to: 'isContract willFailBecauseOf:gas required exceeds allowance or always failing transaction.', }) - assert.equal(result, '0x64x0.95') + assert.strictEqual(result, '0x64x0.95') }) it(`should reject other errors`, async function () { @@ -452,44 +467,44 @@ describe('send utils', function () { to: 'isContract willFailBecauseOf:some other error', }) } catch (err) { - assert.equal(err.message, 'some other error') + assert.strictEqual(err.message, 'some other error') } }) }) describe('getToAddressForGasUpdate()', function () { it('should return empty string if all params are undefined or null', function () { - assert.equal(getToAddressForGasUpdate(undefined, null), '') + assert.strictEqual(getToAddressForGasUpdate(undefined, null), '') }) it('should return the first string that is not defined or null in lower case', function () { - assert.equal(getToAddressForGasUpdate('A', null), 'a') - assert.equal(getToAddressForGasUpdate(undefined, 'B'), 'b') + assert.strictEqual(getToAddressForGasUpdate('A', null), 'a') + assert.strictEqual(getToAddressForGasUpdate(undefined, 'B'), 'b') }) }) describe('removeLeadingZeroes()', function () { it('should remove leading zeroes from int when user types', function () { - assert.equal(removeLeadingZeroes('0'), '0') - assert.equal(removeLeadingZeroes('1'), '1') - assert.equal(removeLeadingZeroes('00'), '0') - assert.equal(removeLeadingZeroes('01'), '1') + assert.strictEqual(removeLeadingZeroes('0'), '0') + assert.strictEqual(removeLeadingZeroes('1'), '1') + assert.strictEqual(removeLeadingZeroes('00'), '0') + assert.strictEqual(removeLeadingZeroes('01'), '1') }) it('should remove leading zeroes from int when user copy/paste', function () { - assert.equal(removeLeadingZeroes('001'), '1') + assert.strictEqual(removeLeadingZeroes('001'), '1') }) it('should remove leading zeroes from float when user types', function () { - assert.equal(removeLeadingZeroes('0.'), '0.') - assert.equal(removeLeadingZeroes('0.0'), '0.0') - assert.equal(removeLeadingZeroes('0.00'), '0.00') - assert.equal(removeLeadingZeroes('0.001'), '0.001') - assert.equal(removeLeadingZeroes('0.10'), '0.10') + assert.strictEqual(removeLeadingZeroes('0.'), '0.') + assert.strictEqual(removeLeadingZeroes('0.0'), '0.0') + assert.strictEqual(removeLeadingZeroes('0.00'), '0.00') + assert.strictEqual(removeLeadingZeroes('0.001'), '0.001') + assert.strictEqual(removeLeadingZeroes('0.10'), '0.10') }) it('should remove leading zeroes from float when user copy/paste', function () { - assert.equal(removeLeadingZeroes('00.1'), '0.1') + assert.strictEqual(removeLeadingZeroes('00.1'), '0.1') }) }) }) diff --git a/ui/app/pages/settings/advanced-tab/advanced-tab.component.js b/ui/app/pages/settings/advanced-tab/advanced-tab.component.js index 0b3a17491..25aefece0 100644 --- a/ui/app/pages/settings/advanced-tab/advanced-tab.component.js +++ b/ui/app/pages/settings/advanced-tab/advanced-tab.component.js @@ -24,8 +24,6 @@ export default class AdvancedTab extends PureComponent { sendHexData: PropTypes.bool, setAdvancedInlineGasFeatureFlag: PropTypes.func, advancedInlineGas: PropTypes.bool, - setTransactionTimeFeatureFlag: PropTypes.func, - transactionTime: PropTypes.bool, showFiatInTestnets: PropTypes.bool, autoLockTimeLimit: PropTypes.number, setAutoLockTimeLimit: PropTypes.func.isRequired, @@ -211,35 +209,6 @@ export default class AdvancedTab extends PureComponent { ) } - renderTransactionTimeEstimates() { - const { t } = this.context - const { transactionTime, setTransactionTimeFeatureFlag } = this.props - - return ( -
-
- {t('transactionTime')} -
- {t('showTransactionTimeDescription')} -
-
-
-
- setTransactionTimeFeatureFlag(!value)} - offLabel={t('off')} - onLabel={t('on')} - /> -
-
-
- ) - } - renderShowConversionInTestnets() { const { t } = this.context const { @@ -503,7 +472,6 @@ export default class AdvancedTab extends PureComponent { {this.renderMobileSync()} {this.renderResetAccount()} {this.renderAdvancedGasInputInline()} - {this.renderTransactionTimeEstimates()} {this.renderHexDataOptIn()} {this.renderShowConversionInTestnets()} {this.renderUseNonceOptIn()} diff --git a/ui/app/pages/settings/advanced-tab/advanced-tab.container.js b/ui/app/pages/settings/advanced-tab/advanced-tab.container.js index 704af8312..fc4fd8db1 100644 --- a/ui/app/pages/settings/advanced-tab/advanced-tab.container.js +++ b/ui/app/pages/settings/advanced-tab/advanced-tab.container.js @@ -21,7 +21,7 @@ export const mapStateToProps = (state) => { metamask, } = state const { - featureFlags: { sendHexData, transactionTime, advancedInlineGas } = {}, + featureFlags: { sendHexData, advancedInlineGas } = {}, threeBoxSyncingAllowed, threeBoxDisabled, useNonceField, @@ -33,7 +33,6 @@ export const mapStateToProps = (state) => { warning, sendHexData, advancedInlineGas, - transactionTime, showFiatInTestnets, autoLockTimeLimit, threeBoxSyncingAllowed, @@ -52,8 +51,6 @@ export const mapDispatchToProps = (dispatch) => { dispatch(showModal({ name: 'CONFIRM_RESET_ACCOUNT' })), setAdvancedInlineGasFeatureFlag: (shouldShow) => dispatch(setFeatureFlag('advancedInlineGas', shouldShow)), - setTransactionTimeFeatureFlag: (shouldShow) => - dispatch(setFeatureFlag('transactionTime', shouldShow)), setUseNonceField: (value) => dispatch(setUseNonceField(value)), setShowFiatConversionOnTestnetsPreference: (value) => { return dispatch(setShowFiatConversionOnTestnetsPreference(value)) diff --git a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js b/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js index 548623187..024702ae3 100644 --- a/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js +++ b/ui/app/pages/settings/advanced-tab/tests/advanced-tab-component.test.js @@ -24,7 +24,7 @@ describe('AdvancedTab Component', function () { }, ) - assert.equal(root.find('.settings-page__content-row').length, 11) + assert.strictEqual(root.find('.settings-page__content-row').length, 10) }) it('should update autoLockTimeLimit', function () { @@ -46,13 +46,13 @@ describe('AdvancedTab Component', function () { }, ) - const autoTimeout = root.find('.settings-page__content-row').at(8) + const autoTimeout = root.find('.settings-page__content-row').at(7) const textField = autoTimeout.find(TextField) textField.props().onChange({ target: { value: 1440 } }) - assert.equal(root.state().autoLockTimeLimit, 1440) + assert.strictEqual(root.state().autoLockTimeLimit, 1440) autoTimeout.find('.settings-tab__rpc-save-button').simulate('click') - assert.equal(setAutoLockTimeLimitSpy.args[0][0], 1440) + assert.strictEqual(setAutoLockTimeLimitSpy.args[0][0], 1440) }) }) diff --git a/ui/app/pages/settings/security-tab/tests/security-tab.test.js b/ui/app/pages/settings/security-tab/tests/security-tab.test.js index d15328d85..d45a47d35 100644 --- a/ui/app/pages/settings/security-tab/tests/security-tab.test.js +++ b/ui/app/pages/settings/security-tab/tests/security-tab.test.js @@ -37,7 +37,7 @@ describe('Security Tab', function () { seedWords.simulate('click') assert(props.history.push.calledOnce) - assert.equal(props.history.push.getCall(0).args[0], '/seed') + assert.strictEqual(props.history.push.getCall(0).args[0], '/seed') }) it('toggles incoming txs', function () { diff --git a/ui/app/pages/swaps/actionable-message/actionable-message.stories.js b/ui/app/pages/swaps/actionable-message/actionable-message.stories.js index 8aabbc235..66ab6031d 100644 --- a/ui/app/pages/swaps/actionable-message/actionable-message.stories.js +++ b/ui/app/pages/swaps/actionable-message/actionable-message.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import ActionableMessage from '.' export default { diff --git a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js index 573bce37a..5a35c724e 100644 --- a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js @@ -1,8 +1,7 @@ import EventEmitter from 'events' -import React, { useContext, useRef, useState, useEffect } from 'react' +import React, { useContext, useRef, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import PropTypes from 'prop-types' -import classnames from 'classnames' import { useHistory } from 'react-router-dom' import { I18nContext } from '../../../contexts/i18n' import { useNewMetricEvent } from '../../../hooks/useMetricEvent' @@ -18,15 +17,9 @@ import { prepareForRetryGetQuotes, prepareToLeaveSwaps, } from '../../../ducks/swaps/swaps' -import { useTransactionTimeRemaining } from '../../../hooks/useTransactionTimeRemaining' -import { usePrevious } from '../../../hooks/usePrevious' import Mascot from '../../../components/ui/mascot' import PulseLoader from '../../../components/ui/pulse-loader' -import { - getBlockExplorerUrlForTx, - getStatusKey, -} from '../../../helpers/utils/transactions.util' -import CountdownTimer from '../countdown-timer' +import { getBlockExplorerUrlForTx } from '../../../helpers/utils/transactions.util' import { QUOTES_EXPIRED_ERROR, SWAP_FAILED_ERROR, @@ -38,7 +31,6 @@ import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes' import { getRenderableNetworkFeesForQuote } from '../swaps.util' import SwapsFooter from '../swaps-footer' -import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction' import SwapFailureIcon from './swap-failure-icon' import SwapSuccessIcon from './swap-success-icon' import QuotesTimeoutIcon from './quotes-timeout-icon' @@ -52,8 +44,6 @@ export default function AwaitingSwap({ tokensReceived, rpcPrefs, submittingSwap, - tradeTxData, - usedGasPrice, inputValue, maxSlippage, }) { @@ -71,7 +61,6 @@ export default function AwaitingSwap({ const currentCurrency = useSelector(getCurrentCurrency) const usdConversionRate = useSelector(getUSDConversionRate) - const [timeRemainingExpired, setTimeRemainingExpired] = useState(false) const [trackedQuotesExpiredEvent, setTrackedQuotesExpiredEvent] = useState( false, ) @@ -109,56 +98,6 @@ export default function AwaitingSwap({ const blockExplorerUrl = txHash && getBlockExplorerUrlForTx(networkId, txHash, rpcPrefs) - const statusKey = tradeTxData && getStatusKey(tradeTxData) - const timeRemaining = useTransactionTimeRemaining( - statusKey === TRANSACTION_STATUSES.SUBMITTED, - true, - tradeTxData?.submittedTime, - usedGasPrice, - true, - true, - ) - const previousTimeRemaining = usePrevious(timeRemaining) - const timeRemainingIsNumber = - typeof timeRemaining === 'number' && !isNaN(timeRemaining) - const previousTimeRemainingIsNumber = - typeof previousTimeRemaining === 'number' && !isNaN(previousTimeRemaining) - const estimatedTransactionWaitTime = timeRemaining * 1000 * 60 - - useEffect(() => { - if ( - !timeRemainingIsNumber && - previousTimeRemainingIsNumber && - !timeRemainingExpired - ) { - setTimeRemainingExpired(true) - } - }, [ - timeRemainingIsNumber, - previousTimeRemainingIsNumber, - timeRemainingExpired, - ]) - - let countdownText - if ( - timeRemainingIsNumber && - !timeRemainingExpired && - tradeTxData?.submittedTime - ) { - countdownText = ( - - ) - } else if (tradeTxData?.submittedTime) { - countdownText = t('swapsAlmostDone') - } else { - countdownText = t('swapEstimatedTimeCalculating') - } - let headerText let statusImage let descriptionText @@ -203,13 +142,6 @@ export default function AwaitingSwap({ submitText = t('tryAgain') statusImage = } else if (!errorKey && !swapComplete) { - /** - * only show estimated time if the transaction has a submitted time, the swap has - * not yet completed and there isn't an error. If the swap has not completed and - * there is no error, but also has no submitted time (has not yet been published), - * then we apply the invisible class to the time estimate div. This creates consistent - * spacing before and after display of the time estimate. - */ headerText = t('swapProcessing') statusImage = submitText = t('swapsViewInActivity') @@ -221,31 +153,12 @@ export default function AwaitingSwap({ {destinationTokenInfo.symbol} , ]) - content = ( - <> -
- {t('swapEstimatedTimeFull', [ - - {t('swapEstimatedTime')} - , - countdownText, - ])} -
- {blockExplorerUrl && ( - - )} - + content = blockExplorerUrl && ( + ) } else if (!errorKey && swapComplete) { headerText = t('swapTransactionComplete') @@ -329,8 +242,6 @@ AwaitingSwap.propTypes = { OFFLINE_FOR_MAINTENANCE, ]), submittingSwap: PropTypes.bool, - tradeTxData: PropTypes.object, - usedGasPrice: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), inputValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), maxSlippage: PropTypes.number, } diff --git a/ui/app/pages/swaps/build-quote/build-quote.stories.js b/ui/app/pages/swaps/build-quote/build-quote.stories.js index 8daffe17f..9a6eaf221 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.stories.js +++ b/ui/app/pages/swaps/build-quote/build-quote.stories.js @@ -1,6 +1,6 @@ import React, { useState } from 'react' import { action } from '@storybook/addon-actions' -import { boolean } from '@storybook/addon-knobs/react' +import { boolean } from '@storybook/addon-knobs' import DropdownInputPair from '../dropdown-input-pair' import DropdownSearchList from '../dropdown-search-list' diff --git a/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js b/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js index 276ab01d4..6970a045a 100644 --- a/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js +++ b/ui/app/pages/swaps/countdown-timer/countdown-timer.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { number } from '@storybook/addon-knobs/react' +import { number } from '@storybook/addon-knobs' import CountdownTimer from './countdown-timer' export default { diff --git a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js index ff939f121..b28fa3772 100644 --- a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js +++ b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text, number } from '@storybook/addon-knobs/react' +import { text, number } from '@storybook/addon-knobs' import ExchangeRateDisplay from './exchange-rate-display' export default { diff --git a/ui/app/pages/swaps/fee-card/fee-card.stories.js b/ui/app/pages/swaps/fee-card/fee-card.stories.js index 6b316caab..af57849f3 100644 --- a/ui/app/pages/swaps/fee-card/fee-card.stories.js +++ b/ui/app/pages/swaps/fee-card/fee-card.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { text } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs' import FeeCard from './fee-card' const tokenApprovalTextComponent = ( diff --git a/ui/app/pages/swaps/index.js b/ui/app/pages/swaps/index.js index f41aef9d6..1d340a61e 100644 --- a/ui/app/pages/swaps/index.js +++ b/ui/app/pages/swaps/index.js @@ -22,7 +22,6 @@ import { getFetchingQuotes, setBalanceError, setTopAssets, - getUsedSwapsGasPrice, getFetchParams, setAggregatorMetadata, getAggregatorMetadata, @@ -94,7 +93,6 @@ export default function Swap() { const [maxSlippage, setMaxSlippage] = useState(fetchParams?.slippage || 2) const routeState = useSelector(getBackgroundSwapRouteState) - const usedGasPrice = useSelector(getUsedSwapsGasPrice) const selectedAccount = useSelector(getSelectedAccount) const quotes = useSelector(getQuotes) const txList = useSelector(currentNetworkTxListSelector) @@ -397,8 +395,6 @@ export default function Swap() { networkId={networkId} txHash={tradeTxData?.hash} tokensReceived={tokensReceived} - tradeTxData={tradeTxData} - usedGasPrice={usedGasPrice} submittingSwap={ routeState === 'awaiting' && !(approveTxId || tradeTxId) } diff --git a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js index f6c1ffeb2..ea267eb17 100644 --- a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js +++ b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text, number, boolean } from '@storybook/addon-knobs/react' +import { text, number, boolean } from '@storybook/addon-knobs' import MainQuoteSummary from './main-quote-summary' export default { diff --git a/ui/app/pages/swaps/select-quote-popover/select-quote-popover.stories.js b/ui/app/pages/swaps/select-quote-popover/select-quote-popover.stories.js index b033e34ed..61693839f 100644 --- a/ui/app/pages/swaps/select-quote-popover/select-quote-popover.stories.js +++ b/ui/app/pages/swaps/select-quote-popover/select-quote-popover.stories.js @@ -1,6 +1,6 @@ import React, { useState } from 'react' import { action } from '@storybook/addon-actions' -import { object } from '@storybook/addon-knobs/react' +import { object } from '@storybook/addon-knobs' import Button from '../../../components/ui/button' import mockQuoteData from './mock-quote-data' import SelectQuotePopover from '.' diff --git a/ui/app/pages/swaps/swaps-footer/swaps-footer.js b/ui/app/pages/swaps/swaps-footer/swaps-footer.js index c158c21fb..870ce028b 100644 --- a/ui/app/pages/swaps/swaps-footer/swaps-footer.js +++ b/ui/app/pages/swaps/swaps-footer/swaps-footer.js @@ -13,13 +13,14 @@ export default function SwapsFooter({ disabled, showTermsOfService, showTopBorder, + className = '', }) { const t = useContext(I18nContext) return (
@@ -62,4 +63,5 @@ SwapsFooter.propTypes = { disabled: PropTypes.bool, showTermsOfService: PropTypes.bool, showTopBorder: PropTypes.bool, + className: PropTypes.string, } diff --git a/ui/app/pages/swaps/swaps.util.test.js b/ui/app/pages/swaps/swaps.util.test.js index edb9bcd2c..77bab1905 100644 --- a/ui/app/pages/swaps/swaps.util.test.js +++ b/ui/app/pages/swaps/swaps.util.test.js @@ -14,24 +14,24 @@ import { const swapsUtils = proxyquire('./swaps.util.js', { '../../helpers/utils/fetch-with-cache': { default: (url, fetchObject) => { - assert.equal(fetchObject.method, 'GET') + assert.strictEqual(fetchObject.method, 'GET') if (url.match(TRADES_BASE_PROD_URL)) { - assert.equal( + assert.strictEqual( url, 'https://api.metaswap.codefi.network/trades?destinationToken=0xE41d2489571d322189246DaFA5ebDe1F4699F498&sourceToken=0x617b3f8050a0BD94b6b1da02B4384eE5B4DF13F4&sourceAmount=2000000000000000000000000000000000000&slippage=3&timeout=10000&walletAddress=0xmockAddress', ) return Promise.resolve(MOCK_TRADE_RESPONSE_2) } if (url.match(TOKENS_BASE_PROD_URL)) { - assert.equal(url, TOKENS_BASE_PROD_URL) + assert.strictEqual(url, TOKENS_BASE_PROD_URL) return Promise.resolve(TOKENS) } if (url.match(AGGREGATOR_METADATA_BASE_PROD_URL)) { - assert.equal(url, AGGREGATOR_METADATA_BASE_PROD_URL) + assert.strictEqual(url, AGGREGATOR_METADATA_BASE_PROD_URL) return Promise.resolve(AGGREGATOR_METADATA) } if (url.match(TOP_ASSET_BASE_PROD_URL)) { - assert.equal(url, TOP_ASSET_BASE_PROD_URL) + assert.strictEqual(url, TOP_ASSET_BASE_PROD_URL) return Promise.resolve(TOP_ASSETS) } return Promise.resolve() @@ -100,31 +100,31 @@ describe('Swaps Util', function () { sourceTokenInfo: { ...TOKENS[0] }, destinationTokenInfo: { ...TOKENS[1] }, }) - assert.deepEqual(result, expectedResult2) + assert.deepStrictEqual(result, expectedResult2) }) }) describe('fetchTokens', function () { it('should fetch tokens', async function () { const result = await fetchTokens(true) - assert.deepEqual(result, TOKENS) + assert.deepStrictEqual(result, TOKENS) }) it('should fetch tokens on prod', async function () { const result = await fetchTokens(false) - assert.deepEqual(result, TOKENS) + assert.deepStrictEqual(result, TOKENS) }) }) describe('fetchAggregatorMetadata', function () { it('should fetch aggregator metadata', async function () { const result = await fetchAggregatorMetadata(true) - assert.deepEqual(result, AGGREGATOR_METADATA) + assert.deepStrictEqual(result, AGGREGATOR_METADATA) }) it('should fetch aggregator metadata on prod', async function () { const result = await fetchAggregatorMetadata(false) - assert.deepEqual(result, AGGREGATOR_METADATA) + assert.deepStrictEqual(result, AGGREGATOR_METADATA) }) }) @@ -148,12 +148,12 @@ describe('Swaps Util', function () { } it('should fetch top assets', async function () { const result = await fetchTopAssets(true) - assert.deepEqual(result, expectedResult) + assert.deepStrictEqual(result, expectedResult) }) it('should fetch top assets on prod', async function () { const result = await fetchTopAssets(false) - assert.deepEqual(result, expectedResult) + assert.deepStrictEqual(result, expectedResult) }) }) }) diff --git a/ui/app/pages/swaps/view-quote/index.scss b/ui/app/pages/swaps/view-quote/index.scss index 1b76853fb..474eced60 100644 --- a/ui/app/pages/swaps/view-quote/index.scss +++ b/ui/app/pages/swaps/view-quote/index.scss @@ -86,14 +86,60 @@ }; } - &__insufficient-eth-warning-wrapper { - margin-top: 8px; + &__price-difference-warning { + &-wrapper { + width: 100%; + + &.medium .actionable-message, + &.fiat-error .actionable-message { + border-color: $Yellow-500; + background: $Yellow-100; + + .actionable-message__message { + color: inherit; + } + } + + &.high .actionable-message { + border-color: $Red-500; + background: $Red-100; + + .actionable-message__message { + color: $Red-500; + } + } + + /* Hides info tooltip if there's a fiat error message */ + &.fiat-error div[data-tooltipped] { + /* !important overrides style being applied directly to tooltip by component */ + display: none !important; + } + } + + &-contents { + display: flex; + + &-title { + font-weight: bold; + } + + i { + margin-inline-start: 10px; + } + } + } + + &__warning-wrapper { width: 100%; align-items: center; justify-content: center; + margin-top: 8px; @media screen and (min-width: 576px) { - min-height: 36px; + &--thin { + min-height: 36px; + } + display: flex; } } @@ -165,4 +211,8 @@ &__metamask-rate-info-icon { margin-left: 4px; } + + &__thin-swaps-footer { + max-height: 82px; + } } diff --git a/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js b/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js new file mode 100644 index 000000000..d32cc5759 --- /dev/null +++ b/ui/app/pages/swaps/view-quote/tests/view-quote-price-difference.test.js @@ -0,0 +1,149 @@ +import assert from 'assert' +import React from 'react' +import { shallow } from 'enzyme' +import { Provider } from 'react-redux' +import configureMockStore from 'redux-mock-store' +import ViewQuotePriceDifference from '../view-quote-price-difference' + +describe('View Price Quote Difference', function () { + const t = (key) => `translate ${key}` + + const state = { + metamask: { + tokens: [], + provider: { type: 'rpc', nickname: '', rpcUrl: '' }, + preferences: { showFiatInTestnets: true }, + currentCurrency: 'usd', + conversionRate: 600.0, + }, + } + + const store = configureMockStore()(state) + + // Sample transaction is 1 $ETH to ~42.880915 $LINK + const DEFAULT_PROPS = { + usedQuote: { + trade: { + data: + '0x5f575529000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000007756e69737761700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca0000000000000000000000000000000000000000000000000dc1a09f859b20000000000000000000000000000000000000000000000000024855454cb32d335f0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000005fc7b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f161421c8e0000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca', + from: '0xd7440fdcb70a9fba55dfe06942ddbc17679c90ac', + value: '0xde0b6b3a7640000', + gas: '0xbbfd0', + to: '0x881D40237659C251811CEC9c364ef91dC08D300C', + }, + sourceAmount: '1000000000000000000', + destinationAmount: '42947749216634160067', + error: null, + sourceToken: '0x0000000000000000000000000000000000000000', + destinationToken: '0x514910771af9ca656af840dff83e8264ecf986ca', + approvalNeeded: null, + maxGas: 770000, + averageGas: 210546, + estimatedRefund: 80000, + fetchTime: 647, + aggregator: 'uniswap', + aggType: 'DEX', + fee: 0.875, + gasMultiplier: 1.5, + priceSlippage: { + ratio: 1.007876641534847, + calculationError: '', + bucket: 'low', + sourceAmountInETH: 1, + destinationAmountInEth: 0.9921849150875727, + }, + slippage: 2, + sourceTokenInfo: { + symbol: 'ETH', + name: 'Ether', + address: '0x0000000000000000000000000000000000000000', + decimals: 18, + iconUrl: 'images/black-eth-logo.svg', + }, + destinationTokenInfo: { + address: '0x514910771af9ca656af840dff83e8264ecf986ca', + symbol: 'LINK', + decimals: 18, + occurances: 12, + iconUrl: + 'https://cloudflare-ipfs.com/ipfs/QmQhZAdcZvW9T2tPm516yHqbGkfhyZwTZmLixW9MXJudTA', + }, + ethFee: '0.011791', + ethValueOfTokens: '0.99220724791716534441', + overallValueOfQuote: '0.98041624791716534441', + metaMaskFeeInEth: '0.00875844985551091729', + isBestQuote: true, + savings: { + performance: '0.00207907025112527799', + fee: '0.005581', + metaMaskFee: '0.00875844985551091729', + total: '-0.0010983796043856393', + medianMetaMaskFee: '0.00874009740688812165', + }, + }, + sourceTokenValue: '1', + destinationTokenValue: '42.947749', + } + + let component + function renderComponent(props) { + component = shallow( + + + , + { + context: { t }, + }, + ) + } + + afterEach(function () { + component.unmount() + }) + + it('does not render when there is no quote', function () { + const props = { ...DEFAULT_PROPS, usedQuote: null } + renderComponent(props) + + const wrappingDiv = component.find( + '.view-quote__price-difference-warning-wrapper', + ) + assert.strictEqual(wrappingDiv.length, 0) + }) + + it('does not render when the item is in the low bucket', function () { + const props = { ...DEFAULT_PROPS } + props.usedQuote.priceSlippage.bucket = 'low' + + renderComponent(props) + const wrappingDiv = component.find( + '.view-quote__price-difference-warning-wrapper', + ) + assert.strictEqual(wrappingDiv.length, 0) + }) + + it('displays an error when in medium bucket', function () { + const props = { ...DEFAULT_PROPS } + props.usedQuote.priceSlippage.bucket = 'medium' + + renderComponent(props) + assert.strictEqual(component.html().includes('medium'), true) + }) + + it('displays an error when in high bucket', function () { + const props = { ...DEFAULT_PROPS } + props.usedQuote.priceSlippage.bucket = 'high' + + renderComponent(props) + assert.strictEqual(component.html().includes('high'), true) + }) + + it('displays a fiat error when calculationError is present', function () { + const props = { ...DEFAULT_PROPS } + props.usedQuote.priceSlippage.calculationError = + 'Could not determine price.' + + renderComponent(props) + assert.strictEqual(component.html().includes('fiat-error'), true) + }) +}) diff --git a/ui/app/pages/swaps/view-quote/view-quote-price-difference.js b/ui/app/pages/swaps/view-quote/view-quote-price-difference.js new file mode 100644 index 000000000..5a3be3cac --- /dev/null +++ b/ui/app/pages/swaps/view-quote/view-quote-price-difference.js @@ -0,0 +1,114 @@ +import React, { useContext } from 'react' + +import PropTypes from 'prop-types' +import classnames from 'classnames' +import BigNumber from 'bignumber.js' +import { useEthFiatAmount } from '../../../hooks/useEthFiatAmount' +import { I18nContext } from '../../../contexts/i18n' + +import ActionableMessage from '../actionable-message' +import Tooltip from '../../../components/ui/tooltip' + +export default function ViewQuotePriceDifference(props) { + const { usedQuote, sourceTokenValue, destinationTokenValue } = props + + const t = useContext(I18nContext) + + const priceSlippageFromSource = useEthFiatAmount( + usedQuote?.priceSlippage?.sourceAmountInETH || 0, + ) + const priceSlippageFromDestination = useEthFiatAmount( + usedQuote?.priceSlippage?.destinationAmountInEth || 0, + ) + + if (!usedQuote || !usedQuote.priceSlippage) { + return null + } + + const { priceSlippage } = usedQuote + + // We cannot present fiat value if there is a calculation error or no slippage + // from source or destination + const priceSlippageUnknownFiatValue = + !priceSlippageFromSource || + !priceSlippageFromDestination || + priceSlippage.calculationError + + let priceDifferencePercentage = 0 + if (priceSlippage.ratio) { + priceDifferencePercentage = parseFloat( + new BigNumber(priceSlippage.ratio, 10) + .minus(1, 10) + .times(100, 10) + .toFixed(2), + 10, + ) + } + + const shouldShowPriceDifferenceWarning = + ['high', 'medium'].includes(priceSlippage.bucket) || + priceSlippageUnknownFiatValue + + if (!shouldShowPriceDifferenceWarning) { + return null + } + + let priceDifferenceTitle = '' + let priceDifferenceMessage = '' + let priceDifferenceClass = '' + if (priceSlippageUnknownFiatValue) { + // A calculation error signals we cannot determine dollar value + priceDifferenceMessage = t('swapPriceDifferenceUnavailable') + priceDifferenceClass = 'fiat-error' + } else { + priceDifferenceTitle = t('swapPriceDifferenceTitle', [ + priceDifferencePercentage, + ]) + priceDifferenceMessage = t('swapPriceDifference', [ + sourceTokenValue, // Number of source token to swap + usedQuote.sourceTokenInfo.symbol, // Source token symbol + priceSlippageFromSource, // Source tokens total value + destinationTokenValue, // Number of destination tokens in return + usedQuote.destinationTokenInfo.symbol, // Destination token symbol, + priceSlippageFromDestination, // Destination tokens total value + ]) + priceDifferenceClass = priceSlippage.bucket + } + + return ( +
+ +
+ {priceDifferenceTitle && ( +
+ {priceDifferenceTitle} +
+ )} + {priceDifferenceMessage} +
+ + + +
+ } + /> +
+ ) +} + +ViewQuotePriceDifference.propTypes = { + usedQuote: PropTypes.object, + sourceTokenValue: PropTypes.string, + destinationTokenValue: PropTypes.string, +} diff --git a/ui/app/pages/swaps/view-quote/view-quote.js b/ui/app/pages/swaps/view-quote/view-quote.js index 8528a38b3..4db97824f 100644 --- a/ui/app/pages/swaps/view-quote/view-quote.js +++ b/ui/app/pages/swaps/view-quote/view-quote.js @@ -74,6 +74,7 @@ import { QUOTES_EXPIRED_ERROR } from '../../../helpers/constants/swaps' import CountdownTimer from '../countdown-timer' import SwapsFooter from '../swaps-footer' import InfoTooltip from '../../../components/ui/info-tooltip' +import ViewQuotePriceDifference from './view-quote-price-difference' export default function ViewQuote() { const history = useHistory() @@ -279,7 +280,7 @@ export default function ViewQuote() { } }, [originalApproveAmount, approveAmount]) - const showWarning = + const showInsufficientWarning = (balanceError || tokenBalanceNeeded || ethBalanceNeeded) && !warningHidden const numberOfQuotes = Object.values(quotes).length @@ -452,7 +453,7 @@ export default function ViewQuote() { ) - const actionableMessage = t('swapApproveNeedMoreTokens', [ + const actionableInsufficientMessage = t('swapApproveNeedMoreTokens', [ {tokenBalanceNeeded || ethBalanceNeeded} , @@ -461,6 +462,17 @@ export default function ViewQuote() { : 'ETH', ]) + const viewQuotePriceDifferenceComponent = ( + + ) + + const isShowingWarning = + showInsufficientWarning || viewQuotePriceDifferenceComponent !== null + return (
@@ -474,17 +486,22 @@ export default function ViewQuote() { onQuoteDetailsIsOpened={quoteDetailsOpened} /> )} -
- {showWarning && ( +
+ {!showInsufficientWarning && viewQuotePriceDifferenceComponent} + {showInsufficientWarning && ( setWarningHidden(true)} /> )}
await dispatch(navigateBackToBuildQuote(history))} disabled={balanceError || gasPrice === null || gasPrice === undefined} + className={isShowingWarning && 'view-quote__thin-swaps-footer'} showTermsOfService showTopBorder /> diff --git a/ui/app/pages/unlock-page/tests/unlock-page.test.js b/ui/app/pages/unlock-page/tests/unlock-page.test.js index 9e5d4266b..34b258469 100644 --- a/ui/app/pages/unlock-page/tests/unlock-page.test.js +++ b/ui/app/pages/unlock-page/tests/unlock-page.test.js @@ -32,7 +32,7 @@ describe('Unlock Page', function () { }) it('renders', function () { - assert.equal(wrapper.length, 1) + assert.strictEqual(wrapper.length, 1) }) it('changes password and submits', function () { @@ -40,9 +40,9 @@ describe('Unlock Page', function () { const loginButton = wrapper.find({ type: 'submit' }).last() const event = { target: { value: 'password' } } - assert.equal(wrapper.instance().state.password, '') + assert.strictEqual(wrapper.instance().state.password, '') passwordField.last().simulate('change', event) - assert.equal(wrapper.instance().state.password, 'password') + assert.strictEqual(wrapper.instance().state.password, 'password') loginButton.simulate('click') assert(props.onSubmit.calledOnce) diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 6f5096700..8b1df8b89 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -1,7 +1,6 @@ import { addHexPrefix } from '../../../app/scripts/lib/util' import { conversionUtil, - multiplyCurrencies, conversionGreaterThan, } from '../helpers/utils/conversion-util' import { formatCurrency } from '../helpers/utils/confirm-tx.util' @@ -14,10 +13,6 @@ import { getCurrentCurrency, getIsMainnet, getPreferences } from '.' const NUMBER_OF_DECIMALS_SM_BTNS = 5 -export function getCustomGasErrors(state) { - return state.gas.errors -} - export function getCustomGasLimit(state) { return state.gas.customData.limit } @@ -26,30 +21,10 @@ export function getCustomGasPrice(state) { return state.gas.customData.price } -export function getCustomGasTotal(state) { - return state.gas.customData.total -} - export function getBasicGasEstimateLoadingStatus(state) { return state.gas.basicEstimateIsLoading } -export function getGasEstimatesLoadingStatus(state) { - return state.gas.gasEstimatesLoading -} - -export function getPriceAndTimeEstimates(state) { - return state.gas.priceAndTimeEstimates -} - -export function getEstimatedGasPrices(state) { - return getPriceAndTimeEstimates(state).map(({ gasprice }) => gasprice) -} - -export function getEstimatedGasTimes(state) { - return getPriceAndTimeEstimates(state).map(({ expectedTime }) => expectedTime) -} - export function getAveragePriceEstimateInHexWEI(state) { const averagePriceEstimate = state.gas.basicEstimates.average return getGasPriceInHexWei(averagePriceEstimate || '0x0') @@ -106,10 +81,6 @@ export function isCustomPriceSafe(state) { return customPriceSafe } -export function getBasicGasEstimateBlockTime(state) { - return state.gas.basicEstimates.blockTime -} - export function basicPriceEstimateToETHTotal( estimate, gasLimit, @@ -151,44 +122,6 @@ export function getRenderableConvertedCurrencyFee( return formatCurrency(feeInCurrency, convertedCurrency) } -export function getTimeEstimateInSeconds(blockWaitEstimate) { - return multiplyCurrencies(blockWaitEstimate, 60, { - toNumericBase: 'dec', - multiplicandBase: 10, - multiplierBase: 10, - numberOfDecimals: 1, - }) -} - -export function formatTimeEstimate(totalSeconds, greaterThanMax, lessThanMin) { - const minutes = Math.floor(totalSeconds / 60) - const seconds = Math.floor(totalSeconds % 60) - - if (!minutes && !seconds) { - return '...' - } - - let symbol = '~' - if (greaterThanMax) { - symbol = '< ' - } else if (lessThanMin) { - symbol = '> ' - } - - const formattedMin = `${minutes ? `${minutes} min` : ''}` - const formattedSec = `${seconds ? `${seconds} sec` : ''}` - const formattedCombined = - formattedMin && formattedSec - ? `${symbol}${formattedMin} ${formattedSec}` - : symbol + [formattedMin, formattedSec].find((t) => t) - - return formattedCombined -} - -export function getRenderableTimeEstimate(blockWaitEstimate) { - return formatTimeEstimate(getTimeEstimateInSeconds(blockWaitEstimate)) -} - export function priceEstimateToWei(priceEstimate) { return conversionUtil(priceEstimate, { fromNumericBase: 'hex', @@ -214,16 +147,7 @@ export function getRenderableGasButtonData( conversionRate, currentCurrency, ) { - const { - safeLow, - average, - fast, - safeLowWait, - avgWait, - fastWait, - fastest, - fastestWait, - } = estimates + const { safeLow, average, fast } = estimates const slowEstimateData = { gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, @@ -236,7 +160,6 @@ export function getRenderableGasButtonData( conversionRate, ) : '', - timeEstimate: safeLowWait && getRenderableTimeEstimate(safeLowWait), priceInHexWei: getGasPriceInHexWei(safeLow), } const averageEstimateData = { @@ -250,7 +173,6 @@ export function getRenderableGasButtonData( conversionRate, ) : '', - timeEstimate: avgWait && getRenderableTimeEstimate(avgWait), priceInHexWei: getGasPriceInHexWei(average), } const fastEstimateData = { @@ -264,29 +186,13 @@ export function getRenderableGasButtonData( conversionRate, ) : '', - timeEstimate: fastWait && getRenderableTimeEstimate(fastWait), priceInHexWei: getGasPriceInHexWei(fast), } - const fastestEstimateData = { - gasEstimateType: GAS_ESTIMATE_TYPES.FASTEST, - feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit), - feeInSecondaryCurrency: showFiat - ? getRenderableConvertedCurrencyFee( - fastest, - gasLimit, - currentCurrency, - conversionRate, - ) - : '', - timeEstimate: fastestWait && getRenderableTimeEstimate(fastestWait), - priceInHexWei: getGasPriceInHexWei(fastest), - } return { slowEstimateData, averageEstimateData, fastEstimateData, - fastestEstimateData, } } diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 8eff1b6e6..d9fd7129a 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -284,13 +284,6 @@ export function getIsMainnet(state) { return networkType === NETWORK_TYPES.MAINNET } -export function isEthereumNetwork(state) { - const networkType = getNetworkIdentifier(state) - const { KOVAN, MAINNET, RINKEBY, ROPSTEN, GOERLI } = NETWORK_TYPES - - return [KOVAN, MAINNET, RINKEBY, ROPSTEN, GOERLI].includes(networkType) -} - export function getPreferences({ metamask }) { return metamask.preferences } diff --git a/ui/app/selectors/tests/confirm-transaction.test.js b/ui/app/selectors/tests/confirm-transaction.test.js index 53ab202ec..df8b3ae86 100644 --- a/ui/app/selectors/tests/confirm-transaction.test.js +++ b/ui/app/selectors/tests/confirm-transaction.test.js @@ -36,7 +36,7 @@ describe('Confirm Transaction Selector', function () { } it('returns number of txs in unapprovedTxs state with the same network plus unapproved signing method counts', function () { - assert.equal(unconfirmedTransactionsCountSelector(state), 4) + assert.strictEqual(unconfirmedTransactionsCountSelector(state), 4) }) }) @@ -58,7 +58,7 @@ describe('Confirm Transaction Selector', function () { } it('returns token address and calculated token amount', function () { - assert.deepEqual(sendTokenTokenAmountAndToAddressSelector(state), { + assert.deepStrictEqual(sendTokenTokenAmountAndToAddressSelector(state), { toAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tokenAmount: '0.01', }) @@ -82,7 +82,7 @@ describe('Confirm Transaction Selector', function () { } it('returns contract exchange rate in metamask state based on confirm transaction txParams token recipient', function () { - assert.equal(contractExchangeRateSelector(state), 10) + assert.strictEqual(contractExchangeRateSelector(state), '10') }) }) @@ -91,7 +91,7 @@ describe('Confirm Transaction Selector', function () { const state = { metamask: { conversionRate: 556.12 }, } - assert.equal(conversionRateSelector(state), 556.12) + assert.strictEqual(conversionRateSelector(state), 556.12) }) }) }) diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index 71c89ffe0..cd5d9686e 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -2,13 +2,8 @@ import assert from 'assert' import proxyquire from 'proxyquire' const { - getCustomGasErrors, getCustomGasLimit, getCustomGasPrice, - getCustomGasTotal, - getEstimatedGasPrices, - getEstimatedGasTimes, - getPriceAndTimeEstimates, getRenderableBasicEstimateData, getRenderableEstimateDataForSmallButtonsFromGWEI, } = proxyquire('../custom-gas', {}) @@ -17,70 +12,14 @@ describe('custom-gas selectors', function () { describe('getCustomGasPrice()', function () { it('should return gas.customData.price', function () { const mockState = { gas: { customData: { price: 'mockPrice' } } } - assert.equal(getCustomGasPrice(mockState), 'mockPrice') + assert.strictEqual(getCustomGasPrice(mockState), 'mockPrice') }) }) describe('getCustomGasLimit()', function () { it('should return gas.customData.limit', function () { const mockState = { gas: { customData: { limit: 'mockLimit' } } } - assert.equal(getCustomGasLimit(mockState), 'mockLimit') - }) - }) - - describe('getCustomGasTotal()', function () { - it('should return gas.customData.total', function () { - const mockState = { gas: { customData: { total: 'mockTotal' } } } - assert.equal(getCustomGasTotal(mockState), 'mockTotal') - }) - }) - - describe('getCustomGasErrors()', function () { - it('should return gas.errors', function () { - const mockState = { gas: { errors: 'mockErrors' } } - assert.equal(getCustomGasErrors(mockState), 'mockErrors') - }) - }) - - describe('getPriceAndTimeEstimates', function () { - it('should return price and time estimates', function () { - const mockState = { - gas: { priceAndTimeEstimates: 'mockPriceAndTimeEstimates' }, - } - assert.equal( - getPriceAndTimeEstimates(mockState), - 'mockPriceAndTimeEstimates', - ) - }) - }) - - describe('getEstimatedGasPrices', function () { - it('should return price and time estimates', function () { - const mockState = { - gas: { - priceAndTimeEstimates: [ - { gasprice: 12, somethingElse: 20 }, - { gasprice: 22, expectedTime: 30 }, - { gasprice: 32, somethingElse: 40 }, - ], - }, - } - assert.deepEqual(getEstimatedGasPrices(mockState), [12, 22, 32]) - }) - }) - - describe('getEstimatedGasTimes', function () { - it('should return price and time estimates', function () { - const mockState = { - gas: { - priceAndTimeEstimates: [ - { somethingElse: 12, expectedTime: 20 }, - { gasPrice: 22, expectedTime: 30 }, - { somethingElse: 32, expectedTime: 40 }, - ], - }, - } - assert.deepEqual(getEstimatedGasTimes(mockState), [20, 30, 40]) + assert.strictEqual(getCustomGasLimit(mockState), 'mockLimit') }) }) @@ -92,7 +31,6 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.01', feeInPrimaryCurrency: '0.0000525 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x9502f900', }, { @@ -100,13 +38,11 @@ describe('custom-gas selectors', function () { feeInPrimaryCurrency: '0.000084 ETH', feeInSecondaryCurrency: '$0.02', priceInHexWei: '0xee6b2800', - timeEstimate: '~5 min 18 sec', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.03', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~3 min 18 sec', priceInHexWei: '0x12a05f200', }, ], @@ -142,7 +78,6 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { @@ -150,13 +85,11 @@ describe('custom-gas selectors', function () { feeInSecondaryCurrency: '$0.38', gasEstimateType: 'AVERAGE', priceInHexWei: '0x1a13b8600', - timeEstimate: '~10 min 6 sec', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, ], @@ -195,21 +128,18 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { gasEstimateType: 'AVERAGE', feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '', - timeEstimate: '~10 min 6 sec', priceInHexWei: '0x1a13b8600', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.00021 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, ], @@ -248,7 +178,6 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { @@ -256,13 +185,11 @@ describe('custom-gas selectors', function () { feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '$0.38', priceInHexWei: '0x1a13b8600', - timeEstimate: '~10 min 6 sec', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, ], @@ -282,15 +209,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 5, - safeLowWait: 13.2, average: 7, - avgWait: 10.1, fast: 10, - fastWait: 6.6, - fastest: 20, - fastestWait: 1.0, }, }, }, @@ -301,7 +222,6 @@ describe('custom-gas selectors', function () { gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', - timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { @@ -309,13 +229,11 @@ describe('custom-gas selectors', function () { feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '$0.38', priceInHexWei: '0x1a13b8600', - timeEstimate: '~10 min 6 sec', }, { gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', - timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, ], @@ -335,15 +253,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 5, - safeLowWait: 13.2, average: 7, - avgWait: 10.1, fast: 10, - fastWait: 6.6, - fastest: 20, - fastestWait: 1.0, }, }, }, @@ -351,7 +263,7 @@ describe('custom-gas selectors', function () { ] it('should return renderable data about basic estimates', function () { tests.forEach((test) => { - assert.deepEqual( + assert.deepStrictEqual( getRenderableBasicEstimateData( test.mockState, '0x5208', @@ -402,15 +314,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 25, - safeLowWait: 6.6, average: 30, - avgWait: 5.5, fast: 50, - fastWait: 3.3, - fastest: 100, - fastestWait: 0.5, }, }, }, @@ -552,15 +458,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 50, - safeLowWait: 13.2, average: 75, - avgWait: 9.6, fast: 100, - fastWait: 6.6, - fastest: 200, - fastestWait: 1.0, }, }, }, @@ -602,15 +502,9 @@ describe('custom-gas selectors', function () { }, gas: { basicEstimates: { - blockTime: 14.16326530612245, safeLow: 50, - safeLowWait: 13.2, average: 75, - avgWait: 9.6, fast: 100, - fastWait: 6.6, - fastest: 200, - fastestWait: 1.0, }, }, }, @@ -618,7 +512,7 @@ describe('custom-gas selectors', function () { ] it('should return renderable data about basic estimates appropriate for buttons with less info', function () { tests.forEach((test) => { - assert.deepEqual( + assert.deepStrictEqual( getRenderableEstimateDataForSmallButtonsFromGWEI(test.mockState), test.expectedResult, ) diff --git a/ui/app/selectors/tests/permissions.test.js b/ui/app/selectors/tests/permissions.test.js index 39646f4d0..4750afa60 100644 --- a/ui/app/selectors/tests/permissions.test.js +++ b/ui/app/selectors/tests/permissions.test.js @@ -64,7 +64,7 @@ describe('selectors', function () { }, } const extensionId = undefined - assert.deepEqual(getConnectedDomainsForSelectedAddress(mockState), [ + assert.deepStrictEqual(getConnectedDomainsForSelectedAddress(mockState), [ { extensionId, icon: 'https://peepeth.com/favicon-32x32.png', @@ -142,7 +142,7 @@ describe('selectors', function () { }, } const extensionId = undefined - assert.deepEqual(getConnectedDomainsForSelectedAddress(mockState), [ + assert.deepStrictEqual(getConnectedDomainsForSelectedAddress(mockState), [ { extensionId, name: 'Remix - Ethereum IDE', @@ -279,36 +279,39 @@ describe('selectors', function () { } it('should return connected accounts sorted by last selected, then by keyring controller order', function () { - assert.deepEqual(getOrderedConnectedAccountsForActiveTab(mockState), [ - { - address: '0xb3958fb96c8201486ae20be1d5c9f58083df343a', - name: 'Account 2', - lastActive: 1586359844192, - lastSelected: 1586359844193, - }, - { - address: '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5', - name: 'Account 1', - lastActive: 1586359844192, - lastSelected: 1586359844192, - }, - { - address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', - name: 'Account 3', - lastActive: 1586359844192, - lastSelected: 1586359844192, - }, - { - address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d', - name: 'Really Long Name That Should Be Truncated', - lastActive: 1586359844192, - }, - { - address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', - name: 'Account 4', - lastActive: 1586359844192, - }, - ]) + assert.deepStrictEqual( + getOrderedConnectedAccountsForActiveTab(mockState), + [ + { + address: '0xb3958fb96c8201486ae20be1d5c9f58083df343a', + name: 'Account 2', + lastActive: 1586359844192, + lastSelected: 1586359844193, + }, + { + address: '0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5', + name: 'Account 1', + lastActive: 1586359844192, + lastSelected: 1586359844192, + }, + { + address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', + name: 'Account 3', + lastActive: 1586359844192, + lastSelected: 1586359844192, + }, + { + address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d', + name: 'Really Long Name That Should Be Truncated', + lastActive: 1586359844192, + }, + { + address: '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4', + name: 'Account 4', + lastActive: 1586359844192, + }, + ], + ) }) }) @@ -415,7 +418,7 @@ describe('selectors', function () { } it('should return a list of permissions strings', function () { - assert.deepEqual(getPermissionsForActiveTab(mockState), [ + assert.deepStrictEqual(getPermissionsForActiveTab(mockState), [ { key: 'eth_accounts', }, diff --git a/ui/app/selectors/tests/selectors.test.js b/ui/app/selectors/tests/selectors.test.js index ed76b7305..be03752a9 100644 --- a/ui/app/selectors/tests/selectors.test.js +++ b/ui/app/selectors/tests/selectors.test.js @@ -5,12 +5,15 @@ import mockState from '../../../../test/data/mock-state.json' describe('Selectors', function () { describe('#getSelectedAddress', function () { it('returns undefined if selectedAddress is undefined', function () { - assert.equal(selectors.getSelectedAddress({ metamask: {} }), undefined) + assert.strictEqual( + selectors.getSelectedAddress({ metamask: {} }), + undefined, + ) }) it('returns selectedAddress', function () { const selectedAddress = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc' - assert.equal( + assert.strictEqual( selectors.getSelectedAddress({ metamask: { selectedAddress } }), selectedAddress, ) @@ -18,7 +21,7 @@ describe('Selectors', function () { }) it('returns selected identity', function () { - assert.deepEqual(selectors.getSelectedIdentity(mockState), { + assert.deepStrictEqual(selectors.getSelectedIdentity(mockState), { address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', name: 'Test Account', }) @@ -26,14 +29,17 @@ describe('Selectors', function () { it('returns selected account', function () { const account = selectors.getSelectedAccount(mockState) - assert.equal(account.balance, '0x0') - assert.equal(account.address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc') + assert.strictEqual(account.balance, '0x0') + assert.strictEqual( + account.address, + '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', + ) }) describe('#getTokenExchangeRates', function () { it('returns token exchange rates', function () { const tokenExchangeRates = selectors.getTokenExchangeRates(mockState) - assert.deepEqual(tokenExchangeRates, { + assert.deepStrictEqual(tokenExchangeRates, { '0x108cf70c7d384c552f42c07c41c0e1e46d77ea0d': 0.00039345803819379796, '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5': 0.00008189274407698049, }) @@ -42,7 +48,7 @@ describe('Selectors', function () { describe('#getAddressBook', function () { it('should return the address book', function () { - assert.deepEqual(selectors.getAddressBook(mockState), [ + assert.deepStrictEqual(selectors.getAddressBook(mockState), [ { address: '0xc42edfcc21ed14dda456aa0756c153f7985d8813', chainId: '0x4', @@ -58,39 +64,39 @@ describe('Selectors', function () { const accountsWithSendEther = selectors.accountsWithSendEtherInfoSelector( mockState, ) - assert.equal(accountsWithSendEther.length, 2) - assert.equal(accountsWithSendEther[0].balance, '0x0') - assert.equal( + assert.strictEqual(accountsWithSendEther.length, 2) + assert.strictEqual(accountsWithSendEther[0].balance, '0x0') + assert.strictEqual( accountsWithSendEther[0].address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', ) - assert.equal(accountsWithSendEther[0].name, 'Test Account') + assert.strictEqual(accountsWithSendEther[0].name, 'Test Account') }) it('returns selected account with balance, address, and name from accountsWithSendEtherInfoSelector', function () { const currentAccountwithSendEther = selectors.getCurrentAccountWithSendEtherInfo( mockState, ) - assert.equal(currentAccountwithSendEther.balance, '0x0') - assert.equal( + assert.strictEqual(currentAccountwithSendEther.balance, '0x0') + assert.strictEqual( currentAccountwithSendEther.address, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', ) - assert.equal(currentAccountwithSendEther.name, 'Test Account') + assert.strictEqual(currentAccountwithSendEther.name, 'Test Account') }) it('#getGasIsLoading', function () { const gasIsLoading = selectors.getGasIsLoading(mockState) - assert.equal(gasIsLoading, false) + assert.strictEqual(gasIsLoading, false) }) it('#getCurrentCurrency', function () { const currentCurrency = selectors.getCurrentCurrency(mockState) - assert.equal(currentCurrency, 'usd') + assert.strictEqual(currentCurrency, 'usd') }) it('#getTotalUnapprovedCount', function () { const totalUnapprovedCount = selectors.getTotalUnapprovedCount(mockState) - assert.equal(totalUnapprovedCount, 1) + assert.strictEqual(totalUnapprovedCount, 1) }) }) diff --git a/ui/app/selectors/tests/send.test.js b/ui/app/selectors/tests/send.test.js index 8af4fb430..eeb080e3b 100644 --- a/ui/app/selectors/tests/send.test.js +++ b/ui/app/selectors/tests/send.test.js @@ -53,7 +53,7 @@ describe('send selectors', function () { describe('accountsWithSendEtherInfoSelector()', function () { it('should return an array of account objects with name info from identities', function () { - assert.deepEqual(accountsWithSendEtherInfoSelector(mockState), [ + assert.deepStrictEqual(accountsWithSendEtherInfoSelector(mockState), [ { code: '0x', balance: '0x47c9d71831c76efe', @@ -88,19 +88,19 @@ describe('send selectors', function () { describe('getBlockGasLimit', function () { it('should return the current block gas limit', function () { - assert.deepEqual(getBlockGasLimit(mockState), '0x4c1878') + assert.deepStrictEqual(getBlockGasLimit(mockState), '0x4c1878') }) }) describe('getConversionRate()', function () { it('should return the eth conversion rate', function () { - assert.deepEqual(getConversionRate(mockState), 1200.88200327) + assert.deepStrictEqual(getConversionRate(mockState), 1200.88200327) }) }) describe('getCurrentAccountWithSendEtherInfo()', function () { it('should return the currently selected account with identity info', function () { - assert.deepEqual(getCurrentAccountWithSendEtherInfo(mockState), { + assert.deepStrictEqual(getCurrentAccountWithSendEtherInfo(mockState), { code: '0x', balance: '0x0', nonce: '0x0', @@ -112,37 +112,37 @@ describe('send selectors', function () { describe('getNativeCurrency()', function () { it('should return the ticker symbol of the selected network', function () { - assert.equal(getNativeCurrency(mockState), 'ETH') + assert.strictEqual(getNativeCurrency(mockState), 'ETH') }) }) describe('getCurrentNetwork()', function () { it('should return the id of the currently selected network', function () { - assert.equal(getCurrentNetwork(mockState), '3') + assert.strictEqual(getCurrentNetwork(mockState), '3') }) }) describe('getGasLimit()', function () { it('should return the send.gasLimit', function () { - assert.equal(getGasLimit(mockState), '0xFFFF') + assert.strictEqual(getGasLimit(mockState), '0xFFFF') }) }) describe('getGasPrice()', function () { it('should return the send.gasPrice', function () { - assert.equal(getGasPrice(mockState), '0xaa') + assert.strictEqual(getGasPrice(mockState), '0xaa') }) }) describe('getGasTotal()', function () { it('should return the send.gasTotal', function () { - assert.equal(getGasTotal(mockState), 'a9ff56') + assert.strictEqual(getGasTotal(mockState), 'a9ff56') }) }) describe('getPrimaryCurrency()', function () { it('should return the symbol of the send token', function () { - assert.equal( + assert.strictEqual( getPrimaryCurrency({ metamask: { send: { token: { symbol: 'DEF' } } }, }), @@ -153,7 +153,7 @@ describe('send selectors', function () { describe('getSendToken()', function () { it('should return the current send token if set', function () { - assert.deepEqual( + assert.deepStrictEqual( getSendToken({ metamask: { send: { @@ -176,7 +176,7 @@ describe('send selectors', function () { describe('getSendTokenContract()', function () { it('should return the contract at the send token address', function () { - assert.equal( + assert.strictEqual( getSendTokenContract({ metamask: { send: { @@ -194,7 +194,7 @@ describe('send selectors', function () { it('should return null if send token is not set', function () { const modifiedMetamaskState = { ...mockState.metamask, send: {} } - assert.equal( + assert.strictEqual( getSendTokenContract({ ...mockState, metamask: modifiedMetamaskState }), null, ) @@ -203,31 +203,31 @@ describe('send selectors', function () { describe('getSendAmount()', function () { it('should return the send.amount', function () { - assert.equal(getSendAmount(mockState), '0x080') + assert.strictEqual(getSendAmount(mockState), '0x080') }) }) describe('getSendEditingTransactionId()', function () { it('should return the send.editingTransactionId', function () { - assert.equal(getSendEditingTransactionId(mockState), 97531) + assert.strictEqual(getSendEditingTransactionId(mockState), 97531) }) }) describe('getSendErrors()', function () { it('should return the send.errors', function () { - assert.deepEqual(getSendErrors(mockState), { someError: null }) + assert.deepStrictEqual(getSendErrors(mockState), { someError: null }) }) }) describe('getSendHexDataFeatureFlagState()', function () { it('should return the sendHexData feature flag state', function () { - assert.deepEqual(getSendHexDataFeatureFlagState(mockState), true) + assert.deepStrictEqual(getSendHexDataFeatureFlagState(mockState), true) }) }) describe('getSendFrom()', function () { it('should return the send.from', function () { - assert.deepEqual( + assert.deepStrictEqual( getSendFrom(mockState), '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', ) @@ -236,7 +236,7 @@ describe('send selectors', function () { describe('getSendFromBalance()', function () { it('should get the send.from balance if it exists', function () { - assert.equal(getSendFromBalance(mockState), '0x37452b1315889f80') + assert.strictEqual(getSendFromBalance(mockState), '0x37452b1315889f80') }) it('should get the selected account balance if the send.from does not exist', function () { @@ -248,13 +248,13 @@ describe('send selectors', function () { }, }, } - assert.equal(getSendFromBalance(editedMockState), '0x0') + assert.strictEqual(getSendFromBalance(editedMockState), '0x0') }) }) describe('getSendFromObject()', function () { it('should return send.from if it exists', function () { - assert.deepEqual(getSendFromObject(mockState), { + assert.deepStrictEqual(getSendFromObject(mockState), { address: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', balance: '0x37452b1315889f80', code: '0x', @@ -271,7 +271,7 @@ describe('send selectors', function () { }, }, } - assert.deepEqual(getSendFromObject(editedMockState), { + assert.deepStrictEqual(getSendFromObject(editedMockState), { code: '0x', balance: '0x0', nonce: '0x0', @@ -282,19 +282,19 @@ describe('send selectors', function () { describe('getSendMaxModeState()', function () { it('should return send.maxModeOn', function () { - assert.equal(getSendMaxModeState(mockState), false) + assert.strictEqual(getSendMaxModeState(mockState), false) }) }) describe('getSendTo()', function () { it('should return send.to', function () { - assert.equal(getSendTo(mockState), '0x987fedabc') + assert.strictEqual(getSendTo(mockState), '0x987fedabc') }) }) describe('getSendToAccounts()', function () { it('should return an array including all the users accounts and the address book', function () { - assert.deepEqual(getSendToAccounts(mockState), [ + assert.deepStrictEqual(getSendToAccounts(mockState), [ { code: '0x', balance: '0x47c9d71831c76efe', @@ -334,13 +334,13 @@ describe('send selectors', function () { describe('getTokenBalance()', function () { it('should', function () { - assert.equal(getTokenBalance(mockState), 3434) + assert.strictEqual(getTokenBalance(mockState), 3434) }) }) describe('getUnapprovedTxs()', function () { it('should return the unapproved txs', function () { - assert.deepEqual(getUnapprovedTxs(mockState), { + assert.deepStrictEqual(getUnapprovedTxs(mockState), { 4768706228115573: { id: 4768706228115573, time: 1487363153561, @@ -375,7 +375,7 @@ describe('send selectors', function () { }, } - assert.equal(sendAmountIsInError(state), true) + assert.strictEqual(sendAmountIsInError(state), true) }) it('should return false if send.errors.amount is falsy', function () { @@ -387,7 +387,7 @@ describe('send selectors', function () { }, } - assert.equal(sendAmountIsInError(state), false) + assert.strictEqual(sendAmountIsInError(state), false) }) }) }) @@ -403,7 +403,7 @@ describe('send selectors', function () { }, } - assert.equal(getGasLoadingError(state), 'abc') + assert.strictEqual(getGasLoadingError(state), 'abc') }) }) @@ -417,7 +417,7 @@ describe('send selectors', function () { }, } - assert.equal(gasFeeIsInError(state), true) + assert.strictEqual(gasFeeIsInError(state), true) }) it('should return false send.errors.gasFee is falsely', function () { @@ -429,7 +429,7 @@ describe('send selectors', function () { }, } - assert.equal(gasFeeIsInError(state), false) + assert.strictEqual(gasFeeIsInError(state), false) }) }) @@ -441,7 +441,7 @@ describe('send selectors', function () { }, } - assert.equal(getGasButtonGroupShown(state), 'foobar') + assert.strictEqual(getGasButtonGroupShown(state), 'foobar') }) }) }) @@ -457,11 +457,14 @@ describe('send selectors', function () { describe('getTitleKey()', function () { it('should return the correct key when "to" is empty', function () { - assert.equal(getTitleKey(getMetamaskSendMockState({})), 'addRecipient') + assert.strictEqual( + getTitleKey(getMetamaskSendMockState({})), + 'addRecipient', + ) }) it('should return the correct key when getSendEditingTransactionId is truthy', function () { - assert.equal( + assert.strictEqual( getTitleKey( getMetamaskSendMockState({ to: true, @@ -474,7 +477,7 @@ describe('send selectors', function () { }) it('should return the correct key when getSendEditingTransactionId is falsy and getSendToken is truthy', function () { - assert.equal( + assert.strictEqual( getTitleKey( getMetamaskSendMockState({ to: true, @@ -487,7 +490,7 @@ describe('send selectors', function () { }) it('should return the correct key when getSendEditingTransactionId is falsy and getSendToken is falsy', function () { - assert.equal( + assert.strictEqual( getTitleKey( getMetamaskSendMockState({ to: true, @@ -510,7 +513,7 @@ describe('send selectors', function () { describe('isSendFormInError()', function () { it('should return true if any of the values of the object returned by getSendErrors are truthy', function () { - assert.equal( + assert.strictEqual( isSendFormInError( getSendMockState({ errors: [true], @@ -521,7 +524,7 @@ describe('send selectors', function () { }) it('should return false if all of the values of the object returned by getSendErrors are falsy', function () { - assert.equal( + assert.strictEqual( isSendFormInError( getSendMockState({ errors: [], @@ -529,7 +532,7 @@ describe('send selectors', function () { ), false, ) - assert.equal( + assert.strictEqual( isSendFormInError( getSendMockState({ errors: [false], diff --git a/ui/app/selectors/tests/transactions.test.js b/ui/app/selectors/tests/transactions.test.js index 6964ad161..593055392 100644 --- a/ui/app/selectors/tests/transactions.test.js +++ b/ui/app/selectors/tests/transactions.test.js @@ -35,7 +35,7 @@ describe('Transaction Selectors', function () { const msgSelector = unapprovedMessagesSelector(state) assert(Array.isArray(msgSelector)) - assert.deepEqual(msgSelector, [msg]) + assert.deepStrictEqual(msgSelector, [msg]) }) it('returns personal sign from unapprovedPersonalMsgsSelector', function () { @@ -62,7 +62,7 @@ describe('Transaction Selectors', function () { const msgSelector = unapprovedMessagesSelector(state) assert(Array.isArray(msgSelector)) - assert.deepEqual(msgSelector, [msg]) + assert.deepStrictEqual(msgSelector, [msg]) }) it('returns typed message from unapprovedTypedMessagesSelector', function () { @@ -90,7 +90,7 @@ describe('Transaction Selectors', function () { const msgSelector = unapprovedMessagesSelector(state) assert(Array.isArray(msgSelector)) - assert.deepEqual(msgSelector, [msg]) + assert.deepStrictEqual(msgSelector, [msg]) }) }) @@ -133,7 +133,7 @@ describe('Transaction Selectors', function () { const selectedTx = transactionsSelector(state) assert(Array.isArray(selectedTx)) - assert.deepEqual(selectedTx, orderedTxList) + assert.deepStrictEqual(selectedTx, orderedTxList) }) }) @@ -191,7 +191,10 @@ describe('Transaction Selectors', function () { }, ] - assert.deepEqual(nonceSortedTransactionsSelector(state), expectedResult) + assert.deepStrictEqual( + nonceSortedTransactionsSelector(state), + expectedResult, + ) }) }) @@ -286,7 +289,7 @@ describe('Transaction Selectors', function () { }, ] - assert.deepEqual( + assert.deepStrictEqual( nonceSortedPendingTransactionsSelector(state), expectedResult, ) @@ -304,7 +307,7 @@ describe('Transaction Selectors', function () { }, ] - assert.deepEqual( + assert.deepStrictEqual( nonceSortedCompletedTransactionsSelector(state), expectedResult, ) @@ -312,7 +315,7 @@ describe('Transaction Selectors', function () { it('submittedPendingTransactionsSelector', function () { const expectedResult = [submittedTx] - assert.deepEqual( + assert.deepStrictEqual( submittedPendingTransactionsSelector(state), expectedResult, ) diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index f9d9de22d..474cdda67 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -2746,3 +2746,29 @@ export function getCurrentWindowTab() { dispatch(setCurrentWindowTab(currentWindowTab)) } } + +// MetaMetrics +/** + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventPayload} MetaMetricsEventPayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPagePayload} MetaMetricsPagePayload + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageOptions} MetaMetricsPageOptions + */ + +/** + * @param {MetaMetricsEventPayload} payload - details of the event to track + * @param {MetaMetricsEventOptions} options - options for routing/handling of event + * @returns {Promise} + */ +export function trackMetaMetricsEvent(payload, options) { + return promisifiedBackground.trackMetaMetricsEvent(payload, options) +} + +/** + * @param {MetaMetricsPagePayload} payload - details of the page viewed + * @param {MetaMetricsPageOptions} options - options for handling the page view + * @returns {void} + */ +export function trackMetaMetricsPage(payload, options) { + return promisifiedBackground.trackMetaMetricsPage(payload, options) +} diff --git a/ui/lib/icon-factory.js b/ui/lib/icon-factory.js index 789d1c34b..fa3f2bbf3 100644 --- a/ui/lib/icon-factory.js +++ b/ui/lib/icon-factory.js @@ -1,5 +1,5 @@ import { isValidAddress } from 'ethereumjs-util' -import contractMap from 'eth-contract-metadata' +import contractMap from '@metamask/contract-metadata' import { checksumAddress } from '../app/helpers/utils/util' let iconFactory diff --git a/ui/lib/local-storage-helpers.js b/ui/lib/local-storage-helpers.js deleted file mode 100644 index 58dc637ed..000000000 --- a/ui/lib/local-storage-helpers.js +++ /dev/null @@ -1,20 +0,0 @@ -export function loadLocalStorageData(itemKey) { - try { - const serializedData = window.localStorage.getItem(itemKey) - if (serializedData === null) { - return undefined - } - return JSON.parse(serializedData) - } catch (err) { - return undefined - } -} - -export function saveLocalStorageData(data, itemKey) { - try { - const serializedData = JSON.stringify(data) - window.localStorage.setItem(itemKey, serializedData) - } catch (err) { - console.warn(err) - } -} diff --git a/ui/lib/storage-helpers.js b/ui/lib/storage-helpers.js new file mode 100644 index 000000000..737147405 --- /dev/null +++ b/ui/lib/storage-helpers.js @@ -0,0 +1,23 @@ +import localforage from 'localforage' + +export async function getStorageItem(key) { + try { + const serializedData = await localforage.getItem(key) + if (serializedData === null) { + return undefined + } + + return JSON.parse(serializedData) + } catch (err) { + return undefined + } +} + +export async function setStorageItem(key, value) { + try { + const serializedData = JSON.stringify(value) + await localforage.setItem(key, serializedData) + } catch (err) { + console.warn(err) + } +} diff --git a/yarn.lock b/yarn.lock index 1348d21e4..f328d7c05 100644 --- a/yarn.lock +++ b/yarn.lock @@ -47,33 +47,53 @@ did-resolver "0.0.6" ipfs-did-document "^1.2.3" -"@babel/code-frame@7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== - dependencies: - "@babel/highlight" "^7.0.0" +"@agoric/babel-standalone@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@agoric/babel-standalone/-/babel-standalone-7.9.5.tgz#1ca0c17844924199d31e49d6b67e8b2a629b8599" + integrity sha512-1Aa23oPuRi4kywUyZODo8zey9Gq2NpD2xUnNvgJLoT8orMQRlVOtvbG3JeHq5sjJERlF/q6csg4/P8t8/5IABA== -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": +"@agoric/make-hardener@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@agoric/make-hardener/-/make-hardener-0.1.1.tgz#9b887da47aeec6637d9db4f0a92a4e740b8262bb" + integrity sha512-3emNc+yWJoFK5JMLoEFPs6rCzkntWQKxpR4gt3jaZYLKoUG4LrTmID3XNe8y40B6SJ3k/wLPodKa0ToQGlhrwQ== + +"@agoric/transform-module@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@agoric/transform-module/-/transform-module-0.4.1.tgz#9fb152364faf372e1bda535cb4ef89717724f57c" + integrity sha512-4TJJHXeXAWu1FCA7yXCAZmhBNoGTB/BEAe2pv+J2X8W/mJTr9b395OkDCSRMpzvmSshLfBx6wT0D7dqWIWEC1w== + +"@babel/code-frame@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== dependencies: "@babel/highlight" "^7.10.4" -"@babel/core@>=7.9.0", "@babel/core@^7.12.1", "@babel/core@^7.4.3", "@babel/core@^7.7.5": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" - integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== +"@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" + integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== + +"@babel/core@>=7.9.0", "@babel/core@^7.12.1", "@babel/core@^7.12.3", "@babel/core@^7.7.5": + version "7.12.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" + integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" + "@babel/generator" "^7.12.5" "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.1" - "@babel/parser" "^7.12.3" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.7" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.9" + "@babel/types" "^7.12.7" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -99,77 +119,93 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468" - integrity sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg== +"@babel/generator@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de" + integrity sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.12.5" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee" - integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw== +"@babel/helper-annotate-as-pure@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" + integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== dependencies: - "@babel/types" "^7.8.3" + "@babel/types" "^7.10.4" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" + integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== dependencies: - "@babel/helper-explode-assignable-expression" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-explode-assignable-expression" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-builder-react-jsx@^7.3.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" - integrity sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw== +"@babel/helper-builder-react-jsx-experimental@^7.12.4": + version "7.12.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.12.4.tgz#55fc1ead5242caa0ca2875dcb8eed6d311e50f48" + integrity sha512-AjEa0jrQqNk7eDQOo0pTfUOwQBMF+xVqrausQwT9/rTKy0g04ggFNaJpaE09IQMn9yExluigWMJcj0WC7bq+Og== dependencies: - "@babel/types" "^7.3.0" - esutils "^2.0.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-module-imports" "^7.12.1" + "@babel/types" "^7.12.1" -"@babel/helper-call-delegate@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" - integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== +"@babel/helper-builder-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" + integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-create-class-features-plugin@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.3.tgz#5b94be88c255f140fd2c10dd151e7f98f4bff397" - integrity sha512-qmp4pD7zeTxsv0JNecSBsEmG1ei2MqwJq4YQcK3ZWm/0t07QstWfvuV/vm3Qt5xNMFETn2SZqpMx2MQzbtq+KA== +"@babel/helper-compilation-targets@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831" + integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw== dependencies: - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-member-expression-to-functions" "^7.8.3" - "@babel/helper-optimise-call-expression" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-replace-supers" "^7.8.3" - "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/compat-data" "^7.12.5" + "@babel/helper-validator-option" "^7.12.1" + browserslist "^4.14.5" + semver "^5.5.0" -"@babel/helper-define-map@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" - integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== +"@babel/helper-create-class-features-plugin@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" + integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.5.5" - lodash "^4.17.13" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.12.1" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.10.4" -"@babel/helper-explode-assignable-expression@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== +"@babel/helper-create-regexp-features-plugin@^7.12.1": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz#2084172e95443fa0a09214ba1bb328f9aea1278f" + integrity sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ== dependencies: - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + regexpu-core "^4.7.1" -"@babel/helper-function-name@^7.1.0", "@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.8.3": +"@babel/helper-define-map@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" + integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.5" + lodash "^4.17.19" + +"@babel/helper-explode-assignable-expression@^7.10.4": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz#8006a466695c4ad86a2a5f2fb15b5f2c31ad5633" + integrity sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-function-name@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== @@ -178,35 +214,35 @@ "@babel/template" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.10.4": +"@babel/helper-get-function-arity@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== dependencies: "@babel/types" "^7.10.4" -"@babel/helper-hoist-variables@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" - integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== +"@babel/helper-hoist-variables@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" + integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== dependencies: - "@babel/types" "^7.4.4" + "@babel/types" "^7.10.4" -"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.8.3": +"@babel/helper-member-expression-to-functions@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz#fba0f2fcff3fba00e6ecb664bb5e6e26e2d6165c" integrity sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ== dependencies: "@babel/types" "^7.12.1" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz#1644c01591a15a2f084dd6d092d9430eb1d1216c" - integrity sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" + integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.12.5" -"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.4.4": +"@babel/helper-module-transforms@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== @@ -221,7 +257,7 @@ "@babel/types" "^7.12.1" lodash "^4.17.19" -"@babel/helper-optimise-call-expression@^7.0.0", "@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.8.3": +"@babel/helper-optimise-call-expression@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== @@ -233,25 +269,16 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== -"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2" - integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q== +"@babel/helper-remap-async-to-generator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd" + integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A== dependencies: - lodash "^4.17.11" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/types" "^7.12.1" -"@babel/helper-remap-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-wrap-function" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-replace-supers@^7.12.1", "@babel/helper-replace-supers@^7.5.5", "@babel/helper-replace-supers@^7.8.3": +"@babel/helper-replace-supers@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.1.tgz#f15c9cc897439281891e11d5ce12562ac0cf3fa9" integrity sha512-zJjTvtNJnCFsCXVi5rUInstLd/EIVNmIKA1Q9ynESmMBWPWd+7sdR+G4/wdu+Mppfep0XLyG2m7EBPvjCeFyrw== @@ -261,14 +288,21 @@ "@babel/traverse" "^7.12.1" "@babel/types" "^7.12.1" -"@babel/helper-simple-access@^7.1.0", "@babel/helper-simple-access@^7.12.1": +"@babel/helper-simple-access@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== dependencies: "@babel/types" "^7.12.1" -"@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.4.4", "@babel/helper-split-export-declaration@^7.8.3": +"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== @@ -280,26 +314,31 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== -"@babel/helper-wrap-function@^7.1.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" - integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.2.0" - -"@babel/helpers@^7.12.1": +"@babel/helper-validator-option@^7.12.1": version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.1.tgz#8a8261c1d438ec18cb890434df4ec768734c1e79" - integrity sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g== + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz#175567380c3e77d60ff98a54bb015fe78f2178d9" + integrity sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A== + +"@babel/helper-wrap-function@^7.10.4": + version "7.12.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz#3332339fc4d1fbbf1c27d7958c27d34708e990d9" + integrity sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helpers@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" + integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== dependencies: "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/traverse" "^7.12.5" + "@babel/types" "^7.12.5" -"@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4": +"@babel/highlight@^7.10.4", "@babel/highlight@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== @@ -308,119 +347,204 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.1", "@babel/parser@^7.10.4", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3", "@babel/parser@^7.7.5": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" - integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== +"@babel/parser@^7.12.7", "@babel/parser@^7.7.5": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.7.tgz#fee7b39fe809d0e73e5b25eecaf5780ef3d73056" + integrity sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg== -"@babel/plugin-proposal-async-generator-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" - integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== +"@babel/plugin-proposal-async-generator-functions@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" + integrity sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" - "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.12.1" + "@babel/plugin-syntax-async-generators" "^7.8.0" -"@babel/plugin-proposal-class-properties@^7.5.5", "@babel/plugin-proposal-class-properties@^7.7.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" - integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA== +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.5.5": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" + integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-dynamic-import@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506" - integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw== +"@babel/plugin-proposal-decorators@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.1.tgz#59271439fed4145456c41067450543aee332d15f" + integrity sha512-knNIuusychgYN8fGJHONL0RbFxLGawhXOJNLBk75TniTsZZeA+wdkDuv6wp4lGwzQEKjZi6/WYtnb3udNPmQmQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-decorators" "^7.12.1" -"@babel/plugin-proposal-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" - integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== +"@babel/plugin-proposal-dynamic-import@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz#43eb5c2a3487ecd98c5c8ea8b5fdb69a2749b2dc" + integrity sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" - integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== +"@babel/plugin-proposal-export-default-from@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.12.1.tgz#c6e62d668a8abcfe0d28b82f560395fecb611c5a" + integrity sha512-z5Q4Ke7j0AexQRfgUvnD+BdCSgpTEKnqQ3kskk2jWtOBulxICzd1X9BGt7kmWftxZ2W3++OZdt5gtmC8KLxdRQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-default-from" "^7.12.1" + +"@babel/plugin-proposal-export-namespace-from@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz#8b9b8f376b2d88f5dd774e4d24a5cc2e3679b6d4" + integrity sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz#d45423b517714eedd5621a9dfdc03fa9f4eb241c" + integrity sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz#f2c490d36e1b3c9659241034a5d2cd50263a2751" + integrity sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4", "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c" + integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-object-rest-spread@^7.5.5", "@babel/plugin-proposal-object-rest-spread@^7.6.2": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb" - integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA== +"@babel/plugin-proposal-numeric-separator@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz#8bf253de8139099fea193b297d23a9d406ef056b" + integrity sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.5.5": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" + integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.12.1" -"@babel/plugin-proposal-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" - integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== +"@babel/plugin-proposal-optional-catch-binding@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz#ccc2421af64d3aae50b558a71cede929a5ab2942" + integrity sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz#ae10b3214cb25f7adb1f3bc87ba42ca10b7e2543" - integrity sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg== +"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.8.3": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz#e02f0ea1b5dc59d401ec16fb824679f683d3303c" + integrity sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" - integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== +"@babel/plugin-proposal-private-methods@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389" + integrity sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-async-generators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" - integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== +"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz#2a183958d417765b9eae334f47758e5d6a82e072" + integrity sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-dynamic-import@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" - integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-flow@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c" - integrity sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg== +"@babel/plugin-syntax-class-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" + integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" - integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== +"@babel/plugin-syntax-decorators@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.1.tgz#81a8b535b284476c41be6de06853a8802b98c5dd" + integrity sha512-ir9YW5daRrTYiy9UJ2TzdNIJEZu8KclVzDcfSt4iEmOtwQ4llPtWInNKJyKnVXp1vE4bbVd5S31M/im3mYMO1w== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-jsx@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" - integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== +"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-default-from@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.12.1.tgz#a9eb31881f4f9a1115a3d2c6d64ac3f6016b5a9d" + integrity sha512-dP5eGg6tHEkhnRD2/vRG/KJKRSg8gtxu2i+P/8/yFPJn/CfPU5G0/7Gks2i3M6IOVAPQekmsLN9LPsmXFFL4Uw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-flow@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.1.tgz#a77670d9abe6d63e8acadf4c31bb1eb5a506bbdd" + integrity sha512-1lBLLmtxrwpm4VKmtVFselI/P3pX+G63fAtUUt6b2Nzgao77KNDwyuRt90Mj2/9pKobtt68FdvjfqohZjg/FCA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" + integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": version "7.8.3" @@ -429,19 +553,26 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-object-rest-spread@^7.2.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" - integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.0": version "7.8.3" @@ -450,253 +581,273 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-transform-arrow-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" - integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== +"@babel/plugin-syntax-top-level-await@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" + integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-async-to-generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" - integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg== +"@babel/plugin-syntax-typescript@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz#460ba9d77077653803c3dd2e673f76d66b4029e5" + integrity sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoped-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" - integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== +"@babel/plugin-transform-arrow-functions@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3" + integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" - integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== +"@babel/plugin-transform-async-to-generator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1" + integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.13" + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.12.1" -"@babel/plugin-transform-classes@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" - integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== +"@babel/plugin-transform-block-scoped-functions@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9" + integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-block-scoping@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz#f0ee727874b42a208a48a586b84c3d222c2bbef1" + integrity sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-classes@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6" + integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.10.4" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" - integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== +"@babel/plugin-transform-computed-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852" + integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-destructuring@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a" - integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ== +"@babel/plugin-transform-destructuring@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847" + integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" - integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== +"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz#a1d16c14862817b6409c0a678d6f9373ca9cd975" + integrity sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-duplicate-keys@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853" - integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ== +"@babel/plugin-transform-duplicate-keys@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz#745661baba295ac06e686822797a69fbaa2ca228" + integrity sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-exponentiation-operator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" - integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== +"@babel/plugin-transform-exponentiation-operator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz#b0f2ed356ba1be1428ecaf128ff8a24f02830ae0" + integrity sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz#d267a081f49a8705fc9146de0768c6b58dccd8f7" - integrity sha512-WyVedfeEIILYEaWGAUWzVNyqG4sfsNooMhXWsu/YzOvVGcsnPb5PguysjJqI3t3qiaYj0BR8T2f5njdjTGe44Q== +"@babel/plugin-transform-flow-strip-types@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.12.1.tgz#8430decfa7eb2aea5414ed4a3fa6e1652b7d77c4" + integrity sha512-8hAtkmsQb36yMmEtk2JZ9JnVyDSnDOdlB+0nEGzIDLuK4yR3JcEjfuFPYkdEPSh8Id+rAMeBEn+X0iVEyho6Hg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-flow" "^7.12.1" -"@babel/plugin-transform-for-of@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" - integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== +"@babel/plugin-transform-for-of@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa" + integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-function-name@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" - integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== +"@babel/plugin-transform-function-name@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667" + integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" - integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== +"@babel/plugin-transform-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57" + integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" - integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== +"@babel/plugin-transform-member-expression-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad" + integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-modules-amd@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91" - integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg== +"@babel/plugin-transform-modules-amd@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz#3154300b026185666eebb0c0ed7f8415fefcf6f9" + integrity sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ== dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74" - integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ== +"@babel/plugin-transform-modules-commonjs@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648" + integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag== dependencies: - "@babel/helper-module-transforms" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.12.1" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249" - integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg== +"@babel/plugin-transform-modules-systemjs@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz#663fea620d593c93f214a464cd399bf6dc683086" + integrity sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q== dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-hoist-variables" "^7.10.4" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-validator-identifier" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" - integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== +"@babel/plugin-transform-modules-umd@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz#eb5a218d6b1c68f3d6217b8fa2cc82fec6547902" + integrity sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q== dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106" - integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz#b407f5c96be0d9f5f88467497fa82b30ac3e8753" + integrity sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q== dependencies: - regexp-tree "^0.1.6" + "@babel/helper-create-regexp-features-plugin" "^7.12.1" -"@babel/plugin-transform-new-target@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" - integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== +"@babel/plugin-transform-new-target@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz#80073f02ee1bb2d365c3416490e085c95759dec0" + integrity sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-object-super@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" - integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== +"@babel/plugin-transform-object-super@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e" + integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" -"@babel/plugin-transform-parameters@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" - integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== +"@babel/plugin-transform-parameters@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d" + integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg== dependencies: - "@babel/helper-call-delegate" "^7.4.4" - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-property-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" - integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== +"@babel/plugin-transform-property-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd" + integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-constant-elements@^7.0.0", "@babel/plugin-transform-react-constant-elements@^7.2.0", "@babel/plugin-transform-react-constant-elements@^7.6.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.8.3.tgz#784c25294bddaad2323eb4ff0c9f4a3f6c87d6bc" - integrity sha512-glrzN2U+egwRfkNFtL34xIBYTxbbUF2qJTP8HD3qETBBqzAWSeNB821X0GjU06+dNpq/UyCIjI72FmGE5NNkQQ== +"@babel/plugin-transform-react-display-name@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz#1cbcd0c3b1d6648c55374a22fc9b6b7e5341c00d" + integrity sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w== dependencies: - "@babel/helper-annotate-as-pure" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-display-name@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0" - integrity sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A== +"@babel/plugin-transform-react-jsx-development@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.7.tgz#4c2a647de79c7e2b16bfe4540677ba3121e82a08" + integrity sha512-Rs3ETtMtR3VLXFeYRChle5SsP/P9Jp/6dsewBQfokDSzKJThlsuFcnzLTDRALiUmTC48ej19YD9uN1mupEeEDg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-builder-react-jsx-experimental" "^7.12.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.12.1" -"@babel/plugin-transform-react-jsx-self@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz#461e21ad9478f1031dd5e276108d027f1b5240ba" - integrity sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg== +"@babel/plugin-transform-react-jsx-self@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.1.tgz#ef43cbca2a14f1bd17807dbe4376ff89d714cf28" + integrity sha512-FbpL0ieNWiiBB5tCldX17EtXgmzeEZjFrix72rQYeq9X6nUK38HCaxexzVQrZWXanxKJPKVVIU37gFjEQYkPkA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz#20c8c60f0140f5dd3cd63418d452801cf3f7180f" - integrity sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g== +"@babel/plugin-transform-react-jsx-source@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.1.tgz#d07de6863f468da0809edcf79a1aa8ce2a82a26b" + integrity sha512-keQ5kBfjJNRc6zZN1/nVHCd6LLIHq4aUKcVnvE/2l+ZZROSbqoiGFRtT5t3Is89XJxBQaP7NLZX2jgGHdZvvFQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx@^7.0.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" - integrity sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg== +"@babel/plugin-transform-react-jsx@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.7.tgz#8b14d45f6eccd41b7f924bcb65c021e9f0a06f7f" + integrity sha512-YFlTi6MEsclFAPIDNZYiCRbneg1MFGao9pPG9uD5htwE0vDbPaMUMeYd6itWjw7K4kro4UbdQf3ljmFl9y48dQ== dependencies: - "@babel/helper-builder-react-jsx" "^7.3.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-builder-react-jsx" "^7.10.4" + "@babel/helper-builder-react-jsx-experimental" "^7.12.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.12.1" -"@babel/plugin-transform-regenerator@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" - integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== +"@babel/plugin-transform-react-pure-annotations@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42" + integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg== dependencies: - regenerator-transform "^0.14.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-reserved-words@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" - integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw== +"@babel/plugin-transform-regenerator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz#5f0a28d842f6462281f06a964e88ba8d7ab49753" + integrity sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz#6fdfc8cc7edcc42b36a7c12188c6787c873adcd8" + integrity sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-runtime@^7.5.5": version "7.5.5" @@ -708,138 +859,189 @@ resolve "^1.8.1" semver "^5.5.1" -"@babel/plugin-transform-shorthand-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" - integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== +"@babel/plugin-transform-shorthand-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" + integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-spread@^7.2.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" - integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== +"@babel/plugin-transform-spread@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e" + integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" -"@babel/plugin-transform-sticky-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" - integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== +"@babel/plugin-transform-sticky-regex@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz#560224613ab23987453948ed21d0b0b193fa7fad" + integrity sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-template-literals@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" - integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== +"@babel/plugin-transform-template-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843" + integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-typeof-symbol@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" - integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== +"@babel/plugin-transform-typeof-symbol@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.1.tgz#9ca6be343d42512fbc2e68236a82ae64bc7af78a" + integrity sha512-EPGgpGy+O5Kg5pJFNDKuxt9RdmTgj5sgrus2XVeMp/ZIbOESadgILUbm50SNpghOh3/6yrbsH+NB5+WJTmsA7Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-unicode-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" - integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== +"@babel/plugin-transform-typescript@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz#d92cc0af504d510e26a754a7dbc2e5c8cd9c7ab4" + integrity sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-create-class-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-typescript" "^7.12.1" -"@babel/preset-env@^7.4.3", "@babel/preset-env@^7.4.5", "@babel/preset-env@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a" - integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A== +"@babel/plugin-transform-unicode-escapes@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz#5232b9f81ccb07070b7c3c36c67a1b78f1845709" + integrity sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.2.0" - "@babel/plugin-proposal-dynamic-import" "^7.5.0" - "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.5.5" - "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-syntax-async-generators" "^7.2.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.5.0" - "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.5.5" - "@babel/plugin-transform-classes" "^7.5.5" - "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.5.0" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/plugin-transform-duplicate-keys" "^7.5.0" - "@babel/plugin-transform-exponentiation-operator" "^7.2.0" - "@babel/plugin-transform-for-of" "^7.4.4" - "@babel/plugin-transform-function-name" "^7.4.4" - "@babel/plugin-transform-literals" "^7.2.0" - "@babel/plugin-transform-member-expression-literals" "^7.2.0" - "@babel/plugin-transform-modules-amd" "^7.5.0" - "@babel/plugin-transform-modules-commonjs" "^7.5.0" - "@babel/plugin-transform-modules-systemjs" "^7.5.0" - "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5" - "@babel/plugin-transform-new-target" "^7.4.4" - "@babel/plugin-transform-object-super" "^7.5.5" - "@babel/plugin-transform-parameters" "^7.4.4" - "@babel/plugin-transform-property-literals" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.4.5" - "@babel/plugin-transform-reserved-words" "^7.2.0" - "@babel/plugin-transform-shorthand-properties" "^7.2.0" - "@babel/plugin-transform-spread" "^7.2.0" - "@babel/plugin-transform-sticky-regex" "^7.2.0" - "@babel/plugin-transform-template-literals" "^7.4.4" - "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.4.4" - "@babel/types" "^7.5.5" - browserslist "^4.6.0" - core-js-compat "^3.1.1" - invariant "^2.2.2" - js-levenshtein "^1.1.3" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-regex@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz#cc9661f61390db5c65e3febaccefd5c6ac3faecb" + integrity sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/preset-env@^7.12.1", "@babel/preset-env@^7.5.5": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.7.tgz#54ea21dbe92caf6f10cb1a0a576adc4ebf094b55" + integrity sha512-OnNdfAr1FUQg7ksb7bmbKoby4qFOHw6DKWWUNB9KqnnCldxhxJlP+21dpyaWFmf2h0rTbOkXJtAGevY3XW1eew== + dependencies: + "@babel/compat-data" "^7.12.7" + "@babel/helper-compilation-targets" "^7.12.5" + "@babel/helper-module-imports" "^7.12.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-validator-option" "^7.12.1" + "@babel/plugin-proposal-async-generator-functions" "^7.12.1" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-dynamic-import" "^7.12.1" + "@babel/plugin-proposal-export-namespace-from" "^7.12.1" + "@babel/plugin-proposal-json-strings" "^7.12.1" + "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-numeric-separator" "^7.12.7" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-catch-binding" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.1" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.12.1" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-async-to-generator" "^7.12.1" + "@babel/plugin-transform-block-scoped-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-computed-properties" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-dotall-regex" "^7.12.1" + "@babel/plugin-transform-duplicate-keys" "^7.12.1" + "@babel/plugin-transform-exponentiation-operator" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-function-name" "^7.12.1" + "@babel/plugin-transform-literals" "^7.12.1" + "@babel/plugin-transform-member-expression-literals" "^7.12.1" + "@babel/plugin-transform-modules-amd" "^7.12.1" + "@babel/plugin-transform-modules-commonjs" "^7.12.1" + "@babel/plugin-transform-modules-systemjs" "^7.12.1" + "@babel/plugin-transform-modules-umd" "^7.12.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1" + "@babel/plugin-transform-new-target" "^7.12.1" + "@babel/plugin-transform-object-super" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-property-literals" "^7.12.1" + "@babel/plugin-transform-regenerator" "^7.12.1" + "@babel/plugin-transform-reserved-words" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/plugin-transform-sticky-regex" "^7.12.7" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/plugin-transform-typeof-symbol" "^7.12.1" + "@babel/plugin-transform-unicode-escapes" "^7.12.1" + "@babel/plugin-transform-unicode-regex" "^7.12.1" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.12.7" + core-js-compat "^3.7.0" semver "^5.5.0" -"@babel/preset-flow@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2" - integrity sha512-bJOHrYOPqJZCkPVbG1Lot2r5OSsB+iUOaxiHdlOeB1yPWS6evswVHwvkDLZ54WTaTRIk89ds0iHmGZSnxlPejQ== +"@babel/preset-flow@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.12.1.tgz#1a81d376c5a9549e75352a3888f8c273455ae940" + integrity sha512-UAoyMdioAhM6H99qPoKvpHMzxmNVXno8GYU/7vZmGaHk6/KqfDYL1W0NxszVbJ2EP271b7e6Ox+Vk2A9QsB3Sw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-flow-strip-types" "^7.12.1" + +"@babel/preset-modules@^0.1.3": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" -"@babel/preset-react@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0" - integrity sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w== +"@babel/preset-react@^7.0.0", "@babel/preset-react@^7.12.1": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.7.tgz#36d61d83223b07b6ac4ec55cf016abb0f70be83b" + integrity sha512-wKeTdnGUP5AEYCYQIMeXMMwU7j+2opxrG0WzuZfxuuW9nhKvvALBjl67653CWamZJVefuJGI219G591RSldrqQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-self" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-react-display-name" "^7.12.1" + "@babel/plugin-transform-react-jsx" "^7.12.7" + "@babel/plugin-transform-react-jsx-development" "^7.12.7" + "@babel/plugin-transform-react-jsx-self" "^7.12.1" + "@babel/plugin-transform-react-jsx-source" "^7.12.1" + "@babel/plugin-transform-react-pure-annotations" "^7.12.1" -"@babel/register@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.5.5.tgz#40fe0d474c8c8587b28d6ae18a03eddad3dac3c1" - integrity sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ== +"@babel/preset-typescript@^7.12.1": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.7.tgz#fc7df8199d6aae747896f1e6c61fc872056632a3" + integrity sha512-nOoIqIqBmHBSEgBXWR4Dv/XBehtIFcw9PqZw6rFYuKrzsZmOQm3PR5siLBnKZFEsDb03IegG8nSjU/iXXXYRmw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-validator-option" "^7.12.1" + "@babel/plugin-transform-typescript" "^7.12.1" + +"@babel/register@^7.12.1", "@babel/register@^7.5.5": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.12.1.tgz#cdb087bdfc4f7241c03231f22e15d211acf21438" + integrity sha512-XWcmseMIncOjoydKZnWvWi0/5CUCD+ZYKhRwgYlWOrA8fGZ/FjuLRpqtIhLOVD/fvR1b9DQHtZPn68VvhpYf+Q== dependencies: - core-js "^3.0.0" find-cache-dir "^2.0.0" - lodash "^4.17.13" - mkdirp "^0.5.1" + lodash "^4.17.19" + make-dir "^2.1.0" pirates "^4.0.0" - source-map-support "^0.5.9" + source-map-support "^0.5.16" "@babel/runtime-corejs3@^7.10.2": version "7.11.2" @@ -856,41 +1058,41 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.1.0", "@babel/template@^7.10.4", "@babel/template@^7.7.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== +"@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.7.4": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" + integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.1", "@babel/traverse@^7.12.1", "@babel/traverse@^7.4.4", "@babel/traverse@^7.7.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e" - integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw== +"@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.5", "@babel/traverse@^7.12.9", "@babel/traverse@^7.7.4": + version "7.12.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.9.tgz#fad26c972eabbc11350e0b695978de6cc8e8596f" + integrity sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" + "@babel/generator" "^7.12.5" "@babel/helper-function-name" "^7.10.4" "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.1" - "@babel/types" "^7.12.1" + "@babel/parser" "^7.12.7" + "@babel/types" "^7.12.7" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.12.1", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.8.3": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" - integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA== +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.12.1", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.7.tgz#6039ff1e242640a29452c9ae572162ec9a8f5d13" + integrity sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" @@ -934,10 +1136,10 @@ "@emotion/utils" "0.11.3" "@emotion/weak-memoize" "0.2.5" -"@emotion/core@^10.0.20", "@emotion/core@^10.0.9": - version "10.0.27" - resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.27.tgz#7c3f78be681ab2273f3bf11ca3e2edc4a9dd1fdc" - integrity sha512-XbD5R36pVbohQMnKfajHv43g8EbN4NHdF6Zh9zg/C0nr0jqwOw3gYnC07Xj3yG43OYSRyrGsoQ5qPwc8ycvLZw== +"@emotion/core@^10.0.9", "@emotion/core@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3" + integrity sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA== dependencies: "@babel/runtime" "^7.5.5" "@emotion/cache" "^10.0.27" @@ -972,6 +1174,13 @@ dependencies: "@emotion/memoize" "0.7.4" +"@emotion/is-prop-valid@^0.8.6": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + "@emotion/memoize@0.7.4": version "0.7.4" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" @@ -1003,7 +1212,7 @@ "@emotion/serialize" "^0.11.15" "@emotion/utils" "0.11.3" -"@emotion/styled@^10.0.17": +"@emotion/styled@^10.0.23": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf" integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q== @@ -1805,6 +2014,11 @@ prop-types "^15.7.2" react-is "^16.8.0" +"@metamask/contract-metadata@^1.19.0": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.19.0.tgz#2f074bce7ab7ffd0d20e3905b1936da0749a0473" + integrity sha512-TklMuz7ZbFJ2Zc6C7I+9qL3J9J+4prs5Ok5MJzoxD/57Iq6espzArhpI275elVCFF9ci8IMvach1kH8+F04/hA== + "@metamask/controllers@^3.1.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-3.2.0.tgz#8ad2e63f7953d294712d9b5bacaea1c5261ce588" @@ -1891,10 +2105,10 @@ human-standard-token-abi "^1.0.2" safe-event-emitter "^1.0.1" -"@metamask/etherscan-link@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-1.3.0.tgz#ce5b9e0083f51386f8f462110b4094cf6243022c" - integrity sha512-2BLaSJLqOIq5CasneVqortc7sPMjgXDTdPv4dSjseF+RUtv/HPTSXZPhV2dFkGd/n+eCQoevPRVOFsVvuRnFeA== +"@metamask/etherscan-link@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-1.4.0.tgz#4631e9beec17de26b35b3ccd643ede2bae8ed811" + integrity sha512-4Bi72Y8/FQZbfTARyv+oWKGuECzdQ37cQKt88Eu5JPDrHAcRDZt4Bt7bWC9phUBrphAr1qbCKh9S90X9hW0pZg== "@metamask/forwarder@^1.1.0": version "1.1.0" @@ -1932,6 +2146,11 @@ gl-mat4 "1.1.4" gl-vec3 "1.0.3" +"@metamask/safe-event-emitter@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" + integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== + "@metamask/test-dapp@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@metamask/test-dapp/-/test-dapp-4.0.1.tgz#fbc66069687f0502ebb4c6ac0fa7c9862ea6563c" @@ -1978,26 +2197,37 @@ dependencies: mkdirp "^1.0.4" -"@popperjs/core@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.4.0.tgz#0e1bdf8d021e7ea58affade33d9d607e11365915" - integrity sha512-NMrDy6EWh9TPdSRiHmHH2ye1v5U0gBD7pRYwSwJvomx7Bm4GG04vu63dYiVzebLOx2obPpJugew06xVP0Nk7hA== +"@pmmmwh/react-refresh-webpack-plugin@^0.4.2": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz#1eec460596d200c0236bf195b078a5d1df89b766" + integrity sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ== + dependencies: + ansi-html "^0.0.7" + error-stack-parser "^2.0.6" + html-entities "^1.2.1" + native-url "^0.2.6" + schema-utils "^2.6.5" + source-map "^0.7.3" + +"@popperjs/core@^2.4.0", "@popperjs/core@^2.4.4", "@popperjs/core@^2.5.4": + version "2.5.4" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.5.4.tgz#de25b5da9f727985a3757fd59b5d028aba75841a" + integrity sha512-ZpKr+WTb8zsajqgDkvCEWgp6d5eJT6Q63Ng2neTbzBO76Lbe91vX/iVIW9dikq+Fs3yEo+ls4cxeXABD2LtcbQ== "@protobufjs/utf8@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= -"@reach/router@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.2.1.tgz#34ae3541a5ac44fa7796e5506a5d7274a162be4e" - integrity sha512-kTaX08X4g27tzIFQGRukaHmNbtMYDS3LEWIS8+l6OayGIw6Oyo1HIF/JzeuR2FoF9z6oV+x/wJSVSq4v8tcUGQ== +"@reach/router@^1.3.3": + version "1.3.4" + resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.4.tgz#d2574b19370a70c80480ed91f3da840136d10f8c" + integrity sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA== dependencies: - create-react-context "^0.2.1" + create-react-context "0.3.0" invariant "^2.2.3" prop-types "^15.6.1" react-lifecycles-compat "^3.0.4" - warning "^3.0.0" "@reduxjs/toolkit@^1.3.2": version "1.3.2" @@ -2142,58 +2372,63 @@ resolved "https://registry.yarnpkg.com/@stablelib/utf8/-/utf8-0.10.1.tgz#eecf54884da7b2bee235e3c70efb8cd5c07ba5bd" integrity sha512-+uM1YZ4MhBC82vt99prF7DXNGqhYmJ9cQ3p5qNowMNkkzn9OWEkqBvguBW3ChAt7JvqZ3SD5HJOfc6YgnfMTHw== -"@storybook/addon-actions@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.3.14.tgz#aacc4d2703fc200a4565bfaa9f5870ed70a6fe32" - integrity sha512-4lKrTMzw/r6VQiBY24v72WC3jibW7pc9BIJgtPpTmTUQWTxPnkmxDfT81pV4BjS1GFH9VCnU6f5fWK+5lrQlsw== +"@storybook/addon-actions@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.1.9.tgz#b6d185b8e4e73691acc428b59e4d331195d64a40" + integrity sha512-vYqwuaBHrjRbbuyf4WBc5uDhrSejVEEiCabuu4g00R3dN7P5Ne/tbSw9EkYbbrRKxlEhdkk83DU1/J/+mCY5jw== dependencies: - "@storybook/addons" "5.3.14" - "@storybook/api" "5.3.14" - "@storybook/client-api" "5.3.14" - "@storybook/components" "5.3.14" - "@storybook/core-events" "5.3.14" - "@storybook/theming" "5.3.14" + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/client-api" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/theming" "6.1.9" core-js "^3.0.1" - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" global "^4.3.2" - polished "^3.3.1" + lodash "^4.17.15" + polished "^3.4.4" prop-types "^15.7.2" - react "^16.8.3" - react-inspector "^4.0.0" - uuid "^3.3.2" + react-inspector "^5.0.1" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + uuid "^8.0.0" -"@storybook/addon-backgrounds@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-5.3.14.tgz#b1b7fb77a82cbdb30a995f2afba2c488c6f43647" - integrity sha512-wrrbVrXV81+iHSf0Ejf9E9vwzVYhvVn0WoqY1ccneEWVWgiPwnptOCS5yYzsCQ2Riye2QutqBvZtaa0k88oKFA== +"@storybook/addon-backgrounds@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.1.9.tgz#4e9647001b2f396f56428218480f541e3a8a0e60" + integrity sha512-0/nnbnWZqo4NjyHFxcCHkcU+t8uUdk///9jSXRs4swmOLIFRaftEc/ZJ2rScu1Sc7y0CQdbk1Jjyx5/2cHBQtw== dependencies: - "@storybook/addons" "5.3.14" - "@storybook/api" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/components" "5.3.14" - "@storybook/core-events" "5.3.14" - "@storybook/theming" "5.3.14" + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/theming" "6.1.9" core-js "^3.0.1" + global "^4.3.2" memoizerific "^1.11.3" - react "^16.8.3" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/addon-knobs@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-5.3.14.tgz#b8b753c7e64f7087668396d66aee253a51717a2d" - integrity sha512-pBpFOdeCR8n8w6QHK1adABt6YKf+Q4itfX0+AtZRGLvbGum9O+paihvP9EVYPlKiG+0T7Zv2vFCl6q6qFjF/Mw== +"@storybook/addon-knobs@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-6.1.9.tgz#49773931770effc208db094c61eeecbceaf5836b" + integrity sha512-aUKD9FaQGl/WOkGT6utElspYZJ7cBtUARe41JN59qOao7RNviabipQUASrjORcYUUU55sfKsLPEqQaEKB3x2bw== dependencies: - "@storybook/addons" "5.3.14" - "@storybook/api" "5.3.14" - "@storybook/client-api" "5.3.14" - "@storybook/components" "5.3.14" - "@storybook/core-events" "5.3.14" - "@storybook/theming" "5.3.14" - "@types/react-color" "^3.0.1" + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-api" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/theming" "6.1.9" copy-to-clipboard "^3.0.8" core-js "^3.0.1" escape-html "^1.0.3" - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" global "^4.3.2" lodash "^4.17.15" prop-types "^15.7.2" @@ -2201,175 +2436,209 @@ react-color "^2.17.0" react-lifecycles-compat "^3.0.4" react-select "^3.0.8" + regenerator-runtime "^0.13.7" -"@storybook/addons@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.14.tgz#ff96c2c46a617f777c3660395017d2aef5319f19" - integrity sha512-zoN1MYlArdThp93i+Ogil/pihyx8n7nkrdSO0j9HUh6jUsGeFFEluPQZdRFte9NIoY6ZWSWwuEMDgrv2Pw9r2Q== +"@storybook/addons@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.1.9.tgz#78f3cb27b7d934f091f311f89b6ca312d34f12b8" + integrity sha512-NRxdlGLmmSoVwlirVRgKC8xmW9cFkG+Sp5GEd4XkJDaaIg2vKR3RuFU9GuvIOVMxOhhERqhQ07bnDaAMKbFzGw== dependencies: - "@storybook/api" "5.3.14" - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/core-events" "5.3.14" + "@storybook/api" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/router" "6.1.9" + "@storybook/theming" "6.1.9" core-js "^3.0.1" global "^4.3.2" - util-deprecate "^1.0.2" + regenerator-runtime "^0.13.7" -"@storybook/api@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.14.tgz#8c2bb226a4a5de7974ee2ccce36986b72f462f1b" - integrity sha512-ANWRMTLEoAfu0IsXqbxmbTpxS8xTByZgLj20tH96bxgH1rJo9KAZnJ8A9kGYr+zklU8QnYvVIgmV3HESXII9zg== +"@storybook/api@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.1.9.tgz#3f9bf00b2b18fa02965079fe775bd713677b30a3" + integrity sha512-S9SXlSiMeI450NIbOnx3UU9TZNyVD7jcBCjfNzhj0PqzRX/IG5Usj+R88Jm6MSIDjtsVjrWRCou+PrCh2xMnlQ== dependencies: - "@reach/router" "^1.2.1" - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/core-events" "5.3.14" + "@reach/router" "^1.3.3" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/core-events" "6.1.9" "@storybook/csf" "0.0.1" - "@storybook/router" "5.3.14" - "@storybook/theming" "5.3.14" - "@types/reach__router" "^1.2.3" + "@storybook/router" "6.1.9" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.1.9" + "@types/reach__router" "^1.3.5" core-js "^3.0.1" - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" global "^4.3.2" lodash "^4.17.15" memoizerific "^1.11.3" - prop-types "^15.6.2" - react "^16.8.3" - semver "^6.0.0" - shallow-equal "^1.1.0" + regenerator-runtime "^0.13.7" store2 "^2.7.1" - telejson "^3.2.0" + telejson "^5.0.2" + ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/channel-postmessage@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.14.tgz#768c87411d98caf09fdd92539b9edaaed26d5965" - integrity sha512-XKHxMSwW3movfTDOashuYlVCX3Hp7+X+amXc/xhDDzbiYjy3/CVm3LlkkM6v451IVEdK6pue4ewqZQWJAYAAEQ== +"@storybook/channel-postmessage@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.1.9.tgz#5d73c67ba94bcf68b14138bba6c5bb0850c72c5e" + integrity sha512-tX7pD9Xrf1WsatpJqtJ6o8MlgxG7jH+oFhNPkGvUbWiolVDQmuDndwM8Hh1kUnOWlyE1AN5hlM7av8MY+9D3NA== dependencies: - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/core-events" "6.1.9" core-js "^3.0.1" global "^4.3.2" - telejson "^3.2.0" + qs "^6.6.0" + telejson "^5.0.2" -"@storybook/channels@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.14.tgz#9969e27761a80afb495bc1475f0173f9b6ef5a76" - integrity sha512-k9QBf9Kwe+iGmdEK/kW5xprqem2SPfBVwET6LWvJkWOl9UQ9VoMuCHgV55p0tzjcugaqWWKoF9+FRMWxWRfsQg== +"@storybook/channels@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.1.9.tgz#94f07ff3615b11c07d1902be6b6cd298c0eea55c" + integrity sha512-aV+KsZPuoTtFKSMUkSCyVlVmtVHkSH35dSbyMazjlUD9cOLwkXB1s+LZL/GxxSR6a6uR75V0QWxItfNxaJETMQ== dependencies: core-js "^3.0.1" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" -"@storybook/client-api@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.14.tgz#5f4b199d2f2b193f9f5a856c5eb8be43a9113d12" - integrity sha512-1qx1NIwto5F9N24Fb6VzKyDzeaZHtWTZ7afPrg56e1tUu7jbog7rELdRezk8+YAujveyMDJu4MxnOSP01sv7YQ== +"@storybook/client-api@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.1.9.tgz#d4a8d38bc657f26e4837831b961e085da1954d51" + integrity sha512-b2DFaGAS5G2ly3UJY5NJNXh/LxgLgSJLbqPL4t48MFW5XjH+rmEWXE9P+ujCaPclH1/y7mZRMprDj3ycDbRo3Q== dependencies: - "@storybook/addons" "5.3.14" - "@storybook/channel-postmessage" "5.3.14" - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/core-events" "5.3.14" + "@storybook/addons" "6.1.9" + "@storybook/channel-postmessage" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/core-events" "6.1.9" "@storybook/csf" "0.0.1" - "@types/webpack-env" "^1.15.0" + "@types/qs" "^6.9.0" + "@types/webpack-env" "^1.15.3" core-js "^3.0.1" - eventemitter3 "^4.0.0" global "^4.3.2" - is-plain-object "^3.0.0" lodash "^4.17.15" memoizerific "^1.11.3" qs "^6.6.0" + regenerator-runtime "^0.13.7" stable "^0.1.8" - ts-dedent "^1.1.0" + store2 "^2.7.1" + ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/client-logger@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.14.tgz#85068f1b665a52163191eb5976f1581bce6df0e4" - integrity sha512-YCHEsOvo6zPb4udlyAwqr5W0Kv9mAEQmcX73w9IDvAxbjR00T7empW7qmbjvviftKB/5MEgDdiYbj64ccs3aqg== +"@storybook/client-logger@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.1.9.tgz#1d61a64000d4691780d75e19b78fd44adfdb5d9c" + integrity sha512-i7Q2ky9+Jwv+wmnlOGxmDOEdmaTIB69OQnnZNWGKufOwoIMjn6QO0VifARyA9W++nNSijjJ5th84tLJALaoCTA== dependencies: core-js "^3.0.1" - -"@storybook/components@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.14.tgz#0f2f90113674e14ee74d5d16d6b3b1220cb0fa16" - integrity sha512-AsjkIFBrrqcBDLxGdmUHiauZo5gOL65eXx8WA7/yJDF8s45VVZX5Z0buOnjFyEhGVus02gwTov8da2irjL862A== - dependencies: - "@storybook/client-logger" "5.3.14" - "@storybook/theming" "5.3.14" - "@types/react-syntax-highlighter" "11.0.2" - "@types/react-textarea-autosize" "^4.3.3" - core-js "^3.0.1" global "^4.3.2" - lodash "^4.17.15" - markdown-to-jsx "^6.9.1" - memoizerific "^1.11.3" - polished "^3.3.1" - popper.js "^1.14.7" - prop-types "^15.7.2" - react "^16.8.3" - react-dom "^16.8.3" - react-focus-lock "^2.1.0" - react-helmet-async "^1.0.2" - react-popper-tooltip "^2.8.3" - react-syntax-highlighter "^11.0.2" - react-textarea-autosize "^7.1.0" - simplebar-react "^1.0.0-alpha.6" - ts-dedent "^1.1.0" -"@storybook/core-events@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.14.tgz#d476eea7032670db1a84bef7e5baadb04c2de529" - integrity sha512-VCPLKqRugsOSx/smMJiJOvRgAzTrMpsbRuFw48kBGkQMP9TEV82Qe/341dv+f4GllPyBZyANG0p0m5+w7ZCURQ== +"@storybook/components@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.1.9.tgz#f25d18f3a410cc7e9549ddb3c971c40d9108d4d8" + integrity sha512-cYYm3fHo9MW0bbl47lu1ncwulV7V9VEF8FC96uvys07oaCTFWKzQ0z/FD0nCqeK6eEz1+SEqnGwLFmOtqlRXDQ== + dependencies: + "@popperjs/core" "^2.4.4" + "@storybook/client-logger" "6.1.9" + "@storybook/csf" "0.0.1" + "@storybook/theming" "6.1.9" + "@types/overlayscrollbars" "^1.9.0" + "@types/react-color" "^3.0.1" + "@types/react-syntax-highlighter" "11.0.4" + core-js "^3.0.1" + fast-deep-equal "^3.1.1" + global "^4.3.2" + lodash "^4.17.15" + markdown-to-jsx "^6.11.4" + memoizerific "^1.11.3" + overlayscrollbars "^1.10.2" + polished "^3.4.4" + react-color "^2.17.0" + react-popper-tooltip "^3.1.0" + react-syntax-highlighter "^13.5.0" + react-textarea-autosize "^8.1.1" + ts-dedent "^2.0.0" + +"@storybook/core-events@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.1.9.tgz#0a88281837d1aa657a93a9abf7f5aad65b8d68e7" + integrity sha512-oOpqpjCTJCt0U5lnQ16OZU0iKIDh2/MIg4yrnDw+Pt6zGyX3zSvtB+9W8LQFnMwm+cXaNmiizGwt/W+4OiORjQ== dependencies: core-js "^3.0.1" -"@storybook/core@5.3.14", "@storybook/core@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.3.14.tgz#510f204219695045f249733bf94018e52c7b1448" - integrity sha512-Y57cchCRw1vvZe8OhMmgAkaHciGLm2eztdfzZMUmeHH8csBt/0RO5gYzOhWDGgdC2D9HSlaysZEDJ6sH3PChlw== +"@storybook/core@6.1.9", "@storybook/core@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.1.9.tgz#e6575e294cb4d2d9b57d5976a145cae8f4a88594" + integrity sha512-guz+R6eDX923Cw7NqgS5PrpTmmjDB+m5X1iF9pwKlpPTfzIiT/wTzJm4PwhFoGONNoXrItObX/6hW6OQbX4aOA== dependencies: - "@babel/plugin-proposal-class-properties" "^7.7.0" - "@babel/plugin-proposal-object-rest-spread" "^7.6.2" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" - "@babel/plugin-transform-react-constant-elements" "^7.2.0" - "@babel/preset-env" "^7.4.5" - "@storybook/addons" "5.3.14" - "@storybook/channel-postmessage" "5.3.14" - "@storybook/client-api" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/core-events" "5.3.14" + "@babel/core" "^7.12.3" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-decorators" "^7.12.1" + "@babel/plugin-proposal-export-default-from" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.1" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-env" "^7.12.1" + "@babel/preset-react" "^7.12.1" + "@babel/preset-typescript" "^7.12.1" + "@babel/register" "^7.12.1" + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/channel-postmessage" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-api" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" "@storybook/csf" "0.0.1" - "@storybook/node-logger" "5.3.14" - "@storybook/router" "5.3.14" - "@storybook/theming" "5.3.14" - "@storybook/ui" "5.3.14" + "@storybook/node-logger" "6.1.9" + "@storybook/router" "6.1.9" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.1.9" + "@storybook/ui" "6.1.9" + "@types/glob-base" "^0.3.0" + "@types/micromatch" "^4.0.1" + "@types/node-fetch" "^2.5.4" airbnb-js-shims "^2.2.1" ansi-to-html "^0.6.11" autoprefixer "^9.7.2" - babel-plugin-add-react-displayname "^0.0.5" + babel-loader "^8.0.6" babel-plugin-emotion "^10.0.20" - babel-plugin-macros "^2.7.0" + babel-plugin-macros "^2.8.0" babel-preset-minify "^0.5.0 || 0.6.0-alpha.5" + better-opn "^2.0.0" boxen "^4.1.0" case-sensitive-paths-webpack-plugin "^2.2.0" - chalk "^3.0.0" - cli-table3 "0.5.1" - commander "^4.0.1" + chalk "^4.0.0" + cli-table3 "0.6.0" + commander "^5.0.0" core-js "^3.0.1" - corejs-upgrade-webpack-plugin "^2.2.0" - css-loader "^3.0.0" + cpy "^8.1.1" + css-loader "^3.5.3" detect-port "^1.3.0" dotenv-webpack "^1.7.0" - ejs "^2.7.4" + ejs "^3.1.2" express "^4.17.0" - file-loader "^4.2.0" + file-loader "^6.0.0" file-system-cache "^1.0.5" - find-cache-dir "^3.0.0" find-up "^4.1.0" - fs-extra "^8.0.1" + fork-ts-checker-webpack-plugin "^4.1.4" + fs-extra "^9.0.0" + glob "^7.1.6" glob-base "^0.3.0" + glob-promise "^3.4.0" global "^4.3.2" - html-webpack-plugin "^4.0.0-beta.2" + html-webpack-plugin "^4.2.1" inquirer "^7.0.0" interpret "^2.0.0" ip "^1.1.5" @@ -2377,30 +2646,31 @@ lazy-universal-dotenv "^3.0.1" micromatch "^4.0.2" node-fetch "^2.6.0" - open "^7.0.0" - pnp-webpack-plugin "1.5.0" + pkg-dir "^4.2.0" + pnp-webpack-plugin "1.6.4" postcss-flexbugs-fixes "^4.1.0" postcss-loader "^3.0.0" pretty-hrtime "^1.0.3" qs "^6.6.0" - raw-loader "^3.1.0" - react-dev-utils "^9.0.0" - regenerator-runtime "^0.13.3" - resolve "^1.11.0" + raw-loader "^4.0.1" + react-dev-utils "^10.0.0" + regenerator-runtime "^0.13.7" resolve-from "^5.0.0" - semver "^6.0.0" serve-favicon "^2.5.0" - shelljs "^0.8.3" - style-loader "^1.0.0" - terser-webpack-plugin "^2.1.2" - ts-dedent "^1.1.0" + shelljs "^0.8.4" + stable "^0.1.8" + style-loader "^1.2.1" + telejson "^5.0.2" + terser-webpack-plugin "^3.0.0" + ts-dedent "^2.0.0" unfetch "^4.1.0" - url-loader "^2.0.1" + url-loader "^4.0.0" util-deprecate "^1.0.2" - webpack "^4.33.0" + webpack "^4.44.2" webpack-dev-middleware "^3.7.0" + webpack-filter-warnings-plugin "^1.2.1" webpack-hot-middleware "^2.25.0" - webpack-virtual-modules "^0.2.0" + webpack-virtual-modules "^0.2.2" "@storybook/csf@0.0.1": version "0.0.1" @@ -2409,59 +2679,63 @@ dependencies: lodash "^4.17.15" -"@storybook/node-logger@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.3.14.tgz#5e4e02585b37754bbebb8810ffb17c8ce706a1f8" - integrity sha512-/phRS49/hMZ5SU4EKUxX2kFepm9iw1cJBzggOz0GA1Yj4r9g1TA1H+OD7QvZvVTC3AESf/ZUJyaqnXEh/l+hpg== +"@storybook/node-logger@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.1.9.tgz#c63a61f72209d76eeeffe9d151fec043864b9438" + integrity sha512-2gP9BSBXEOGIcUyzRdIkIJi1UEINUAIyuv9bfKODo4GfujRg7DLz/mpi/FdwmulGg/viXWSXa6ccb6ziIgY9RA== dependencies: "@types/npmlog" "^4.1.2" - chalk "^3.0.0" + chalk "^4.0.0" core-js "^3.0.1" npmlog "^4.1.2" pretty-hrtime "^1.0.3" - regenerator-runtime "^0.13.3" -"@storybook/react@^5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-5.3.14.tgz#6715d9ee64e1c7b5c1e45cdbbf6df809bad60b8c" - integrity sha512-8n0oCkaxFMrimngxnISEQFkHGSF5z65Lh1XPypjIndIJ0b/IVWRJcUEh3M3xOaydFatEG+lfQbF/5OznyYEefA== +"@storybook/react@^6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-6.1.9.tgz#063427015b3d0ce582b1b6b7826d40d963d265ce" + integrity sha512-HJWHQE+eCC7sz1vqvgmBMn2sA1uc0ByEj+NeSgyi45jBFI+Ke4a8hxx6k5XA7k9gLznqG8TPGg0z6EdQTJTLkQ== dependencies: - "@babel/plugin-transform-react-constant-elements" "^7.6.3" - "@babel/preset-flow" "^7.0.0" - "@babel/preset-react" "^7.0.0" - "@storybook/addons" "5.3.14" - "@storybook/core" "5.3.14" - "@storybook/node-logger" "5.3.14" - "@svgr/webpack" "^4.0.3" - "@types/webpack-env" "^1.15.0" + "@babel/preset-flow" "^7.12.1" + "@babel/preset-react" "^7.12.1" + "@pmmmwh/react-refresh-webpack-plugin" "^0.4.2" + "@storybook/addons" "6.1.9" + "@storybook/core" "6.1.9" + "@storybook/node-logger" "6.1.9" + "@storybook/semver" "^7.3.2" + "@types/webpack-env" "^1.15.3" babel-plugin-add-react-displayname "^0.0.5" babel-plugin-named-asset-import "^0.3.1" - babel-plugin-react-docgen "^4.0.0" + babel-plugin-react-docgen "^4.2.1" core-js "^3.0.1" global "^4.3.2" lodash "^4.17.15" - mini-css-extract-plugin "^0.7.0" prop-types "^15.7.2" - react-dev-utils "^9.0.0" - regenerator-runtime "^0.13.3" - semver "^6.0.0" - ts-dedent "^1.1.0" - webpack "^4.33.0" + react-dev-utils "^10.0.0" + react-docgen-typescript-plugin "^0.6.2" + react-refresh "^0.8.3" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + webpack "^4.44.2" -"@storybook/router@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.14.tgz#6535267624da5f54971c37e497df1c161f65be8f" - integrity sha512-O0KwQFncdBeq+O2Aq8UAFBVWjWmP5rtqoacUOFSGkXgObOnyniEraLiPH7rPtq2dAlSpgYI9+srQAZfo52Hz2A== +"@storybook/router@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.1.9.tgz#c0b24dc3ab53d58541b81c7abea2f11d7fbbebf6" + integrity sha512-kIlmSFBnqI198oMCncFZR7MxoV5/kP6KS0paFcyu1XE1zO2ovV6eQZ8pPpOjSsD/ISu4Y44uE+ZDNsEehjj6GQ== dependencies: - "@reach/router" "^1.2.1" - "@storybook/csf" "0.0.1" - "@types/reach__router" "^1.2.3" + "@reach/router" "^1.3.3" + "@types/reach__router" "^1.3.5" core-js "^3.0.1" global "^4.3.2" - lodash "^4.17.15" memoizerific "^1.11.3" qs "^6.6.0" - util-deprecate "^1.0.2" + +"@storybook/semver@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" + integrity sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg== + dependencies: + core-js "^3.6.5" + find-up "^4.1.0" "@storybook/storybook-deployer@^2.8.6": version "2.8.6" @@ -2474,63 +2748,59 @@ shelljs "^0.8.1" yargs "^15.0.0" -"@storybook/theming@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.14.tgz#4923739ad0d7d673b7844f27da8a3c6cf118790f" - integrity sha512-raqXC3yJycEt1CrCAfnBYUA6pyJI80E9M26EeQl3UfytJOL6euprOi+D17QvxqBn7jmmf9ZDw5XRkvJhQ17Y7Q== +"@storybook/theming@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.1.9.tgz#8c584aa623f3d6e33b1e3b3de2ec1f41bdc5d9ab" + integrity sha512-orzMQkyEhAQEi0E9iwmUkzh5yPHoYGBz17t2aydDeT6oGKii6if8Mq2oPVycfVKZ84QO7GFAS9q1nVCRcuD8oA== dependencies: - "@emotion/core" "^10.0.20" - "@emotion/styled" "^10.0.17" - "@storybook/client-logger" "5.3.14" + "@emotion/core" "^10.1.1" + "@emotion/is-prop-valid" "^0.8.6" + "@emotion/styled" "^10.0.23" + "@storybook/client-logger" "6.1.9" core-js "^3.0.1" deep-object-diff "^1.1.0" emotion-theming "^10.0.19" global "^4.3.2" memoizerific "^1.11.3" - polished "^3.3.1" - prop-types "^15.7.2" + polished "^3.4.4" resolve-from "^5.0.0" - ts-dedent "^1.1.0" + ts-dedent "^2.0.0" -"@storybook/ui@5.3.14": - version "5.3.14" - resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.3.14.tgz#f3c49241d615bb20cb6facef84b4c432a85d814b" - integrity sha512-4zQOxpcvbKqRevmFw3Er6AWr2MeEMQfnuYh4Vm5G5YpiTyM6PU0VTVRzKnkEbNBcgjClD7nwXSbkUJjW6MJ8SA== +"@storybook/ui@6.1.9": + version "6.1.9" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.1.9.tgz#1ed3168d9fe5827285c13d8507dd1fd872830542" + integrity sha512-4MK5iTf7kI5DYVeWRiD6lkXdd0S6eiQJu9lvWqMOQJLOH5Bq77g0Ejo+38RTEQpV6we7hCPWWnRXQBjmJ2+19w== dependencies: - "@emotion/core" "^10.0.20" - "@storybook/addons" "5.3.14" - "@storybook/api" "5.3.14" - "@storybook/channels" "5.3.14" - "@storybook/client-logger" "5.3.14" - "@storybook/components" "5.3.14" - "@storybook/core-events" "5.3.14" - "@storybook/router" "5.3.14" - "@storybook/theming" "5.3.14" + "@emotion/core" "^10.1.1" + "@storybook/addons" "6.1.9" + "@storybook/api" "6.1.9" + "@storybook/channels" "6.1.9" + "@storybook/client-logger" "6.1.9" + "@storybook/components" "6.1.9" + "@storybook/core-events" "6.1.9" + "@storybook/router" "6.1.9" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.1.9" + "@types/markdown-to-jsx" "^6.11.0" copy-to-clipboard "^3.0.8" core-js "^3.0.1" core-js-pure "^3.0.1" + downshift "^6.0.6" emotion-theming "^10.0.19" - fast-deep-equal "^2.0.1" - fuse.js "^3.4.6" + fuse.js "^3.6.1" global "^4.3.2" lodash "^4.17.15" - markdown-to-jsx "^6.9.3" + markdown-to-jsx "^6.11.4" memoizerific "^1.11.3" - polished "^3.3.1" - prop-types "^15.7.2" + polished "^3.4.4" qs "^6.6.0" - react "^16.8.3" - react-dom "^16.8.3" react-draggable "^4.0.3" react-helmet-async "^1.0.2" react-hotkeys "2.0.0" react-sizeme "^2.6.7" - regenerator-runtime "^0.13.2" + regenerator-runtime "^0.13.7" resolve-from "^5.0.0" - semver "^6.0.0" store2 "^2.7.1" - telejson "^3.2.0" - util-deprecate "^1.0.2" "@stylelint/postcss-css-in-js@^0.37.1": version "0.37.2" @@ -2547,111 +2817,6 @@ remark "^12.0.0" unist-util-find-all-after "^3.0.1" -"@svgr/babel-plugin-add-jsx-attribute@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" - integrity sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig== - -"@svgr/babel-plugin-remove-jsx-attribute@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz#297550b9a8c0c7337bea12bdfc8a80bb66f85abc" - integrity sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ== - -"@svgr/babel-plugin-remove-jsx-empty-expression@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz#c196302f3e68eab6a05e98af9ca8570bc13131c7" - integrity sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w== - -"@svgr/babel-plugin-replace-jsx-attribute-value@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz#310ec0775de808a6a2e4fd4268c245fd734c1165" - integrity sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w== - -"@svgr/babel-plugin-svg-dynamic-title@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.0.tgz#826c7d30f8f98f26bdb4af205a5dfbf1f04d80ec" - integrity sha512-3eI17Pb3jlg3oqV4Tie069n1SelYKBUpI90txDcnBWk4EGFW+YQGyQjy6iuJAReH0RnpUJ9jUExrt/xniGvhqw== - -"@svgr/babel-plugin-svg-em-dimensions@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz#9a94791c9a288108d20a9d2cc64cac820f141391" - integrity sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w== - -"@svgr/babel-plugin-transform-react-native-svg@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz#151487322843359a1ca86b21a3815fd21a88b717" - integrity sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw== - -"@svgr/babel-plugin-transform-svg-component@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz#5f1e2f886b2c85c67e76da42f0f6be1b1767b697" - integrity sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw== - -"@svgr/babel-preset@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.3.0.tgz#8a0bcc95ea7124762699e87a45ab11f408e8765e" - integrity sha512-Lgy1RJiZumGtv6yJroOxzFuL64kG/eIcivJQ7y9ljVWL+0QXvFz4ix1xMrmjMD+rpJWwj50ayCIcFelevG/XXg== - dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^4.2.0" - "@svgr/babel-plugin-remove-jsx-attribute" "^4.2.0" - "@svgr/babel-plugin-remove-jsx-empty-expression" "^4.2.0" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^4.2.0" - "@svgr/babel-plugin-svg-dynamic-title" "^4.3.0" - "@svgr/babel-plugin-svg-em-dimensions" "^4.2.0" - "@svgr/babel-plugin-transform-react-native-svg" "^4.2.0" - "@svgr/babel-plugin-transform-svg-component" "^4.2.0" - -"@svgr/core@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.0.tgz#4a2bcb41e0946679a2ebe6b5bb2edd88ed35706b" - integrity sha512-Ycu1qrF5opBgKXI0eQg3ROzupalCZnSDETKCK/3MKN4/9IEmt3jPX/bbBjftklnRW+qqsCEpO0y/X9BTRw2WBg== - dependencies: - "@svgr/plugin-jsx" "^4.3.0" - camelcase "^5.3.1" - cosmiconfig "^5.2.0" - -"@svgr/hast-util-to-babel-ast@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.2.0.tgz#dd743435a5f3a8e84a1da067f27b5fae3d7b6b63" - integrity sha512-IvAeb7gqrGB5TH9EGyBsPrMRH/QCzIuAkLySKvH2TLfLb2uqk98qtJamordRQTpHH3e6TORfBXoTo7L7Opo/Ow== - dependencies: - "@babel/types" "^7.4.0" - -"@svgr/plugin-jsx@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.0.tgz#6be203abc58e187545aa1b9a51df30d051b658e2" - integrity sha512-0ab8zJdSOTqPfjZtl89cjq2IOmXXUYV3Fs7grLT9ur1Al3+x3DSp2+/obrYKUGbQUnLq96RMjSZ7Icd+13vwlQ== - dependencies: - "@babel/core" "^7.4.3" - "@svgr/babel-preset" "^4.3.0" - "@svgr/hast-util-to-babel-ast" "^4.2.0" - rehype-parse "^6.0.0" - unified "^7.1.0" - vfile "^4.0.0" - -"@svgr/plugin-svgo@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-4.2.0.tgz#2a594a2d3312955e75fd87dc77ae51f377c809f3" - integrity sha512-zUEKgkT172YzHh3mb2B2q92xCnOAMVjRx+o0waZ1U50XqKLrVQ/8dDqTAtnmapdLsGurv8PSwenjLCUpj6hcvw== - dependencies: - cosmiconfig "^5.2.0" - merge-deep "^3.0.2" - svgo "^1.2.1" - -"@svgr/webpack@^4.0.3": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.3.0.tgz#4462e05070d91c04806b99c30a703fb2b50b2bb9" - integrity sha512-rYcwi1pUnaZoOUEa8xhrX10FHnONvube1WBoJ5PQf/Cbl0GuiUUSdXSVaFgxWdeyv6jCG0vWH1mrCHhspaJv1Q== - dependencies: - "@babel/core" "^7.4.3" - "@babel/plugin-transform-react-constant-elements" "^7.0.0" - "@babel/preset-env" "^7.4.3" - "@babel/preset-react" "^7.0.0" - "@svgr/core" "^4.3.0" - "@svgr/plugin-jsx" "^4.3.0" - "@svgr/plugin-svgo" "^4.2.0" - loader-utils "^1.2.3" - "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -2686,6 +2851,11 @@ "@babel/runtime" "^7.10.3" "@testing-library/dom" "^7.17.1" +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + "@types/aria-query@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" @@ -2698,30 +2868,46 @@ dependencies: "@types/node" "*" +"@types/braces@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb" + integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw== + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== -"@types/events@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/glob-base@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/glob-base/-/glob-base-0.3.0.tgz#a581d688347e10e50dd7c17d6f2880a10354319d" + integrity sha1-pYHWiDR+EOUN18F9byiAoQNUMZ0= -"@types/glob@^7.1.1": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" - integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== +"@types/glob@*", "@types/glob@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== dependencies: - "@types/events" "*" "@types/minimatch" "*" "@types/node" "*" +"@types/hast@^2.0.0": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.1.tgz#b16872f2a6144c7025f296fb9636a667ebb79cd9" + integrity sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q== + dependencies: + "@types/unist" "*" + "@types/history@*": version "4.7.3" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.3.tgz#856c99cdc1551d22c22b18b5402719affec9839a" integrity sha512-cS5owqtwzLN5kY+l+KgKdRJ/Cee8tlmQoGQuIE9tWnSmS3JMKzmxo2HIAk2wODMifGwO20d62xZQLYz+RLfXmw== +"@types/html-minifier-terser@^5.0.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" + integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== + "@types/invariant@^2.2.29": version "2.2.29" resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.29.tgz#aa845204cd0a289f65d47e0de63a6a815e30cc66" @@ -2752,10 +2938,10 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/json-schema@^7.0.4": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== "@types/json5@^0.0.29": version "0.0.29" @@ -2767,6 +2953,20 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.124.tgz#16fb067a8fc4be42f044c505d8b5316c6f54de93" integrity sha512-6bKEUVbHJ8z34jisA7lseJZD2g31SIvee3cGX2KEZCS4XXWNbjPZpmO1/2rGNR9BhGtaYr6iYXPl1EzRrDAFTA== +"@types/markdown-to-jsx@^6.11.0": + version "6.11.3" + resolved "https://registry.yarnpkg.com/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz#cdd1619308fecbc8be7e6a26f3751260249b020e" + integrity sha512-30nFYpceM/ZEvhGiqWjm5quLUxNeld0HCzJEXMZZDpq53FPkS85mTwkWtCXzCqq8s5JYLgM5W392a02xn8Bdaw== + dependencies: + "@types/react" "*" + +"@types/micromatch@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" + integrity sha512-my6fLBvpY70KattTNzYOK6KU1oR1+UCz9ug/JbcF5UrEmeCt9P7DV2t7L8+t18mMPINqGQCE4O8PLOPbI84gxw== + dependencies: + "@types/braces" "*" + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -2777,6 +2977,14 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= +"@types/node-fetch@^2.5.4": + version "2.5.7" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" + integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node@*", "@types/node@^12.0.12", "@types/node@^12.12.6": version "12.19.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.1.tgz#303f74c8a2b35644594139e948b2be470ae1186f" @@ -2807,6 +3015,11 @@ resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.2.tgz#d070fe6a6b78755d1092a3dc492d34c3d8f871c4" integrity sha512-4QQmOF5KlwfxJ5IGXFIudkeLCdMABz03RcUXu+LCb24zmln8QW6aDjuGl4d4XPVLf2j+FnjelHTP7dvceAFbhA== +"@types/overlayscrollbars@^1.9.0": + version "1.12.0" + resolved "https://registry.yarnpkg.com/@types/overlayscrollbars/-/overlayscrollbars-1.12.0.tgz#98456caceca8ad73bd5bb572632a585074e70764" + integrity sha512-h/pScHNKi4mb+TrJGDon8Yb06ujFG0mSg12wIO0sWMUF3dQIe2ExRRdNRviaNt9IjxIiOfnRr7FsQAdHwK4sMg== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -2834,10 +3047,15 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== -"@types/reach__router@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.2.6.tgz#b14cf1adbd1a365d204bbf6605cd9dd7b8816c87" - integrity sha512-Oh5DAVr/L2svBvubw6QEFpXGu295Y406BPs4i9t1n2pp7M+q3pmCmhzb9oZV5wncR41KCD3NHl1Yhi7uKnTPsA== +"@types/qs@^6.9.0": + version "6.9.5" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" + integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== + +"@types/reach__router@^1.3.5": + version "1.3.6" + resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.6.tgz#413417ce74caab331c70ce6a03a4c825188e4709" + integrity sha512-RHYataCUPQnt+GHoASyRLq6wmZ0n8jWlBW8Lxcwd30NN6vQfbmTeoSDfkgxO0S1lEzArp8OFDsq5KIs7FygjtA== dependencies: "@types/history" "*" "@types/react" "*" @@ -2849,10 +3067,10 @@ dependencies: "@types/react" "*" -"@types/react-syntax-highlighter@11.0.2": - version "11.0.2" - resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz#a2e3ff657d7c47813f80ca930f3d959c31ec51e3" - integrity sha512-iMNcixH8330f2dq0RY+VOXCP8JFehgmOhLOtnO85Ty+qu0fHXJNEqWx5VuFv8v0aEq0U/N9d/k1yvA+c6PEmPw== +"@types/react-syntax-highlighter@11.0.4": + version "11.0.4" + resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz#d86d17697db62f98046874f62fdb3e53a0bbc4cd" + integrity sha512-9GfTo3a0PHwQeTVoqs0g5bS28KkSY48pp5659wA+Dp4MqceDEa8EHBqrllJvvtyusszyJhViUEap0FDvlk/9Zg== dependencies: "@types/react" "*" @@ -2863,13 +3081,6 @@ dependencies: "@types/react" "*" -"@types/react-textarea-autosize@^4.3.3": - version "4.3.5" - resolved "https://registry.yarnpkg.com/@types/react-textarea-autosize/-/react-textarea-autosize-4.3.5.tgz#6c4d2753fa1864c98c0b2b517f67bb1f6e4c46de" - integrity sha512-PiDL83kPMTolyZAWW3lyzO6ktooTb9tFTntVy7CA83/qFLWKLJ5bLeRboy6J6j3b1e8h2Eec6gBTEOOJRjV14A== - dependencies: - "@types/react" "*" - "@types/react-transition-group@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d" @@ -2899,6 +3110,16 @@ dependencies: "@types/node" "*" +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/tapable@*", "@types/tapable@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" + integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== + "@types/testing-library__react-hooks@^3.0.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.2.0.tgz#52f3a109bef06080e3b1e3ae7ea1c014ce859897" @@ -2907,32 +3128,43 @@ "@types/react" "*" "@types/react-test-renderer" "*" +"@types/uglify-js@*": + version "3.11.1" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.11.1.tgz#97ff30e61a0aa6876c270b5f538737e2d6ab8ceb" + integrity sha512-7npvPKV+jINLu1SpSYVWG8KvyJBhBa8tmzMMdDoVc2pWUYHN8KIXlPJhjJ4LT97c4dXJA2SHL/q6ADbDriZN+Q== + dependencies: + source-map "^0.6.1" + "@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== -"@types/vfile-message@*": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/vfile-message/-/vfile-message-1.0.1.tgz#e1e9895cc6b36c462d4244e64e6d0b6eaf65355a" - integrity sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA== +"@types/webpack-env@^1.15.3": + version "1.16.0" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.0.tgz#8c0a9435dfa7b3b1be76562f3070efb3f92637b4" + integrity sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw== + +"@types/webpack-sources@*": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.0.0.tgz#08216ab9be2be2e1499beaebc4d469cec81e82a7" + integrity sha512-a5kPx98CNFRKQ+wqawroFunvFqv7GHm/3KOI52NY9xWADgc8smu4R6prt4EU/M4QfVjvgBkMqU4fBhw3QfMVkg== dependencies: "@types/node" "*" - "@types/unist" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" -"@types/vfile@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/vfile/-/vfile-3.0.2.tgz#19c18cd232df11ce6fa6ad80259bc86c366b09b9" - integrity sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw== +"@types/webpack@^4.41.8": + version "4.41.25" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.25.tgz#4d3b5aecc4e44117b376280fbfd2dc36697968c4" + integrity sha512-cr6kZ+4m9lp86ytQc1jPOJXgINQyz3kLLunZ57jznW+WIAL0JqZbGubQk4GlD42MuQL5JGOABrxdpqqWeovlVQ== dependencies: + "@types/anymatch" "*" "@types/node" "*" - "@types/unist" "*" - "@types/vfile-message" "*" - -"@types/webpack-env@^1.15.0": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.0.tgz#bd9956d5044b1fb43e869a9ba9148862ff98d9fd" - integrity sha512-TfcyNecCz8Z9/s90gBOBniyzZrTru8u2Vp0VZODq4KEBaQu8bfXvu7o/KUOecMpzjbFPUA7aqgSq628Iue5BQg== + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" "@types/yargs-parser@*": version "15.0.0" @@ -2946,152 +3178,163 @@ dependencies: "@types/yargs-parser" "*" -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== dependencies: - "@webassemblyjs/wast-printer" "1.8.5" + "@webassemblyjs/wast-printer" "1.9.0" -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" + "@webassemblyjs/ast" "1.9.0" -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" +"@webpack-contrib/schema-utils@^1.0.0-beta.0": + version "1.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@webpack-contrib/schema-utils/-/schema-utils-1.0.0-beta.0.tgz#bf9638c9464d177b48209e84209e23bee2eb4f65" + integrity sha512-LonryJP+FxQQHsjGBi6W786TQB1Oym+agTpY0c+Kj8alnIw+DLUJb6SI8Y1GHGhLCH1yPRrucjObUmxNICQ1pg== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chalk "^2.3.2" + strip-ansi "^4.0.0" + text-table "^0.2.0" + webpack-log "^1.1.2" + "@wry/equality@^0.1.2": version "0.1.9" resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.9.tgz#b13e18b7a8053c6858aa6c85b54911fb31e3a909" @@ -3271,10 +3514,10 @@ acorn@^3.0.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= -acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.2.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== +acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" @@ -3324,23 +3567,18 @@ addons-linter@1.14.0: optionalDependencies: fsevents "2.0.7" -address@1.0.3, address@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" - integrity sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg== +address@1.1.2, address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -adjust-sourcemap-loader@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.2.0.tgz#e33fde95e50db9f2a802e3647e311d2fc5000c69" - integrity sha512-958oaHHVEXMvsY7v7cC5gEkNIcoaAVIhZ4mBReYVZJOTP9IgKmzLjIOhTtzpLMu+qriXvLsVjJ155EeInp45IQ== +adjust-sourcemap-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz#5ae12fb5b7b1c585e80bbb5a63ec163a1a45e61e" + integrity sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw== dependencies: - assert "^1.3.0" - camelcase "^1.2.1" - loader-utils "^1.1.0" - lodash.assign "^4.0.1" - lodash.defaults "^3.1.2" - object-path "^0.9.2" - regex-parser "^2.2.9" + loader-utils "^2.0.0" + regex-parser "^2.2.11" adm-zip@0.4.11: version "0.4.11" @@ -3452,10 +3690,10 @@ ajv-keywords@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== ajv-merge-patch@4.1.0: version "4.1.0" @@ -3483,7 +3721,7 @@ ajv@^4.7.0: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.5.5, ajv@^6.9.1: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5, ajv@^6.9.1: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3579,7 +3817,7 @@ ansi-gray@^0.1.1: dependencies: ansi-wrap "0.1.0" -ansi-html@0.0.7: +ansi-html@0.0.7, ansi-html@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= @@ -3812,6 +4050,11 @@ aria-query@^4.2.2: "@babel/runtime" "^7.10.2" "@babel/runtime-corejs3" "^7.10.2" +arity-n@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745" + integrity sha1-2edrEXM+CFacCEeuezmyhgswt0U= + arr-diff@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" @@ -3876,11 +4119,6 @@ array-filter@^1.0.0: resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= -array-filter@~0.0.0: - version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" - integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= - array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -3920,16 +4158,6 @@ array-last@^1.1.1: dependencies: is-number "^4.0.0" -array-map@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= - array-slice@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" @@ -3949,7 +4177,7 @@ array-sort@^1.0.0: get-value "^2.0.6" kind-of "^5.0.2" -array-union@^1.0.1: +array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= @@ -4021,7 +4249,7 @@ arrify@^2.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== -asap@^2.0.0, asap@^2.0.6, asap@~2.0.3: +asap@^2.0.0, asap@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -4082,7 +4310,7 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -assert@^1.1.1, assert@^1.3.0, assert@^1.4.0, assert@^1.4.1: +assert@^1.1.1, assert@^1.4.0, assert@^1.4.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== @@ -4100,12 +4328,14 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-types@0.11.3: - version "0.11.3" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.3.tgz#c20757fe72ee71278ea0ff3d87e5c2ca30d9edf8" - integrity sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA== +ast-types@0.x.x, ast-types@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" + integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== + dependencies: + tslib "^2.0.1" -ast-types@0.x.x, ast-types@^0.13.2: +ast-types@^0.13.2: version "0.13.2" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== @@ -4177,7 +4407,7 @@ async-iterator-to-stream@^1.1.0: dependencies: readable-stream "^3.0.5" -async-limiter@~1.0.0: +async-limiter@^1.0.0, async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== @@ -4286,6 +4516,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + atob@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" @@ -4570,10 +4805,10 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== dependencies: object.assign "^4.1.0" @@ -4593,7 +4828,7 @@ babel-plugin-emotion@^10.0.20, babel-plugin-emotion@^10.0.27: find-root "^1.1.0" source-map "^0.5.7" -babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.7.0: +babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== @@ -4681,14 +4916,14 @@ babel-plugin-named-asset-import@^0.3.1: resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.2.tgz#20978ed446b8e1bf4a2f42d0a94c0ece85f75f4f" integrity sha512-CxwvxrZ9OirpXQ201Ec57OmGhmI8/ui/GwTDy0hSp6CmRvgRC0pSair6Z04Ck+JStA0sMPZzSJ3uE4n17EXpPQ== -babel-plugin-react-docgen@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.1.0.tgz#1dfa447dac9ca32d625a123df5733a9e47287c26" - integrity sha512-vzpnBlfGv8XOhJM2zbPyyqw2OLEbelgZZsaaRRTpVwNKuYuc+pUg4+dy7i9gCRms0uOQn4osX571HRcCJMJCmA== +babel-plugin-react-docgen@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz#7cc8e2f94e8dc057a06e953162f0810e4e72257b" + integrity sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ== dependencies: + ast-types "^0.14.2" lodash "^4.17.15" react-docgen "^5.0.0" - recast "^0.14.7" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" @@ -5196,10 +5431,10 @@ base64-arraybuffer@0.1.5: resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base64id@1.0.0: version "1.0.0" @@ -5255,6 +5490,13 @@ better-assert@~1.0.0: dependencies: callsite "1.0.0" +better-opn@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" + integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== + dependencies: + open "^7.0.3" + big.js@^5.1.2, big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -5816,14 +6058,15 @@ browserify@^16.1.0, browserify@^16.5.1: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.5.4.tgz#166c4ecef3b51737a42436ea8002aeea466ea2c7" - integrity sha512-rAjx494LMjqKnMPhFkuLmLp8JWEX0o8ADTGeAbOqaF+XCvYLreZrG5uVjnPBlAQ8REZK4pzXGvp0bWgrFtKaag== +browserslist@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.10.0.tgz#f179737913eaf0d2b98e4926ac1ca6a15cbcc6a9" + integrity sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA== dependencies: - caniuse-lite "^1.0.30000955" - electron-to-chromium "^1.3.122" - node-releases "^1.1.13" + caniuse-lite "^1.0.30001035" + electron-to-chromium "^1.3.378" + node-releases "^1.1.52" + pkg-up "^3.1.0" browserslist@^3.1.1, browserslist@^3.2.6: version "3.2.8" @@ -5833,15 +6076,16 @@ browserslist@^3.1.1, browserslist@^3.2.6: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.12.0, browserslist@^4.6.0: - version "4.13.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.13.0.tgz#42556cba011e1b0a2775b611cba6a8eca18e940d" - integrity sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ== +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.14.7: + version "4.14.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.7.tgz#c071c1b3622c1c2e790799a37bb09473a4351cb6" + integrity sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ== dependencies: - caniuse-lite "^1.0.30001093" - electron-to-chromium "^1.3.488" - escalade "^3.0.1" - node-releases "^1.1.58" + caniuse-lite "^1.0.30001157" + colorette "^1.2.1" + electron-to-chromium "^1.3.591" + escalade "^3.1.1" + node-releases "^1.1.66" bs58@4.0.1, bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" @@ -5984,12 +6228,12 @@ buffer@^4.3.0: isarray "^1.0.0" buffer@^5.0.5, buffer@^5.2.1: - version "5.4.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" - integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" + base64-js "^1.3.1" + ieee754 "^1.1.13" buffer@~5.2.1: version "5.2.1" @@ -6046,13 +6290,6 @@ bytewise@~1.1.0: bytewise-core "^1.2.2" typewise "^1.0.3" -c3@^0.7.10: - version "0.7.12" - resolved "https://registry.yarnpkg.com/c3/-/c3-0.7.12.tgz#ad6205703bab9c2cbedc0223ba7fb2aabc31e94b" - integrity sha512-8gXyKMr9oM171aRGCOqezwEbWwEtIKmEkyvdfgH4oIunSsiTVWyw9Cz6os78LkYPRLMbHDgKcjkQh4EPCrRupQ== - dependencies: - d3 "^5.8.0" - cacache@^12.0.2: version "12.0.3" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" @@ -6074,31 +6311,7 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" - integrity sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w== - dependencies: - chownr "^1.1.2" - figgy-pudding "^3.5.1" - fs-minipass "^2.0.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - infer-owner "^1.0.4" - lru-cache "^5.1.1" - minipass "^3.0.0" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - p-map "^3.0.0" - promise-inflight "^1.0.1" - rimraf "^2.7.1" - ssri "^7.0.0" - unique-filename "^1.1.1" - -cacache@^15.0.4: +cacache@^15.0.4, cacache@^15.0.5: version "15.0.5" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.5.tgz#69162833da29170d6732334643c60e005f5f17d0" integrity sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== @@ -6203,13 +6416,6 @@ callbackify@^1.1.0: resolved "https://registry.yarnpkg.com/callbackify/-/callbackify-1.1.0.tgz#d2a36986d28aa69714526c111209beeb9979d31e" integrity sha1-0qNphtKKppcUUmwREgm+65l50x4= -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -6217,13 +6423,6 @@ caller-path@^0.1.0: dependencies: callsites "^0.2.0" -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - callsite@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" @@ -6234,23 +6433,18 @@ callsites@^0.2.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= +camel-case@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547" + integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q== dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" + pascal-case "^3.1.1" + tslib "^1.10.0" camelcase-keys@^2.0.0: version "2.1.0" @@ -6274,10 +6468,10 @@ camelcase@5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== -camelcase@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= +camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^2.0.0: version "2.1.1" @@ -6289,30 +6483,20 @@ camelcase@^3.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= -camelcase@^4.0.0, camelcase@^4.1.0: +camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -camelcase@^5.0.0, camelcase@^5.2.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - camelcase@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e" integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w== -can-use-dom@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/can-use-dom/-/can-use-dom-0.1.0.tgz#22cc4a34a0abc43950f42c6411024a3f6366b45a" - integrity sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo= - -caniuse-lite@^1.0.30000810, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000955, caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001097: - version "1.0.30001100" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001100.tgz#2a58615e0c01cf716ab349b20ca4d86ef944aa4e" - integrity sha512-0eYdp1+wFCnMlCj2oudciuQn2B9xAFq3WpgpcBIZTxk/1HNA/O2YA7rpeYhnOqsqAJq1AHUgx6i1jtafg7m2zA== +caniuse-lite@^1.0.30000810, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001097, caniuse-lite@^1.0.30001157: + version "1.0.30001162" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001162.tgz#9f83aad1f42539ce9aab58bb177598f2f8e22ec6" + integrity sha512-E9FktFxaNnp4ky3ucIGzEXLM+Knzlpuq1oN1sFAU0KeayygabGTmOsndpo8QrL4D9pcThlf4D2pUKaDxPCUmVw== capture-stack-trace@^1.0.0: version "1.0.1" @@ -6344,7 +6528,7 @@ cbor-sync@^1.0.4: resolved "https://registry.yarnpkg.com/cbor-sync/-/cbor-sync-1.0.4.tgz#5a11a1ab75c2a14d1af1b237fd84aa8c1593662f" integrity sha512-GWlXN4wiz0vdWWXBU71Dvc1q3aBo0HytqwAZnXF1wOwjqNnDWA1vZ1gDMFLlqohak31VQzmhiYfiCX5QSSfagA== -ccount@^1.0.0, ccount@^1.0.3: +ccount@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.4.tgz#9cf2de494ca84060a2a8d2854edd6dfb0445f386" integrity sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w== @@ -6513,10 +6697,10 @@ chokidar@3.3.0: optionalDependencies: fsevents "~2.1.1" -chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.1: - version "2.1.6" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" - integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== +chokidar@^2.0.0, chokidar@^2.1.1, chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" async-each "^1.0.1" @@ -6532,7 +6716,22 @@ chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.1: optionalDependencies: fsevents "^1.2.7" -chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.2: +chokidar@^3.3.0, chokidar@^3.4.1: + version "3.4.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" + integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.1.2" + +chownr@^1.0.1, chownr@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== @@ -6634,10 +6833,10 @@ classnames@^2.2.4, classnames@^2.2.5, classnames@^2.2.6: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== -clean-css@4.2.x: - version "4.2.1" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" - integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== +clean-css@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== dependencies: source-map "~0.6.0" @@ -6677,13 +6876,13 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-table3@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" - integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== +cli-table3@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" + integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== dependencies: object-assign "^4.1.0" - string-width "^2.1.1" + string-width "^4.2.0" optionalDependencies: colors "^1.1.2" @@ -6901,7 +7100,7 @@ color@^0.11.3: color-convert "^1.3.0" color-string "^0.3.0" -colorette@^1.2.0: +colorette@^1.2.0, colorette@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== @@ -6934,7 +7133,7 @@ combine-source-map@^0.8.0, combine-source-map@~0.8.0: lodash.memoize "~3.0.3" source-map "~0.5.3" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -6946,25 +7145,20 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz#419cd7fb3258b1ed838dc0953167a25e152f5b59" integrity sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ== -commander@2, commander@^2.15.0, commander@^2.15.1, commander@^2.16.0, commander@^2.19.0, commander@^2.20.0, commander@^2.6.0: +commander@^2.15.0, commander@^2.15.1, commander@^2.16.0, commander@^2.19.0, commander@^2.20.0, commander@^2.6.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@2.17.x: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" - integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== - -commander@~2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== +commander@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== commander@~2.8.1: version "2.8.1" @@ -7003,6 +7197,18 @@ component-type@^1.2.1: resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9" integrity sha1-ikeQFwAjjk/DIml3EjAibyS0Fak= +compose-function@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f" + integrity sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8= + dependencies: + arity-n "^1.0.4" + +compute-scroll-into-view@^1.0.14: + version "1.0.16" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.16.tgz#5b7bf4f7127ea2c19b750353d7ce6776a90ee088" + integrity sha512-a85LHKY81oQnikatZYA90pufpZ6sQx++BoCxOEMsjpZx+ZnaKGQnCyCehTRr/1p9GBIAHTjcU9k71kSYWloLiQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -7135,7 +7341,7 @@ continuable-cache@^0.3.1: resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f" integrity sha1-vXJ6f67XfnH/OYWskzUakSczrQ8= -convert-source-map@1.X, convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.7.0: +convert-source-map@1.7.0, convert-source-map@1.X, convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -7229,36 +7435,25 @@ copy-webpack-plugin@^6.0.3: serialize-javascript "^4.0.0" webpack-sources "^1.4.3" -core-js-compat@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.3.tgz#0cc3ba4c7f62928c2837e1cffbe8dc78b4f1ae14" - integrity sha512-EP018pVhgwsKHz3YoN1hTq49aRe+h017Kjz0NQz3nXV0cCRMvH3fLQl+vEPGr4r4J5sk4sU3tUC7U1aqTCeJeA== +core-js-compat@^3.7.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.0.tgz#3248c6826f4006793bd637db608bca6e4cd688b1" + integrity sha512-o9QKelQSxQMYWHXc/Gc4L8bx/4F7TTraE5rhuN8I7mKBt5dBIUpXpIR3omv70ebr8ST5R3PqbDQr+ZI3+Tt1FQ== dependencies: - browserslist "^4.6.0" - core-js-pure "3.1.3" - semver "^6.1.0" - -core-js-pure@3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.3.tgz#4c90752d5b9471f641514f3728f51c1e0783d0b5" - integrity sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA== + browserslist "^4.14.7" + semver "7.0.0" core-js-pure@^3.0.0, core-js-pure@^3.0.1: version "3.6.5" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= - core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.3: version "2.6.11" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== -core-js@^3.0.0, core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5: +core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5: version "3.6.5" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== @@ -7268,14 +7463,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -corejs-upgrade-webpack-plugin@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/corejs-upgrade-webpack-plugin/-/corejs-upgrade-webpack-plugin-2.2.0.tgz#503293bf1fdcb104918eb40d0294e4776ad6923a" - integrity sha512-J0QMp9GNoiw91Kj/dkIQFZeiCXgXoja/Wlht1SPybxerBWh4NCmb0pOgCv61lrlQZETwvVVfAFAA3IqoEO9aqQ== - dependencies: - resolve-from "^5.0.0" - webpack "^4.38.0" - cors@^2.7.1, cors@^2.8.1: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -7294,16 +7481,6 @@ cosmiconfig@^4.0.0: parse-json "^4.0.0" require-from-string "^2.0.1" -cosmiconfig@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -7326,6 +7503,31 @@ coveralls@^3.0.0: minimist "^1.2.0" request "^2.79.0" +cp-file@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" + integrity sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw== + dependencies: + graceful-fs "^4.1.2" + make-dir "^3.0.0" + nested-error-stacks "^2.0.0" + p-event "^4.1.0" + +cpy@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.1.tgz#066ed4c6eaeed9577df96dae4db9438c1a90df62" + integrity sha512-vqHT+9o67sMwJ5hUd/BAOYeemkU+MuFRsK2c36Xc3eefQpAsp1kAsyDxEDcc5JS1+y9l/XHPrIsVTcyGGmkUUQ== + dependencies: + arrify "^2.0.1" + cp-file "^7.0.0" + globby "^9.2.0" + has-glob "^1.0.0" + junk "^3.1.0" + nested-error-stacks "^2.1.0" + p-all "^2.1.0" + p-filter "^2.1.0" + p-map "^3.0.0" + crdts@~0.1.2: version "0.1.5" resolved "https://registry.yarnpkg.com/crdts/-/crdts-0.1.5.tgz#89413e8adfc3ab943300a890ee6392db5ba60c06" @@ -7369,21 +7571,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.3, create-hmac@^1.1.4, safe-buffer "^5.0.1" sha.js "^2.4.8" -create-react-context@<=0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.2.tgz#9836542f9aaa22868cd7d4a6f82667df38019dca" - integrity sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A== +create-react-context@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" + integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== dependencies: - fbjs "^0.8.0" - gud "^1.0.0" - -create-react-context@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.3.tgz#9ec140a6914a22ef04b8b09b7771de89567cb6f3" - integrity sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag== - dependencies: - fbjs "^0.8.0" gud "^1.0.0" + warning "^4.0.3" cross-fetch@2.2.2: version "2.2.2" @@ -7401,16 +7595,14 @@ cross-fetch@^2.1.0, cross-fetch@^2.1.1: node-fetch "2.1.2" whatwg-fetch "2.0.4" -cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== +cross-spawn@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" cross-spawn@^3.0.0: version "3.0.1" @@ -7429,6 +7621,17 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -7487,23 +7690,24 @@ css-loader@^2.1.1: postcss-value-parser "^3.3.0" schema-utils "^1.0.0" -css-loader@^3.0.0: - version "3.4.2" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.4.2.tgz#d3fdb3358b43f233b78501c5ed7b1c6da6133202" - integrity sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA== +css-loader@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== dependencies: camelcase "^5.3.1" cssesc "^3.0.0" icss-utils "^4.1.1" loader-utils "^1.2.3" normalize-path "^3.0.0" - postcss "^7.0.23" + postcss "^7.0.32" postcss-modules-extract-imports "^2.0.0" postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.1.1" + postcss-modules-scope "^2.2.0" postcss-modules-values "^3.0.0" - postcss-value-parser "^4.0.2" - schema-utils "^2.6.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" css-select-base-adapter@^0.1.1: version "0.1.1" @@ -7624,259 +7828,6 @@ cyclist@~0.2.2: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= -cytoplasm@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/cytoplasm/-/cytoplasm-3.3.1.tgz#6d10099e536b12c642e8375b47cbffac66656a4b" - integrity sha512-38swm2Lr7cmTh0KRYtiUOCT5PT2TPp31Lpp3wcAIm3iGT4KdGGewyTydkFhBEDrKik/umgmG2hVoG5A1fKQY+g== - -d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" - integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== - -d3-axis@1: - version "1.0.12" - resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9" - integrity sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ== - -d3-brush@1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.6.tgz#33691f2032d9db6c5d8cb684ff255a9883629e21" - integrity sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w== - dependencies: - d3-dispatch "1" - d3-drag "1" - d3-interpolate "1" - d3-selection "1" - d3-transition "1" - -d3-chord@1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.6.tgz#309157e3f2db2c752f0280fedd35f2067ccbb15f" - integrity sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA== - dependencies: - d3-array "1" - d3-path "1" - -d3-collection@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" - integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== - -d3-color@1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.2.3.tgz#6c67bb2af6df3cc8d79efcc4d3a3e83e28c8048f" - integrity sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw== - -d3-contour@1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.3.2.tgz#652aacd500d2264cb3423cee10db69f6f59bead3" - integrity sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg== - dependencies: - d3-array "^1.1.1" - -d3-dispatch@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.5.tgz#e25c10a186517cd6c82dd19ea018f07e01e39015" - integrity sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g== - -d3-drag@1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.2.3.tgz#46e206ad863ec465d88c588098a1df444cd33c64" - integrity sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg== - dependencies: - d3-dispatch "1" - d3-selection "1" - -d3-dsv@1: - version "1.0.10" - resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.10.tgz#4371c489a2a654a297aca16fcaf605a6f31a6f51" - integrity sha512-vqklfpxmtO2ZER3fq/B33R/BIz3A1PV0FaZRuFM8w6jLo7sUX1BZDh73fPlr0s327rzq4H6EN1q9U+eCBCSN8g== - dependencies: - commander "2" - iconv-lite "0.4" - rw "1" - -d3-ease@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.5.tgz#8ce59276d81241b1b72042d6af2d40e76d936ffb" - integrity sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ== - -d3-fetch@1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-1.1.2.tgz#957c8fbc6d4480599ba191b1b2518bf86b3e1be2" - integrity sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA== - dependencies: - d3-dsv "1" - -d3-force@1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.1.2.tgz#16664d0ac71d8727ef5effe0b374feac8050d6cd" - integrity sha512-p1vcHAUF1qH7yR+e8ip7Bs61AHjLeKkIn8Z2gzwU2lwEf2wkSpWdjXG0axudTHsVFnYGlMkFaEsVy2l8tAg1Gw== - dependencies: - d3-collection "1" - d3-dispatch "1" - d3-quadtree "1" - d3-timer "1" - -d3-format@1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.3.2.tgz#6a96b5e31bcb98122a30863f7d92365c00603562" - integrity sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ== - -d3-geo@1: - version "1.11.3" - resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.11.3.tgz#5bb08388f45e4b281491faa72d3abd43215dbd1c" - integrity sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ== - dependencies: - d3-array "1" - -d3-hierarchy@1: - version "1.1.8" - resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz#7a6317bd3ed24e324641b6f1e76e978836b008cc" - integrity sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w== - -d3-interpolate@1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.3.2.tgz#417d3ebdeb4bc4efcc8fd4361c55e4040211fd68" - integrity sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w== - dependencies: - d3-color "1" - -d3-path@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.7.tgz#8de7cd693a75ac0b5480d3abaccd94793e58aae8" - integrity sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA== - -d3-polygon@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.5.tgz#9a645a0a64ff6cbf9efda96ee0b4a6909184c363" - integrity sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w== - -d3-quadtree@1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.5.tgz#305394840b01f51a341a0da5008585e837fe7e9b" - integrity sha512-U2tjwDFbZ75JRAg8A+cqMvqPg1G3BE7UTJn3h8DHjY/pnsAfWdbJKgyfcy7zKjqGtLAmI0q8aDSeG1TVIKRaHQ== - -d3-random@1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.2.tgz#2833be7c124360bf9e2d3fd4f33847cfe6cab291" - integrity sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ== - -d3-scale-chromatic@1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz#dad4366f0edcb288f490128979c3c793583ed3c0" - integrity sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw== - dependencies: - d3-color "1" - d3-interpolate "1" - -d3-scale@2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.1.2.tgz#4e932b7b60182aee9073ede8764c98423e5f9a94" - integrity sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q== - dependencies: - d3-array "^1.2.0" - d3-collection "1" - d3-format "1" - d3-interpolate "1" - d3-time "1" - d3-time-format "2" - -d3-selection@1, d3-selection@^1.1.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.2.tgz#6e70a9df60801c8af28ac24d10072d82cbfdf652" - integrity sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ== - -d3-shape@1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.2.2.tgz#f9dba3777a5825f9a8ce8bc928da08c17679e9a7" - integrity sha512-hUGEozlKecFZ2bOSNt7ENex+4Tk9uc/m0TtTEHBvitCBxUNjhzm5hS2GrrVRD/ae4IylSmxGeqX5tWC2rASMlQ== - dependencies: - d3-path "1" - -d3-time-format@2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.1.3.tgz#ae06f8e0126a9d60d6364eac5b1533ae1bac826b" - integrity sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA== - dependencies: - d3-time "1" - -d3-time@1: - version "1.0.10" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.10.tgz#8259dd71288d72eeacfd8de281c4bf5c7393053c" - integrity sha512-hF+NTLCaJHF/JqHN5hE8HVGAXPStEq6/omumPE/SxyHVrR7/qQxusFDo0t0c/44+sCGHthC7yNGFZIEgju0P8g== - -d3-timer@1: - version "1.0.9" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.9.tgz#f7bb8c0d597d792ff7131e1c24a36dd471a471ba" - integrity sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg== - -d3-transition@1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.1.3.tgz#3a435b05ce9cef9524fe0d38121cfb6905331ca6" - integrity sha512-tEvo3qOXL6pZ1EzcXxFcPNxC/Ygivu5NoBY6mbzidATAeML86da+JfVIUzon3dNM6UX6zjDx+xbYDmMVtTSjuA== - dependencies: - d3-color "1" - d3-dispatch "1" - d3-ease "1" - d3-interpolate "1" - d3-selection "^1.1.0" - d3-timer "1" - -d3-voronoi@1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297" - integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg== - -d3-zoom@1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.7.3.tgz#f444effdc9055c38077c4299b4df999eb1d47ccb" - integrity sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg== - dependencies: - d3-dispatch "1" - d3-drag "1" - d3-interpolate "1" - d3-selection "1" - d3-transition "1" - -d3@^5.15.0, d3@^5.8.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/d3/-/d3-5.15.0.tgz#ffd44958e6a3cb8a59a84429c45429b8bca5677a" - integrity sha512-C+E80SL2nLLtmykZ6klwYj5rPqB5nlfN5LdWEAVdWPppqTD8taoJi2PxLZjPeYT8FFRR2yucXq+kBlOnnvZeLg== - dependencies: - d3-array "1" - d3-axis "1" - d3-brush "1" - d3-chord "1" - d3-collection "1" - d3-color "1" - d3-contour "1" - d3-dispatch "1" - d3-drag "1" - d3-dsv "1" - d3-ease "1" - d3-fetch "1" - d3-force "1" - d3-format "1" - d3-geo "1" - d3-hierarchy "1" - d3-interpolate "1" - d3-path "1" - d3-polygon "1" - d3-quadtree "1" - d3-random "1" - d3-scale "2" - d3-scale-chromatic "1" - d3-selection "1" - d3-shape "1" - d3-time "1" - d3-time-format "2" - d3-timer "1" - d3-transition "1" - d3-voronoi "1" - d3-zoom "1" - d64@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/d64/-/d64-1.0.0.tgz#4002a87e850cbfc9f9d9706b60fca613a3336e90" @@ -8011,7 +7962,7 @@ debug@3.1.0, debug@=3.1.0, debug@~3.1.0: dependencies: ms "2.0.0" -debug@3.2.6, debug@3.X, debug@^3.0.0, debug@^3.1.0, debug@^3.2.5, debug@^3.2.6: +debug@3.2.6, debug@3.X, debug@^3.0.0, debug@^3.1.0, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -8115,6 +8066,11 @@ decompress@^4.0.0, decompress@^4.2.0: pify "^2.3.0" strip-dirs "^2.0.0" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-eql@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" @@ -8513,6 +8469,13 @@ dir-glob@2.0.0: arrify "^1.0.1" path-type "^3.0.0" +dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -8704,6 +8667,14 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" +dot-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" + integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + dot-prop@^4.1.0, dot-prop@^5.1.1: version "5.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" @@ -8775,6 +8746,16 @@ download@^7.1.0: p-event "^2.1.0" pify "^3.0.0" +downshift@^6.0.6: + version "6.0.6" + resolved "https://registry.yarnpkg.com/downshift/-/downshift-6.0.6.tgz#82aee8e2e260d7ad99df8a0969bd002dd523abe8" + integrity sha512-tmLab3cXCn6PtZYl9V8r/nB2m+7/nCNrwo0B3kTHo/2lRBHr+1en1VNOQt2wIt0ajanAnxquZ00WPCyxe6cNFQ== + dependencies: + "@babel/runtime" "^7.11.2" + compute-scroll-into-view "^1.0.14" + prop-types "^15.7.2" + react-is "^16.13.1" + drbg.js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" @@ -8844,22 +8825,22 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^2.4.1, ejs@^2.7.4: +ejs@^2.4.1: version "2.7.4" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== -ejs@^3.0.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.3.tgz#514d967a8894084d18d3d47bd169a1c0560f093d" - integrity sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg== +ejs@^3.0.2, ejs@^3.1.2: + version "3.1.5" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.5.tgz#aed723844dc20acb4b170cd9ab1017e476a0d93b" + integrity sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w== dependencies: jake "^10.6.1" -electron-to-chromium@^1.3.122, electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.488: - version "1.3.498" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.498.tgz#fd7188c8a49d6d0b5df1df55a1f1a4bf2c177457" - integrity sha512-W1hGwaQEU8j9su2jeAr3aabkPuuXw+j8t73eajGAkEJWbfWiwbxBwQN/8Qmv2qCy3uCDm2rOAaZneYQM8VGC4w== +electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.591: + version "1.3.610" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.610.tgz#1254eb394acd220a836ea1f203f8cded4e487052" + integrity sha512-eFDC+yVQpEhtlapk4CYDPfV9ajF9cEof5TBcO49L1ETO+aYogrKWDmYpZyxBScMNe8Bo/gJamH4amQ4yyvXg4g== electron@^9.1.0: version "9.1.2" @@ -8959,6 +8940,15 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.0, end-of-stream@ dependencies: once "^1.4.0" +endent@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/endent/-/endent-2.0.1.tgz#fb18383a3f37ae3213a5d9f6c4a880d1061eb4c5" + integrity sha512-mADztvcC+vCk4XEZaCz6xIPO2NHQuprv5CAEjuVAu6aZwqAj7nVNlMyl1goPFYqCCpS2OJV9jwpumJLkotZrNw== + dependencies: + dedent "^0.7.0" + fast-json-parse "^1.0.3" + objectorarray "^1.0.4" + engine.io-client@~3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.3.2.tgz#04e068798d75beda14375a264bb3d742d7bc33aa" @@ -8999,13 +8989,13 @@ engine.io@~3.3.1: engine.io-parser "~2.1.0" ws "~6.1.0" -enhanced-resolve@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== +enhanced-resolve@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126" + integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ== dependencies: graceful-fs "^4.1.2" - memory-fs "^0.4.0" + memory-fs "^0.5.0" tapable "^1.0.0" enquirer@^2.3.5: @@ -9025,14 +9015,6 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== -envify@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" - integrity sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw== - dependencies: - esprima "^4.0.0" - through "~2.3.4" - enzyme-adapter-react-16@^1.15.1: version "1.15.1" resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.1.tgz#8ad55332be7091dc53a25d7d38b3485fc2ba50d5" @@ -9126,6 +9108,13 @@ error-inject@^1.0.0: resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= +error-stack-parser@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== + dependencies: + stackframe "^1.1.1" + error@^7.0.0: version "7.0.2" resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02" @@ -9197,7 +9186,7 @@ es6-error@^4.0.1, es6-error@^4.1.1: resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: +es6-iterator@2.0.3, es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= @@ -9269,10 +9258,10 @@ es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: es6-iterator "^2.0.1" es6-symbol "^3.1.1" -escalade@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" - integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" @@ -9284,6 +9273,11 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -9634,7 +9628,7 @@ esprima@3.x.x: resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= -esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: +esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -9668,7 +9662,7 @@ estree-is-function@^1.0.0: resolved "https://registry.yarnpkg.com/estree-is-function/-/estree-is-function-1.0.0.tgz#c0adc29806d7f18a74db7df0f3b2666702e37ad2" integrity sha512-nSCWn1jkSq2QAtkaVLJZY2ezwcFO161HVc174zL1KPW3RJ+O6C3eJb8Nx7OXzvhoEv+nLgSR1g71oWUHUDTrJA== -esutils@^2.0.0, esutils@^2.0.2: +esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== @@ -9703,7 +9697,7 @@ eth-block-tracker@^4.4.2: pify "^3.0.0" safe-event-emitter "^1.0.1" -eth-contract-metadata@^1.11.0, eth-contract-metadata@^1.16.0: +eth-contract-metadata@^1.11.0: version "1.17.0" resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.17.0.tgz#96d4b056ac9a7175eeba091dbabd0713cfd4c703" integrity sha512-vlw4OiW3+9J3kJfEtPCyiSW9fhdWTqrAhXcvdMY2CevGxbhvOd5Lz59DeWerSTV3IoSXttghDurPA76dAeTV+A== @@ -9916,6 +9910,13 @@ eth-rpc-errors@^4.0.0: dependencies: fast-safe-stringify "^2.0.6" +eth-rpc-errors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.2.tgz#11bc164e25237a679061ac05b7da7537b673d3b7" + integrity sha512-n+Re6Gu8XGyfFy1it0AwbD1x0MUzspQs0D5UiPs1fFPCr6WAwZM+vbIhXheBFrpgosqN9bs5PqlB4Q61U/QytQ== + dependencies: + fast-safe-stringify "^2.0.6" + eth-sig-util@^1.4.0, eth-sig-util@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" @@ -10556,7 +10557,7 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@4.0.4, eventemitter3@^4.0.0: +eventemitter3@4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== @@ -10581,13 +10582,6 @@ events@^3.0.0: resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== -eventsource@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" - integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== - dependencies: - original "^1.0.0" - evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -10774,13 +10768,10 @@ extend@3, extend@3.0.2, extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extension-port-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/extension-port-stream/-/extension-port-stream-1.0.0.tgz#5da21d4627dfef6013ae101cb3ff8eacaf18b279" - integrity sha512-FsFr64yr6ituPdaGP6Io5recGFWVjJoDYt7asz2AvPkYqGN9c923nmEtyHH+413066bjGcQZaF8w5wn9HbNXiQ== - dependencies: - readable-stream "^2.3.6" - util "^0.11.0" +extension-port-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/extension-port-stream/-/extension-port-stream-2.0.0.tgz#c52da241eef4643171b7c6d696baa4a3453c5a9a" + integrity sha512-7ju8jisPXY8w8UiUczF61hRN6bpx/YTZYU9J901GnEqu7vQnweMAwS30k+SgXCcY9S38Zno+fhuu1iaxd+0swg== extensionizer@^1.0.1: version "1.0.1" @@ -10902,7 +10893,7 @@ fast-future@~1.0.2: resolved "https://registry.yarnpkg.com/fast-future/-/fast-future-1.0.2.tgz#8435a9aaa02d79248d17d704e76259301d99280a" integrity sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo= -fast-glob@^2.0.2: +fast-glob@^2.0.2, fast-glob@^2.2.6: version "2.2.7" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== @@ -10977,12 +10968,12 @@ fastq@^1.6.0: dependencies: reusify "^1.0.0" -fault@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.3.tgz#4da88cf979b6b792b4e13c7ec836767725170b7e" - integrity sha512-sfFuP4X0hzrbGKjAUNXYvNqsZ5F6ohx/dZ9I0KQud/aiZNwg263r5L9yGB0clvXHCkzXh5W3t7RSHchggYIFmA== +fault@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== dependencies: - format "^0.2.2" + format "^0.2.0" faye-websocket@~0.10.0: version "0.10.0" @@ -10991,26 +10982,6 @@ faye-websocket@~0.10.0: dependencies: websocket-driver ">=0.5.1" -faye-websocket@~0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" - integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg= - dependencies: - websocket-driver ">=0.5.1" - -fbjs@^0.8.0: - version "0.8.16" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" - integrity sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s= - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.9" - fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -11075,13 +11046,13 @@ file-loader@^1.1.11: loader-utils "^1.0.2" schema-utils "^0.4.5" -file-loader@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" - integrity sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA== +file-loader@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== dependencies: - loader-utils "^1.2.3" - schema-utils "^2.5.0" + loader-utils "^2.0.0" + schema-utils "^3.0.0" file-system-cache@^1.0.5: version "1.0.5" @@ -11163,7 +11134,12 @@ filenamify@^2.0.0: strip-outer "^1.0.0" trim-repeated "^1.0.0" -filesize@3.6.1, filesize@^3.6.1: +filesize@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.0.1.tgz#f850b509909c7c86f7e450ea19006c31c2ed3d2f" + integrity sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg== + +filesize@^3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== @@ -11226,7 +11202,7 @@ find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.0.0, find-cache-dir@^3.2.0, find-cache-dir@^3.3.1: +find-cache-dir@^3.2.0, find-cache-dir@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== @@ -11247,6 +11223,14 @@ find-up@3.0.0, find-up@^3.0.0: dependencies: locate-path "^3.0.0" +find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -11262,14 +11246,6 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - find-versions@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.1.0.tgz#10161f29cf3eb4350dec10a29bdde75bff0df32d" @@ -11403,11 +11379,6 @@ fnv1a@^1.0.1: resolved "https://registry.yarnpkg.com/fnv1a/-/fnv1a-1.0.1.tgz#915e2d6d023c43d5224ad9f6d2a3c4156f5712f5" integrity sha1-kV4tbQI8Q9UiStn20qPEFW9XEvU= -focus-lock@^0.6.6: - version "0.6.6" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.6.6.tgz#98119a755a38cfdbeda0280eaa77e307eee850c7" - integrity sha512-Dx69IXGCq1qsUExWuG+5wkiMqVM/zGx/reXSJSLogECwp3x6KeNQZ+NAetgxEFpnC41rD8U3+jRCW68+LNzdtw== - follow-redirects@1.5.10: version "1.5.10" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" @@ -11464,14 +11435,27 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -fork-ts-checker-webpack-plugin@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.1.1.tgz#caf2a210778fb1e171b6993ca0a40f9b6589e3b7" - integrity sha512-gqWAEMLlae/oeVnN6RWCAhesOJMswAN1MaKNqhhjXHV5O0/rTUjWI4UbgQHdlrVbCnb+xLotXmJbBlC66QmpFw== +fork-ts-checker-webpack-plugin@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz#a1642c0d3e65f50c2cc1742e9c0a80f441f86b19" + integrity sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ== dependencies: babel-code-frame "^6.22.0" chalk "^2.4.1" - chokidar "^2.0.4" + chokidar "^3.3.0" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +fork-ts-checker-webpack-plugin@^4.1.4: + version "4.1.6" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" + integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== + dependencies: + "@babel/code-frame" "^7.5.5" + chalk "^2.4.1" micromatch "^3.1.10" minimatch "^3.0.4" semver "^5.6.0" @@ -11487,7 +11471,16 @@ form-data@^2.3.1, form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -format@^0.2.2: +form-data@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" + integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +format@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= @@ -11575,7 +11568,7 @@ fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^8.0.1, fs-extra@^8.1.0: +fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== @@ -11584,6 +11577,16 @@ fs-extra@^8.0.1, fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" + integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^1.0.0" + fs-minipass@^1.2.5: version "1.2.6" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" @@ -11634,10 +11637,10 @@ fsevents@^1.2.7: nan "^2.12.1" node-pre-gyp "^0.12.0" -fsevents@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" - integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== +fsevents@~2.1.1, fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== fsm-event@^2.1.0: version "2.1.0" @@ -11696,10 +11699,10 @@ functions-have-names@^1.1.1: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.0.tgz#83da7583e4ea0c9ac5ff530f73394b033e0bf77d" integrity sha512-zKXyzksTeaCSw5wIX79iCA40YAa6CJMJgNg9wdkU/ERBrIdPSimPICYiLp65lRbSBqtiHql/HZfS2DyI/AH6tQ== -fuse.js@^3.2.0, fuse.js@^3.4.6: - version "3.4.6" - resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.6.tgz#545c3411fed88bf2e27c457cab6e73e7af697a45" - integrity sha512-H6aJY4UpLFwxj1+5nAvufom5b2BT2v45P1MkPvdGIK8fWjQx/7o6tTT1+ALV0yawQvbmvCF0ufl2et8eJ7v7Cg== +fuse.js@^3.2.0, fuse.js@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.6.1.tgz#7de85fdd6e1b3377c23ce010892656385fd9b10c" + integrity sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw== ganache-cli@^6.12.1: version "6.12.1" @@ -12009,6 +12012,13 @@ glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" +glob-promise@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" + integrity sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw== + dependencies: + "@types/glob" "*" + glob-stream@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" @@ -12257,6 +12267,20 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + globjoin@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" @@ -12391,7 +12415,7 @@ got@^8.3.1: url-parse-lax "^3.0.0" url-to-options "^1.0.1" -graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2: +graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== @@ -12671,15 +12695,7 @@ gulplog@^1.0.0: dependencies: glogg "^1.0.0" -gzip-size@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" - integrity sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA== - dependencies: - duplexer "^0.1.1" - pify "^3.0.0" - -gzip-size@^5.1.1: +gzip-size@5.1.1, gzip-size@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== @@ -12756,6 +12772,13 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-1.0.0.tgz#9aaa9eedbffb1ba3990a7b0010fb678ee0081207" + integrity sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc= + dependencies: + is-glob "^3.0.0" + has-localstorage@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-localstorage/-/has-localstorage-1.0.1.tgz#fe62406c4767fbd6d784dac6905928108b82971b" @@ -12863,30 +12886,20 @@ hashlru@^2.3.0: resolved "https://registry.yarnpkg.com/hashlru/-/hashlru-2.3.0.tgz#5dc15928b3f6961a2056416bb3a4910216fdfb51" integrity sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A== -hast-util-from-parse5@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.1.tgz#7da8841d707dcf7be73715f7f3b14e021c4e469a" - integrity sha512-UfPzdl6fbxGAxqGYNThRUhRlDYY7sXu6XU9nQeX4fFZtV+IHbyEJtd+DUuwOqNV4z3K05E/1rIkoVr/JHmeWWA== - dependencies: - ccount "^1.0.3" - hastscript "^5.0.0" - property-information "^5.0.0" - web-namespaces "^1.1.2" - xtend "^4.0.1" +hast-util-parse-selector@^2.0.0: + version "2.2.5" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" + integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== -hast-util-parse-selector@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz#66aabccb252c47d94975f50a281446955160380b" - integrity sha512-jIMtnzrLTjzqgVEQqPEmwEZV+ea4zHRFTP8Z2Utw0I5HuBOXHzUPPQWr6ouJdJqDKLbFU/OEiYwZ79LalZkmmw== - -hastscript@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.0.tgz#a19b3cca6a26a2bcd0f1b1eac574af9427c1c7df" - integrity sha512-7mOQX5VfVs/gmrOGlN8/EDfp1GqV6P3gTNVt+KnX4gbYhpASTM8bklFdFQCbFRAadURXAmw0R1QQdBdqp7jswQ== +hastscript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" + integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== dependencies: + "@types/hast" "^2.0.0" comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.2.0" - property-information "^5.0.1" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" space-separated-tokens "^1.0.0" hdkey@0.8.0: @@ -12906,7 +12919,7 @@ hdkey@^0.7.0: coinstring "^2.0.0" secp256k1 "^3.0.1" -he@1.2.0, he@1.2.x: +he@1.2.0, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -12921,10 +12934,10 @@ hi-base32@~0.5.0: resolved "https://registry.yarnpkg.com/hi-base32/-/hi-base32-0.5.0.tgz#61329f76a31f31008533f1c36f2473e259d64571" integrity sha512-DDRmxSyoYuvjUb9EnXdoiMChBZ7ZcUVJsK5Frd3kqMhuBxvmZdnBeynAVfj7/ECbn++CekcoprvC/rprHPAtow== -highlight.js@~9.13.0: - version "9.13.1" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" - integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== +highlight.js@^10.1.1, highlight.js@~10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.4.0.tgz#ef3ce475e5dfa7a48484260b49ea242ddab823a0" + integrity sha512-EfrUGcQ63oLJbj0J0RI9ebX6TAITbsDBLbsjr881L/X5fMO9+oadKzEF21C7R3ULKG6Gv3uoab2HiqVJa/4+oA== history@^4.9.0: version "4.10.1" @@ -13003,44 +13016,47 @@ html-encoding-sniffer@^1.0.1: dependencies: whatwg-encoding "^1.0.1" -html-entities@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" - integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= +html-entities@^1.2.0, html-entities@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" + integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== html-escaper@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491" integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig== -html-minifier@^3.5.20: - version "3.5.21" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" - integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== +html-minifier-terser@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" html-tags@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== -html-webpack-plugin@^4.0.0-beta.2: - version "4.0.0-beta.5" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.5.tgz#2c53083c1151bfec20479b1f8aaf0039e77b5513" - integrity sha512-y5l4lGxOW3pz3xBTFdfB9rnnrWRPVxlAhX6nrBYIcW+2k2zC3mSp/3DxlWVCMBfnO6UAnoF8OcFn0IMy6kaKAQ== +html-webpack-plugin@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz#625097650886b97ea5dae331c320e3238f6c121c" + integrity sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw== dependencies: - html-minifier "^3.5.20" - loader-utils "^1.1.0" - lodash "^4.17.11" + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.15" pretty-error "^2.1.1" - tapable "^1.1.0" + tapable "^1.1.3" util.promisify "1.0.0" htmlescape@^1.1.0: @@ -13198,18 +13214,18 @@ hyphenate-style-name@^1.0.3: resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48" integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ== -iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ== + +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ== - icss-replace-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" @@ -13243,10 +13259,10 @@ idna-uts46@^1.0.1: dependencies: punycode "^2.1.0" -ieee754@^1.1.4, ieee754@^1.1.8: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.1.8: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== iferr@^0.1.5: version "0.1.5" @@ -13265,7 +13281,7 @@ ignore@^3.2.0, ignore@^3.3.5: resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" integrity sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA== -ignore@^4.0.6: +ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== @@ -13349,14 +13365,6 @@ import-cwd@^2.0.0: dependencies: import-from "^2.1.0" -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" @@ -13478,23 +13486,23 @@ inquirer@5.2.0: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" - integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== +inquirer@7.0.4, inquirer@^7.0.0: + version "7.0.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" + integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== dependencies: - ansi-escapes "^3.2.0" + ansi-escapes "^4.2.1" chalk "^2.4.2" - cli-cursor "^2.1.0" + cli-cursor "^3.1.0" cli-width "^2.0.0" external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.11" - mute-stream "0.0.7" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.0.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^5.1.0" through "^2.3.6" inquirer@^0.12.0: @@ -13535,25 +13543,6 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" -inquirer@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" - integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^2.4.2" - cli-cursor "^3.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" - run-async "^2.2.0" - rxjs "^6.5.3" - string-width "^4.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - insert-module-globals@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.2.0.tgz#ec87e5b42728479e327bd5c5c71611ddfb4752ba" @@ -14366,10 +14355,13 @@ is-docker@^2.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ== -is-dom@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.0.9.tgz#483832d52972073de12b9fe3f60320870da8370d" - integrity sha1-SDgy1SlyBz3hK5/j9gMghw2oNw0= +is-dom@^1.0.0, is-dom@^1.0.9: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" + integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ== + dependencies: + is-object "^1.0.1" + is-window "^1.0.2" is-dotfile@^1.0.0: version "1.0.3" @@ -14439,10 +14431,10 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-function@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" - integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= +is-function@^1.0.1, is-function@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== is-generator-function@^1.0.7: version "1.0.7" @@ -14463,7 +14455,7 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-glob@^3.1.0: +is-glob@^3.0.0, is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= @@ -14686,13 +14678,6 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-plain-object@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928" - integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg== - dependencies: - isobject "^4.0.0" - is-png@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d" @@ -14767,10 +14752,10 @@ is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== -is-root@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.0.0.tgz#838d1e82318144e5a6f77819d90207645acc7019" - integrity sha512-F/pJIk8QD6OX5DNhRB7hWamLsUilmkDGho48KbgZ6xg/lmAZXHxzXQ91jzB3yRSw5kdQGGGc4yz8HYhTYIMWPg== +is-root@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== is-ssh@^1.3.0: version "1.3.1" @@ -14845,6 +14830,11 @@ is-whitespace-character@^1.0.0: resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz#b3ad9546d916d7d3ffa78204bca0c26b56257fac" integrity sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ== +is-window@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d" + integrity sha1-LIlspT25feRdPDMTOmXYyfVjSA0= + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -14942,14 +14932,6 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== -isomorphic-fetch@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - isomorphic-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" @@ -15064,11 +15046,12 @@ jed@1.1.1: resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4" integrity sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ= -jest-worker@^25.4.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.5.0.tgz#2611d071b79cea0f43ee57a3d118593ac1547db1" - integrity sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw== +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: + "@types/node" "*" merge-stream "^2.0.0" supports-color "^7.0.0" @@ -15101,11 +15084,6 @@ js-base64@^2.1.8: resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582" integrity sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw== -js-levenshtein@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== - js-sha256@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" @@ -15251,6 +15229,14 @@ json-rpc-engine@^5.2.0, json-rpc-engine@^5.3.0: eth-rpc-errors "^3.0.0" safe-event-emitter "^1.0.1" +json-rpc-engine@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz#bf5ff7d029e1c1bf20cb6c0e9f348dcd8be5a393" + integrity sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ== + dependencies: + "@metamask/safe-event-emitter" "^2.0.0" + eth-rpc-errors "^4.0.2" + json-rpc-error@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" @@ -15317,11 +15303,6 @@ json-text-sequence@~0.1.0: dependencies: delimit-stream "0.1.0" -json3@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== - json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -15355,6 +15336,15 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -15771,25 +15761,6 @@ latest-version@^5.0.0: dependencies: package-json "^6.3.0" -lavamoat-core@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/lavamoat-core/-/lavamoat-core-6.2.0.tgz#ff1e39c0407f4bf5b94847c5dfaf5b09f28ac77a" - integrity sha512-sY0ddwWou2WGnpEFG/8CGguo6XKq2hc5etIDQ47TYUEJB9BaWGuWulekcrTsTQ0f7EN5r0Y2QtV5ZxxM0fMm8w== - dependencies: - cytoplasm "^3.3.1" - fromentries "^1.2.0" - json-stable-stringify "^1.0.1" - lavamoat-tofu "^5.1.1" - resolve "^1.15.1" - -lavamoat-tofu@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lavamoat-tofu/-/lavamoat-tofu-5.1.1.tgz#67d3c5775b587dd439c426f1cd86650b10443760" - integrity sha512-LIZTifbbTATA5UClVGI7YGMTOjUXjrVCBOz0DaeUicldLonLlwG81/53/vTIfPM1xV/KA85MIzGPHz4pDdiVkA== - dependencies: - "@babel/parser" "^7.10.1" - "@babel/traverse" "^7.10.1" - lazy-cache@^0.2.3: version "0.2.7" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" @@ -16610,6 +16581,13 @@ localforage@1.8.1: dependencies: lie "3.1.1" +localforage@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.9.0.tgz#f3e4d32a8300b362b4634cc4e066d9d00d2f09d1" + integrity sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g== + dependencies: + lie "3.1.1" + localstorage-down@^0.6.7: version "0.6.7" resolved "https://registry.yarnpkg.com/localstorage-down/-/localstorage-down-0.6.7.tgz#d0799a93b31e6c5fa5188ec06242eb1cce9d6d15" @@ -16669,53 +16647,7 @@ lockfile-lint@^4.0.0: lockfile-lint-api "^5.0.12" yargs "^15.0.2" -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= - -lodash._bindcallback@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= - -lodash._createassigner@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" - integrity sha1-g4pbri/aymOsIt7o4Z+k5taXCxE= - dependencies: - lodash._bindcallback "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash.restparam "^3.0.0" - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= - -lodash.assign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" - integrity sha1-POnwI0tLIiPilrj6CsH+6OvKZPo= - dependencies: - lodash._baseassign "^3.0.0" - lodash._createassigner "^3.0.0" - lodash.keys "^3.0.0" - -lodash.assign@^4.0.1, lodash.assign@^4.2.0: +lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= @@ -16725,24 +16657,6 @@ lodash.clonedeep@4.5.0, lodash.clonedeep@^4.3.2: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - -lodash.defaults@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-3.1.2.tgz#c7308b18dbf8bc9372d701a73493c61192bd2e2c" - integrity sha1-xzCLGNv4vJNy1wGnNJPGEZK9Liw= - dependencies: - lodash.assign "^3.0.0" - lodash.restparam "^3.0.0" - -lodash.defaults@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= - lodash.escape@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" @@ -16773,16 +16687,6 @@ lodash.includes@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= - lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" @@ -16823,25 +16727,11 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - lodash.map@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - lodash.memoize@~3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" @@ -16852,11 +16742,6 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash.restparam@^3.0.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" @@ -16882,7 +16767,7 @@ lodash.uniqby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= -lodash@4.17.20, lodash@=3.10.1, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.2, lodash@~4.17.4: +lodash@4.17.20, lodash@=3.10.1, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.2, lodash@~4.17.4: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -16899,7 +16784,7 @@ log-symbols@3.0.0: dependencies: chalk "^2.4.2" -log-symbols@^2.2.0: +log-symbols@^2.1.0, log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== @@ -16926,6 +16811,14 @@ loglevel@^1.4.1, loglevel@^1.5.0: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934" integrity sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ= +loglevelnext@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.5.tgz#36fc4f5996d6640f539ff203ba819641680d75a2" + integrity sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A== + dependencies: + es6-symbol "^3.1.1" + object.assign "^4.1.0" + logplease@^1.2.14, logplease@~1.2.14, logplease@~1.2.15: version "1.2.15" resolved "https://registry.yarnpkg.com/logplease/-/logplease-1.2.15.tgz#3da442e93751a5992cc19010a826b08d0293c48a" @@ -16976,10 +16869,12 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= +lower-case@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" + integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== + dependencies: + tslib "^1.10.0" lowercase-keys@1.0.0: version "1.0.0" @@ -16996,13 +16891,13 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -lowlight@~1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.11.0.tgz#1304d83005126d4e8b1dc0f07981e9b689ec2efc" - integrity sha512-xrGGN6XLL7MbTMdPD6NfWPwY43SNkjf/d0mecSx/CW36fUZTjRHEq0/Cdug3TWKtRXLWi7iMl1eP0olYxj/a4A== +lowlight@^1.14.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.17.0.tgz#a1143b2fba8239df8cd5893f9fe97aaf8465af4a" + integrity sha512-vmtBgYKD+QVNy7tIa7ulz5d//Il9R4MooOVh4nkOf9R9Cb/Dk5TXMSTieg/vDulkBkIWj59/BIlyFQxT9X1oAQ== dependencies: - fault "^1.0.2" - highlight.js "~9.13.0" + fault "^1.0.0" + highlight.js "~10.4.0" lpad-align@^1.0.1: version "1.1.2" @@ -17093,7 +16988,7 @@ make-dir@^1.0.0, make-dir@^1.2.0: dependencies: pify "^3.0.0" -make-dir@^2.0.0: +make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -17115,11 +17010,6 @@ make-iterator@^1.0.0: dependencies: kind-of "^6.0.2" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - map-age-cleaner@^0.1.1, map-age-cleaner@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -17171,7 +17061,7 @@ markdown-table@^2.0.0: dependencies: repeat-string "^1.0.0" -markdown-to-jsx@^6.9.1, markdown-to-jsx@^6.9.3: +markdown-to-jsx@^6.11.4: version "6.11.4" resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz#b4528b1ab668aef7fe61c1535c27e837819392c5" integrity sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw== @@ -17326,7 +17216,7 @@ memoizerific@^1.11.3: dependencies: map-or-similar "^1.5.0" -memory-fs@^0.4.0, memory-fs@^0.4.1: +memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= @@ -17334,6 +17224,14 @@ memory-fs@^0.4.0, memory-fs@^0.4.1: errno "^0.1.3" readable-stream "^2.0.1" +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + meow@^3.3.0, meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -17508,10 +17406,10 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.42.0, mime-db@1.x.x, mime-db@^1.28.0: - version "1.42.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== +mime-db@1.44.0, mime-db@1.x.x, mime-db@^1.28.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== mime-db@~1.33.0: version "1.33.0" @@ -17525,19 +17423,19 @@ mime-types@2.1.18: dependencies: mime-db "~1.33.0" -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@^2.1.18, mime-types@^2.1.21, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.25" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@^2.1.18, mime-types@^2.1.21, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: - mime-db "1.42.0" + mime-db "1.44.0" mime@1.6.0, mime@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.4.2, mime@^2.4.4: +mime@^2.4.2: version "2.4.4" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== @@ -17578,16 +17476,6 @@ mini-create-react-context@^0.3.0: gud "^1.0.0" tiny-warning "^1.0.2" -mini-css-extract-plugin@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.7.0.tgz#5ba8290fbb4179a43dd27cca444ba150bee743a0" - integrity sha512-RQIw6+7utTYn8DBGsf/LpRgZCJMpZt+kuawJ/fju0KiOL6nAaTBNmCJwS7HtwSCXfS47gCkmtBFS7HdsquhdxQ== - dependencies: - loader-utils "^1.1.0" - normalize-url "1.9.1" - schema-utils "^1.0.0" - webpack-sources "^1.1.0" - minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -17719,7 +17607,7 @@ mkdirp@*, mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: +mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -18048,9 +17936,9 @@ nano-json-stream-parser@^0.1.2: integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= nanoid@^2.0.0, nanoid@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.6.tgz#0665418f692e54cf44f34d4010761f3240a03314" - integrity sha512-2NDzpiuEy3+H0AVtdt8LoFi7PnqkOnIzYmJQp7xsEU6VexLluHQwKREuiz57XaQC5006seIadPrIZJhyS2n7aw== + version "2.1.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" + integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== nanoid@^3.1.12: version "3.1.16" @@ -18080,6 +17968,13 @@ napi-macros@~1.8.1: resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-1.8.2.tgz#299265c1d8aa401351ad0675107d751228c03eda" integrity sha512-Tr0DNY4RzTaBG2W2m3l7ZtFuJChTH6VZhXVhkGGjF/4cZTt+i8GcM9ozD+30Lmr4mDoZ5Xx34t2o4GJqYWDGcg== +native-url@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.2.6.tgz#ca1258f5ace169c716ff44eccbddb674e10399ae" + integrity sha512-k4bDC87WtgrdD362gZz6zoiXQrl40kYlBmpfmSjwRO1VU0V5ccwJTlxuE72F6m3V0vc1xOf6n3UCP9QyerRqmA== + dependencies: + querystring "^0.2.0" + natural-compare-lite@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -18141,6 +18036,11 @@ neo-async@^2.5.0, neo-async@^2.6.1: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61" + integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== + netmask@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" @@ -18168,12 +18068,13 @@ nise@^4.0.1: just-extend "^4.0.2" path-to-regexp "^1.7.0" -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== +no-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8" + integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw== dependencies: - lower-case "^1.1.1" + lower-case "^2.0.1" + tslib "^1.10.0" nock@^9.0.14: version "9.1.5" @@ -18215,7 +18116,12 @@ node-fetch@2.1.2: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^1.0.1, node-fetch@~1.7.1: +node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-fetch@~1.7.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== @@ -18223,11 +18129,6 @@ node-fetch@^1.0.1, node-fetch@~1.7.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - node-forge@^0.10.0, node-forge@^0.7.1, node-forge@^0.7.5, node-forge@~0.7.6: version "0.10.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" @@ -18360,10 +18261,10 @@ node-preload@^0.2.0: dependencies: process-on-spawn "^1.0.0" -node-releases@^1.1.13, node-releases@^1.1.58: - version "1.1.59" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.59.tgz#4d648330641cec704bff10f8e4fe28e453ab8e8e" - integrity sha512-H3JrdUczbdiwxN5FuJPyCHnGHIFqQ0wWxo+9j1kAXAzqNMAHlo+4I/sYYxpyK0irQ73HgdiyzD32oqQDcU2Osw== +node-releases@^1.1.52, node-releases@^1.1.66: + version "1.1.67" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" + integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== node-sass@^4.14.1, node-sass@^4.8.3: version "4.14.1" @@ -18473,16 +18374,6 @@ normalize-selector@^0.2.0: resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM= -normalize-url@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - normalize-url@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" @@ -18679,11 +18570,6 @@ object-keys@~0.4.0: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= -object-path@^0.9.2: - version "0.9.2" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5" - integrity sha1-D9mnT8X60a45aLWGvaXGMr1sBaU= - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -18789,6 +18675,11 @@ object.values@^1.0.4, object.values@^1.1.0, object.values@^1.1.1: function-bind "^1.1.1" has "^1.0.3" +objectorarray@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.4.tgz#d69b2f0ff7dc2701903d308bb85882f4ddb49483" + integrity sha512-91k8bjcldstRz1bG6zJo8lWD7c6QXcB4nTDUqiEvIL1xAsLoZlOOZZG+nd6YPz+V7zY1580J4Xxh1vZtyv4i/w== + oboe@2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" @@ -18861,10 +18752,10 @@ only@~0.0.2: resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= -open@^7.0.0, open@^7.0.3: - version "7.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-7.1.0.tgz#68865f7d3cb238520fa1225a63cf28bcf8368a1c" - integrity sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA== +open@^7.0.2, open@^7.0.3: + version "7.3.0" + resolved "https://registry.yarnpkg.com/open/-/open-7.3.0.tgz#45461fdee46444f3645b6e14eb3ca94b82e1be69" + integrity sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw== dependencies: is-docker "^2.0.0" is-wsl "^2.1.1" @@ -18874,13 +18765,6 @@ opencollective-postinstall@^2.0.0: resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== -opn@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" - integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== - dependencies: - is-wsl "^1.1.0" - optimist@~0.3.5: version "0.3.7" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9" @@ -19075,13 +18959,6 @@ ordered-read-streams@^1.0.0: dependencies: readable-stream "^2.0.1" -original@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" - integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== - dependencies: - url-parse "^1.4.3" - os-browserify@^0.3.0, os-browserify@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -19144,6 +19021,18 @@ outpipe@^1.1.0: dependencies: shell-quote "^1.4.2" +overlayscrollbars@^1.10.2: + version "1.13.0" + resolved "https://registry.yarnpkg.com/overlayscrollbars/-/overlayscrollbars-1.13.0.tgz#1edb436328133b94877b558f77966d5497ca36a7" + integrity sha512-p8oHrMeRAKxXDMPI/EBNITj/zTVHKNnAnM59Im+xnoZUlV07FyTg46wom2286jJlXGGfcPFG/ba5NUiCwWNd4w== + +p-all@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" + integrity sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA== + dependencies: + p-map "^2.0.0" + p-cancelable@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" @@ -19190,6 +19079,20 @@ p-event@^2.1.0: dependencies: p-timeout "^2.0.1" +p-event@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-filter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" + integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== + dependencies: + p-map "^2.0.0" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -19217,19 +19120,19 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.3.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" -p-limit@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" - integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== +p-limit@^3.0.1, p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - p-try "^2.0.0" + yocto-queue "^0.1.0" p-locate@^2.0.0: version "2.0.0" @@ -19327,6 +19230,13 @@ p-timeout@^2.0.1: dependencies: p-finally "^1.0.0" +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-times@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-times/-/p-times-2.1.0.tgz#b3e7f9159f916cacb6aae06d67c79451b0076c6c" @@ -19418,12 +19328,13 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= +param-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238" + integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA== dependencies: - no-case "^2.2.0" + dot-case "^3.0.3" + tslib "^1.10.0" parent-module@^1.0.0: version "1.0.1" @@ -19450,18 +19361,6 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" -parse-entities@^1.1.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" - integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - parse-entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" @@ -19566,11 +19465,6 @@ parse5@^3.0.1, parse5@^3.0.2: dependencies: "@types/node" "*" -parse5@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== - parseqs@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" @@ -19590,6 +19484,14 @@ parseurl@^1.3.2, parseurl@~1.3.2, parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +pascal-case@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" + integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -19938,19 +19840,19 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-dir@^4.1.0: +pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" -pkg-up@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= +pkg-up@3.1.0, pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== dependencies: - find-up "^2.1.0" + find-up "^3.0.0" plugin-error@1.0.1, plugin-error@^1.0.1: version "1.0.1" @@ -19997,12 +19899,12 @@ pn@^1.0.0: resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== -pnp-webpack-plugin@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.5.0.tgz#62a1cd3068f46d564bb33c56eb250e4d586676eb" - integrity sha512-jd9olUr9D7do+RN8Wspzhpxhgp1n6Vd0NtQ4SFkmIACZoEL1nkyAdW9Ygrinjec0vgDcWjscFQQ1gDW8rsfKTg== +pnp-webpack-plugin@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== dependencies: - ts-pnp "^1.1.2" + ts-pnp "^1.1.6" po2json@0.4.5: version "0.4.5" @@ -20012,12 +19914,12 @@ po2json@0.4.5: gettext-parser "1.1.0" nomnom "1.8.1" -polished@^3.3.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/polished/-/polished-3.4.0.tgz#29b2a028ee0408df5dded55a2a25e913bc6749a9" - integrity sha512-GiuavmunMIKMOEoSPkXoqBYM2ZcI4YIwCaiwmTOQ55Zq4HG2kD0YZt3WlLZ2l3U9XhJ1LM/fgjCFHHffiZP0YQ== +polished@^3.4.4: + version "3.6.7" + resolved "https://registry.yarnpkg.com/polished/-/polished-3.6.7.tgz#44cbd0047f3187d83db0c479ef0c7d5583af5fb6" + integrity sha512-b4OViUOihwV0icb9PHmWbR+vPqaSzSAEbgLskvb7ANPATVXGiYv/TQFHQo65S53WU9i5EQ1I03YDOJW7K0bmYg== dependencies: - "@babel/runtime" "^7.4.4" + "@babel/runtime" "^7.9.2" polyfill-crypto.getrandomvalues@^1.0.0: version "1.0.0" @@ -20031,7 +19933,7 @@ popper.js@1.16.1-lts: resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05" integrity sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA== -popper.js@^1.11.1, popper.js@^1.14.4, popper.js@^1.14.7: +popper.js@^1.11.1: version "1.15.0" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2" integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA== @@ -20118,10 +20020,10 @@ postcss-modules-local-by-default@^3.0.2: postcss-selector-parser "^6.0.2" postcss-value-parser "^4.0.0" -postcss-modules-scope@^2.1.0, postcss-modules-scope@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz#33d4fc946602eb5e9355c4165d68a10727689dba" - integrity sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ== +postcss-modules-scope@^2.1.0, postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== dependencies: postcss "^7.0.6" postcss-selector-parser "^6.0.0" @@ -20198,7 +20100,7 @@ postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== @@ -20212,6 +20114,15 @@ postcss@7.0.18: source-map "^0.6.1" supports-color "^6.1.0" +postcss@7.0.21: + version "7.0.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" + integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + postcss@^6.0.1, postcss@^6.0.19, postcss@^6.0.23: version "6.0.23" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" @@ -20221,7 +20132,7 @@ postcss@^6.0.1, postcss@^6.0.19, postcss@^6.0.23: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.23, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: +postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: version "7.0.32" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== @@ -20252,7 +20163,7 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^1.0.0, prepend-http@^1.0.1: +prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= @@ -20326,14 +20237,14 @@ priorityqueue@~0.2.1: resolved "https://registry.yarnpkg.com/priorityqueue/-/priorityqueue-0.2.1.tgz#f57e623f20237f30c142d4cb45fafed9e7d51403" integrity sha512-Dr6ZkRFGZHoAri6iNp5KvspOrFPfhxJ5AExXqLy5ChgdwALd3nC+q5/QG+gmjmf9W63joDXc+Zp0h05Ug/RtYg== -prismjs@^1.8.4, prismjs@~1.16.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.16.0.tgz#406eb2c8aacb0f5f0f1167930cb83835d10a4308" - integrity sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA== +prismjs@^1.21.0, prismjs@~1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.22.0.tgz#73c3400afc58a823dd7eed023f8e1ce9fd8977fa" + integrity sha512-lLJ/Wt9yy0AiSYBf212kK3mM5L8ycwlyTlSxHBAneXLR0nzFMlZ5y7riFPF3E33zXOF2IH95xdY5jIyZbM9z/w== optionalDependencies: clipboard "^2.0.0" -private@^0.1.6, private@^0.1.8, private@~0.1.5: +private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -20445,13 +20356,6 @@ promise.prototype.finally@^3.1.0: es-abstract "^1.9.0" function-bind "^1.1.1" -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - promise@~1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-1.3.0.tgz#e5cc9a4c8278e4664ffedc01c7da84842b040175" @@ -20473,7 +20377,7 @@ prop-types-exact@^1.2.0: object.assign "^4.1.0" reflect.ownkeys "^0.2.0" -prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@15.7.2, prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -20496,7 +20400,7 @@ proper-lockfile@^4.0.0: retry "^0.12.0" signal-exit "^3.0.2" -property-information@^5.0.0, property-information@^5.0.1: +property-information@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.1.0.tgz#e4755eee5319f03f7f6f5a9bc1a6a7fea6609e2c" integrity sha512-tODH6R3+SwTkAQckSp2S9xyYX8dEKYkeXw+4TmJzTxnNzd6mQPu1OD4f9zPrvw/Rm4wpPgI+Zp63mNSGNzUgHg== @@ -20877,14 +20781,6 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - query-string@^5.0.1: version "5.1.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" @@ -20904,11 +20800,6 @@ querystring@0.2.0, querystring@^0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== - quick-format-unescaped@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-3.0.2.tgz#0137e94d8fb37ffeb70040535111c378e75396fb" @@ -21027,13 +20918,13 @@ raw-body@~1.1.0: bytes "1" string_decoder "0.10" -raw-loader@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-3.1.0.tgz#5e9d399a5a222cc0de18f42c3bc5e49677532b3f" - integrity sha512-lzUVMuJ06HF4rYveaz9Tv0WRlUMxJ0Y1hgSkkgg+50iEdaI0TthyEDe08KIHb0XsF6rn8WYTqPCaGTZg3sX+qA== +raw-loader@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== dependencies: - loader-utils "^1.1.0" - schema-utils "^2.0.1" + loader-utils "^2.0.0" + schema-utils "^3.0.0" rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: version "1.2.8" @@ -21045,13 +20936,6 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-clientside-effect@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.2.tgz#6212fb0e07b204e714581dd51992603d1accc837" - integrity sha512-nRmoyxeok5PBO6ytPvSjKp9xwXg9xagoTK1mMjwnQxqM9Hd7MNPl+LS1bOSOe+CV2+4fnEquc7H/S8QD3q697A== - dependencies: - "@babel/runtime" "^7.0.0" - react-color@^2.17.0: version "2.17.3" resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.17.3.tgz#b8556d744f95193468c7061d2aa19180118d4a48" @@ -21064,35 +20948,34 @@ react-color@^2.17.0: reactcss "^1.2.0" tinycolor2 "^1.4.1" -react-dev-utils@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-9.0.1.tgz#5c03d85a0b2537d0c46af7165c24a7dfb274bef2" - integrity sha512-pnaeMo/Pxel8aZpxk1WwxT3uXxM3tEwYvsjCYn5R7gNxjhN1auowdcLDzFB8kr7rafAj2rxmvfic/fbac5CzwQ== +react-dev-utils@^10.0.0: + version "10.2.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" + integrity sha512-XxTbgJnYZmxuPtY3y/UV0D8/65NKkmaia4rXzViknVnZeVlklSh8u6TnaEYPfAi/Gh1TP4mEOXHI6jQOPbeakQ== dependencies: - "@babel/code-frame" "7.0.0" - address "1.0.3" - browserslist "4.5.4" + "@babel/code-frame" "7.8.3" + address "1.1.2" + browserslist "4.10.0" chalk "2.4.2" - cross-spawn "6.0.5" + cross-spawn "7.0.1" detect-port-alt "1.1.6" - escape-string-regexp "1.0.5" - filesize "3.6.1" - find-up "3.0.0" - fork-ts-checker-webpack-plugin "1.1.1" + escape-string-regexp "2.0.0" + filesize "6.0.1" + find-up "4.1.0" + fork-ts-checker-webpack-plugin "3.1.1" global-modules "2.0.0" globby "8.0.2" - gzip-size "5.0.0" + gzip-size "5.1.1" immer "1.10.0" - inquirer "6.2.2" - is-root "2.0.0" + inquirer "7.0.4" + is-root "2.1.0" loader-utils "1.2.3" - opn "5.4.0" - pkg-up "2.0.0" - react-error-overlay "^5.1.6" + open "^7.0.2" + pkg-up "3.1.0" + react-error-overlay "^6.0.7" recursive-readdir "2.2.2" - shell-quote "1.6.1" - sockjs-client "1.3.0" - strip-ansi "5.2.0" + shell-quote "1.7.2" + strip-ansi "6.0.0" text-table "0.2.0" react-devtools-core@4.8.2: @@ -21135,6 +21018,32 @@ react-dnd@^3.0.2: prop-types "^15.5.10" shallowequal "^1.0.2" +react-docgen-typescript-loader@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/react-docgen-typescript-loader/-/react-docgen-typescript-loader-3.7.2.tgz#45cb2305652c0602767242a8700ad1ebd66bbbbd" + integrity sha512-fNzUayyUGzSyoOl7E89VaPKJk9dpvdSgyXg81cUkwy0u+NBvkzQG3FC5WBIlXda0k/iaxS+PWi+OC+tUiGxzPA== + dependencies: + "@webpack-contrib/schema-utils" "^1.0.0-beta.0" + loader-utils "^1.2.3" + react-docgen-typescript "^1.15.0" + +react-docgen-typescript-plugin@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-0.6.2.tgz#c83305206c61d5c7e004eaf2dc4661367ddc105d" + integrity sha512-Orw0WKdJGAg5eMZGbEMw/rKonoxbi8epU6RJWTW3ukWuTarxckFXTltGvm8XADAWlBHak30KD71XThtJruxfTg== + dependencies: + debug "^4.1.1" + endent "^2.0.1" + micromatch "^4.0.2" + react-docgen-typescript "^1.20.1" + react-docgen-typescript-loader "^3.7.2" + tslib "^2.0.0" + +react-docgen-typescript@^1.15.0, react-docgen-typescript@^1.20.1: + version "1.20.5" + resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-1.20.5.tgz#fb8d78a707243498436c2952bd3f6f488a68d4f3" + integrity sha512-AbLGMtn76bn7SYBJSSaKJrZ0lgNRRR3qL60PucM5M4v/AXyC8221cKBXW5Pyt9TfDRfe+LDnPNlg7TibxX0ovA== + react-docgen@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.1.0.tgz#8e69f1d2e9153c535c20162ea1b85878b059b474" @@ -21149,7 +21058,7 @@ react-docgen@^5.0.0: node-dir "^0.1.10" strip-indent "^3.0.0" -react-dom@^16.12.0, react-dom@^16.8.3: +react-dom@^16.12.0: version "16.12.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11" integrity sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw== @@ -21167,10 +21076,10 @@ react-draggable@^4.0.3: classnames "^2.2.5" prop-types "^15.6.0" -react-error-overlay@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.6.tgz#0cd73407c5d141f9638ae1e0c63e7b2bf7e9929d" - integrity sha512-X1Y+0jR47ImDVr54Ab6V9eGk0Hnu7fVWGeHQSOXHf/C2pF9c6uy3gef8QUeuUiWlNb0i08InPSE5a/KJzNzw1Q== +react-error-overlay@^6.0.7: + version "6.0.8" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.8.tgz#474ed11d04fc6bda3af643447d85e9127ed6b5de" + integrity sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw== react-fast-compare@2.0.4: version "2.0.4" @@ -21182,18 +21091,6 @@ react-fast-compare@^3.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.1.1.tgz#0becf31e3812fa70dc231e259f40d892d4767900" integrity sha512-SCsAORWK59BvauR2L1BTdjQbJcSGJJz03U0awektk2hshLKrITDDFTlgGCqIZpTDlPC/NFlZee6xTMzXPVLiHw== -react-focus-lock@^2.1.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.2.1.tgz#1d12887416925dc53481914b7cedd39494a3b24a" - integrity sha512-47g0xYcCTZccdzKRGufepY8oZ3W1Qg+2hn6u9SHZ0zUB6uz/4K4xJe7yYFNZ1qT6m+2JDm82F6QgKeBTbjW4PQ== - dependencies: - "@babel/runtime" "^7.0.0" - focus-lock "^0.6.6" - prop-types "^15.6.2" - react-clientside-effect "^1.2.2" - use-callback-ref "^1.2.1" - use-sidecar "^1.0.1" - react-helmet-async@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.0.2.tgz#bb55dd8268f7b15aac69c6b22e2f950abda8cc44" @@ -21232,16 +21129,16 @@ react-inspector@^2.3.0: babel-runtime "^6.26.0" is-dom "^1.0.9" -react-inspector@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-4.0.1.tgz#0f888f78ff7daccbc7be5d452b20c96dc6d5fbb8" - integrity sha512-xSiM6CE79JBqSj8Fzd9dWBHv57tLTH7OM57GP3VrE5crzVF3D5Khce9w1Xcw75OAbvrA0Mi2vBneR1OajKmXFg== +react-inspector@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.0.tgz#45a325e15f33e595be5356ca2d3ceffb7d6b8c3a" + integrity sha512-JAwswiengIcxi4X/Ssb8nf6suOuQsyit8Fxo04+iPKTnPNY3XIOuagjMZSzpJDDKkYcc/ARlySOYZZv626WUvA== dependencies: - "@babel/runtime" "^7.6.3" - is-dom "^1.0.9" - prop-types "^15.6.1" + "@babel/runtime" "^7.0.0" + is-dom "^1.0.0" + prop-types "^15.0.0" -react-is@^16.10.2, react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.10.2, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -21260,30 +21157,19 @@ react-motion@^0.5.2: prop-types "^15.5.8" raf "^3.1.0" -react-popper-tooltip@^2.8.3: - version "2.8.3" - resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.8.3.tgz#1c63e7473a96362bd93be6c94fa404470a265197" - integrity sha512-g5tfxmuj8ClNVwH4zswYJcD3GKoc5RMeRawd/WZnbyZGEDecsRKaVL+Kj7L3BG7w5qb6/MHcLTG8yE4CidwezQ== +react-popper-tooltip@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-3.1.1.tgz#329569eb7b287008f04fcbddb6370452ad3f9eac" + integrity sha512-EnERAnnKRptQBJyaee5GJScWNUKQPDD2ywvzZyUjst/wj5U64C8/CnSYLNEmP2hG0IJ3ZhtDxE8oDN+KOyavXQ== dependencies: - "@babel/runtime" "^7.4.5" - react-popper "^1.3.3" + "@babel/runtime" "^7.12.5" + "@popperjs/core" "^2.5.4" + react-popper "^2.2.4" -react-popper@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.3.tgz#2c6cef7515a991256b4f0536cd4bdcb58a7b6af6" - integrity sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w== - dependencies: - "@babel/runtime" "^7.1.2" - create-react-context "<=0.2.2" - popper.js "^1.14.4" - prop-types "^15.6.1" - typed-styles "^0.0.7" - warning "^4.0.2" - -react-popper@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.3.tgz#33d425fa6975d4bd54d9acd64897a89d904b9d97" - integrity sha512-mOEiMNT1249js0jJvkrOjyHsGvqcJd3aGW/agkiMoZk3bZ1fXN1wQszIQSjHIai48fE67+zwF8Cs+C4fWqlfjw== +react-popper@^2.2.3, react-popper@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.4.tgz#d2ad3d2474ac9f1abf93df3099d408e5aa6a2e22" + integrity sha512-NacOu4zWupdQjVXq02XpTD3yFPSfg5a7fex0wa3uGKVkFK7UN6LvVxgcb+xYr56UCuWiNPMH20tntdVdJRwYew== dependencies: react-fast-compare "^3.0.1" warning "^4.0.2" @@ -21299,6 +21185,11 @@ react-redux@^7.2.0: prop-types "^15.7.2" react-is "^16.9.0" +react-refresh@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" + integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== + react-router-dom@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18" @@ -21368,16 +21259,16 @@ react-sizeme@^2.6.7: shallowequal "^1.1.0" throttle-debounce "^2.1.0" -react-syntax-highlighter@^11.0.2: - version "11.0.2" - resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz#4e3f376e752b20d2f54e4c55652fd663149e4029" - integrity sha512-kqmpM2OH5OodInbEADKARwccwSQWBfZi0970l5Jhp4h39q9Q65C4frNcnd6uHE5pR00W8pOWj9HDRntj2G4Rww== +react-syntax-highlighter@^13.5.0: + version "13.5.3" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-13.5.3.tgz#9712850f883a3e19eb858cf93fad7bb357eea9c6" + integrity sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg== dependencies: "@babel/runtime" "^7.3.1" - highlight.js "~9.13.0" - lowlight "~1.11.0" - prismjs "^1.8.4" - refractor "^2.4.1" + highlight.js "^10.1.1" + lowlight "^1.14.0" + prismjs "^1.21.0" + refractor "^3.1.0" react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0: version "16.12.0" @@ -21389,13 +21280,14 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0: react-is "^16.8.6" scheduler "^0.18.0" -react-textarea-autosize@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.0.tgz#3132cb77e65d94417558d37c0bfe415a5afd3445" - integrity sha512-c2FlR/fP0qbxmlrW96SdrbgP/v0XZMTupqB90zybvmDVDutytUgPl7beU35klwcTeMepUIQEpQUn3P3bdshGPg== +react-textarea-autosize@^8.1.1: + version "8.3.0" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz#e6e2fd186d9f61bb80ac6e2dcb4c55504f93c2fa" + integrity sha512-3GLWFAan2pbwBeoeNDoqGmSbrShORtgWfaWX0RJDivsUrpShh01saRM5RU/i4Zmf+whpBVEY5cA90Eq8Ub1N3w== dependencies: - "@babel/runtime" "^7.1.2" - prop-types "^15.6.0" + "@babel/runtime" "^7.10.2" + use-composed-ref "^1.0.0" + use-latest "^1.0.0" react-tippy@^1.2.2: version "1.2.2" @@ -21443,7 +21335,7 @@ react-transition-group@^4.4.0: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^16.12.0, react@^16.8.3: +react@^16.12.0: version "16.12.0" resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83" integrity sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA== @@ -21630,6 +21522,13 @@ readdirp@~3.2.0: dependencies: picomatch "^2.0.4" +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + readline2@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" @@ -21639,16 +21538,6 @@ readline2@^1.0.1: is-fullwidth-code-point "^1.0.0" mute-stream "0.0.5" -recast@^0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.14.7.tgz#4f1497c2b5826d42a66e8e3c9d80c512983ff61d" - integrity sha512-/nwm9pkrcWagN40JeJhkPaRxiHXBRkXyRh/hgU088Z/v+qCy+zIHHY6bC6o7NaKAxPqtE6nD8zBH1LfU0/Wx6A== - dependencies: - ast-types "0.11.3" - esprima "~4.0.0" - private "~0.1.5" - source-map "~0.6.1" - receptacle@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/receptacle/-/receptacle-1.3.2.tgz#a7994c7efafc7a01d0e2041839dab6c4951360d2" @@ -21698,12 +21587,12 @@ redux-devtools-core@^0.2.1: remotedev-serialize "^0.1.8" redux-devtools-instrument@^1.9.4: - version "1.9.6" - resolved "https://registry.yarnpkg.com/redux-devtools-instrument/-/redux-devtools-instrument-1.9.6.tgz#6b412595f74b9d48cfd4ecc13e585b1588ed6e7e" - integrity sha512-MwvY4cLEB2tIfWWBzrUR02UM9qRG2i7daNzywRvabOSVdvAY7s9BxSwMmVRH1Y/7QWjplNtOwgT0apKhHg2Qew== + version "1.10.0" + resolved "https://registry.yarnpkg.com/redux-devtools-instrument/-/redux-devtools-instrument-1.10.0.tgz#036caf79fa1e5f25ec4bae38a9af4f08c69e323a" + integrity sha512-X8JRBCzX2ADSMp+iiV7YQ8uoTNyEm0VPFPd4T854coz6lvRiBrFSqAr9YAS2n8Kzxx8CJQotR0QF9wsMM+3DvA== dependencies: - lodash "^4.2.0" - symbol-observable "^1.0.2" + lodash "^4.17.19" + symbol-observable "^1.2.0" redux-mock-store@^1.5.4: version "1.5.4" @@ -21730,19 +21619,19 @@ reflect.ownkeys@^0.2.0: resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= -refractor@^2.4.1: - version "2.9.0" - resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.9.0.tgz#0a381aadb51513e4e6ec1ed410b5104dd65e2489" - integrity sha512-lCnCYvXpqd8hC7ksuvo516rz5q4NwzBbq0X5qjH5pxRfcQKiQxKZ8JctrSQmrR/7pcV2TRrs9TT+Whmq/wtluQ== +refractor@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.2.0.tgz#bc46f7cfbb6adbf45cd304e8e299b7fa854804e0" + integrity sha512-hSo+EyMIZTLBvNNgIU5lW4yjCzNYMZ4dcEhBq/3nReGfqzd2JfVhdlPDfU9rEsgcAyWx+OimIIUoL4ZU7NtYHQ== dependencies: - hastscript "^5.0.0" - parse-entities "^1.1.2" - prismjs "~1.16.0" + hastscript "^6.0.0" + parse-entities "^2.0.0" + prismjs "~1.22.0" -regenerate-unicode-properties@^8.0.2: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== dependencies: regenerate "^1.4.0" @@ -21766,10 +21655,10 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: - version "0.13.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" - integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== +regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== regenerator-transform@^0.10.0: version "0.10.1" @@ -21780,12 +21669,12 @@ regenerator-transform@^0.10.0: babel-types "^6.19.0" private "^0.1.6" -regenerator-transform@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf" - integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w== +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== dependencies: - private "^0.1.6" + "@babel/runtime" "^7.8.4" regex-cache@^0.4.2: version "0.4.4" @@ -21802,15 +21691,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regex-parser@^2.2.9: - version "2.2.9" - resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.9.tgz#a372f45a248b62976a568037c1b6e60a60599192" - integrity sha512-VncXxOF6uFlYog5prG2j+e2UGJeam5MfNiJnB/qEgo4KTnMm2XrELCg4rNZ6IlaEUZnGlb8aB6lXowCRQtTkkA== - -regexp-tree@^0.1.6: - version "0.1.10" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.10.tgz#d837816a039c7af8a8d64d7a7c3cf6a1d93450bc" - integrity sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ== +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: version "1.3.0" @@ -21839,17 +21723,17 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" -regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== +regexpu-core@^4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" + integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" - regjsgen "^0.5.0" - regjsparser "^0.6.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" + unicode-match-property-value-ecmascript "^1.2.0" registry-auth-token@^3.0.1: version "3.4.0" @@ -21886,10 +21770,10 @@ regjsgen@^0.2.0: resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= -regjsgen@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" - integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== +regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.1.4: version "0.1.5" @@ -21898,23 +21782,14 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" -regjsparser@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" - integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== dependencies: jsesc "~0.5.0" -rehype-parse@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.0.tgz#f681555f2598165bee2c778b39f9073d17b16bca" - integrity sha512-V2OjMD0xcSt39G4uRdMTqDXXm6HwkUbLMDayYKA/d037j8/OtVSQ+tqKwYWOuyBeoCs/3clXRe30VUjeMDTBSA== - dependencies: - hast-util-from-parse5 "^5.0.0" - parse5 "^5.0.0" - xtend "^4.0.1" - -relateurl@0.2.x: +relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= @@ -22003,9 +21878,9 @@ remote-redux-devtools@^0.5.16: socketcluster-client "^14.2.1" remotedev-serialize@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/remotedev-serialize/-/remotedev-serialize-0.1.8.tgz#c99cb184e7f71a906162abc404be8ce33810205f" - integrity sha512-3YG/FDcOmiK22bl5oMRM8RRnbGrFEuPGjbcDG+z2xi5aQaNQNZ8lqoRnZTwXVfaZtutXuiAQOgPRrogzQk8edg== + version "0.1.9" + resolved "https://registry.yarnpkg.com/remotedev-serialize/-/remotedev-serialize-0.1.9.tgz#5e67e05cbca75d408d769d057dc59d0f56cd2c43" + integrity sha512-5tFdZg9mSaAWTv6xmQ7HtHjKMLSFQFExEZOtJe10PLsv1wb7cy7kYHtBvTYRro27/3fRGEcQBRNKSaixOpb69w== dependencies: jsan "^3.1.13" @@ -22185,11 +22060,6 @@ require-uncached@^1.0.2: caller-path "^0.1.0" resolve-from "^1.0.0" -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - reselect@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" @@ -22200,11 +22070,6 @@ reselect@^4.0.0: resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== -resize-observer-polyfill@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" - integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== - resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" @@ -22253,20 +22118,21 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== -resolve-url-loader@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-2.3.0.tgz#e1b37034d48f22f8cfb9f04c026faaa070fdaf26" - integrity sha512-RaEUWgF/B6aTg9VKaOv2o6dfm5f75/lGh8S+SQwoMcBm48WkA2nhLR+V7KEawkxXjU4lLB16IVeHCe7F69nyVw== +resolve-url-loader@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz#235e2c28e22e3e432ba7a5d4e305c59a58edfc08" + integrity sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ== dependencies: - adjust-sourcemap-loader "^1.1.0" - camelcase "^4.1.0" - convert-source-map "^1.5.1" - loader-utils "^1.1.0" - lodash.defaults "^4.0.0" - rework "^1.0.1" - rework-visit "^1.0.0" - source-map "^0.5.7" - urix "^0.1.0" + adjust-sourcemap-loader "3.0.0" + camelcase "5.3.1" + compose-function "3.0.3" + convert-source-map "1.7.0" + es6-iterator "2.0.3" + loader-utils "1.2.3" + postcss "7.0.21" + rework "1.0.1" + rework-visit "1.0.0" + source-map "0.6.1" resolve-url@^0.2.1: version "0.2.1" @@ -22278,7 +22144,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: +resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: version "1.18.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== @@ -22351,12 +22217,12 @@ reusify@^1.0.0: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rework-visit@^1.0.0: +rework-visit@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" integrity sha1-mUWygD8hni96ygCtuLyfZA+ELJo= -rework@^1.0.1: +rework@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/rework/-/rework-1.0.1.tgz#30806a841342b54510aa4110850cd48534144aa7" integrity sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc= @@ -22364,7 +22230,7 @@ rework@^1.0.1: convert-source-map "^0.3.3" css "^2.0.0" -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -22401,9 +22267,9 @@ rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3: bn.js "^4.11.1" rn-host-detect@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.1.5.tgz#fbecb982b73932f34529e97932b9a63e58d8deb6" - integrity sha512-ufk2dFT3QeP9HyZ/xTuMtW27KnFy815CYitJMqQm+pgG3ZAtHBsrU8nXizNKkqXGy3bQmhEoloVbrfbvMJMqkg== + version "1.2.0" + resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.2.0.tgz#8b0396fc05631ec60c1cb8789e5070cdb04d0da0" + integrity sha512-btNg5kzHcjZZ7t7mvvV/4wNJ9e3MPgrWivkRgWURzXL0JJ0pwWlU4zrbmdlz3HHzHOxhBhHB4D+/dbMFfu4/4A== roarr@^2.15.3: version "2.15.3" @@ -22493,11 +22359,6 @@ rustbn.js@~0.2.0: resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== -rw@1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" - integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= - rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" @@ -22637,6 +22498,11 @@ sc-errors@^1.4.1: resolved "https://registry.yarnpkg.com/sc-errors/-/sc-errors-1.4.1.tgz#53e80030fe647e133d73b51eaa7d2b0f7591fd5b" integrity sha512-dBn92iIonpChTxYLgKkIT/PCApvmYT6EPIbRvbQKTgY6tbEbIy8XVUv4pGyKwEK4nCmvX4TKXcN0iXC6tNW6rQ== +sc-errors@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sc-errors/-/sc-errors-2.0.1.tgz#3af2d934dfd82116279a4b2c1552c1e021ddcb03" + integrity sha512-JoVhq3Ud+3Ujv2SIG7W0XtjRHsrNgl6iXuHHsh0s+Kdt5NwI6N2EGAZD4iteitdDv68ENBkpjtSvN597/wxPSQ== + sc-formatter@^3.0.1, sc-formatter@^3.0.2, sc-formatter@~3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/sc-formatter/-/sc-formatter-3.0.2.tgz#9abdb14e71873ce7157714d3002477bbdb33c4e6" @@ -22684,14 +22550,23 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.4, schema-utils@^2.6.6, schema-utils@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== +schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" scope-analyzer@^2.0.1: version "2.1.1" @@ -22706,11 +22581,6 @@ scope-analyzer@^2.0.1: estree-is-function "^1.0.0" get-assigned-identifiers "^1.1.0" -scrollbarwidth@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/scrollbarwidth/-/scrollbarwidth-0.1.3.tgz#1b0de64e288c38c427f4a01fe00a462a04b94fdf" - integrity sha1-Gw3mTiiMOMQn9KAf4ApGKgS5T98= - scrypt-js@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" @@ -22847,6 +22717,11 @@ semver@6.3.0, semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.2.0, semver resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" @@ -22941,6 +22816,15 @@ servify@^0.1.12: request "^2.79.0" xhr "^2.3.3" +ses@0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/ses/-/ses-0.11.0.tgz#1e470112ed320d169f0b850525858129c0be0881" + integrity sha512-3HH+23C4bijk9VegfiP+cBMqkGim/TMsj/DK5nh/pJFiNrCMfi5euvVluIV66ry202+uckg7nXKrgrEcBwU8SA== + dependencies: + "@agoric/babel-standalone" "^7.9.5" + "@agoric/make-hardener" "^0.1.0" + "@agoric/transform-module" "^0.4.1" + sesify-tofu@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/sesify-tofu/-/sesify-tofu-2.0.4.tgz#b31d4c8d67ea2d61e9c5be4948f085a849f3e632" @@ -23054,11 +22938,6 @@ shallow-copy@~0.0.1: resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA= -shallow-equal@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.1.0.tgz#cc022f030dcba0d1c198abf658a3c6c744e171ca" - integrity sha512-0SW1nWo1hnabO62SEeHsl8nmTVVEzguVWZCj5gaQrgWAxz/BaCja4OWdJBWLVPDxdtE/WU7c98uUCCXyPHSCvw== - shallowequal@1.1.0, shallowequal@^1.0.2, shallowequal@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" @@ -23096,15 +22975,10 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@1.6.1, shell-quote@^1.4.2, shell-quote@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" - integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= - dependencies: - array-filter "~0.0.0" - array-map "~0.0.0" - array-reduce "~0.0.0" - jsonify "~0.0.0" +shell-quote@1.7.2, shell-quote@^1.4.2, shell-quote@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== shelljs@^0.7.5: version "0.7.8" @@ -23115,10 +22989,10 @@ shelljs@^0.7.5: interpret "^1.0.0" rechoir "^0.6.2" -shelljs@^0.8.1, shelljs@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" - integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== +shelljs@^0.8.1, shelljs@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" + integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -23176,27 +23050,6 @@ simple-peer@^9.3.0: randombytes "^2.0.3" readable-stream "^3.4.0" -simplebar-react@^1.0.0-alpha.6: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simplebar-react/-/simplebar-react-1.0.0.tgz#8fe914d7f980dd077cc9dfd3e22ec5596f006b8d" - integrity sha512-FbM2yn7D/UzrJGCY60CKeLkZ3gOs7tYr7KmyamteUt9SKh2x4yW5KVM4IQBw86x4ofRoD6FT19MWmfMKv4Onhw== - dependencies: - prop-types "^15.6.1" - simplebar "^4.0.0" - -simplebar@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-4.0.0.tgz#7f1b9e735ec94a58f887d4803f6b15abf401b6b5" - integrity sha512-td6vJVhqIXfa3JgNZR5OgETPLfmHNSSpt+OXIbk6WH/nOrUtX3Qcyio30+5rdxxAV/61+F5eJ4jJV4Ek7/KJYQ== - dependencies: - can-use-dom "^0.1.0" - core-js "^3.0.1" - lodash.debounce "^4.0.8" - lodash.memoize "^4.1.2" - lodash.throttle "^4.1.1" - resize-observer-polyfill "^1.5.1" - scrollbarwidth "^0.1.3" - single-call-balance-checker-abi@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/single-call-balance-checker-abi/-/single-call-balance-checker-abi-1.0.0.tgz#b369009fd4cc6214968cdba650ad93986315d92d" @@ -23346,9 +23199,9 @@ socket.io@^2.1.1: socket.io-parser "~3.3.0" socketcluster-client@^14.2.1: - version "14.2.2" - resolved "https://registry.yarnpkg.com/socketcluster-client/-/socketcluster-client-14.2.2.tgz#60b31318abe6828ba7233f5a9a32540263fd23b6" - integrity sha512-vofmFcTaHaIf+MqAR0OZS7e30X4jxbDPJl+taCe8kLGJ5rVOrKeuU0sGyHyHyqW87AIR6jqc4KODl4WQJ4SsAA== + version "14.3.1" + resolved "https://registry.yarnpkg.com/socketcluster-client/-/socketcluster-client-14.3.1.tgz#bfc3591c0cad2668e7b3512a102f3844f5f2e84d" + integrity sha512-Sd/T0K/9UlqTfz+HUuFq90dshA5OBJPQbdkRzGtcKIOm52fkdsBTt0FYpiuzzxv5VrU7PWpRm6KIfNXyPwlLpw== dependencies: buffer "^5.2.1" clone "2.1.1" @@ -23356,10 +23209,10 @@ socketcluster-client@^14.2.1: linked-list "0.1.0" querystring "0.2.0" sc-channel "^1.2.0" - sc-errors "^1.4.1" + sc-errors "^2.0.1" sc-formatter "^3.0.1" uuid "3.2.1" - ws "5.1.1" + ws "7.1.0" socketcluster-server@^14.3.2: version "14.4.0" @@ -23394,18 +23247,6 @@ socketcluster@^14.3.3: uid-number "0.0.6" uuid "3.2.1" -sockjs-client@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177" - integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg== - dependencies: - debug "^3.2.5" - eventsource "^1.0.7" - faye-websocket "~0.11.1" - inherits "^2.0.3" - json3 "^3.3.2" - url-parse "^1.4.3" - socks-proxy-agent@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" @@ -23492,7 +23333,7 @@ source-map-support@0.5.12: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@0.5.13, source-map-support@^0.5.1, source-map-support@^0.5.11, source-map-support@^0.5.9, source-map-support@~0.5.12, source-map-support@~0.5.4: +source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== @@ -23507,11 +23348,24 @@ source-map-support@^0.4.15: dependencies: source-map "^0.5.6" +source-map-support@^0.5.1, source-map-support@^0.5.11, source-map-support@^0.5.16, source-map-support@~0.5.12, source-map-support@~0.5.4: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + source-map@0.X, source-map@^0.7.2, source-map@^0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" @@ -23536,11 +23390,6 @@ source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, sour resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - sourcemap-codec@^1.4.1: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" @@ -23671,14 +23520,6 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" - integrity sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g== - dependencies: - figgy-pudding "^3.5.1" - minipass "^3.1.1" - ssri@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808" @@ -23696,6 +23537,11 @@ stack-trace@0.0.10: resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= +stackframe@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" + integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== + state-toggle@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.2.tgz#75e93a61944116b4959d665c8db2d243631d6ddc" @@ -24013,12 +23859,12 @@ stringify-object@^3.0.0: is-obj "^1.0.1" is-regexp "^1.0.0" -strip-ansi@5.2.0, strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== +strip-ansi@6.0.0, strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== dependencies: - ansi-regex "^4.1.0" + ansi-regex "^5.0.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" @@ -24034,12 +23880,12 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: - ansi-regex "^5.0.0" + ansi-regex "^4.1.0" strip-ansi@~0.1.0: version "0.1.1" @@ -24149,13 +23995,13 @@ style-loader@^0.21.0: loader-utils "^1.1.0" schema-utils "^0.4.5" -style-loader@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.1.3.tgz#9e826e69c683c4d9bf9db924f85e9abb30d5e200" - integrity sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw== +style-loader@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== dependencies: - loader-utils "^1.2.3" - schema-utils "^2.6.4" + loader-utils "^2.0.0" + schema-utils "^2.7.0" style-search@^0.1.0: version "0.1.0" @@ -24320,7 +24166,7 @@ svg-tags@^1.0.0: resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= -svgo@^1.0.5, svgo@^1.2.1: +svgo@^1.0.5: version "1.3.0" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ== @@ -24361,15 +24207,10 @@ swarm-js@^0.1.40: tar "^4.0.2" xhr-request "^1.0.1" -symbol-observable@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= - -symbol-observable@^1.0.2, symbol-observable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +symbol-observable@1.0.1, symbol-observable@^1.2.0, symbol-observable@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" + integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== symbol-tree@^3.2.1: version "3.2.2" @@ -24412,7 +24253,7 @@ table@^5.2.3, table@^5.4.6: slice-ansi "^2.1.0" string-width "^3.0.0" -tapable@^1.0.0, tapable@^1.1.0, tapable@^1.1.3: +tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== @@ -24527,18 +24368,18 @@ tdigest@^0.1.1: dependencies: bintrees "1.0.1" -telejson@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-3.3.0.tgz#6d814f3c0d254d5c4770085aad063e266b56ad03" - integrity sha512-er08AylQ+LEbDLp1GRezORZu5wKOHaBczF6oYJtgC3Idv10qZ8A3p6ffT+J5BzDKkV9MqBvu8HAKiIIOp6KJ2w== +telejson@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-5.1.0.tgz#cc04e4c2a355f9eb6af557e37acd6449feb1d146" + integrity sha512-Yy0N2OV0mosmr1SCZEm3Ezhu/oi5Dbao5RqauZu4+VI5I/XtVBHXajRk0txuqbFYtKdzzWGDZFGSif9ovVLjEA== dependencies: "@types/is-function" "^1.0.0" global "^4.4.0" - is-function "^1.0.1" - is-regex "^1.0.4" + is-function "^1.0.2" + is-regex "^1.1.1" is-symbol "^1.0.3" isobject "^4.0.0" - lodash "^4.17.15" + lodash "^4.17.20" memoizerific "^1.11.3" temp-dir@^1.0.0: @@ -24588,22 +24429,22 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser-webpack-plugin@^2.1.2: - version "2.3.8" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz#894764a19b0743f2f704e7c2a848c5283a696724" - integrity sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w== +terser-webpack-plugin@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-3.1.0.tgz#91e6d39571460ed240c0cf69d295bcf30ebf98cb" + integrity sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA== dependencies: - cacache "^13.0.1" + cacache "^15.0.5" find-cache-dir "^3.3.1" - jest-worker "^25.4.0" - p-limit "^2.3.0" + jest-worker "^26.2.1" + p-limit "^3.0.2" schema-utils "^2.6.6" serialize-javascript "^4.0.0" source-map "^0.6.1" - terser "^4.6.12" + terser "^4.8.0" webpack-sources "^1.4.3" -terser@^4.1.2, terser@^4.6.12: +terser@^4.1.2, terser@^4.6.12, terser@^4.6.3, terser@^4.8.0: version "4.8.0" resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== @@ -25003,10 +24844,15 @@ ts-custom-error@^2.2.1: resolved "https://registry.yarnpkg.com/ts-custom-error/-/ts-custom-error-2.2.1.tgz#47086fbc34df5c7c2d4fba8c92d8767662066951" integrity sha512-lHKZtU+PXkVuap6nlFZybIAFLUO8B3jbCs1VynBL8AUSAHfeG6HpztcBTDRp5I+fN5820N9kGg+eTIvr+le2yg== -ts-dedent@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-1.1.1.tgz#68fad040d7dbd53a90f545b450702340e17d18f3" - integrity sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg== +ts-dedent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.0.0.tgz#47c5eb23d9096f3237cc413bc82d387d36dbe690" + integrity sha512-DfxKjSFQfw9+uf7N9Cy8Ebx9fv5fquK4hZ6SD3Rzr+1jKP6AVA6H8+B5457ZpUs0JKsGpGqIevbpZ9DMQJDp1A== + +ts-essentials@^2.0.3: + version "2.0.12" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" + integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== ts-invariant@^0.4.0: version "0.4.4" @@ -25015,10 +24861,10 @@ ts-invariant@^0.4.0: dependencies: tslib "^1.9.3" -ts-pnp@^1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.5.tgz#840e0739c89fce5f3abd9037bb091dbff16d9dec" - integrity sha512-ti7OGMOUOzo66wLF3liskw6YQIaSsBgc4GOAlWRnIEj8htCxJUxskanMUoJOD6MDCRAXo36goXJZch+nOS0VMA== +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== tsconfig-paths@^3.9.0: version "3.9.0" @@ -25030,10 +24876,15 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.9.0, tslib@^1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.0, tslib@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" + integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== tsscmp@1.0.6: version "1.0.6" @@ -25142,11 +24993,6 @@ type-is@^1.6.16, type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typed-styles@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" - integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== - typedarray-to-buffer@^3.1.5, typedarray-to-buffer@~3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -25186,19 +25032,6 @@ typical@^5.0.0: resolved "https://registry.yarnpkg.com/typical/-/typical-5.1.0.tgz#7116ca103caf2574985fc84fbaa8fd0ee5ea1684" integrity sha512-t5Ik8UAwBal1P1XzuVE4dc+RYQZicLUGJdvqr/vdqsED7SQECgsGBylldSsfWZL7RQjxT3xhQcKHWhLaVSR6YQ== -ua-parser-js@^0.7.9: - version "0.7.17" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" - integrity sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g== - -uglify-js@3.4.x: - version "3.4.10" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" - integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== - dependencies: - commander "~2.19.0" - source-map "~0.6.1" - uid-number@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" @@ -25303,30 +25136,16 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== unicode-property-aliases-ecmascript@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== -unified@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13" - integrity sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw== - dependencies: - "@types/unist" "^2.0.0" - "@types/vfile" "^3.0.0" - bail "^1.0.0" - extend "^3.0.0" - is-plain-obj "^1.1.0" - trough "^1.0.0" - vfile "^3.0.0" - x-is-string "^0.1.0" - unified@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/unified/-/unified-9.0.0.tgz#12b099f97ee8b36792dbad13d278ee2f696eed1d" @@ -25407,11 +25226,6 @@ unist-util-remove-position@^2.0.0: dependencies: unist-util-visit "^2.0.0" -unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c" - integrity sha1-PMvcU2ee7W7PN3fdf14yKcG2qjw= - unist-util-stringify-position@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.1.tgz#de2a2bc8d3febfa606652673a91455b6a36fb9f3" @@ -25441,6 +25255,16 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" integrity sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc= +universalify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" + integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + unorm@^1.3.3: version "1.5.0" resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.5.0.tgz#01fa9b76f1c60f7916834605c032aa8962c3f00a" @@ -25520,11 +25344,6 @@ uport-base64url@3.0.2-alpha.0: dependencies: buffer "^5.2.1" -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= - uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -25545,14 +25364,14 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-loader@^2.0.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" - integrity sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog== +url-loader@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== dependencies: - loader-utils "^1.2.3" - mime "^2.4.4" - schema-utils "^2.5.0" + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.0.0" url-parse-lax@^1.0.0: version "1.0.0" @@ -25568,14 +25387,6 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-parse@^1.4.3: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - url-set-query@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" @@ -25602,18 +25413,24 @@ ursa-optional@~0.9.10: bindings "^1.3.0" nan "^2.11.1" -use-callback-ref@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.1.tgz#898759ccb9e14be6c7a860abafa3ffbd826c89bb" - integrity sha512-C3nvxh0ZpaOxs9RCnWwAJ+7bJPwQI8LHF71LzbQ3BvzH5XkdtlkMadqElGevg5bYBDFip4sAnD4m06zAKebg1w== - -use-sidecar@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.2.tgz#e72f582a75842f7de4ef8becd6235a4720ad8af6" - integrity sha512-287RZny6m5KNMTb/Kq9gmjafi7lQL0YHO1lYolU6+tY1h9+Z3uCtkJJ3OSOq3INwYf2hBryCcDh4520AhJibMA== +use-composed-ref@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.1.0.tgz#9220e4e94a97b7b02d7d27eaeab0b37034438bbc" + integrity sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg== dependencies: - detect-node "^2.0.4" - tslib "^1.9.3" + ts-essentials "^2.0.3" + +use-isomorphic-layout-effect@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.0.tgz#4db2111e0d53ca694187ea5fd5cb2ba610286fe0" + integrity sha512-kady5Z1O1qx5RitodCCKbpJSVEtECXYcnBnb5Q48Bz5V6gBmTu85ZcGdVwVFs8+DaOurNb/L5VdGHoQRMknghw== + +use-latest@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232" + integrity sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw== + dependencies: + use-isomorphic-layout-effect "^1.0.0" use@^3.1.0: version "3.1.0" @@ -25733,6 +25550,11 @@ uuid@^3.0.1, uuid@^3.1.0, uuid@^3.2.1, uuid@^3.2.2, uuid@^3.3.2, uuid@^3.3.3: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== +uuid@^8.0.0: + version "8.3.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" + integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== + v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" @@ -25806,13 +25628,6 @@ vfile-location@^3.0.0: resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.0.1.tgz#d78677c3546de0f7cd977544c367266764d31bb3" integrity sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ== -vfile-message@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.0.0.tgz#a6adb0474ea400fa25d929f1d673abea6a17e359" - integrity sha512-HPREhzTOB/sNDc9/Mxf8w0FmHnThg5CRSJdR9VRFkD2riqYWs+fuXlj5z8mIpv2LrD7uU41+oPWFOL4Mjlf+dw== - dependencies: - unist-util-stringify-position "^1.1.1" - vfile-message@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.1.tgz#951881861c22fc1eb39f873c0b93e336a64e8f6d" @@ -25821,16 +25636,6 @@ vfile-message@^2.0.0: "@types/unist" "^2.0.2" unist-util-stringify-position "^2.0.0" -vfile@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803" - integrity sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ== - dependencies: - is-buffer "^2.0.0" - replace-ext "1.0.0" - unist-util-stringify-position "^1.0.0" - vfile-message "^1.0.0" - vfile@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.1.tgz#fc3d43a1c71916034216bf65926d5ee3c64ed60c" @@ -25946,7 +25751,7 @@ warning@^3.0.0: dependencies: loose-envify "^1.0.0" -warning@^4.0.2: +warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== @@ -25966,14 +25771,23 @@ watchify@^3.11.1: through2 "^2.0.0" xtend "^4.0.0" -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: - chokidar "^2.0.2" graceful-fs "^4.1.2" neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" wcwidth@^1.0.0: version "1.0.1" @@ -25990,11 +25804,6 @@ weak@^1.0.0: bindings "^1.2.1" nan "^2.0.5" -web-namespaces@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.3.tgz#9bbf5c99ff0908d2da031f1d732492a96571a83f" - integrity sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA== - web3-bzz@1.2.11: version "1.2.11" resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" @@ -26326,6 +26135,11 @@ webpack-dev-middleware@^3.7.0: range-parser "^1.2.1" webpack-log "^2.0.0" +webpack-filter-warnings-plugin@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz#dc61521cf4f9b4a336fbc89108a75ae1da951cdb" + integrity sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg== + webpack-hot-middleware@^2.25.0: version "2.25.0" resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz#4528a0a63ec37f8f8ef565cf9e534d57d09fe706" @@ -26336,6 +26150,16 @@ webpack-hot-middleware@^2.25.0: querystring "^0.2.0" strip-ansi "^3.0.0" +webpack-log@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-1.2.0.tgz#a4b34cda6b22b518dbb0ab32e567962d5c72a43d" + integrity sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA== + dependencies: + chalk "^2.1.0" + log-symbols "^2.1.0" + loglevelnext "^1.0.1" + uuid "^3.1.0" + webpack-log@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" @@ -26344,7 +26168,7 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -26352,40 +26176,40 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack- source-list-map "^2.0.0" source-map "~0.6.1" -webpack-virtual-modules@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.1.tgz#8ab73d4df0fd37ed27bb8d823bc60ea7266c8bf7" - integrity sha512-0PWBlxyt4uGDofooIEanWhhyBOHdd+lr7QpYNDLC7/yc5lqJT8zlc04MTIBnKj+c2BlQNNuwE5er/Tg4wowHzA== +webpack-virtual-modules@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" + integrity sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA== dependencies: debug "^3.0.0" -webpack@^4.33.0, webpack@^4.38.0, webpack@^4.41.6: - version "4.41.6" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.6.tgz#12f2f804bf6542ef166755050d4afbc8f66ba7e1" - integrity sha512-yxXfV0Zv9WMGRD+QexkZzmGIh54bsvEs+9aRWxnN8erLWEOehAKUTeNBoUbA6HPEZPlRo7KDi2ZcNveoZgK9MA== +webpack@^4.41.6, webpack@^4.44.2: + version "4.44.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72" + integrity sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" ajv "^6.10.2" ajv-keywords "^3.4.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" + enhanced-resolve "^4.3.0" eslint-scope "^4.0.3" json-parse-better-errors "^1.0.2" loader-runner "^2.4.0" loader-utils "^1.2.3" memory-fs "^0.4.1" micromatch "^3.1.10" - mkdirp "^0.5.1" + mkdirp "^0.5.3" neo-async "^2.6.1" node-libs-browser "^2.2.1" schema-utils "^1.0.0" tapable "^1.1.3" terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" + watchpack "^1.7.4" webpack-sources "^1.4.1" "webrtcsupport@github:ipfs/webrtcsupport": @@ -26429,7 +26253,7 @@ whatwg-fetch@2.0.4: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== -whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1: +whatwg-fetch@^3.0.0, whatwg-fetch@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3" integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ== @@ -26597,13 +26421,6 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.1.1.tgz#1d43704689711ac1942fd2f283e38f825c4b8b95" - integrity sha512-bOusvpCb09TOBLbpMKszd45WKC2KPtxiyiHanv+H2DE3Az+1db5a/L7sVJZVDPUC1Br8f0SKRr1KjLpD1U/IAw== - dependencies: - async-limiter "~1.0.0" - ws@6.1.2: version "6.1.2" resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" @@ -26611,6 +26428,13 @@ ws@6.1.2: dependencies: async-limiter "~1.0.0" +ws@7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.1.0.tgz#0395646c6fcc3ac56abf61ce1a42039637a6bd98" + integrity sha512-Swie2C4fs7CkwlHu1glMePLYJJsWjzhl1vm3ZaLplD0h7OMkZyZ6kLTB/OagiU923bZrPFXuDTeEqaEN4NWG4g== + dependencies: + async-limiter "^1.0.0" + ws@7.2.3, ws@^7: version "7.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" @@ -26647,11 +26471,6 @@ ws@~6.1.0: dependencies: async-limiter "~1.0.0" -x-is-string@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" - integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= - xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -26940,6 +26759,11 @@ ylru@^1.2.0: resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" integrity sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ== +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + zcash-bitcore-lib@~0.13.20-rc3: version "0.13.20-rc3" resolved "https://registry.yarnpkg.com/zcash-bitcore-lib/-/zcash-bitcore-lib-0.13.20-rc3.tgz#813a0f56dcf8b76bc1429951bea6d1236c507008"