From 4b44e1ef979600dcb7165ab0abc7c299d6b0c3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Salgado?= Date: Wed, 21 Oct 2020 09:59:31 +0100 Subject: [PATCH 01/31] feat: token management screen --- lib/new-admin/graphql/schema.js | 11 ++- lib/token-manager.js | 8 ++ .../pages/TokenManagement/TokenManagement.js | 97 +++++++++++++++++++ .../TokenManagement/TokenManagement.styles.js | 33 +++++++ new-lamassu-admin/src/routing/routes.js | 17 ++++ 5 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 lib/token-manager.js create mode 100644 new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js create mode 100644 new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index 9cc8fba0..a39eb05d 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -9,6 +9,7 @@ const customers = require('../../customers') const { machineAction } = require('../machines') const logs = require('../../logs') const settingsLoader = require('../../new-settings-loader') +const tokenManager = require('../../token-manager') const serverVersion = require('../../../package.json').version @@ -155,6 +156,12 @@ const typeDefs = gql` uptime: Int! } + type UserToken { + token: String! + name: String! + created: Date! + } + type Transaction { id: ID! txClass: String! @@ -217,6 +224,7 @@ const typeDefs = gql` transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String accounts: JSONObject config: JSONObject + userTokens: [UserToken] } enum MachineAction { @@ -273,7 +281,8 @@ const resolvers = { transactionsCsv: (...[, { from, until, limit, offset }]) => transactions.batch(from, until, limit, offset).then(parseAsync), config: () => settingsLoader.loadLatestConfigOrNone(), - accounts: () => settingsLoader.loadAccounts() + accounts: () => settingsLoader.loadAccounts(), + userTokens: () => tokenManager.getTokenList() }, Mutation: { machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }), diff --git a/lib/token-manager.js b/lib/token-manager.js new file mode 100644 index 00000000..74bde507 --- /dev/null +++ b/lib/token-manager.js @@ -0,0 +1,8 @@ +const db = require('./db') + +function getTokenList() { + const sql = `select * from user_tokens` + return db.any(sql); +} + +module.exports = { getTokenList } \ No newline at end of file diff --git a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js new file mode 100644 index 00000000..1ee83b29 --- /dev/null +++ b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js @@ -0,0 +1,97 @@ +import { useQuery } from '@apollo/react-hooks' +import { makeStyles } from '@material-ui/core/styles' +import gql from 'graphql-tag' +import moment from 'moment' +import * as R from 'ramda' +import React from 'react' + +import Title from 'src/components/Title' +// import DataTable from 'src/components/tables/DataTable' +import { Table as EditableTable } from 'src/components/editableTable' + +import { mainStyles } from './TokenManagement.styles' + +const useStyles = makeStyles(mainStyles) + +const GET_USER_TOKENS = gql` + { + userTokens { + token + name + created + } + } +` + +const Tokens = () => { + const classes = useStyles() + + const { data: tknResponse } = useQuery(GET_USER_TOKENS) + + const elements = [ + { + name: 'name', + header: 'Name', + width: 312, + textAlign: 'center', + size: 'sm' + }, + { + name: 'token', + header: 'Token', + width: 520, + textAlign: 'center', + size: 'sm' + }, + { + name: 'created', + header: 'Date (UTC)', + width: 140, + textAlign: 'right', + size: 'sm', + view: t => moment.utc(t).format('YYYY-MM-DD') + }, + { + name: 'created', + header: 'Time (UTC)', + width: 140, + textAlign: 'right', + size: 'sm', + view: t => moment.utc(t).format('HH:mm:ss') + } + ] + + return ( + <> + {console.log(tknResponse)} +
+
+ Token Management +
+
+ + + ) + + /* return ( + <> + {console.log(tknResponse)} +
+
+ Token Management +
+
+ + + ) */ +} + +export default Tokens diff --git a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js new file mode 100644 index 00000000..9d52042f --- /dev/null +++ b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js @@ -0,0 +1,33 @@ +import typographyStyles from 'src/components/typography/styles' +import baseStyles from 'src/pages/Logs.styles' + +const { label1 } = typographyStyles +const { titleWrapper, titleAndButtonsContainer, buttonsWrapper } = baseStyles + +const mainStyles = { + titleWrapper, + titleAndButtonsContainer, + buttonsWrapper, + headerLabels: { + display: 'flex', + flexDirection: 'row', + '& div': { + display: 'flex', + alignItems: 'center' + }, + '& > div:first-child': { + marginRight: 24 + }, + '& span': { + extend: label1, + marginLeft: 6 + } + }, + overflowTd: { + overflow: 'hidden', + whiteSpace: 'nowrap', + textOverflow: 'ellipsis' + } +} + +export { mainStyles } diff --git a/new-lamassu-admin/src/routing/routes.js b/new-lamassu-admin/src/routing/routes.js index 0a1e1f0c..43f5deb6 100644 --- a/new-lamassu-admin/src/routing/routes.js +++ b/new-lamassu-admin/src/routing/routes.js @@ -22,6 +22,7 @@ import Notifications from 'src/pages/Notifications/Notifications' import OperatorInfo from 'src/pages/OperatorInfo/OperatorInfo' import ServerLogs from 'src/pages/ServerLogs' import Services from 'src/pages/Services/Services' +import TokenManagement from 'src/pages/TokenManagement/TokenManagement' import Transactions from 'src/pages/Transactions/Transactions' import Triggers from 'src/pages/Triggers' import WalletSettings from 'src/pages/Wallet/Wallet' @@ -153,6 +154,22 @@ const tree = [ component: CustomerProfile } ] + }, + { + key: 'system', + label: 'System', + route: '/system', + get component() { + return () => + }, + children: [ + { + key: 'token-management', + label: 'Token Management', + route: '/system/token-management', + component: TokenManagement + } + ] } ] From c4e7547c45a560530884ba7b2c93a231d70b767c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Salgado?= Date: Thu, 22 Oct 2020 11:24:00 +0100 Subject: [PATCH 02/31] feat: add revoke token button --- lib/new-admin/graphql/schema.js | 4 +- lib/token-manager.js | 13 ++- .../pages/TokenManagement/TokenManagement.js | 79 +++++++++++-------- .../TokenManagement/TokenManagement.styles.js | 27 +------ 4 files changed, 58 insertions(+), 65 deletions(-) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index a39eb05d..db678330 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -243,6 +243,7 @@ const typeDefs = gql` saveConfig(config: JSONObject): JSONObject createPairingTotem(name: String!): String saveAccounts(accounts: JSONObject): JSONObject + revokeToken(token: String!): UserToken } ` @@ -293,7 +294,8 @@ const resolvers = { .then(it => { notify() return it - }) + }), + revokeToken: (...[, { token }]) => tokenManager.revokeToken(token) } } diff --git a/lib/token-manager.js b/lib/token-manager.js index 74bde507..3c9a7cc5 100644 --- a/lib/token-manager.js +++ b/lib/token-manager.js @@ -1,8 +1,13 @@ const db = require('./db') -function getTokenList() { - const sql = `select * from user_tokens` - return db.any(sql); +function getTokenList () { + const sql = `select * from user_tokens` + return db.any(sql) } -module.exports = { getTokenList } \ No newline at end of file +function revokeToken (token) { + const sql = `delete from user_tokens where token = $1` + return db.none(sql, [token]) +} + +module.exports = { getTokenList, revokeToken } \ No newline at end of file diff --git a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js index 1ee83b29..c503a547 100644 --- a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js +++ b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js @@ -1,4 +1,4 @@ -import { useQuery } from '@apollo/react-hooks' +import { useQuery, useMutation } from '@apollo/react-hooks' import { makeStyles } from '@material-ui/core/styles' import gql from 'graphql-tag' import moment from 'moment' @@ -6,15 +6,16 @@ import * as R from 'ramda' import React from 'react' import Title from 'src/components/Title' -// import DataTable from 'src/components/tables/DataTable' -import { Table as EditableTable } from 'src/components/editableTable' +import { IconButton } from 'src/components/buttons' +import DataTable from 'src/components/tables/DataTable' +import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg' import { mainStyles } from './TokenManagement.styles' const useStyles = makeStyles(mainStyles) const GET_USER_TOKENS = gql` - { + query userTokens { userTokens { token name @@ -23,64 +24,72 @@ const GET_USER_TOKENS = gql` } ` +const REVOKE_USER_TOKEN = gql` + mutation revokeToken($token: String!) { + revokeToken(token: $token) { + token + } + } +` + const Tokens = () => { const classes = useStyles() const { data: tknResponse } = useQuery(GET_USER_TOKENS) + const [revokeToken] = useMutation(REVOKE_USER_TOKEN, { + onCompleted: () => console.log('passed'), + onError: () => console.log('failed'), + refetchQueries: () => ['userTokens'] + }) + const elements = [ { - name: 'name', header: 'Name', - width: 312, + width: 257, textAlign: 'center', - size: 'sm' + size: 'sm', + view: t => t.name }, { - name: 'token', header: 'Token', - width: 520, + width: 505, textAlign: 'center', - size: 'sm' + size: 'sm', + view: t => t.token }, { - name: 'created', header: 'Date (UTC)', - width: 140, + width: 145, textAlign: 'right', size: 'sm', - view: t => moment.utc(t).format('YYYY-MM-DD') + view: t => moment.utc(t.created).format('YYYY-MM-DD') }, { - name: 'created', header: 'Time (UTC)', - width: 140, + width: 145, textAlign: 'right', size: 'sm', - view: t => moment.utc(t).format('HH:mm:ss') + view: t => moment.utc(t.created).format('HH:mm:ss') + }, + { + header: '', + width: 80, + textAlign: 'center', + size: 'sm', + view: t => ( + { + revokeToken({ variables: { token: t.token } }) + }}> + + + ) } ] return ( <> - {console.log(tknResponse)} -
-
- Token Management -
-
- - - ) - - /* return ( - <> - {console.log(tknResponse)}
Token Management @@ -91,7 +100,7 @@ const Tokens = () => { data={R.path(['userTokens'])(tknResponse)} /> - ) */ + ) } export default Tokens diff --git a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js index 9d52042f..e5ac1d06 100644 --- a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js +++ b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js @@ -1,33 +1,10 @@ -import typographyStyles from 'src/components/typography/styles' import baseStyles from 'src/pages/Logs.styles' -const { label1 } = typographyStyles -const { titleWrapper, titleAndButtonsContainer, buttonsWrapper } = baseStyles +const { titleWrapper, titleAndButtonsContainer } = baseStyles const mainStyles = { titleWrapper, - titleAndButtonsContainer, - buttonsWrapper, - headerLabels: { - display: 'flex', - flexDirection: 'row', - '& div': { - display: 'flex', - alignItems: 'center' - }, - '& > div:first-child': { - marginRight: 24 - }, - '& span': { - extend: label1, - marginLeft: 6 - } - }, - overflowTd: { - overflow: 'hidden', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis' - } + titleAndButtonsContainer } export { mainStyles } From 791b275cdf62ac5ca0cd508977a54497ff8cab79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Salgado?= Date: Mon, 26 Oct 2020 09:57:31 +0000 Subject: [PATCH 03/31] feat: add request data to user_tokens and token filtering --- lib/new-admin/admin-server.js | 2 +- lib/new-admin/graphql/schema.js | 4 ++-- lib/new-admin/login.js | 10 +++++++--- lib/token-manager.js | 8 ++++---- migrations/1603438527057-add-browser-os-info.js | 15 +++++++++++++++ .../src/pages/TokenManagement/TokenManagement.js | 16 +++++++++++----- new-lamassu-admin/src/utils/browser-os.js | 14 ++++++++++++++ package-lock.json | 7 ++++++- package.json | 1 + 9 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 migrations/1603438527057-add-browser-os-info.js create mode 100644 new-lamassu-admin/src/utils/browser-os.js diff --git a/lib/new-admin/admin-server.js b/lib/new-admin/admin-server.js index 60e36eb9..cbc85541 100644 --- a/lib/new-admin/admin-server.js +++ b/lib/new-admin/admin-server.js @@ -71,7 +71,7 @@ app.get('/api/register', (req, res, next) => { if (!otp) return next() - return login.register(otp) + return login.register(req) .then(r => { if (r.expired) return res.status(401).send('OTP expired, generate new registration link') diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index db678330..cb1a9e2b 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -224,7 +224,7 @@ const typeDefs = gql` transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String accounts: JSONObject config: JSONObject - userTokens: [UserToken] + userTokens(browser: String!, os: String!): [UserToken] } enum MachineAction { @@ -283,7 +283,7 @@ const resolvers = { transactions.batch(from, until, limit, offset).then(parseAsync), config: () => settingsLoader.loadLatestConfigOrNone(), accounts: () => settingsLoader.loadAccounts(), - userTokens: () => tokenManager.getTokenList() + userTokens: (...[, { browser, os }]) => tokenManager.getTokenList(browser, os) }, Mutation: { machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }), diff --git a/lib/new-admin/login.js b/lib/new-admin/login.js index 0eaaff21..278c4714 100644 --- a/lib/new-admin/login.js +++ b/lib/new-admin/login.js @@ -1,5 +1,6 @@ const crypto = require('crypto') +const browserOS = require('../../new-lamassu-admin/src/utils/browser-os') const db = require('../db') function generateOTP (name) { @@ -21,15 +22,18 @@ function validateOTP (otp) { .catch(() => ({ success: false, expired: false })) } -function register (otp) { +function register (req) { + const otp = req.query.otp + return validateOTP(otp) .then(r => { if (!r.success) return r + const deviceInfo = browserOS.getInformation(req.headers['user-agent']) const token = crypto.randomBytes(32).toString('hex') - const sql = 'insert into user_tokens (token, name) values ($1, $2)' + const sql = 'insert into user_tokens (token, name, browser_version, os_version, ip_address) values ($1, $2, $3, $4, $5)' - return db.none(sql, [token, r.name]) + return db.none(sql, [token, r.name, deviceInfo.browser, deviceInfo.OS, browserOS.getRequestIP(req)]) .then(() => ({ success: true, token: token })) }) .catch(() => ({ success: false, expired: false })) diff --git a/lib/token-manager.js b/lib/token-manager.js index 3c9a7cc5..25e52b88 100644 --- a/lib/token-manager.js +++ b/lib/token-manager.js @@ -1,8 +1,8 @@ const db = require('./db') -function getTokenList () { - const sql = `select * from user_tokens` - return db.any(sql) +function getTokenList (browser, os) { + const sql = `select * from user_tokens where browser_version=$1 and os_version=$2` + return db.any(sql, [browser, os]) } function revokeToken (token) { @@ -10,4 +10,4 @@ function revokeToken (token) { return db.none(sql, [token]) } -module.exports = { getTokenList, revokeToken } \ No newline at end of file +module.exports = { getTokenList, revokeToken } diff --git a/migrations/1603438527057-add-browser-os-info.js b/migrations/1603438527057-add-browser-os-info.js new file mode 100644 index 00000000..e0e5e613 --- /dev/null +++ b/migrations/1603438527057-add-browser-os-info.js @@ -0,0 +1,15 @@ +const db = require('./db') + +exports.up = function (next) { + var sql = [ + 'ALTER TABLE user_tokens ADD COLUMN browser_version text', + 'ALTER TABLE user_tokens ADD COLUMN os_version text', + 'ALTER TABLE user_tokens ADD COLUMN ip_address inet', + ] + + db.multi(sql, next) +} + +exports.down = function (next) { + next() +} diff --git a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js index c503a547..57aad2a4 100644 --- a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js +++ b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js @@ -9,14 +9,15 @@ import Title from 'src/components/Title' import { IconButton } from 'src/components/buttons' import DataTable from 'src/components/tables/DataTable' import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg' +import * as browserOS from 'src/utils/browser-os' import { mainStyles } from './TokenManagement.styles' const useStyles = makeStyles(mainStyles) const GET_USER_TOKENS = gql` - query userTokens { - userTokens { + query userTokens($browser: String!, $os: String!) { + userTokens(browser: $browser, os: $os) { token name created @@ -35,11 +36,16 @@ const REVOKE_USER_TOKEN = gql` const Tokens = () => { const classes = useStyles() - const { data: tknResponse } = useQuery(GET_USER_TOKENS) + const userAgent = browserOS.getInformation(navigator.userAgent) + + const { data: tknResponse } = useQuery(GET_USER_TOKENS, { + variables: { + browser: `${userAgent.browser}`, + os: `${userAgent.OS}` + } + }) const [revokeToken] = useMutation(REVOKE_USER_TOKEN, { - onCompleted: () => console.log('passed'), - onError: () => console.log('failed'), refetchQueries: () => ['userTokens'] }) diff --git a/new-lamassu-admin/src/utils/browser-os.js b/new-lamassu-admin/src/utils/browser-os.js new file mode 100644 index 00000000..13bef62e --- /dev/null +++ b/new-lamassu-admin/src/utils/browser-os.js @@ -0,0 +1,14 @@ +const parser = require('ua-parser-js') + +function getRequestIP(req) { + return req.ip +} + +function getInformation(uaString) { + const userAgent = parser(uaString) + const browser = `${userAgent.browser.name} ${userAgent.browser.version}` + const OS = `${userAgent.os.name} ${userAgent.os.version}` + return { browser: browser, OS: OS } +} + +module.exports = { getRequestIP, getInformation } diff --git a/package-lock.json b/package-lock.json index 699052b0..233ba9ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10541,6 +10541,11 @@ "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" }, + "ua-parser-js": { + "version": "0.7.22", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz", + "integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==" + }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -10795,7 +10800,7 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.7.tgz", "integrity": "sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ==", "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git", + "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2-cookies": "^1.1.0", diff --git a/package.json b/package.json index 31b53418..9fb7380f 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "socket.io-client": "^2.0.3", "talisman": "^0.20.0", "twilio": "^3.6.1", + "ua-parser-js": "^0.7.22", "uuid": "^3.1.0", "web3": "^0.20.6", "winston": "^2.4.2", From 839e6aae47373154e32bc3a363343aa16947d04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Salgado?= Date: Mon, 26 Oct 2020 16:03:02 +0000 Subject: [PATCH 04/31] refactor: user agent parsing --- lib/new-admin/admin-server.js | 4 ++- lib/new-admin/graphql/schema.js | 6 ++-- lib/new-admin/login.js | 10 ++---- lib/token-manager.js | 6 ++-- .../1603438527057-add-browser-os-info.js | 3 +- .../pages/TokenManagement/TokenManagement.js | 31 +++++-------------- .../TokenManagement/TokenManagement.styles.js | 10 ------ new-lamassu-admin/src/utils/browser-os.js | 14 --------- 8 files changed, 21 insertions(+), 63 deletions(-) delete mode 100644 new-lamassu-admin/src/pages/TokenManagement/TokenManagement.styles.js delete mode 100644 new-lamassu-admin/src/utils/browser-os.js diff --git a/lib/new-admin/admin-server.js b/lib/new-admin/admin-server.js index cbc85541..79927743 100644 --- a/lib/new-admin/admin-server.js +++ b/lib/new-admin/admin-server.js @@ -68,10 +68,12 @@ app.use('/front-camera-photo', serveStatic(frontCameraBasedir, { index: false }) app.get('/api/register', (req, res, next) => { const otp = req.query.otp + const ua = req.headers['user-agent'] + const ip = req.ip if (!otp) return next() - return login.register(req) + return login.register(otp, ua, ip) .then(r => { if (r.expired) return res.status(401).send('OTP expired, generate new registration link') diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index cb1a9e2b..09e7645b 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -160,6 +160,8 @@ const typeDefs = gql` token: String! name: String! created: Date! + user_agent: String! + ip_address: String! } type Transaction { @@ -224,7 +226,7 @@ const typeDefs = gql` transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String accounts: JSONObject config: JSONObject - userTokens(browser: String!, os: String!): [UserToken] + userTokens: [UserToken] } enum MachineAction { @@ -283,7 +285,7 @@ const resolvers = { transactions.batch(from, until, limit, offset).then(parseAsync), config: () => settingsLoader.loadLatestConfigOrNone(), accounts: () => settingsLoader.loadAccounts(), - userTokens: (...[, { browser, os }]) => tokenManager.getTokenList(browser, os) + userTokens: () => tokenManager.getTokenList() }, Mutation: { machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }), diff --git a/lib/new-admin/login.js b/lib/new-admin/login.js index 278c4714..4f58c3d3 100644 --- a/lib/new-admin/login.js +++ b/lib/new-admin/login.js @@ -1,6 +1,5 @@ const crypto = require('crypto') -const browserOS = require('../../new-lamassu-admin/src/utils/browser-os') const db = require('../db') function generateOTP (name) { @@ -22,18 +21,15 @@ function validateOTP (otp) { .catch(() => ({ success: false, expired: false })) } -function register (req) { - const otp = req.query.otp - +function register (otp, ua, ip) { return validateOTP(otp) .then(r => { if (!r.success) return r - const deviceInfo = browserOS.getInformation(req.headers['user-agent']) const token = crypto.randomBytes(32).toString('hex') - const sql = 'insert into user_tokens (token, name, browser_version, os_version, ip_address) values ($1, $2, $3, $4, $5)' + const sql = 'insert into user_tokens (token, name, user_agent, ip_address) values ($1, $2, $3, $4)' - return db.none(sql, [token, r.name, deviceInfo.browser, deviceInfo.OS, browserOS.getRequestIP(req)]) + return db.none(sql, [token, r.name, ua, ip]) .then(() => ({ success: true, token: token })) }) .catch(() => ({ success: false, expired: false })) diff --git a/lib/token-manager.js b/lib/token-manager.js index 25e52b88..32209969 100644 --- a/lib/token-manager.js +++ b/lib/token-manager.js @@ -1,8 +1,8 @@ const db = require('./db') -function getTokenList (browser, os) { - const sql = `select * from user_tokens where browser_version=$1 and os_version=$2` - return db.any(sql, [browser, os]) +function getTokenList () { + const sql = `select * from user_tokens` + return db.any(sql) } function revokeToken (token) { diff --git a/migrations/1603438527057-add-browser-os-info.js b/migrations/1603438527057-add-browser-os-info.js index e0e5e613..b4e75aa8 100644 --- a/migrations/1603438527057-add-browser-os-info.js +++ b/migrations/1603438527057-add-browser-os-info.js @@ -2,8 +2,7 @@ const db = require('./db') exports.up = function (next) { var sql = [ - 'ALTER TABLE user_tokens ADD COLUMN browser_version text', - 'ALTER TABLE user_tokens ADD COLUMN os_version text', + 'ALTER TABLE user_tokens ADD COLUMN user_agent text', 'ALTER TABLE user_tokens ADD COLUMN ip_address inet', ] diff --git a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js index 57aad2a4..7d1fc085 100644 --- a/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js +++ b/new-lamassu-admin/src/pages/TokenManagement/TokenManagement.js @@ -1,26 +1,22 @@ import { useQuery, useMutation } from '@apollo/react-hooks' -import { makeStyles } from '@material-ui/core/styles' import gql from 'graphql-tag' import moment from 'moment' import * as R from 'ramda' import React from 'react' -import Title from 'src/components/Title' import { IconButton } from 'src/components/buttons' +import TitleSection from 'src/components/layout/TitleSection' import DataTable from 'src/components/tables/DataTable' import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg' -import * as browserOS from 'src/utils/browser-os' - -import { mainStyles } from './TokenManagement.styles' - -const useStyles = makeStyles(mainStyles) const GET_USER_TOKENS = gql` - query userTokens($browser: String!, $os: String!) { - userTokens(browser: $browser, os: $os) { + query userTokens { + userTokens { token name created + user_agent + ip_address } } ` @@ -34,16 +30,7 @@ const REVOKE_USER_TOKEN = gql` ` const Tokens = () => { - const classes = useStyles() - - const userAgent = browserOS.getInformation(navigator.userAgent) - - const { data: tknResponse } = useQuery(GET_USER_TOKENS, { - variables: { - browser: `${userAgent.browser}`, - os: `${userAgent.OS}` - } - }) + const { data: tknResponse } = useQuery(GET_USER_TOKENS) const [revokeToken] = useMutation(REVOKE_USER_TOKEN, { refetchQueries: () => ['userTokens'] @@ -96,11 +83,7 @@ const Tokens = () => { return ( <> -
-
- Token Management -
-
+ Date: Tue, 17 Nov 2020 18:16:05 +0000 Subject: [PATCH 05/31] fix: fudge factor text(crypto atoms) --- new-lamassu-admin/src/pages/Cashout/Cashout.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/new-lamassu-admin/src/pages/Cashout/Cashout.js b/new-lamassu-admin/src/pages/Cashout/Cashout.js index d9f6e477..3cac4fb5 100644 --- a/new-lamassu-admin/src/pages/Cashout/Cashout.js +++ b/new-lamassu-admin/src/pages/Cashout/Cashout.js @@ -89,7 +89,7 @@ const CashOut = ({ name: SCREEN_KEY }) => {

Automatically accept customer deposits as complete if their - received amount is 10 crypto atoms or less. + received amount is 100 crypto atoms or less.

(Crypto atoms are the smallest unit in each cryptocurrency. E.g., From fd6f1a2fe04c7ee0a2fdf0430ae82b66e930e4d8 Mon Sep 17 00:00:00 2001 From: Cesar Date: Mon, 16 Nov 2020 15:14:51 +0000 Subject: [PATCH 06/31] feat: create blacklist page --- lib/blacklist.js | 54 ++++-- lib/new-admin/graphql/schema.js | 25 ++- .../src/pages/Blacklist/Blacklist.js | 183 ++++++++++++++++++ .../src/pages/Blacklist/Blacklist.styles.js | 39 ++++ .../src/pages/Blacklist/BlacklistModal.js | 76 ++++++++ .../src/pages/Blacklist/BlacklistTable.js | 60 ++++++ .../src/pages/Blacklist/index.js | 3 + new-lamassu-admin/src/routing/routes.js | 7 + .../src/styling/icons/menu/search-zodiac.svg | 13 ++ 9 files changed, 446 insertions(+), 14 deletions(-) create mode 100644 new-lamassu-admin/src/pages/Blacklist/Blacklist.js create mode 100644 new-lamassu-admin/src/pages/Blacklist/Blacklist.styles.js create mode 100644 new-lamassu-admin/src/pages/Blacklist/BlacklistModal.js create mode 100644 new-lamassu-admin/src/pages/Blacklist/BlacklistTable.js create mode 100644 new-lamassu-admin/src/pages/Blacklist/index.js create mode 100644 new-lamassu-admin/src/styling/icons/menu/search-zodiac.svg diff --git a/lib/blacklist.js b/lib/blacklist.js index e66ac3ff..4415675f 100644 --- a/lib/blacklist.js +++ b/lib/blacklist.js @@ -1,22 +1,52 @@ const db = require('./db') -function blocked (address, cryptoCode) { - const sql = `select * from blacklist where address = $1 and crypto_code = $2` - return db.any(sql, [ - address, - cryptoCode - ]) +// Get all blacklist rows from the DB "blacklist" table +const getBlacklist = () => { + return db.any('select * from blacklist').then(res => + res.map(item => ({ + cryptoCode: item.crypto_code, + address: item.address, + createdByOperator: item.created_by_operator + })) + ) } -function addToUsedAddresses (address, cryptoCode) { +// Delete row from blacklist table by crypto code and address +const deleteFromBlacklist = (cryptoCode, address) => { + return db.none( + 'delete from blacklist where crypto_code = $1 and address = $2;', + [cryptoCode, address] + ) +} + +const insertIntoBlacklist = (cryptoCode, address) => { + return db + .any( + 'insert into blacklist(crypto_code, address, created_by_operator) values($1, $2, $3);', + [cryptoCode, address, true] + ) + .then(() => { + return { cryptoCode, address } + }) +} + +function blocked(address, cryptoCode) { + const sql = `select * from blacklist where address = $1 and crypto_code = $2` + return db.any(sql, [address, cryptoCode]) +} + +function addToUsedAddresses(address, cryptoCode) { // ETH reuses addresses if (cryptoCode === 'ETH') return Promise.resolve() const sql = `insert into blacklist(crypto_code, address, created_by_operator) values ($1, $2, 'f')` - return db.oneOrNone(sql, [ - cryptoCode, - address - ]) + return db.oneOrNone(sql, [cryptoCode, address]) } -module.exports = { blocked, addToUsedAddresses } +module.exports = { + blocked, + addToUsedAddresses, + getBlacklist, + deleteFromBlacklist, + insertIntoBlacklist +} diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index 09e7645b..b474e550 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -10,6 +10,7 @@ const { machineAction } = require('../machines') const logs = require('../../logs') const settingsLoader = require('../../new-settings-loader') const tokenManager = require('../../token-manager') +const blacklist = require('../../blacklist') const serverVersion = require('../../../package.json').version @@ -18,7 +19,13 @@ const funding = require('../funding') const supervisor = require('../supervisor') const serverLogs = require('../server-logs') const pairing = require('../pairing') -const { accounts: accountsConfig, coins, countries, currencies, languages } = require('../config') +const { + accounts: accountsConfig, + coins, + countries, + currencies, + languages +} = require('../config') const typeDefs = gql` scalar JSON @@ -192,7 +199,7 @@ const typeDefs = gql` customerId: ID txVersion: Int! termsAccepted: Boolean - commissionPercentage: String + commissionPercentage: String rawTickerPrice: String isPaperWallet: Boolean customerPhone: String @@ -206,6 +213,12 @@ const typeDefs = gql` machineName: String } + type Blacklist { + createdByOperator: Boolean! + cryptoCode: String! + address: String! + } + type Query { countries: [Country] currencies: [Currency] @@ -226,6 +239,7 @@ const typeDefs = gql` transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String accounts: JSONObject config: JSONObject + blacklist: [Blacklist] userTokens: [UserToken] } @@ -246,6 +260,8 @@ const typeDefs = gql` createPairingTotem(name: String!): String saveAccounts(accounts: JSONObject): JSONObject revokeToken(token: String!): UserToken + deleteBlacklistRow(cryptoCode: String, address: String): Blacklist + insertBlacklistRow(cryptoCode: String!, address: String!): Blacklist } ` @@ -285,6 +301,7 @@ const resolvers = { transactions.batch(from, until, limit, offset).then(parseAsync), config: () => settingsLoader.loadLatestConfigOrNone(), accounts: () => settingsLoader.loadAccounts(), + blacklist: () => blacklist.getBlacklist(), userTokens: () => tokenManager.getTokenList() }, Mutation: { @@ -297,6 +314,10 @@ const resolvers = { notify() return it }), + deleteBlacklistRow: (...[, { cryptoCode, address }]) => + blacklist.deleteFromBlacklist(cryptoCode, address), + insertBlacklistRow: (...[, { cryptoCode, address }]) => + blacklist.insertIntoBlacklist(cryptoCode, address), revokeToken: (...[, { token }]) => tokenManager.revokeToken(token) } } diff --git a/new-lamassu-admin/src/pages/Blacklist/Blacklist.js b/new-lamassu-admin/src/pages/Blacklist/Blacklist.js new file mode 100644 index 00000000..3f673d9c --- /dev/null +++ b/new-lamassu-admin/src/pages/Blacklist/Blacklist.js @@ -0,0 +1,183 @@ +import { useQuery, useMutation } from '@apollo/react-hooks' +import { Box } from '@material-ui/core' +import Grid from '@material-ui/core/Grid' +import { makeStyles } from '@material-ui/core/styles' +import gql from 'graphql-tag' +import * as R from 'ramda' +import React, { useState } from 'react' + +import Tooltip from 'src/components/Tooltip' +import { Link } from 'src/components/buttons' +import { Switch } from 'src/components/inputs' +import Sidebar from 'src/components/layout/Sidebar' +import TitleSection from 'src/components/layout/TitleSection' +import { H4, Label2, P } from 'src/components/typography' +import { fromNamespace, toNamespace } from 'src/utils/config' + +import styles from './Blacklist.styles' +import BlackListModal from './BlacklistModal' +import BlacklistTable from './BlacklistTable' + +const useStyles = makeStyles(styles) + +const groupByCode = R.groupBy(obj => obj.cryptoCode) + +const DELETE_ROW = gql` + mutation DeleteBlacklistRow($cryptoCode: String!, $address: String!) { + deleteBlacklistRow(cryptoCode: $cryptoCode, address: $address) { + cryptoCode + address + } + } +` + +const GET_BLACKLIST = gql` + query getBlacklistData { + blacklist { + cryptoCode + address + } + cryptoCurrencies { + display + code + } + } +` + +const SAVE_CONFIG = gql` + mutation Save($config: JSONObject) { + saveConfig(config: $config) + } +` + +const GET_INFO = gql` + query getData { + config + } +` + +const ADD_ROW = gql` + mutation InsertBlacklistRow($cryptoCode: String!, $address: String!) { + insertBlacklistRow(cryptoCode: $cryptoCode, address: $address) { + cryptoCode + address + } + } +` + +const Blacklist = () => { + const { data: blacklistResponse } = useQuery(GET_BLACKLIST) + const { data: configData } = useQuery(GET_INFO) + const [showModal, setShowModal] = useState(false) + const [clickedItem, setClickedItem] = useState({ + code: 'BTC', + display: 'Bitcoin' + }) + const [deleteEntry] = useMutation(DELETE_ROW, { + onError: () => console.error('Error while deleting row'), + refetchQueries: () => ['getBlacklistData'] + }) + + const [addEntry] = useMutation(ADD_ROW, { + onError: () => console.error('Error while adding row'), + onCompleted: () => setShowModal(false), + refetchQueries: () => ['getBlacklistData'] + }) + + const [saveConfig] = useMutation(SAVE_CONFIG, { + refetchQueries: () => ['getData'] + }) + + const classes = useStyles() + + const blacklistData = R.path(['blacklist'])(blacklistResponse) ?? [] + const availableCurrencies = + R.path(['cryptoCurrencies'], blacklistResponse) ?? [] + + const formattedData = groupByCode(blacklistData) + + const complianceConfig = + configData?.config && fromNamespace('compliance')(configData.config) + + const rejectAddressReuse = complianceConfig?.rejectAddressReuse ?? false + + const addressReuseSave = rawConfig => { + const config = toNamespace('compliance')(rawConfig) + return saveConfig({ variables: { config } }) + } + + const onClickSidebarItem = e => { + setClickedItem({ code: e.code, display: e.display }) + } + + const handleDeleteEntry = (cryptoCode, address) => { + deleteEntry({ variables: { cryptoCode, address } }) + } + + const toggleModal = () => setShowModal(!showModal) + + const addToBlacklist = (cryptoCode, address) => { + addEntry({ variables: { cryptoCode, address } }) + } + + return ( + <> + + Blacklist new addresses + + + it.display} + onClick={onClickSidebarItem} + /> +

+ +

+ {clickedItem.display + ? `${clickedItem.display} blacklisted addresses` + : ''}{' '} +

+ +

Reject reused addresses

+ { + addressReuseSave({ rejectAddressReuse: event.target.checked }) + }} + value={rejectAddressReuse} + /> + {rejectAddressReuse ? 'On' : 'Off'} + +

+ The "Reject reused addresses" option means that all addresses + that are used once will be automatically rejected if there's + an attempt to use them again on a new transaction. +

+
+
+
+ +
+ + {showModal && ( + setShowModal(false)} + selectedCoin={clickedItem} + addToBlacklist={addToBlacklist} + /> + )} + + ) +} + +export default Blacklist diff --git a/new-lamassu-admin/src/pages/Blacklist/Blacklist.styles.js b/new-lamassu-admin/src/pages/Blacklist/Blacklist.styles.js new file mode 100644 index 00000000..b4374d41 --- /dev/null +++ b/new-lamassu-admin/src/pages/Blacklist/Blacklist.styles.js @@ -0,0 +1,39 @@ +import { spacer, fontPrimary, primaryColor, white } from 'src/styling/variables' + +export default { + grid: { + flex: 1, + height: '100%' + }, + content: { + display: 'flex', + flexDirection: 'column', + flex: 1, + marginLeft: spacer * 6 + }, + footer: { + margin: [['auto', 0, spacer * 3, 'auto']] + }, + modalTitle: { + lineHeight: '120%', + color: primaryColor, + fontSize: 14, + fontFamily: fontPrimary, + fontWeight: 900 + }, + subtitle: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + flexDirection: 'row' + }, + white: { + color: white + }, + deleteButton: { + paddingLeft: 13 + }, + addressRow: { + marginLeft: 8 + } +} diff --git a/new-lamassu-admin/src/pages/Blacklist/BlacklistModal.js b/new-lamassu-admin/src/pages/Blacklist/BlacklistModal.js new file mode 100644 index 00000000..1e6877e2 --- /dev/null +++ b/new-lamassu-admin/src/pages/Blacklist/BlacklistModal.js @@ -0,0 +1,76 @@ +import { makeStyles } from '@material-ui/core/styles' +import { Formik, Form, Field } from 'formik' +import * as R from 'ramda' +import React from 'react' +import * as Yup from 'yup' + +import Modal from 'src/components/Modal' +import { Link } from 'src/components/buttons' +import { TextInput } from 'src/components/inputs/formik' +import { H3 } from 'src/components/typography' + +import styles from './Blacklist.styles' +const useStyles = makeStyles(styles) + +const BlackListModal = ({ onClose, selectedCoin, addToBlacklist }) => { + const classes = useStyles() + + const handleAddToBlacklist = address => { + addToBlacklist(selectedCoin.code, address) + } + + const placeholderAddress = { + BTC: '1ADwinnimZKGgQ3dpyfoUZvJh4p1UWSSpD', + ETH: '0x71C7656EC7ab88b098defB751B7401B5f6d8976F', + LTC: 'LPKvbjwV1Kaksktzkr7TMK3FQtQEEe6Wqa', + DASH: 'XqQ7gU8eM76rEfey726cJpT2RGKyJyBrcn', + ZEC: 't1KGyyv24eL354C9gjveBGEe8Xz9UoPKvHR', + BCH: 'qrd6za97wm03lfyg82w0c9vqgc727rhemg5yd9k3dm' + } + + return ( + + { + handleAddToBlacklist(address) + resetForm() + }}> +
+

+ {selectedCoin.display + ? `Blacklist ${R.toLower(selectedCoin.display)} address` + : ''} +

+ + +
+
+ + Blacklist address + +
+
+ ) +} + +export default BlackListModal diff --git a/new-lamassu-admin/src/pages/Blacklist/BlacklistTable.js b/new-lamassu-admin/src/pages/Blacklist/BlacklistTable.js new file mode 100644 index 00000000..95b66110 --- /dev/null +++ b/new-lamassu-admin/src/pages/Blacklist/BlacklistTable.js @@ -0,0 +1,60 @@ +import { makeStyles } from '@material-ui/core/styles' +import * as R from 'ramda' +import React from 'react' + +import { IconButton } from 'src/components/buttons' +import DataTable from 'src/components/tables/DataTable' +import { Label1 } from 'src/components/typography' +import CopyToClipboard from 'src/pages/Transactions/CopyToClipboard' +import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg' + +import styles from './Blacklist.styles' + +const useStyles = makeStyles(styles) + +const BlacklistTable = ({ data, selectedCoin, handleDeleteEntry }) => { + const classes = useStyles() + + const elements = [ + { + name: 'address', + header: {'Addresses'}, + width: 800, + textAlign: 'left', + size: 'sm', + view: it => ( +
+ {R.path(['address'], it)} +
+ ) + }, + { + name: 'deleteButton', + header: {'Delete'}, + width: 130, + textAlign: 'center', + size: 'sm', + view: it => ( + + handleDeleteEntry( + R.path(['cryptoCode'], it), + R.path(['address'], it) + ) + }> + + + ) + } + ] + const dataToShow = selectedCoin + ? data[selectedCoin.code] + : data[R.keys(data)[0]] + + return ( + + ) +} + +export default BlacklistTable diff --git a/new-lamassu-admin/src/pages/Blacklist/index.js b/new-lamassu-admin/src/pages/Blacklist/index.js new file mode 100644 index 00000000..4a7e8ce4 --- /dev/null +++ b/new-lamassu-admin/src/pages/Blacklist/index.js @@ -0,0 +1,3 @@ +import Blacklist from './Blacklist' + +export default Blacklist diff --git a/new-lamassu-admin/src/routing/routes.js b/new-lamassu-admin/src/routing/routes.js index 43f5deb6..404ade02 100644 --- a/new-lamassu-admin/src/routing/routes.js +++ b/new-lamassu-admin/src/routing/routes.js @@ -10,6 +10,7 @@ import { import { AppContext } from 'src/App' import AuthRegister from 'src/pages/AuthRegister' +import Blacklist from 'src/pages/Blacklist' import Cashout from 'src/pages/Cashout' import Commissions from 'src/pages/Commissions' import { Customers, CustomerProfile } from 'src/pages/Customers' @@ -148,6 +149,12 @@ const tree = [ route: '/compliance/customers', component: Customers }, + { + key: 'blacklist', + label: 'Blacklist', + route: '/compliance/blacklist', + component: Blacklist + }, { key: 'customer', route: '/compliance/customer/:id', diff --git a/new-lamassu-admin/src/styling/icons/menu/search-zodiac.svg b/new-lamassu-admin/src/styling/icons/menu/search-zodiac.svg new file mode 100644 index 00000000..99fb94be --- /dev/null +++ b/new-lamassu-admin/src/styling/icons/menu/search-zodiac.svg @@ -0,0 +1,13 @@ + + + + Created with Sketch. + + + + + + + + + \ No newline at end of file From a6b6ebd0bc869d25e5737c901d0d0398ad710d23 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Tue, 17 Nov 2020 11:00:14 +0000 Subject: [PATCH 07/31] fix: fix for requested changes pr #513 --- lib/new-admin/graphql/schema.js | 2 +- .../src/pages/Blacklist/Blacklist.js | 4 +--- package-lock.json | 21 +------------------ 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index b474e550..7ed1801d 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -260,7 +260,7 @@ const typeDefs = gql` createPairingTotem(name: String!): String saveAccounts(accounts: JSONObject): JSONObject revokeToken(token: String!): UserToken - deleteBlacklistRow(cryptoCode: String, address: String): Blacklist + deleteBlacklistRow(cryptoCode: String!, address: String!): Blacklist insertBlacklistRow(cryptoCode: String!, address: String!): Blacklist } ` diff --git a/new-lamassu-admin/src/pages/Blacklist/Blacklist.js b/new-lamassu-admin/src/pages/Blacklist/Blacklist.js index 3f673d9c..ce91ef55 100644 --- a/new-lamassu-admin/src/pages/Blacklist/Blacklist.js +++ b/new-lamassu-admin/src/pages/Blacklist/Blacklist.js @@ -114,8 +114,6 @@ const Blacklist = () => { deleteEntry({ variables: { cryptoCode, address } }) } - const toggleModal = () => setShowModal(!showModal) - const addToBlacklist = (cryptoCode, address) => { addEntry({ variables: { cryptoCode, address } }) } @@ -123,7 +121,7 @@ const Blacklist = () => { return ( <> - Blacklist new addresses + setShowModal(false)}>Blacklist new addresses Date: Thu, 19 Nov 2020 15:03:46 +0000 Subject: [PATCH 08/31] fix: user_agent nullable --- lib/new-admin/graphql/schema.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index 7ed1801d..d299dd1e 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -167,8 +167,8 @@ const typeDefs = gql` token: String! name: String! created: Date! - user_agent: String! - ip_address: String! + user_agent: String + ip_address: String } type Transaction { From fd0f42c0ce3cec11d0f581b38d52f75312b09f3a Mon Sep 17 00:00:00 2001 From: Taranto Date: Sat, 21 Nov 2020 14:45:09 +0000 Subject: [PATCH 09/31] chore: add georgian as support language --- data/languages.json | 1 + 1 file changed, 1 insertion(+) diff --git a/data/languages.json b/data/languages.json index 0aa52f4c..b61a3758 100644 --- a/data/languages.json +++ b/data/languages.json @@ -225,6 +225,7 @@ "it-CH", "it-IT", "ja-JP", + "ka-GE", "ko-KR", "ky-KG", "lt-LT", From 532a5eda5da7dc48523e59b2a031ecc240e2f671 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Fri, 27 Nov 2020 17:40:06 +0000 Subject: [PATCH 10/31] chore: Removed useless switch for commissions in coinatmradar settings --- .../src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js b/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js index 4bdf6d4e..e4628803 100644 --- a/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js +++ b/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js @@ -86,12 +86,12 @@ const CoinATMRadar = memo(() => { label={coinAtmRadarConfig.active ? 'Yes' : 'No'} />

{'Machine info'}

- save({ commissions: value })} - /> + /> */} Date: Fri, 27 Nov 2020 18:08:23 +0000 Subject: [PATCH 11/31] fix: coinatmradar request error 400 --- lib/coinatmradar/coinatmradar.js | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/coinatmradar/coinatmradar.js b/lib/coinatmradar/coinatmradar.js index 0d83e0f8..822dd8e1 100644 --- a/lib/coinatmradar/coinatmradar.js +++ b/lib/coinatmradar/coinatmradar.js @@ -67,24 +67,16 @@ function mapMachine (rates, settings, machineRow) { const triggerCashLimit = complianceTriggers.getCashLimit(triggers) const locale = configManager.getLocale(deviceId, config) const cashOutConfig = configManager.getCashOut(deviceId, config) + const cashOutEnabled = cashOutConfig.active ? cashOutConfig.active : false const lastOnline = machineRow.last_online.toISOString() const status = machineRow.stale ? 'online' : 'offline' - const showSupportedCryptocurrencies = coinAtmRadar.supportedCryptocurrencies - const showSupportedFiat = coinAtmRadar.supportedFiat - const showSupportedBuySellDirection = coinAtmRadar.supportedBuySellDirection const showLimitsAndVerification = coinAtmRadar.limitsAndVerification const cashLimit = showLimitsAndVerification ? ( triggerCashLimit || Infinity ) : null - const cryptoCurrencies = locale.cryptoCurrencies - const cashInEnabled = showSupportedBuySellDirection ? true : null - const cashOutEnabled = showSupportedBuySellDirection ? cashOutConfig.active : null - const fiat = showSupportedFiat ? locale.fiatCurrency : null const identification = mapIdentification(config) - const coins = showSupportedCryptocurrencies ? - _.map(_.partial(mapCoin, [rates, deviceId, settings]), cryptoCurrencies) - : null + const coins = _.map(_.partial(mapCoin, [rates, deviceId, settings]), cryptoCurrencies) return { machineId: deviceId, @@ -102,14 +94,14 @@ function mapMachine (rates, settings, machineRow) { }, status, lastOnline, - cashIn: cashInEnabled, + cashIn: true, cashOut: cashOutEnabled, manufacturer: 'lamassu', cashInTxLimit: cashLimit, cashOutTxLimit: cashLimit, cashInDailyLimit: cashLimit, cashOutDailyLimit: cashLimit, - fiatCurrency: fiat, + fiatCurrency: locale.fiatCurrency, identification, coins } @@ -139,7 +131,6 @@ function sendRadar (data) { timeout: TIMEOUT, maxContentLength: MAX_CONTENT_LENGTH } - console.log('%j', data) return axios(config) From 95a1385a1e038f77d1e3193376085f5a5a96dd69 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Mon, 30 Nov 2020 15:03:06 +0000 Subject: [PATCH 12/31] fix: getCashLimit wasn't returning actual value, cashLimit was assigned to an object instead of a number --- lib/coinatmradar/coinatmradar.js | 5 +---- lib/compliance-triggers.js | 5 ++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/coinatmradar/coinatmradar.js b/lib/coinatmradar/coinatmradar.js index 822dd8e1..79465bf5 100644 --- a/lib/coinatmradar/coinatmradar.js +++ b/lib/coinatmradar/coinatmradar.js @@ -64,7 +64,6 @@ function mapMachine (rates, settings, machineRow) { const coinAtmRadar = configManager.getCoinAtmRadar(config) const triggers = configManager.getTriggers(config) - const triggerCashLimit = complianceTriggers.getCashLimit(triggers) const locale = configManager.getLocale(deviceId, config) const cashOutConfig = configManager.getCashOut(deviceId, config) const cashOutEnabled = cashOutConfig.active ? cashOutConfig.active : false @@ -72,12 +71,10 @@ function mapMachine (rates, settings, machineRow) { const lastOnline = machineRow.last_online.toISOString() const status = machineRow.stale ? 'online' : 'offline' const showLimitsAndVerification = coinAtmRadar.limitsAndVerification - - const cashLimit = showLimitsAndVerification ? ( triggerCashLimit || Infinity ) : null + const cashLimit = showLimitsAndVerification ? ( complianceTriggers.getCashLimit(triggers)?.threshold || Infinity ) : null const cryptoCurrencies = locale.cryptoCurrencies const identification = mapIdentification(config) const coins = _.map(_.partial(mapCoin, [rates, deviceId, settings]), cryptoCurrencies) - return { machineId: deviceId, address: { diff --git a/lib/compliance-triggers.js b/lib/compliance-triggers.js index 600c457e..da4191a3 100644 --- a/lib/compliance-triggers.js +++ b/lib/compliance-triggers.js @@ -15,9 +15,8 @@ function maxDaysThreshold (triggers) { } function getCashLimit (triggers) { - const withFiat = _.filter(({ triggerType }) => _.includes(['txVolume', 'txAmount'])(triggerType)) - const blocking = _.filter(({ requirement }) => _.includes(['block', 'suspend'])(requirement)) - + const withFiat = _.filter(({ triggerType }) => _.includes(triggerType, ['txVolume', 'txAmount'])) + const blocking = _.filter(({ requirement }) => _.includes(requirement, ['block', 'suspend'])) return _.compose(_.minBy('threshold'), blocking, withFiat)(triggers) } From 906863ede31bffd43eb8f7325a56619a0788a62e Mon Sep 17 00:00:00 2001 From: Neal Date: Wed, 2 Dec 2020 11:53:10 -0500 Subject: [PATCH 13/31] chore: update wallet nodes --- lib/blockchain/common.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/blockchain/common.js b/lib/blockchain/common.js index 2ae62bc7..a5643ea3 100644 --- a/lib/blockchain/common.js +++ b/lib/blockchain/common.js @@ -25,24 +25,24 @@ const BINARIES = { dir: 'bitcoin-0.20.1/bin' }, ETH: { - url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.23-8c2f2715.tar.gz', - dir: 'geth-linux-amd64-1.9.23-8c2f2715' + url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.24-cc05b050.tar.gz', + dir: 'geth-linux-amd64-1.9.24-cc05b050' }, ZEC: { - url: 'https://download.z.cash/downloads/zcash-4.1.0-linux64-debian-stretch.tar.gz', - dir: 'zcash-4.1.0/bin' + url: 'https://z.cash/downloads/zcash-4.1.1-linux64-debian-stretch.tar.gz', + dir: 'zcash-4.1.1/bin' }, DASH: { - url: 'https://github.com/dashpay/dash/releases/download/v0.16.0.1/dashcore-0.16.0.1-x86_64-linux-gnu.tar.gz', - dir: 'dashcore-0.16.0/bin' + url: 'https://github.com/dashpay/dash/releases/download/v0.16.1.1/dashcore-0.16.1.1-x86_64-linux-gnu.tar.gz', + dir: 'dashcore-0.16.1/bin' }, LTC: { url: 'https://download.litecoin.org/litecoin-0.18.1/linux/litecoin-0.18.1-x86_64-linux-gnu.tar.gz', dir: 'litecoin-0.18.1/bin' }, BCH: { - url: 'https://github.com/bitcoin-cash-node/bitcoin-cash-node/releases/download/v22.1.0/bitcoin-cash-node-22.1.0-x86_64-linux-gnu.tar.gz', - dir: 'bitcoin-cash-node-22.1.0/bin', + url: 'https://github.com/bitcoin-cash-node/bitcoin-cash-node/releases/download/v22.2.0/bitcoin-cash-node-22.2.0-x86_64-linux-gnu.tar.gz', + dir: 'bitcoin-cash-node-22.2.0/bin', files: [['bitcoind', 'bitcoincashd'], ['bitcoin-cli', 'bitcoincash-cli']] } } From 5aa61e8b4f790c9cbe3f98451bcbc058d527ca1d Mon Sep 17 00:00:00 2001 From: Neal Date: Wed, 2 Dec 2020 11:54:29 -0500 Subject: [PATCH 14/31] feat: enable RBF by default --- lib/blockchain/bitcoin.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/blockchain/bitcoin.js b/lib/blockchain/bitcoin.js index 78c95ba1..e5b6b86c 100644 --- a/lib/blockchain/bitcoin.js +++ b/lib/blockchain/bitcoin.js @@ -25,5 +25,6 @@ connections=40 keypool=10000 prune=4000 daemon=0 -addresstype=p2sh-segwit` +addresstype=p2sh-segwit +walletrbf=1` } From e325d6d2b1b749d0d0979dcb52fe2247b50c9a0c Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 2 Dec 2020 19:02:57 +0000 Subject: [PATCH 15/31] Feat: validate axios request and enable commissions switch --- lib/coinatmradar/coinatmradar.js | 58 ++++++++++++++++++- .../OperatorInfo/CoinATMRadar/CoinATMRadar.js | 4 +- package-lock.json | 42 ++++++++++++++ package.json | 3 +- 4 files changed, 103 insertions(+), 4 deletions(-) diff --git a/lib/coinatmradar/coinatmradar.js b/lib/coinatmradar/coinatmradar.js index 79465bf5..cddc608b 100644 --- a/lib/coinatmradar/coinatmradar.js +++ b/lib/coinatmradar/coinatmradar.js @@ -1,6 +1,7 @@ const axios = require('axios') const _ = require('lodash/fp') const hkdf = require('futoin-hkdf') +const yup = require("yup") const pify = require('pify') const fs = pify(require('fs')) @@ -114,6 +115,60 @@ function getMachines (rates, settings) { .then(_.map(_.partial(mapMachine, [rates, settings]))) } +function validateData (data) { + const schema = yup.object().shape({ + operatorId: yup.string().required('operatorId not provided'), + operator: yup.object().shape({ + name: yup.string().nullable(), + phone: yup.string().nullable(), + email: yup.string().email().nullable() + }), + timestamp: yup.string().required('timestamp not provided'), + machines: yup.array().of(yup.object().shape({ + machineId: yup.string().required('machineId not provided'), + address: yup.object().required('address object not provided').shape({ + streetAddress: yup.string().nullable(), + city: yup.string().nullable(), + region: yup.string().nullable(), + postalCode: yup.string().nullable(), + country: yup.string().nullable() + }), + location: yup.object().required('location object not provided').shape({ + name: yup.string().nullable(), + url: yup.string().nullable(), + phone: yup.string().nullable() + }), + status: yup.string().required('status not provided').oneOf(['online', 'offline']), + lastOnline: yup.string().required('date in isostring format not provided'), + cashIn: yup.boolean().required('cashIn boolean not defined'), + cashOut: yup.boolean().required('cashOut boolean not defined'), + manufacturer: yup.string().required('manufacturer not provided'), + cashInTxLimit: yup.number().nullable(), + cashOutTxLimit: yup.number().nullable(), + cashInDailyLimit: yup.number().nullable(), + cashOutDailyLimit: yup.number().nullable(), + fiatCurrency: yup.string().required('fiatCurrency not provided'), + identification: yup.object().shape({ + isPhone: yup.boolean().required('isPhone boolean not defined'), + isPalmVein: yup.boolean().required('isPalmVein boolean not defined'), + isPhoto: yup.boolean().required('isPhoto boolean not defined'), + isIdDocScan: yup.boolean().required('isIdDocScan boolean not defined'), + isFingerprint: yup.boolean().required('isFingerprint boolean not defined') + }), + coins: yup.array().of(yup.object().shape({ + cryptoCode: yup.string().required('cryptoCode not provided'), + cashInFee: yup.number().nullable(), + cashOutFee: yup.number().nullable(), + cashInFixedFee: yup.number().nullable(), + cashInRate: yup.number().nullable(), + cashOutRate: yup.number().nullable(), + })) + })) + }) + + return schema.validate(data) +} + function sendRadar (data) { const url = _.get(['coinAtmRadar', 'url'], options) @@ -130,7 +185,8 @@ function sendRadar (data) { } console.log('%j', data) - return axios(config) + return validateData(data) + .then(() => axios(config)) .then(r => console.log(r.status)) } diff --git a/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js b/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js index e4628803..4bdf6d4e 100644 --- a/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js +++ b/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js @@ -86,12 +86,12 @@ const CoinATMRadar = memo(() => { label={coinAtmRadarConfig.active ? 'Yes' : 'No'} />

{'Machine info'}

- {/* save({ commissions: value })} - /> */} + /> Date: Mon, 7 Dec 2020 18:20:06 +0000 Subject: [PATCH 16/31] Chore: add jest tests --- lib/coinatmradar/coinatmradar.js | 64 +- lib/coinatmradar/test/coinatmradar.test.js | 259 ++ lib/plugins.js | 1 - package-lock.json | 4635 ++++++++++++++++++++ package.json | 2 + 5 files changed, 4899 insertions(+), 62 deletions(-) create mode 100644 lib/coinatmradar/test/coinatmradar.test.js diff --git a/lib/coinatmradar/coinatmradar.js b/lib/coinatmradar/coinatmradar.js index cddc608b..c94b1594 100644 --- a/lib/coinatmradar/coinatmradar.js +++ b/lib/coinatmradar/coinatmradar.js @@ -1,7 +1,6 @@ const axios = require('axios') const _ = require('lodash/fp') const hkdf = require('futoin-hkdf') -const yup = require("yup") const pify = require('pify') const fs = pify(require('fs')) @@ -25,7 +24,6 @@ module.exports = { update } function mapCoin (rates, deviceId, settings, cryptoCode) { const config = settings.config const buildedRates = plugins(settings, deviceId).buildRates(rates)[cryptoCode] || { cashIn: null, cashOut: null } - const commissions = configManager.getCommissions(cryptoCode, deviceId, config) const coinAtmRadar = configManager.getCoinAtmRadar(config) @@ -110,65 +108,10 @@ function getMachines (rates, settings) { where display=TRUE and paired=TRUE order by created` - return db.any(sql, [STALE_INTERVAL]) .then(_.map(_.partial(mapMachine, [rates, settings]))) } -function validateData (data) { - const schema = yup.object().shape({ - operatorId: yup.string().required('operatorId not provided'), - operator: yup.object().shape({ - name: yup.string().nullable(), - phone: yup.string().nullable(), - email: yup.string().email().nullable() - }), - timestamp: yup.string().required('timestamp not provided'), - machines: yup.array().of(yup.object().shape({ - machineId: yup.string().required('machineId not provided'), - address: yup.object().required('address object not provided').shape({ - streetAddress: yup.string().nullable(), - city: yup.string().nullable(), - region: yup.string().nullable(), - postalCode: yup.string().nullable(), - country: yup.string().nullable() - }), - location: yup.object().required('location object not provided').shape({ - name: yup.string().nullable(), - url: yup.string().nullable(), - phone: yup.string().nullable() - }), - status: yup.string().required('status not provided').oneOf(['online', 'offline']), - lastOnline: yup.string().required('date in isostring format not provided'), - cashIn: yup.boolean().required('cashIn boolean not defined'), - cashOut: yup.boolean().required('cashOut boolean not defined'), - manufacturer: yup.string().required('manufacturer not provided'), - cashInTxLimit: yup.number().nullable(), - cashOutTxLimit: yup.number().nullable(), - cashInDailyLimit: yup.number().nullable(), - cashOutDailyLimit: yup.number().nullable(), - fiatCurrency: yup.string().required('fiatCurrency not provided'), - identification: yup.object().shape({ - isPhone: yup.boolean().required('isPhone boolean not defined'), - isPalmVein: yup.boolean().required('isPalmVein boolean not defined'), - isPhoto: yup.boolean().required('isPhoto boolean not defined'), - isIdDocScan: yup.boolean().required('isIdDocScan boolean not defined'), - isFingerprint: yup.boolean().required('isFingerprint boolean not defined') - }), - coins: yup.array().of(yup.object().shape({ - cryptoCode: yup.string().required('cryptoCode not provided'), - cashInFee: yup.number().nullable(), - cashOutFee: yup.number().nullable(), - cashInFixedFee: yup.number().nullable(), - cashInRate: yup.number().nullable(), - cashOutRate: yup.number().nullable(), - })) - })) - }) - - return schema.validate(data) -} - function sendRadar (data) { const url = _.get(['coinAtmRadar', 'url'], options) @@ -183,11 +126,10 @@ function sendRadar (data) { timeout: TIMEOUT, maxContentLength: MAX_CONTENT_LENGTH } - console.log('%j', data) + // console.log('%j', data) - return validateData(data) - .then(() => axios(config)) - .then(r => console.log(r.status)) + return axios.default(config) + .then(r => console.log(r.status)) } function mapRecord (rates, settings) { diff --git a/lib/coinatmradar/test/coinatmradar.test.js b/lib/coinatmradar/test/coinatmradar.test.js new file mode 100644 index 00000000..6ba2f194 --- /dev/null +++ b/lib/coinatmradar/test/coinatmradar.test.js @@ -0,0 +1,259 @@ +const yup = require('yup') + +const BigNumber = require('../../../lib/bn') +const car = require('../coinatmradar') + +afterEach(() => { + // https://stackoverflow.com/questions/58151010/difference-between-resetallmocks-resetmodules-resetmoduleregistry-restoreallm + jest.restoreAllMocks() +}) + +const settings = { + config: { + wallets_BTC_coin: 'BTC', + wallets_BTC_wallet: 'mock-wallet', + wallets_BTC_ticker: 'kraken', + wallets_BTC_exchange: 'mock-exchange', + wallets_BTC_zeroConf: 'all-zero-conf', + locale_id: '1983951f-6c73-4308-ae6e-f6f56dfa5e11', + locale_country: 'US', + locale_fiatCurrency: 'USD', + locale_languages: ['en-US'], + locale_cryptoCurrencies: ['BTC', 'ETH', 'LTC', 'DASH', 'ZEC', 'BCH'], + commissions_minimumTx: 1, + commissions_fixedFee: 2, + commissions_cashOut: 11, + commissions_cashIn: 11, + commissions_id: '960bb192-db37-40eb-9b59-2c2c78620de6', + wallets_ETH_active: true, + wallets_ETH_ticker: 'bitstamp', + wallets_ETH_wallet: 'mock-wallet', + wallets_ETH_exchange: 'mock-exchange', + wallets_ETH_zeroConf: 'mock-zero-conf', + wallets_LTC_active: true, + wallets_LTC_ticker: 'kraken', + wallets_LTC_wallet: 'mock-wallet', + wallets_LTC_exchange: 'mock-exchange', + wallets_LTC_zeroConf: 'mock-zero-conf', + wallets_DASH_active: true, + wallets_DASH_ticker: 'coinbase', + wallets_DASH_wallet: 'mock-wallet', + wallets_DASH_exchange: 'mock-exchange', + wallets_DASH_zeroConf: 'mock-zero-conf', + wallets_ZEC_active: true, + wallets_ZEC_ticker: 'coinbase', + wallets_ZEC_wallet: 'mock-wallet', + wallets_ZEC_exchange: 'mock-exchange', + wallets_ZEC_zeroConf: 'mock-zero-conf', + wallets_BCH_active: true, + wallets_BCH_ticker: 'bitpay', + wallets_BCH_wallet: 'mock-wallet', + wallets_BCH_exchange: 'mock-exchange', + wallets_BCH_zeroConf: 'mock-zero-conf', + cashOut_7e531a2666987aa27b9917ca17df7998f72771c57fdb21c90bc033999edd17e4_zeroConfLimit: 50, + cashOut_7e531a2666987aa27b9917ca17df7998f72771c57fdb21c90bc033999edd17e4_bottom: 20, + cashOut_7e531a2666987aa27b9917ca17df7998f72771c57fdb21c90bc033999edd17e4_top: 5, + cashOut_7e531a2666987aa27b9917ca17df7998f72771c57fdb21c90bc033999edd17e4_active: true, + cashOut_f02af604ca9010bd9ae04c427a24da90130da10d355f0a9b235886a89008fc05_zeroConfLimit: 200, + cashOut_f02af604ca9010bd9ae04c427a24da90130da10d355f0a9b235886a89008fc05_bottom: 20, + cashOut_f02af604ca9010bd9ae04c427a24da90130da10d355f0a9b235886a89008fc05_top: 5, + cashOut_f02af604ca9010bd9ae04c427a24da90130da10d355f0a9b235886a89008fc05_active: true, + notifications_email_active: false, + notifications_sms_active: true, + notifications_email_errors: false, + notifications_sms_errors: true, + coinAtmRadar_active: true, + coinAtmRadar_commissions: true, + coinAtmRadar_limitsAndVerification: true, + triggers: [ + { + requirement: 'suspend', + suspensionDays: 1, + threshold: 123, + id: '9c3b5af8-b1d1-4125-b169-0e913b33894c', + direction: 'both', + triggerType: 'txAmount' + }, + { + requirement: 'sms', + threshold: 999, + thresholdDays: 1, + id: 'b0e1e6a8-be1b-4e43-ac5f-3e4951e86f8b', + direction: 'both', + triggerType: 'txVelocity' + }, + { + requirement: 'sms', + threshold: 888, + thresholdDays: 1, + id: '6ac38fe6-172c-48a4-8a7f-605213cbd600', + direction: 'both', + triggerType: 'txVolume' + } + ], + notifications_sms_transactions: true, + notifications_highValueTransaction: 50 + }, + accounts: {} +} + +const rates = [ + { + rates: { + ask: BigNumber(19164.3), + bid: BigNumber(19164.2) + }, + timestamp: +new Date() + }, + { + rates: { + ask: BigNumber(594.54), + bid: BigNumber(594.09) + }, + timestamp: +new Date() + }, + { + rates: { + ask: BigNumber(84.38), + bid: BigNumber(84.37) + }, + timestamp: +new Date() + }, + { + rates: { + ask: BigNumber(102.8), + bid: BigNumber(101.64) + }, + timestamp: +new Date() + }, + { + rates: { + ask: BigNumber(74.91), + bid: BigNumber(74.12) + }, + timestamp: +new Date() + }, + { + rates: { + ask: BigNumber(284.4), + bid: BigNumber(284.4) + }, + timestamp: +new Date() + } +] + +const dbResponse = [ + { + device_id: + 'mock7e531a2666987aa27b9917ca17df7998f72771c57fdb21c90bc033999edd17e4', + last_online: new Date('2020-11-16T13:11:03.169Z'), + stale: false + }, + { + device_id: + '9871e58aa2643ff9445cbc299b50397430ada75157d6c29b4c93548fff0f48f7', + last_online: new Date('2020-11-16T16:21:35.948Z'), + stale: false + }, + { + device_id: + '5ae0d02dedeb77b6521bd5eb7c9159bdc025873fa0bcb6f87aaddfbda0c50913', + last_online: new Date('2020-11-19T15:07:57.089Z'), + stale: false + }, + { + device_id: + 'f02af604ca9010bd9ae04c427a24da90130da10d355f0a9b235886a89008fc05', + last_online: new Date('2020-11-26T20:05:57.792Z'), + stale: false + }, + { + device_id: + '490ab16ee0c124512dc769be1f3e7ee3894ce1e5b4b8b975e134fb326e551e88', + last_online: new Date('2020-12-04T16:48:05.129Z'), + stale: false + } +] + +function validateData(data) { + const schema = yup.object().shape({ + operatorId: yup.string().required('operatorId not provided'), + operator: yup.object().shape({ + name: yup.string().nullable(), + phone: yup.string().nullable(), + email: yup.string().email().nullable() + }), + timestamp: yup.string().required('timestamp not provided'), + machines: yup.array().of( + yup.object().shape({ + machineId: yup.string().required('machineId not provided'), + address: yup.object().required('address object not provided').shape({ + streetAddress: yup.string().nullable(), + city: yup.string().nullable(), + region: yup.string().nullable(), + postalCode: yup.string().nullable(), + country: yup.string().nullable() + }), + location: yup.object().required('location object not provided').shape({ + name: yup.string().nullable(), + url: yup.string().nullable(), + phone: yup.string().nullable() + }), + status: yup + .string() + .required('status not provided') + .oneOf(['online', 'offline']), + lastOnline: yup + .string() + .required('date in isostring format not provided'), + cashIn: yup.boolean().required('cashIn boolean not defined'), + cashOut: yup.boolean().required('cashOut boolean not defined'), + manufacturer: yup.string().required('manufacturer not provided'), + cashInTxLimit: yup.number().nullable(), + cashOutTxLimit: yup.number().nullable(), + cashInDailyLimit: yup.number().nullable(), + cashOutDailyLimit: yup.number().nullable(), + fiatCurrency: yup.string().required('fiatCurrency not provided'), + identification: yup.object().shape({ + isPhone: yup.boolean().required('isPhone boolean not defined'), + isPalmVein: yup.boolean().required('isPalmVein boolean not defined'), + isPhoto: yup.boolean().required('isPhoto boolean not defined'), + isIdDocScan: yup + .boolean() + .required('isIdDocScan boolean not defined'), + isFingerprint: yup + .boolean() + .required('isFingerprint boolean not defined') + }), + coins: yup.array().of( + yup.object().shape({ + cryptoCode: yup.string().required('cryptoCode not provided'), + cashInFee: yup.number().nullable(), + cashOutFee: yup.number().nullable(), + cashInFixedFee: yup.number().nullable(), + cashInRate: yup.number().nullable(), + cashOutRate: yup.number().nullable() + }) + ) + }) + ) + }) + return schema.validate(data) +} + +const db = require('../../db') +jest.mock('../../db') +test('Verify axios request schema', async () => { + const axios = require('axios') + + jest.spyOn(axios, 'default').mockImplementation( + jest.fn(req => + validateData(req.data) + .then(() => ({ status: 'mock status 200' })) + .catch(e => fail(e)) + ) + ) + + db.any.mockResolvedValue(dbResponse) + await car.update(rates, settings) +}) diff --git a/lib/plugins.js b/lib/plugins.js index a66e3446..503c06f8 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -58,7 +58,6 @@ function plugins (settings, deviceId) { cashOut: cashOutCommission && rate.bid.div(cashOutCommission).round(5) } }) - return rates } diff --git a/package-lock.json b/package-lock.json index 2d5742d0..cdc4c723 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,12 +56,195 @@ "@babel/highlight": "^7.10.4" } }, + "@babel/core": { + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", + "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-module-transforms": "^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", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.7.tgz", + "integrity": "sha512-I5xc9oSJ2h59OwyUqjv95HRyzxj53DAubUERgQMrpcCEYQyToeHA+NEcUEsVWB4j53RDeskeBJ0SgRAYHDBckw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", + "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.1", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, + "@babel/helpers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" + } + }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", @@ -73,6 +256,120 @@ "js-tokens": "^4.0.0" } }, + "@babel/parser": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", + "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@babel/runtime": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", @@ -88,6 +385,78 @@ } } }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.9.tgz", + "integrity": "sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, "@concordance/react": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@concordance/react/-/react-2.0.0.tgz", @@ -128,6 +497,525 @@ } } }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + } + }, + "@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -214,6 +1102,24 @@ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "dev": true }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -231,6 +1137,47 @@ "@types/node": "*" } }, + "@types/babel__core": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", + "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.16.tgz", + "integrity": "sha512-S63Dt4CZOkuTmpLGGWtT/mQdVORJOpx6SZWGVaP56dda/0Nx5nEe82K7/LAm8zYr6SfMq+1N2OreIOrHAx656w==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, "@types/bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", @@ -328,6 +1275,15 @@ "@types/node": "*" } }, + "@types/graceful-fs": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", + "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/graphql-upload": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/@types/graphql-upload/-/graphql-upload-8.0.4.tgz", @@ -349,6 +1305,30 @@ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz", "integrity": "sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==" }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/keygrip": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", @@ -426,6 +1406,12 @@ "@types/node": "*" } }, + "@types/prettier": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz", + "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==", + "dev": true + }, "@types/qs": { "version": "6.9.5", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", @@ -453,6 +1439,12 @@ "@types/mime": "*" } }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "@types/ws": { "version": "7.2.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.2.7.tgz", @@ -461,6 +1453,21 @@ "@types/node": "*" } }, + "@types/yargs": { + "version": "15.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.11.tgz", + "integrity": "sha512-jfcNBxHFYJ4nPIacsi3woz1+kvUO6s1CyeEhtnDHBjHUMNj5UlW2GynmnSgiJJEdNg9yW5C8lfoNRZrHGv5EqA==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, "@wry/equality": { "version": "0.1.11", "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.11.tgz", @@ -469,6 +1476,12 @@ "tslib": "^1.9.3" } }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -489,6 +1502,16 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", @@ -868,6 +1891,24 @@ "sprintf-js": "~1.0.2" } }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, "array-filter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", @@ -901,6 +1942,12 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", @@ -953,6 +2000,12 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, "ast-types": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", @@ -1000,6 +2053,12 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, "ava": { "version": "3.8.2", "resolved": "https://registry.npmjs.org/ava/-/ava-3.8.2.tgz", @@ -1385,6 +2444,128 @@ } } }, + "babel-jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "dev": true, + "requires": { + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.0.tgz", + "integrity": "sha512-mGkvkpocWJes1CmMKtgGUwCeeq0pOhALyymozzDWYomHTbDLwueDYG6p4TK1YOeYHCzBzYPsWkgTto10JubI1Q==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -1411,6 +2592,61 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "base-x": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", @@ -2231,6 +3467,12 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -2278,6 +3520,15 @@ "safe-buffer": "^5.1.2" } }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, "buffer-compare": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz", @@ -2341,6 +3592,23 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -2411,6 +3679,15 @@ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -2449,6 +3726,12 @@ "supports-color": "^5.3.0" } }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", @@ -2508,6 +3791,35 @@ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", "dev": true }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -2789,6 +4101,22 @@ } } }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3256,6 +4584,12 @@ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, "core-js": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", @@ -3368,6 +4702,29 @@ "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -3405,6 +4762,17 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, "date-fns": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", @@ -3454,6 +4822,12 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-5.0.8.tgz", "integrity": "sha1-tIw/t9c6LU1JQOCzjxzSHbWzZ84=" }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", @@ -3472,6 +4846,12 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -3494,6 +4874,47 @@ "object-keys": "^1.0.12" } }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "degenerator": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", @@ -3608,6 +5029,12 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, "dicer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", @@ -3622,6 +5049,12 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3666,6 +5099,23 @@ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, "domhandler": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", @@ -4626,6 +6076,138 @@ "safe-buffer": "^5.1.1" } }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -4717,6 +6299,36 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, "external-editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", @@ -4727,6 +6339,71 @@ "tmp": "^0.0.33" } }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "extract-zip": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", @@ -4792,6 +6469,15 @@ "reusify": "^1.0.4" } }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -4895,6 +6581,12 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", @@ -4925,6 +6617,15 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -5061,12 +6762,24 @@ } } }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", @@ -5120,6 +6833,12 @@ } } }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -5272,6 +6991,13 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, "grpc": { "version": "1.24.3", "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.3.tgz", @@ -5385,6 +7111,58 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", @@ -5523,11 +7301,26 @@ } } }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, "html-entities": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==" }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "htmlparser2": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", @@ -5628,6 +7421,12 @@ } } }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, "iconv": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/iconv/-/iconv-2.3.5.tgz", @@ -5752,6 +7551,12 @@ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -5763,6 +7568,26 @@ "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", "dev": true }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "is-arguments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", @@ -5802,17 +7627,78 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "dev": true, + "optional": true + }, "is-error": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", "dev": true }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5829,6 +7715,12 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, "is-generator-function": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", @@ -5915,6 +7807,12 @@ "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", "dev": true }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, "is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", @@ -5974,6 +7872,22 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, "is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", @@ -5990,11 +7904,124 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, "isurl": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", @@ -6009,6 +8036,1479 @@ "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" }, + "jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + } + } + }, + "jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" + } + }, + "jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "dev": true, + "requires": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + } + }, + "jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + } + } + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-watcher": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "js-sha3": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz", @@ -6067,6 +9567,71 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, + "jsdom": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", + "dev": true + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "ws": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", + "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==", + "dev": true + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", @@ -6123,6 +9688,15 @@ } } }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -6243,6 +9817,12 @@ "json-buffer": "3.0.0" } }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, "klaw": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", @@ -6251,6 +9831,12 @@ "graceful-fs": "^4.1.9" } }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, "kraken-api": { "version": "github:DeX3/npm-kraken-api#ca939e6dd6c6cd9d3ca9a6ee52dc2170a8d25978", "from": "github:DeX3/npm-kraken-api", @@ -6276,6 +9862,12 @@ "invert-kv": "^1.0.0" } }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -6644,6 +10236,15 @@ "pify": "^3.0.0" } }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, "manakin": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/manakin/-/manakin-0.5.2.tgz", @@ -6658,6 +10259,21 @@ "p-defer": "^1.0.0" } }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, "matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -6718,6 +10334,12 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6827,6 +10449,36 @@ "minipass": "^2.9.0" } }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -6966,6 +10618,25 @@ "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40=" }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7053,6 +10724,52 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", + "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", + "dev": true, + "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "node-pre-gyp": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", @@ -7182,6 +10899,15 @@ "npm-normalize-package-bin": "^1.0.1" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", @@ -7203,6 +10929,12 @@ "resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz", "integrity": "sha1-StCAk21EPCVhrtnyGX7//iX05QY=" }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -7218,6 +10950,37 @@ "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "object-inspect": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", @@ -7233,6 +10996,15 @@ "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.5.tgz", "integrity": "sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg==" }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, "object.assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", @@ -7274,6 +11046,15 @@ "es-abstract": "^1.17.0-next.1" } }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, "obliterator": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", @@ -7689,6 +11470,12 @@ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=" }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, "parseqs": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", @@ -7710,6 +11497,12 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7943,6 +11736,15 @@ "pinkie": "^2.0.0" } }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, "pkg-conf": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", @@ -8025,6 +11827,12 @@ "resolved": "https://registry.npmjs.org/pop-iterate/-/pop-iterate-1.0.1.tgz", "integrity": "sha1-zqz9q0q/NT16DyqqLB/Hs/lBO6M=" }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, "postgres-array": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", @@ -8058,6 +11866,56 @@ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", + "dev": true + } + } + }, "pretty-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", @@ -8091,6 +11949,16 @@ "with-callback": "^1.0.2" } }, + "prompts": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, "prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", @@ -8565,6 +12433,16 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, "regexp-quote": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/regexp-quote/-/regexp-quote-0.0.0.tgz", @@ -8594,6 +12472,24 @@ "rc": "^1.2.8" } }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -8646,6 +12542,26 @@ "throttleit": "^1.0.0" } }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8705,6 +12621,12 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -8723,6 +12645,12 @@ "signal-exit": "^3.0.2" } }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -8951,6 +12879,12 @@ "resolved": "https://registry.npmjs.org/rootpath/-/rootpath-0.1.2.tgz", "integrity": "sha1-Wzeah9ypBum5HWkKWZQ5vvJn6ms=" }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -8997,11 +12931,161 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, "sanitize-html": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.13.0.tgz", @@ -9017,6 +13101,15 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "scmp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz", @@ -9143,6 +13236,38 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -9194,11 +13319,24 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -9261,6 +13399,119 @@ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=" }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "sntp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", @@ -9481,6 +13732,19 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, "source-map-support": { "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", @@ -9490,6 +13754,12 @@ "source-map": "^0.6.0" } }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, "spawn-command": { "version": "0.0.2-1", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", @@ -9541,6 +13811,15 @@ "through": "2" } }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, "split2": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", @@ -9856,11 +14135,38 @@ } } }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, "stellar-base": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/stellar-base/-/stellar-base-0.9.0.tgz", @@ -9943,6 +14249,33 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -9997,6 +14330,18 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", @@ -10160,11 +14505,44 @@ "has-flag": "^3.0.0" } }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "table": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", @@ -10260,12 +14638,56 @@ "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", "dev": true }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, "throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", @@ -10338,17 +14760,61 @@ "os-tmpdir": "~1.0.2" } }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "dev": true }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -10402,6 +14868,15 @@ "punycode": "^2.1.1" } }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -10518,6 +14993,12 @@ "prelude-ls": "~1.1.2" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", @@ -10576,6 +15057,18 @@ "resolved": "https://registry.npmjs.org/unicode/-/unicode-12.1.0.tgz", "integrity": "sha512-Ty6+Ew21DiYTWLYtd05RF/X4c1ekOvOgANyHbBj0h3MaXpfaGr2Rdmc0hMFuGQLyPLb9cU4ArNxl0bTF5HSzXw==" }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", @@ -10601,6 +15094,46 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, "update-notifier": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", @@ -10686,6 +15219,12 @@ "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.1.tgz", "integrity": "sha512-xVrGVi94ueCJNrBSTjWqjvtgvl3cyOTThp2zaMaFNGp3F542TR6sM3f2o8RqZl+AwteClSVmoCyt0ka4RjQOQg==" }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, "url-parse": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", @@ -10715,6 +15254,12 @@ "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, "utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", @@ -10759,6 +15304,25 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, + "v8-to-istanbul": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.0.0.tgz", + "integrity": "sha512-fLL2rFuQpMtm9r8hrAV2apXX/WqHJ6+IC4/eQVdMDGBUgH/YMV4Gv3duk3kjmyg6uiQWBAA9nJwue4iJUOkHeA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -10792,6 +15356,33 @@ "extsprintf": "^1.2.0" } }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -10829,12 +15420,44 @@ } } }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, "well-known-symbols": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", "dev": true }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", + "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^6.1.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -11113,6 +15736,12 @@ "cookiejar": "^2.1.1" } }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, "xml-stream": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/xml-stream/-/xml-stream-0.4.5.tgz", @@ -11160,6 +15789,12 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", diff --git a/package.json b/package.json index 5a4480d6..b2b7b9a5 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "scripts": { "start": "node bin/lamassu-server", "test": "mocha --recursive tests", + "jtest": "jest", "build-admin": "npm run build-admin:css && npm run build-admin:main && npm run build-admin:lamassu", "server": "nodemon bin/lamassu-server --mockSms", "admin-server": "nodemon bin/lamassu-admin-server --dev", @@ -123,6 +124,7 @@ "devDependencies": { "ava": "3.8.2", "concurrently": "^5.3.0", + "jest": "^26.6.3", "mocha": "^5.0.1", "nodemon": "^2.0.6", "rewire": "^4.0.1", From 4a763b87b4c2d4fd2c75af68173f4fe1697bd33e Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Fri, 11 Dec 2020 16:20:31 +0000 Subject: [PATCH 17/31] Fix: apply change requests --- lib/coinatmradar/coinatmradar.js | 3 +-- lib/coinatmradar/test/coinatmradar.test.js | 6 +++--- lib/plugins.js | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/coinatmradar/coinatmradar.js b/lib/coinatmradar/coinatmradar.js index c94b1594..f90e03e7 100644 --- a/lib/coinatmradar/coinatmradar.js +++ b/lib/coinatmradar/coinatmradar.js @@ -126,10 +126,9 @@ function sendRadar (data) { timeout: TIMEOUT, maxContentLength: MAX_CONTENT_LENGTH } - // console.log('%j', data) return axios.default(config) - .then(r => console.log(r.status)) + .then(r => console.log(r.status)) } function mapRecord (rates, settings) { diff --git a/lib/coinatmradar/test/coinatmradar.test.js b/lib/coinatmradar/test/coinatmradar.test.js index 6ba2f194..732a1ac0 100644 --- a/lib/coinatmradar/test/coinatmradar.test.js +++ b/lib/coinatmradar/test/coinatmradar.test.js @@ -1,7 +1,9 @@ const yup = require('yup') - const BigNumber = require('../../../lib/bn') const car = require('../coinatmradar') +const db = require('../../db') + +jest.mock('../../db') afterEach(() => { // https://stackoverflow.com/questions/58151010/difference-between-resetallmocks-resetmodules-resetmoduleregistry-restoreallm @@ -241,8 +243,6 @@ function validateData(data) { return schema.validate(data) } -const db = require('../../db') -jest.mock('../../db') test('Verify axios request schema', async () => { const axios = require('axios') diff --git a/lib/plugins.js b/lib/plugins.js index 503c06f8..a66e3446 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -58,6 +58,7 @@ function plugins (settings, deviceId) { cashOut: cashOutCommission && rate.bid.div(cashOutCommission).round(5) } }) + return rates } From 3e1e2b4831c0ec2c995ea14a104d66db22ddd995 Mon Sep 17 00:00:00 2001 From: Jose Sousa Date: Mon, 23 Nov 2020 18:59:13 +0000 Subject: [PATCH 18/31] chore: title and sidebar moved to app.js --- new-lamassu-admin/src/App.js | 62 ++++++++++- .../src/pages/OperatorInfo/OperatorInfo.js | 100 ------------------ new-lamassu-admin/src/routing/routes.js | 68 +++++++++++- 3 files changed, 122 insertions(+), 108 deletions(-) delete mode 100644 new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js diff --git a/new-lamassu-admin/src/App.js b/new-lamassu-admin/src/App.js index 0ff35c15..fe50fead 100644 --- a/new-lamassu-admin/src/App.js +++ b/new-lamassu-admin/src/App.js @@ -1,4 +1,5 @@ import CssBaseline from '@material-ui/core/CssBaseline' +import Grid from '@material-ui/core/Grid' import { StylesProvider, jssPreset, @@ -8,12 +9,24 @@ import { import { create } from 'jss' import extendJss from 'jss-plugin-extend' import React, { createContext, useContext, useState } from 'react' -import { useLocation, BrowserRouter as Router } from 'react-router-dom' +import { + useLocation, + useHistory, + BrowserRouter as Router +} from 'react-router-dom' +import Sidebar from 'src/components/layout/Sidebar' +import TitleSection from 'src/components/layout/TitleSection' import ApolloProvider from 'src/utils/apollo' import Header from './components/layout/Header' -import { tree, Routes } from './routing/routes' +import { + getTitle, + tree, + hasSidebar, + Routes, + getSidebarData +} from './routing/routes' import global from './styling/global' import theme from './styling/theme' import { backgroundColor, mainWidth } from './styling/variables' @@ -46,6 +59,18 @@ const useStyles = makeStyles({ flex: 1, display: 'flex', flexDirection + }, + grid: { + flex: 1, + height: '100%' + }, + contentWithSidebar: { + flex: 1, + marginLeft: 48, + paddingTop: 15 + }, + contentWithoutSidebar: { + width: mainWidth } }) @@ -54,15 +79,46 @@ const AppContext = createContext() const Main = () => { const classes = useStyles() const location = useLocation() + const history = useHistory() const { wizardTested } = useContext(AppContext) + const route = location.pathname + + const title = getTitle(route) + const sidebar = hasSidebar(route) + const sidebarData = sidebar ? getSidebarData(route) : [] + const is404 = location.pathname === '/404' + const isSelected = it => location.pathname === it.route + + const onClick = it => history.push(it.route) + + const contentClassName = sidebar + ? classes.contentWithSidebar + : classes.contentWithoutSidebar + return (
{!is404 && wizardTested &&
}
- + {title && !is404 && wizardTested && ( + + )} + + + {sidebar && !is404 && wizardTested && ( + it.label} + onClick={onClick} + /> + )} +
+ +
+
) diff --git a/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js b/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js deleted file mode 100644 index 794530d2..00000000 --- a/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js +++ /dev/null @@ -1,100 +0,0 @@ -import { makeStyles } from '@material-ui/core' -import Grid from '@material-ui/core/Grid' -import React from 'react' -import { - Route, - Switch, - Redirect, - useLocation, - useHistory -} from 'react-router-dom' - -import Sidebar from 'src/components/layout/Sidebar' -import TitleSection from 'src/components/layout/TitleSection' - -import CoinAtmRadar from './CoinATMRadar' -import ContactInfo from './ContactInfo' -import ReceiptPrinting from './ReceiptPrinting' -import TermsConditions from './TermsConditions' - -const styles = { - grid: { - flex: 1, - height: '100%' - }, - content: { - flex: 1, - marginLeft: 48, - paddingTop: 15 - } -} - -const useStyles = makeStyles(styles) - -const innerRoutes = [ - { - label: 'Contact information', - route: '/settings/operator-info/contact-info', - component: ContactInfo - }, - { - label: 'Receipt', - route: '/settings/operator-info/receipt-printing', - component: ReceiptPrinting - }, - { - label: 'Coin ATM Radar', - route: '/settings/operator-info/coin-atm-radar', - component: CoinAtmRadar - }, - { - label: 'Terms & Conditions', - route: '/settings/operator-info/terms-conditions', - component: TermsConditions - } -] - -const Routes = ({ wizard }) => ( - - - - {innerRoutes.map(({ route, component: Page, key }) => ( - - - - ))} - -) - -const OperatorInfo = ({ wizard = false }) => { - const classes = useStyles() - const history = useHistory() - const location = useLocation() - - const isSelected = it => location.pathname === it.route - - const onClick = it => history.push(it.route) - - return ( - <> - - - it.label} - onClick={onClick} - /> -
- -
-
- - ) -} - -export default OperatorInfo diff --git a/new-lamassu-admin/src/routing/routes.js b/new-lamassu-admin/src/routing/routes.js index 404ade02..b7918eb7 100644 --- a/new-lamassu-admin/src/routing/routes.js +++ b/new-lamassu-admin/src/routing/routes.js @@ -20,7 +20,10 @@ import MachineLogs from 'src/pages/MachineLogs' import CashCassettes from 'src/pages/Maintenance/CashCassettes' import MachineStatus from 'src/pages/Maintenance/MachineStatus' import Notifications from 'src/pages/Notifications/Notifications' -import OperatorInfo from 'src/pages/OperatorInfo/OperatorInfo' +import CoinAtmRadar from 'src/pages/OperatorInfo/CoinATMRadar' +import ContactInfo from 'src/pages/OperatorInfo/ContactInfo' +import ReceiptPrinting from 'src/pages/OperatorInfo/ReceiptPrinting' +import TermsConditions from 'src/pages/OperatorInfo/TermsConditions' import ServerLogs from 'src/pages/ServerLogs' import Services from 'src/pages/Services/Services' import TokenManagement from 'src/pages/TokenManagement/TokenManagement' @@ -125,7 +128,36 @@ const tree = [ key: namespaces.OPERATOR_INFO, label: 'Operator Info', route: '/settings/operator-info', - component: OperatorInfo + children: [ + { + key: 'contact-info', + label: 'Contact information', + title: 'Operator information', + route: '/settings/operator-info/contact-info', + component: ContactInfo + }, + { + key: 'receipt-printing', + label: 'Receipt', + title: 'Operator information', + route: '/settings/operator-info/receipt-printing', + component: ReceiptPrinting + }, + { + key: 'coin-atm-radar', + label: 'Coin ATM Radar', + title: 'Operator information', + route: '/settings/operator-info/coin-atm-radar', + component: CoinAtmRadar + }, + { + key: 'terms-conditions', + label: 'Terms & Conditions', + title: 'Operator information', + route: '/settings/operator-info/terms-conditions', + component: TermsConditions + } + ] } ] }, @@ -181,10 +213,33 @@ const tree = [ ] const map = R.map(R.when(R.has('children'), R.prop('children'))) -const leafRoutes = R.compose(R.flatten, map)(tree) -const parentRoutes = R.filter(R.has('children'))(tree) +const mappedRoutes = R.compose(R.flatten, map)(tree) +const parentRoutes = R.filter(R.has('children'))(tree).concat( + R.filter(R.has('children'))(mappedRoutes) +) +const leafRoutes = R.compose(R.flatten, map)(mappedRoutes) +const thirdLevelRoutes = R.compose( + R.flatten, + R.map(R.prop('children')), + R.filter(R.has('children')) +)(mappedRoutes) const flattened = R.concat(leafRoutes, parentRoutes) +const getTitle = route => + R.prop('title', R.find(R.propEq('route', route))(flattened)) + +const hasSidebar = route => R.any(r => r.route === route, thirdLevelRoutes) + +const getSidebarData = route => { + const parentRoute = R.dropLast( + 1, + R.dropLastWhile(x => x !== '/', route) + ) + const parent = R.find(R.propEq('route', parentRoute))(flattened) + + return parent?.children +} + const Routes = () => { const history = useHistory() const location = useLocation() @@ -201,6 +256,9 @@ const Routes = () => { + + + {flattened.map(({ route, component: Page, key }) => ( @@ -215,4 +273,4 @@ const Routes = () => { ) } -export { tree, Routes } +export { getTitle, tree, getSidebarData, hasSidebar, Routes } From 7b1564c56978375c050e0593870a7c16c0d0bf69 Mon Sep 17 00:00:00 2001 From: Jose Sousa Date: Wed, 25 Nov 2020 10:52:51 +0000 Subject: [PATCH 19/31] fix: redirect to third level --- new-lamassu-admin/src/App.js | 17 +++----- new-lamassu-admin/src/routing/routes.js | 52 ++++++++++++------------- 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/new-lamassu-admin/src/App.js b/new-lamassu-admin/src/App.js index fe50fead..66e2ba1a 100644 --- a/new-lamassu-admin/src/App.js +++ b/new-lamassu-admin/src/App.js @@ -20,13 +20,7 @@ import TitleSection from 'src/components/layout/TitleSection' import ApolloProvider from 'src/utils/apollo' import Header from './components/layout/Header' -import { - getTitle, - tree, - hasSidebar, - Routes, - getSidebarData -} from './routing/routes' +import { tree, hasSidebar, Routes, getParent } from './routing/routes' import global from './styling/global' import theme from './styling/theme' import { backgroundColor, mainWidth } from './styling/variables' @@ -84,9 +78,8 @@ const Main = () => { const route = location.pathname - const title = getTitle(route) const sidebar = hasSidebar(route) - const sidebarData = sidebar ? getSidebarData(route) : [] + const parent = sidebar ? getParent(route) : {} const is404 = location.pathname === '/404' @@ -102,14 +95,14 @@ const Main = () => {
{!is404 && wizardTested &&
}
- {title && !is404 && wizardTested && ( - + {sidebar && !is404 && wizardTested && ( + )} {sidebar && !is404 && wizardTested && ( it.label} onClick={onClick} diff --git a/new-lamassu-admin/src/routing/routes.js b/new-lamassu-admin/src/routing/routes.js index b7918eb7..de280ba2 100644 --- a/new-lamassu-admin/src/routing/routes.js +++ b/new-lamassu-admin/src/routing/routes.js @@ -128,32 +128,32 @@ const tree = [ key: namespaces.OPERATOR_INFO, label: 'Operator Info', route: '/settings/operator-info', + title: 'Operator Information', + get component() { + return () => + }, children: [ { key: 'contact-info', label: 'Contact information', - title: 'Operator information', route: '/settings/operator-info/contact-info', component: ContactInfo }, { key: 'receipt-printing', label: 'Receipt', - title: 'Operator information', route: '/settings/operator-info/receipt-printing', component: ReceiptPrinting }, { key: 'coin-atm-radar', label: 'Coin ATM Radar', - title: 'Operator information', route: '/settings/operator-info/coin-atm-radar', component: CoinAtmRadar }, { key: 'terms-conditions', label: 'Terms & Conditions', - title: 'Operator information', route: '/settings/operator-info/terms-conditions', component: TermsConditions } @@ -214,31 +214,32 @@ const tree = [ const map = R.map(R.when(R.has('children'), R.prop('children'))) const mappedRoutes = R.compose(R.flatten, map)(tree) -const parentRoutes = R.filter(R.has('children'))(tree).concat( - R.filter(R.has('children'))(mappedRoutes) +const parentRoutes = R.filter(R.has('children'))(mappedRoutes).concat( + R.filter(R.has('children'))(tree) ) const leafRoutes = R.compose(R.flatten, map)(mappedRoutes) -const thirdLevelRoutes = R.compose( - R.flatten, - R.map(R.prop('children')), - R.filter(R.has('children')) -)(mappedRoutes) + const flattened = R.concat(leafRoutes, parentRoutes) -const getTitle = route => - R.prop('title', R.find(R.propEq('route', route))(flattened)) - -const hasSidebar = route => R.any(r => r.route === route, thirdLevelRoutes) - -const getSidebarData = route => { - const parentRoute = R.dropLast( - 1, - R.dropLastWhile(x => x !== '/', route) +const hasSidebar = route => + R.any(r => r.route === route)( + R.compose( + R.flatten, + R.map(R.prop('children')), + R.filter(R.has('children')) + )(mappedRoutes) ) - const parent = R.find(R.propEq('route', parentRoute))(flattened) - return parent?.children -} +const getParent = route => + R.find( + R.propEq( + 'route', + R.dropLast( + 1, + R.dropLastWhile(x => x !== '/', route) + ) + ) + )(flattened) const Routes = () => { const history = useHistory() @@ -256,9 +257,6 @@ const Routes = () => { - - - {flattened.map(({ route, component: Page, key }) => ( @@ -273,4 +271,4 @@ const Routes = () => { ) } -export { getTitle, tree, getSidebarData, hasSidebar, Routes } +export { tree, getParent, hasSidebar, Routes } From 35e71b95369eb3948245fea7731589ac5d675c24 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 25 Nov 2020 19:00:50 +0000 Subject: [PATCH 20/31] feat: Add restart services button in machine admin actions --- .../pages/Maintenance/MachineDetailsCard.js | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js index d04dc8fa..f755dd3f 100644 --- a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js +++ b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js @@ -128,19 +128,19 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { /> { setErrorMessage(null) machineAction({ variables: { deviceId: machine.deviceId, - action: `${action?.command}`.toLowerCase(), - ...(action?.command === 'Rename' && { newName: value }) + action: `${action?.command}`, + ...(action?.command === 'rename' && { newName: value }) } }) }} @@ -174,7 +174,8 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { InverseIcon={EditReversedIcon} onClick={() => setAction({ - command: 'Rename', + command: 'rename', + humanReadable: 'Rename', confirmationMessage: 'Write the new name for this machine' }) }> @@ -188,7 +189,8 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { disabled={loading} onClick={() => setAction({ - command: 'Unpair' + command: 'unpair', + humanReadable: 'Unpair' }) }> Unpair @@ -201,26 +203,42 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { disabled={loading} onClick={() => setAction({ - command: 'Reboot' + command: 'reboot', + humanReadable: 'Reboot' }) }> Reboot setAction({ - command: 'Shutdown', + command: 'shutdown', + humanReadable: 'Shutdown', message: 'In order to bring it back online, the machine will need to be visited and its power reset.' }) }> Shutdown + + setAction({ + command: 'restartServices', + humanReadable: 'Restart services for' + }) + }> + Restart Services +
From 179a0270e5a9b668aacf5258c9905b44bb1b96a6 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Mon, 30 Nov 2020 11:53:24 +0000 Subject: [PATCH 21/31] fix: rename humanReadable to display --- .../src/pages/Maintenance/MachineDetailsCard.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js index f755dd3f..4abaea31 100644 --- a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js +++ b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js @@ -128,7 +128,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { /> { onClick={() => setAction({ command: 'rename', - humanReadable: 'Rename', + display: 'Rename', confirmationMessage: 'Write the new name for this machine' }) }> @@ -190,7 +190,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { onClick={() => setAction({ command: 'unpair', - humanReadable: 'Unpair' + display: 'Unpair' }) }> Unpair @@ -204,7 +204,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { onClick={() => setAction({ command: 'reboot', - humanReadable: 'Reboot' + display: 'Reboot' }) }> Reboot @@ -218,7 +218,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { onClick={() => setAction({ command: 'shutdown', - humanReadable: 'Shutdown', + display: 'Shutdown', message: 'In order to bring it back online, the machine will need to be visited and its power reset.' }) @@ -234,7 +234,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { onClick={() => setAction({ command: 'restartServices', - humanReadable: 'Restart services for' + display: 'Restart services for' }) }> Restart Services From e11d894bd61e6da7860773679a6a8da3e1c2879d Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 25 Nov 2020 17:05:31 +0000 Subject: [PATCH 22/31] feat: Changed add machine button to be according to spec --- new-lamassu-admin/src/components/layout/Header.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/new-lamassu-admin/src/components/layout/Header.js b/new-lamassu-admin/src/components/layout/Header.js index 97ae6995..e3ce2d77 100644 --- a/new-lamassu-admin/src/components/layout/Header.js +++ b/new-lamassu-admin/src/components/layout/Header.js @@ -3,9 +3,11 @@ import classnames from 'classnames' import React, { memo, useState } from 'react' import { NavLink, useHistory } from 'react-router-dom' -import { Link } from 'src/components/buttons' +import ActionButton from 'src/components/buttons/ActionButton' import { H4 } from 'src/components/typography' import AddMachine from 'src/pages/AddMachine' +import { ReactComponent as AddIconReverse } from 'src/styling/icons/button/add/white.svg' +import { ReactComponent as AddIcon } from 'src/styling/icons/button/add/zodiac.svg' import { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg' import styles from './Header.styles' @@ -76,9 +78,14 @@ const Header = memo(({ tree }) => { ))} - setOpen(true)}> - Add Machine - + setOpen(true)}> + Add machine +
From d5f3763e918b1d25cd5d857513d704fc5fcb91e8 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 25 Nov 2020 19:08:23 +0000 Subject: [PATCH 23/31] fix: Removed useless className --- new-lamassu-admin/src/components/layout/Header.js | 1 - 1 file changed, 1 deletion(-) diff --git a/new-lamassu-admin/src/components/layout/Header.js b/new-lamassu-admin/src/components/layout/Header.js index e3ce2d77..d21acb46 100644 --- a/new-lamassu-admin/src/components/layout/Header.js +++ b/new-lamassu-admin/src/components/layout/Header.js @@ -79,7 +79,6 @@ const Header = memo(({ tree }) => { ))} Date: Tue, 1 Dec 2020 14:32:21 +0000 Subject: [PATCH 24/31] feat: Customer transactions fetching with dataloader library --- lib/new-admin/graphql/schema.js | 5 ++- lib/new-admin/transactions.js | 57 +++++++++++++++++++++++++++++++-- package-lock.json | 5 +++ package.json | 1 + 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index d299dd1e..9aa3b63d 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -3,6 +3,7 @@ const { parseAsync } = require('json2csv') const { GraphQLDateTime } = require('graphql-iso-date') const { GraphQLJSON, GraphQLJSONObject } = require('graphql-type-json') const got = require('got') +const DataLoader = require('dataloader') const machineLoader = require('../../machine-loader') const customers = require('../../customers') @@ -265,6 +266,8 @@ const typeDefs = gql` } ` +const transactionsLoader = new DataLoader(ids => transactions.getCustomerTransactionsBatch(ids)) + const notify = () => got.post('http://localhost:3030/dbChange') .catch(e => console.error('Error: lamassu-server not responding')) @@ -273,7 +276,7 @@ const resolvers = { JSONObject: GraphQLJSONObject, Date: GraphQLDateTime, Customer: { - transactions: parent => transactions.getCustomerTransactions(parent.id) + transactions: parent => transactionsLoader.load(parent.id) }, Query: { countries: () => countries, diff --git a/lib/new-admin/transactions.js b/lib/new-admin/transactions.js index 657ab4ea..519271a4 100644 --- a/lib/new-admin/transactions.js +++ b/lib/new-admin/transactions.js @@ -67,7 +67,6 @@ function batch (from = new Date(0).toISOString(), until = new Date().toISOString function getCustomerTransactions (customerId) { const packager = _.flow(it => { - console.log() return it }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) @@ -110,6 +109,60 @@ function getCustomerTransactions (customerId) { .then(packager) } +async function getCustomerTransactionsBatch(ids) { + const packager = _.flow(it => { + return it + }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) + + const cashInSql = `select 'cashIn' as tx_class, txs.*, + c.phone as customer_phone, + c.id_card_data_number as customer_id_card_data_number, + c.id_card_data_expiration as customer_id_card_data_expiration, + c.id_card_data as customer_id_card_data, + c.name as customer_name, + c.front_camera_path as customer_front_camera_path, + c.id_card_photo_path as customer_id_card_photo_path, + ((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired + from cash_in_txs as txs + left outer join customers c on txs.customer_id = c.id + where c.id::text LIKE ANY($1) + order by created desc limit $3` + + const cashOutSql = `select 'cashOut' as tx_class, + txs.*, + actions.tx_hash, + c.phone as customer_phone, + c.id_card_data_number as customer_id_card_data_number, + c.id_card_data_expiration as customer_id_card_data_expiration, + c.id_card_data as customer_id_card_data, + c.name as customer_name, + c.front_camera_path as customer_front_camera_path, + c.id_card_photo_path as customer_id_card_photo_path, + (extract(epoch from (now() - greatest(txs.created, txs.confirmed_at))) * 1000) >= $3 as expired + from cash_out_txs txs + inner join cash_out_actions actions on txs.id = actions.tx_id + and actions.action = 'provisionAddress' + left outer join customers c on txs.customer_id = c.id + where c.id::text LIKE ANY ($1) + order by created desc limit $2` + + const cashIns = await db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS]) + const cashOuts = await db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE]) + const transactions = await packager([...cashIns, ...cashOuts]) + + + const transactionMap = {} + transactions.forEach(transaction => { + if(!transactionMap[transaction.customerId]) { + transactionMap[transaction.customerId] = [transaction] + } + else { + transactionMap[transaction.customerId].push(transaction) + } + }) + return ids.map(id => transactionMap[id]) +} + function single (txId) { const packager = _.flow(_.compact, _.map(camelize), addNames) @@ -156,4 +209,4 @@ function cancel (txId) { .then(() => single(txId)) } -module.exports = { batch, getCustomerTransactions, single, cancel } +module.exports = { batch, getCustomerTransactions, single, cancel, getCustomerTransactionsBatch } diff --git a/package-lock.json b/package-lock.json index 58fcbfc0..f10f1027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3390,6 +3390,11 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" }, + "dataloader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.0.0.tgz", + "integrity": "sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ==" + }, "date-fns": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", diff --git a/package.json b/package.json index 9fb7380f..ddb3615a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "console-log-level": "^1.4.0", "cookie-parser": "^1.4.3", "cors": "^2.8.5", + "dataloader": "^2.0.0", "ethereumjs-tx": "^1.3.3", "ethereumjs-util": "^5.2.0", "ethereumjs-wallet": "^0.6.3", From ed4e654036c30fc0fb7a1c4ea2a24e2a9948798e Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Wed, 2 Dec 2020 16:01:33 +0000 Subject: [PATCH 25/31] Chore: remove unused code and use lodash --- lib/new-admin/transactions.js | 69 +++++------------------------------ 1 file changed, 9 insertions(+), 60 deletions(-) diff --git a/lib/new-admin/transactions.js b/lib/new-admin/transactions.js index 519271a4..68fef36e 100644 --- a/lib/new-admin/transactions.js +++ b/lib/new-admin/transactions.js @@ -65,51 +65,7 @@ function batch (from = new Date(0).toISOString(), until = new Date().toISOString .then(packager) } -function getCustomerTransactions (customerId) { - const packager = _.flow(it => { - return it - }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) - - const cashInSql = `select 'cashIn' as tx_class, txs.*, - c.phone as customer_phone, - c.id_card_data_number as customer_id_card_data_number, - c.id_card_data_expiration as customer_id_card_data_expiration, - c.id_card_data as customer_id_card_data, - c.name as customer_name, - c.front_camera_path as customer_front_camera_path, - c.id_card_photo_path as customer_id_card_photo_path, - ((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired - from cash_in_txs as txs - left outer join customers c on txs.customer_id = c.id - where c.id = $1 - order by created desc limit $3` - - const cashOutSql = `select 'cashOut' as tx_class, - txs.*, - actions.tx_hash, - c.phone as customer_phone, - c.id_card_data_number as customer_id_card_data_number, - c.id_card_data_expiration as customer_id_card_data_expiration, - c.id_card_data as customer_id_card_data, - c.name as customer_name, - c.front_camera_path as customer_front_camera_path, - c.id_card_photo_path as customer_id_card_photo_path, - (extract(epoch from (now() - greatest(txs.created, txs.confirmed_at))) * 1000) >= $3 as expired - from cash_out_txs txs - inner join cash_out_actions actions on txs.id = actions.tx_id - and actions.action = 'provisionAddress' - left outer join customers c on txs.customer_id = c.id - where c.id = $1 - order by created desc limit $2` - - return Promise.all([ - db.any(cashInSql, [customerId, cashInTx.PENDING_INTERVAL, NUM_RESULTS]), - db.any(cashOutSql, [customerId, NUM_RESULTS, REDEEMABLE_AGE]) - ]) - .then(packager) -} - -async function getCustomerTransactionsBatch(ids) { +function getCustomerTransactionsBatch (ids) { const packager = _.flow(it => { return it }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) @@ -146,21 +102,14 @@ async function getCustomerTransactionsBatch(ids) { where c.id::text LIKE ANY ($1) order by created desc limit $2` - const cashIns = await db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS]) - const cashOuts = await db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE]) - const transactions = await packager([...cashIns, ...cashOuts]) - - - const transactionMap = {} - transactions.forEach(transaction => { - if(!transactionMap[transaction.customerId]) { - transactionMap[transaction.customerId] = [transaction] - } - else { - transactionMap[transaction.customerId].push(transaction) - } + return Promise.all([ + db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS]), + db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE]) + ]) + .then(packager).then(transactions => { + const transactionMap = _.groupBy('customerId', transactions) + return ids.map(id => transactionMap[id]) }) - return ids.map(id => transactionMap[id]) } function single (txId) { @@ -209,4 +158,4 @@ function cancel (txId) { .then(() => single(txId)) } -module.exports = { batch, getCustomerTransactions, single, cancel, getCustomerTransactionsBatch } +module.exports = { batch, single, cancel, getCustomerTransactionsBatch } From 0b02c7feae03c0eeb0765cc5390430846dd32d9a Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Fri, 4 Dec 2020 13:43:06 +0000 Subject: [PATCH 26/31] Fix: fix query --- lib/new-admin/transactions.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/new-admin/transactions.js b/lib/new-admin/transactions.js index 68fef36e..79285e06 100644 --- a/lib/new-admin/transactions.js +++ b/lib/new-admin/transactions.js @@ -1,4 +1,5 @@ const _ = require('lodash/fp') +const pgp = require('pg-promise')() const db = require('../db') const machineLoader = require('../machine-loader') @@ -81,7 +82,7 @@ function getCustomerTransactionsBatch (ids) { ((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired from cash_in_txs as txs left outer join customers c on txs.customer_id = c.id - where c.id::text LIKE ANY($1) + where c.id IN ($1^) order by created desc limit $3` const cashOutSql = `select 'cashOut' as tx_class, @@ -99,12 +100,11 @@ function getCustomerTransactionsBatch (ids) { inner join cash_out_actions actions on txs.id = actions.tx_id and actions.action = 'provisionAddress' left outer join customers c on txs.customer_id = c.id - where c.id::text LIKE ANY ($1) + where c.id IN ($1^) order by created desc limit $2` - return Promise.all([ - db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS]), - db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE]) + db.any(cashInSql, [_.map(pgp.as.text, ids).join(','), cashInTx.PENDING_INTERVAL, NUM_RESULTS]), + db.any(cashOutSql, [_.map(pgp.as.text, ids).join(','), NUM_RESULTS, REDEEMABLE_AGE]) ]) .then(packager).then(transactions => { const transactionMap = _.groupBy('customerId', transactions) From 1913390eaea09899d58b241a022ccc7ce7d06b1f Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Thu, 10 Dec 2020 12:14:39 +0000 Subject: [PATCH 27/31] Fix: notification override alerts not being sent --- lib/plugins.js | 2 +- .../src/pages/Notifications/sections/FiatBalanceOverrides.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/plugins.js b/lib/plugins.js index a66e3446..fe3d4e16 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -637,7 +637,7 @@ function plugins (settings, deviceId) { const notifications = configManager.getNotifications(null, device.deviceId, settings.config) - const machineName = device.machineName + const machineName = device.name const cashInAlert = device.cashbox > notifications.cashInAlertThreshold ? { diff --git a/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceOverrides.js b/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceOverrides.js index 2cf4aaf2..442eaa63 100644 --- a/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceOverrides.js +++ b/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceOverrides.js @@ -9,8 +9,8 @@ import Autocomplete from 'src/components/inputs/formik/Autocomplete' import NotificationsCtx from '../NotificationsContext' import { transformNumber } from '../helper' -const CASSETTE_1_KEY = 'cassette1' -const CASSETTE_2_KEY = 'cassette2' +const CASSETTE_1_KEY = 'fiatBalanceCassette1' +const CASSETTE_2_KEY = 'fiatBalanceCassette2' const MACHINE_KEY = 'machine' const NAME = 'fiatBalanceOverrides' From a432d913bed907c20ae67815c4cd8ca5978a23a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Salgado?= Date: Mon, 14 Dec 2020 11:26:54 +0000 Subject: [PATCH 28/31] fix: override fields update --- lib/customers.js | 7 +++++-- lib/new-admin/admin-server.js | 1 + lib/new-admin/graphql/schema.js | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/customers.js b/lib/customers.js index fcb85c62..5c82ede0 100644 --- a/lib/customers.js +++ b/lib/customers.js @@ -97,7 +97,7 @@ function update (id, data, userToken, txId) { * * @returns {Promise} Newly updated Customer */ -async function updateCustomer (id, data) { +async function updateCustomer (id, data, userToken) { const formattedData = _.pick( [ 'authorized_override', @@ -110,7 +110,10 @@ async function updateCustomer (id, data) { ], _.mapKeys(_.snakeCase, data)) - const sql = Pgp.helpers.update(formattedData, _.keys(formattedData), 'customers') + + const enhancedUpdateData = enhanceAtFields(enhanceOverrideFields(formattedData, userToken)) + const updateData = updateOverride(enhancedUpdateData) + + const sql = Pgp.helpers.update(updateData, _.keys(updateData), 'customers') + ' where id=$1' await db.none(sql, [id]) diff --git a/lib/new-admin/admin-server.js b/lib/new-admin/admin-server.js index 79927743..0837ade1 100644 --- a/lib/new-admin/admin-server.js +++ b/lib/new-admin/admin-server.js @@ -49,6 +49,7 @@ const apolloServer = new ApolloServer({ const success = await login.authenticate(token) if (!success) throw new AuthenticationError('Authentication failed') + return { req: { ...req } } } }) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index 9aa3b63d..ae4a993a 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -311,7 +311,10 @@ const resolvers = { machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }), createPairingTotem: (...[, { name }]) => pairing.totem(name), saveAccounts: (...[, { accounts }]) => settingsLoader.saveAccounts(accounts), - setCustomer: (...[, { customerId, customerInput } ]) => customers.updateCustomer(customerId, customerInput), + setCustomer: (root, args, context, info) => { + const token = context.req.cookies && context.req.cookies.token + return customers.updateCustomer(args.customerId, args.customerInput, token) + }, saveConfig: (...[, { config }]) => settingsLoader.saveConfig(config) .then(it => { notify() From 6994303069610d5954badb1efaa2ecd2f4b44167 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Tue, 15 Dec 2020 14:58:11 +0000 Subject: [PATCH 29/31] Feat: warn admin before restarting services --- lib/machine-loader.js | 7 +- lib/new-admin/graphql/schema.js | 20 +++++ lib/postgresql_interface.js | 12 +++ .../src/components/ConfirmDialog.js | 2 + .../pages/Maintenance/MachineDetailsCard.js | 82 +++++++++++++++++-- .../Maintenance/MachineDetailsCard.styles.js | 11 ++- 6 files changed, 126 insertions(+), 8 deletions(-) diff --git a/lib/machine-loader.js b/lib/machine-loader.js index 24c5f5ab..5d3d23f0 100644 --- a/lib/machine-loader.js +++ b/lib/machine-loader.js @@ -9,7 +9,7 @@ const dbm = require('./postgresql_interface') const configManager = require('./new-config-manager') const settingsLoader = require('./new-settings-loader') -module.exports = {getMachineName, getMachines, getMachineNames, setMachine} +module.exports = {getMachineName, getMachines, getMachine, getMachineNames, setMachine} function getMachines () { return db.any('select * from devices where display=TRUE order by created') @@ -88,6 +88,11 @@ function getMachineName (machineId) { .then(it => it.name) } +function getMachine (machineId) { + const sql = 'select * from devices where device_id=$1' + return db.oneOrNone(sql, [machineId]).then(res => _.mapKeys(_.camelCase)(res)) +} + function renameMachine (rec) { const sql = 'update devices set name=$1 where device_id=$2' return db.none(sql, [rec.newName, rec.deviceId]) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index ae4a993a..42da3110 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -12,6 +12,7 @@ const logs = require('../../logs') const settingsLoader = require('../../new-settings-loader') const tokenManager = require('../../token-manager') const blacklist = require('../../blacklist') +const machineEventsByIdBatch = require("../../postgresql_interface").machineEventsByIdBatch const serverVersion = require('../../../package.json').version @@ -70,6 +71,7 @@ const typeDefs = gql` cassette1: Int cassette2: Int statuses: [MachineStatus] + latestEvent: MachineEvent } type Customer { @@ -220,6 +222,16 @@ const typeDefs = gql` address: String! } + type MachineEvent { + id: ID + deviceId: String + eventType: String + note: String + created: Date + age: Float + deviceTime: Date + } + type Query { countries: [Country] currencies: [Currency] @@ -227,6 +239,7 @@ const typeDefs = gql` accountsConfig: [AccountConfig] cryptoCurrencies: [CryptoCurrency] machines: [Machine] + machine(deviceId: ID!): Machine customers: [Customer] customer(customerId: ID!): Customer machineLogs(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): [MachineLog] @@ -267,6 +280,9 @@ const typeDefs = gql` ` const transactionsLoader = new DataLoader(ids => transactions.getCustomerTransactionsBatch(ids)) +const machineEventsLoader = new DataLoader(ids => { + return machineEventsByIdBatch(ids) +}, { cache: false }) const notify = () => got.post('http://localhost:3030/dbChange') .catch(e => console.error('Error: lamassu-server not responding')) @@ -278,6 +294,9 @@ const resolvers = { Customer: { transactions: parent => transactionsLoader.load(parent.id) }, + Machine: { + latestEvent: parent => machineEventsLoader.load(parent.deviceId) + }, Query: { countries: () => countries, currencies: () => currencies, @@ -285,6 +304,7 @@ const resolvers = { accountsConfig: () => accountsConfig, cryptoCurrencies: () => coins, machines: () => machineLoader.getMachineNames(), + machine: (...[, { deviceId }]) => machineLoader.getMachine(deviceId), customers: () => customers.getCustomersList(), customer: (...[, { customerId }]) => customers.getCustomerById(customerId), funding: () => funding.getFunding(), diff --git a/lib/postgresql_interface.js b/lib/postgresql_interface.js index aa8cc126..eb030e91 100644 --- a/lib/postgresql_interface.js +++ b/lib/postgresql_interface.js @@ -1,4 +1,6 @@ +const _ = require('lodash/fp') const db = require('./db') +const pgp = require('pg-promise')() function getInsertQuery (tableName, fields) { // outputs string like: '$1, $2, $3...' with proper No of items @@ -48,6 +50,16 @@ exports.machineEvent = function machineEvent (rec) { .then(() => db.none(deleteSql)) } +exports.machineEventsByIdBatch = function machineEventsByIdBatch (machineIds) { + const formattedIds = _.map(pgp.as.text, machineIds).join(',') + const sql = `SELECT *, (EXTRACT(EPOCH FROM (now() - created))) * 1000 AS age FROM machine_events WHERE device_id IN ($1^) ORDER BY age ASC LIMIT 1` + return db.any(sql, [formattedIds]).then(res => { + const events = _.map(_.mapKeys(_.camelCase))(res) + const eventMap = _.groupBy('deviceId', events) + return machineIds.map(id => _.prop([0], eventMap[id])) + }) +} + exports.machineEvents = function machineEvents () { const sql = 'SELECT *, (EXTRACT(EPOCH FROM (now() - created))) * 1000 AS age FROM machine_events' diff --git a/new-lamassu-admin/src/components/ConfirmDialog.js b/new-lamassu-admin/src/components/ConfirmDialog.js index 294b2bd7..bab70a09 100644 --- a/new-lamassu-admin/src/components/ConfirmDialog.js +++ b/new-lamassu-admin/src/components/ConfirmDialog.js @@ -65,6 +65,7 @@ export const ConfirmDialog = memo( onConfirmed, onDissmised, initialValue = '', + disabled = false, ...props }) => { const classes = useStyles() @@ -101,6 +102,7 @@ export const ConfirmDialog = memo( {message &&

{message}

} { + if (!machineState) { + return true + } + const staticStates = [ + 'chooseCoin', + 'idle', + 'pendingIdle', + 'dualIdle', + 'networkDown', + 'unpaired', + 'maintenance', + 'virgin', + 'wifiList' + ] + return staticStates.includes(machineState) +} + const article = ({ code: status }) => supportArtices.find(({ code: article }) => article === status) @@ -69,10 +97,50 @@ const Item = ({ children, ...props }) => ( ) const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { - const [action, setAction] = useState(null) + const [action, setAction] = useState({ command: null }) const [errorMessage, setErrorMessage] = useState(null) const classes = useMDStyles() + const [ + fetchMachineEvents, + { loading: loadingEvents, data: machineEventsLazy } + ] = useLazyQuery(MACHINE, { + variables: { + deviceId: machine.deviceId + } + }) + + useEffect(() => { + if (action.command === 'restartServices') { + fetchMachineEvents() + } + }, [action.command, fetchMachineEvents]) + + useEffect(() => { + if (machineEventsLazy && action.command === 'restartServices') { + const state = JSON.parse( + machineEventsLazy.machine.latestEvent?.note ?? '{"state": null}' + ).state + if (!isStaticState(state)) { + setAction(action => ({ + ...action, + message: ( + + A user may be in the middle of a transaction and they could lose + their funds if you continue. + + ) + })) + } else { + // clear message from object when state goes from not static to static + setAction(action => ({ + ...action, + message: null + })) + } + } + }, [action.command, classes.warning, machineEventsLazy]) + const [machineAction, { loading }] = useMutation(MACHINE_ACTION, { onError: ({ message }) => { const errorMessage = message ?? 'An error ocurred' @@ -80,11 +148,12 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { }, onCompleted: () => { onActionSuccess && onActionSuccess() - setAction(null) + setAction({ command: null }) } }) - const confirmDialogOpen = Boolean(action) + const confirmDialogOpen = Boolean(action.command) + const disabled = !!(action?.command === 'restartServices' && loadingEvents) return ( <> @@ -127,6 +196,7 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { className={classes.separator} /> { }) }} onDissmised={() => { - setAction(null) + setAction({ command: null }) setErrorMessage(null) }} /> diff --git a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.styles.js b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.styles.js index 00ac1ab8..16da4fae 100644 --- a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.styles.js +++ b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.styles.js @@ -4,7 +4,13 @@ import { detailsRowStyles, labelStyles } from 'src/pages/Transactions/Transactions.styles' -import { spacer, comet, primaryColor, fontSize4 } from 'src/styling/variables' +import { + spacer, + comet, + primaryColor, + fontSize4, + errorColor +} from 'src/styling/variables' const machineDetailsStyles = { ...detailsRowStyles, @@ -58,6 +64,9 @@ const machineDetailsStyles = { marginRight: 60, marginLeft: 'auto', background: fade(comet, 0.5) + }, + warning: { + color: errorColor } } From bb9da7ff8078fdfe083814c732e20f6003d56093 Mon Sep 17 00:00:00 2001 From: Cesar <26280794+csrapr@users.noreply.github.com> Date: Tue, 15 Dec 2020 21:21:56 +0000 Subject: [PATCH 30/31] Chore: remove unneeded useEffect --- .../pages/Maintenance/MachineDetailsCard.js | 65 ++++++++----------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js index d23c8c5e..14d72b55 100644 --- a/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js +++ b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js @@ -3,7 +3,7 @@ import { Grid, Divider } from '@material-ui/core' import { makeStyles } from '@material-ui/core/styles' import gql from 'graphql-tag' import moment from 'moment' -import React, { useState, useEffect } from 'react' +import React, { useState } from 'react' import { ConfirmDialog } from 'src/components/ConfirmDialog' import { Status } from 'src/components/Status' @@ -96,50 +96,36 @@ const Item = ({ children, ...props }) => ( ) +const getState = machineEventsLazy => + JSON.parse(machineEventsLazy.machine.latestEvent?.note ?? '{"state": null}') + .state + const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { const [action, setAction] = useState({ command: null }) const [errorMessage, setErrorMessage] = useState(null) const classes = useMDStyles() - const [ - fetchMachineEvents, - { loading: loadingEvents, data: machineEventsLazy } - ] = useLazyQuery(MACHINE, { - variables: { - deviceId: machine.deviceId - } - }) + const warningMessage = ( + + A user may be in the middle of a transaction and they could lose their + funds if you continue. + + ) - useEffect(() => { - if (action.command === 'restartServices') { - fetchMachineEvents() - } - }, [action.command, fetchMachineEvents]) - - useEffect(() => { - if (machineEventsLazy && action.command === 'restartServices') { - const state = JSON.parse( - machineEventsLazy.machine.latestEvent?.note ?? '{"state": null}' - ).state - if (!isStaticState(state)) { - setAction(action => ({ - ...action, - message: ( - - A user may be in the middle of a transaction and they could lose - their funds if you continue. - - ) - })) - } else { - // clear message from object when state goes from not static to static - setAction(action => ({ - ...action, - message: null - })) + const [fetchMachineEvents, { loading: loadingEvents }] = useLazyQuery( + MACHINE, + { + variables: { + deviceId: machine.deviceId + }, + onCompleted: machineEventsLazy => { + const message = !isStaticState(getState(machineEventsLazy)) + ? warningMessage + : null + setAction(action => ({ ...action, message })) } } - }, [action.command, classes.warning, machineEventsLazy]) + ) const [machineAction, { loading }] = useMutation(MACHINE_ACTION, { onError: ({ message }) => { @@ -301,12 +287,13 @@ const MachineDetailsRow = ({ it: machine, onActionSuccess }) => { Icon={RebootIcon} InverseIcon={RebootReversedIcon} disabled={loading} - onClick={() => + onClick={() => { + fetchMachineEvents() setAction({ command: 'restartServices', display: 'Restart services for' }) - }> + }}> Restart Services
From b1ac484c0bb25636f51df72dd02cfacfffe19f73 Mon Sep 17 00:00:00 2001 From: Liordino Neto Date: Wed, 16 Dec 2020 00:51:21 -0300 Subject: [PATCH 31/31] fix: make the number of suspension days required only when the 'Suspend' requirement is selected --- new-lamassu-admin/src/pages/Triggers/helper.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/new-lamassu-admin/src/pages/Triggers/helper.js b/new-lamassu-admin/src/pages/Triggers/helper.js index cc7b1ce8..d4b5cf5f 100644 --- a/new-lamassu-admin/src/pages/Triggers/helper.js +++ b/new-lamassu-admin/src/pages/Triggers/helper.js @@ -76,7 +76,10 @@ const threshold = Yup.object().shape({ }) const requirement = Yup.object().shape({ requirement: Yup.string().required(), - suspensionDays: Yup.number() + suspensionDays: Yup.number().when('requirement', { + is: 'suspend', + then: Yup.number().required() + }) }) const Schema = Yup.object().shape({