diff --git a/.babelrc b/.babelrc index 7f5fce00e..701fada78 100644 --- a/.babelrc +++ b/.babelrc @@ -2,9 +2,6 @@ "presets": [ "@babel/preset-env", "@babel/preset-react", - ["react-app", { "typescript": true }] - ], - "plugins": [ - "react-hot-loader/babel" + "@babel/preset-typescript" ] } \ No newline at end of file diff --git a/e2e-tests/account_secret_key.cer b/e2e-tests/account_secret_key.cer new file mode 100644 index 000000000..191e0b76c --- /dev/null +++ b/e2e-tests/account_secret_key.cer @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIMLtdAiYwOcQ6J8UW1mgDe6VeQrsker8nKp6MK61kC35 +-----END PRIVATE KEY----- diff --git a/e2e-tests/constants.ts b/e2e-tests/constants.ts index 8ca898274..04534c06d 100644 --- a/e2e-tests/constants.ts +++ b/e2e-tests/constants.ts @@ -5,7 +5,14 @@ export const twentyFourWordsSecretPhrase = 'hold matrix spider subway bottom jazz charge fire lawn valley stay coil moral hospital dream cycle multiply december agree huge major tower devote old'; export const twelveWordsSecretPhrase = 'small vendor member cry motion lava hurdle gravity cry sentence medal seminar'; -export const secretKeyPath = path.join(__dirname, './account_secret_key.pem'); +export const secretKeyPathForPEM = path.join( + __dirname, + './account_secret_key.pem' +); +export const secretKeyPathForCER = path.join( + __dirname, + './account_secret_key.cer' +); export const torusSecretKeyHex = '1ac774d1b4e05a5546ddc8345e8ccf1d7ef3d19b0e5cd722f161260e6bf1d35d'; @@ -14,23 +21,31 @@ export const ACCOUNT_NAMES = { defaultFirstAccountName: 'Account 1', defaultSecondAccountName: 'Account 2', createdAccountName: 'New account 1', - importedAccountName: 'Imported account', - renamedAccountName: 'Renamed account', importedPemAccountName: 'Imported pem account', + renamedAccountName: 'Renamed account', + importedCerAccountName: 'Imported cer account', importedTorusAccountName: 'Torus account' }; export const PLAYGROUND_URL = 'https://cspr-wallet-playground.dev.make.services/'; -export const IMPORTED_ACCOUNT = { - accountName: ACCOUNT_NAMES.importedAccountName, +export const IMPORTED_PEM_ACCOUNT = { + accountName: ACCOUNT_NAMES.importedPemAccountName, publicKey: '0184f6d260f4ee6869ddb36affe15456de6ae045278fa2f467bb677561ce0dad55', truncatedPublicKey: '0184f...dad55', mediumTruncatedPublicKey: '0184f6d260...561ce0dad55' }; +export const IMPORTED_CER_ACCOUNT = { + accountName: ACCOUNT_NAMES.importedCerAccountName, + publicKey: + '01a8d1042fa244f39fe4caa1660fc6dce522b3afe649dbe61f7d16e240168e6ff2', + truncatedPublicKey: '01a8d...e6ff2', + mediumTruncatedPublicKey: '01a8d1042f...40168e6ff2' +}; + export const IMPORTED_TORUS_ACCOUNT = { accountName: ACCOUNT_NAMES.importedTorusAccountName, publicKey: diff --git a/e2e-tests/popup/buy-cspr/buy-cspr.spec.ts b/e2e-tests/popup/buy-cspr/buy-cspr.spec.ts new file mode 100644 index 000000000..420f74246 --- /dev/null +++ b/e2e-tests/popup/buy-cspr/buy-cspr.spec.ts @@ -0,0 +1,138 @@ +import { popup, popupExpect } from '../../fixtures'; + +popup.describe('Popup UI: buy cspr', () => { + popup( + 'should redirect to Topper provider page', + async ({ popupPage, unlockVault, context }) => { + await unlockVault(); + + await popupPage.getByTestId('network-switcher').click(); + await popupPage.getByText('Mainnet').click(); + + await popupPage.getByText('Buy').click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Pick country' }) + ).toBeVisible(); + + await popupPage.getByRole('button', { name: 'Next' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Enter amount' }) + ).toBeVisible(); + await popupPage.getByRole('button', { name: 'Next' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Pick provider' }) + ).toBeVisible(); + + await popupExpect( + popupPage.getByRole('button', { name: 'Confirm' }) + ).toBeDisabled(); + + await popupPage.getByText('Topper by Uphold').click(); + + await popupExpect( + popupPage.getByRole('button', { name: 'Confirm' }) + ).not.toBeDisabled(); + + const [torusPage] = await Promise.all([ + context.waitForEvent('page'), + popupPage.getByRole('button', { name: 'Confirm' }).click() + ]); + + await new Promise(r => setTimeout(r, 2000)); + + console.log(torusPage.url()); + popupExpect(torusPage.url()).toContain('https://app.topperpay.com/'); + } + ); + + popup( + 'should redirect to Ramp provider page', + async ({ popupPage, unlockVault, context }) => { + await unlockVault(); + + await popupPage.getByTestId('network-switcher').click(); + await popupPage.getByText('Mainnet').click(); + + await popupPage.getByText('Buy').click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Pick country' }) + ).toBeVisible(); + + await popupPage.getByRole('button', { name: 'Next' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Enter amount' }) + ).toBeVisible(); + await popupPage.getByRole('button', { name: 'Next' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Pick provider' }) + ).toBeVisible(); + + await popupExpect( + popupPage.getByRole('button', { name: 'Confirm' }) + ).toBeDisabled(); + + await popupPage.getByText('Ramp').click(); + + await popupExpect( + popupPage.getByRole('button', { name: 'Confirm' }) + ).not.toBeDisabled(); + + const [rampPage] = await Promise.all([ + context.waitForEvent('page'), + popupPage.getByRole('button', { name: 'Confirm' }).click() + ]); + + await new Promise(r => setTimeout(r, 2000)); + + console.log(rampPage.url()); + popupExpect(rampPage.url()).toContain('https://app.ramp.network/'); + } + ); + + popup( + 'should display and empty provider page when no available provider', + async ({ popupPage, unlockVault }) => { + await unlockVault(); + + await popupPage.getByTestId('network-switcher').click(); + await popupPage.getByText('Mainnet').click(); + + await popupPage.getByText('Buy').click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Pick country' }) + ).toBeVisible(); + + await popupPage.getByTestId('country-row').click(); + + await popupPage + .getByPlaceholder('Search', { exact: true }) + .fill('Ukraine'); + + await popupPage.getByText('Ukraine').click(); + + await popupPage.getByRole('button', { name: 'Next' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Enter amount' }) + ).toBeVisible(); + await popupPage.getByTestId('currency-row').click(); + + await popupPage.getByPlaceholder('Search', { exact: true }).fill('UAH'); + + await popupPage.getByText('UAH').click(); + + await popupPage.getByRole('button', { name: 'Next' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'No available provider' }) + ).toBeVisible(); + } + ); +}); diff --git a/e2e-tests/popup/common/wallet.spec.ts b/e2e-tests/popup/common/wallet.spec.ts index c81c680c2..67ef612fc 100644 --- a/e2e-tests/popup/common/wallet.spec.ts +++ b/e2e-tests/popup/common/wallet.spec.ts @@ -1,5 +1,5 @@ -import { popup, popupExpect } from '../../fixtures'; import { ACCOUNT_NAMES } from '../../constants'; +import { popup, popupExpect } from '../../fixtures'; popup.describe('Popup UI: lock/unlock/reset wallet', () => { popup( diff --git a/e2e-tests/popup/contacts/contacts.spec.ts b/e2e-tests/popup/contacts/contacts.spec.ts index e7d617f1c..461e3efc6 100644 --- a/e2e-tests/popup/contacts/contacts.spec.ts +++ b/e2e-tests/popup/contacts/contacts.spec.ts @@ -1,9 +1,9 @@ -import { popup, popupExpect } from '../../fixtures'; import { DEFAULT_FIRST_ACCOUNT, DEFAULT_SECOND_ACCOUNT, vaultPassword } from '../../constants'; +import { popup, popupExpect } from '../../fixtures'; popup.describe('Popup UI: contacts', () => { popup( diff --git a/e2e-tests/popup/create-account/create-account.spec.ts b/e2e-tests/popup/create-account/create-account.spec.ts index d22a7be51..b4adbd803 100644 --- a/e2e-tests/popup/create-account/create-account.spec.ts +++ b/e2e-tests/popup/create-account/create-account.spec.ts @@ -1,5 +1,5 @@ -import { popup, popupExpect } from '../../fixtures'; import { ACCOUNT_NAMES } from '../../constants'; +import { popup, popupExpect } from '../../fixtures'; popup.describe('Popup UI: create account', () => { popup.beforeEach(async ({ unlockVault, popupPage }) => { diff --git a/e2e-tests/popup/disconnect-account/disconnect-account.spec.ts b/e2e-tests/popup/disconnect-account/disconnect-account.spec.ts index 47064c612..b862603fc 100644 --- a/e2e-tests/popup/disconnect-account/disconnect-account.spec.ts +++ b/e2e-tests/popup/disconnect-account/disconnect-account.spec.ts @@ -1,5 +1,5 @@ -import { popup, popupExpect } from '../../fixtures'; import { ACCOUNT_NAMES, PLAYGROUND_URL } from '../../constants'; +import { popup, popupExpect } from '../../fixtures'; popup.describe('Popup UI: disconnect account', () => { popup.beforeEach(async ({ connectAccounts }) => { diff --git a/e2e-tests/popup/import-account-with-file/import-account-with-file.spec.ts b/e2e-tests/popup/import-account-with-file/import-account-with-file.spec.ts index 92104ef5d..c7847bd4a 100644 --- a/e2e-tests/popup/import-account-with-file/import-account-with-file.spec.ts +++ b/e2e-tests/popup/import-account-with-file/import-account-with-file.spec.ts @@ -1,13 +1,69 @@ -import { popup, popupExpect } from '../../fixtures'; import { ACCOUNT_NAMES, - IMPORTED_ACCOUNT, - secretKeyPath + IMPORTED_CER_ACCOUNT, + IMPORTED_PEM_ACCOUNT, + secretKeyPathForCER, + secretKeyPathForPEM } from '../../constants'; +import { popup, popupExpect } from '../../fixtures'; popup.describe('Popup UI: import account with file', () => { popup( - 'should import account via a file', + 'should import account via .pem file', + async ({ unlockVault, context, popupPage }) => { + await unlockVault(); + + await popupPage.getByTestId('menu-open-icon').click(); + + const [importAccountPage] = await Promise.all([ + context.waitForEvent('page'), + popupPage.getByText('Import account').click() + ]); + + const fileChooserPromise = importAccountPage.waitForEvent('filechooser'); + + await popupExpect( + importAccountPage.getByRole('heading', { + name: 'Import account from secret key file' + }) + ).toBeVisible(); + + await importAccountPage + .getByRole('button', { name: 'Upload your file' }) + .click(); + + const fileChooser = await fileChooserPromise; + await fileChooser.setFiles(secretKeyPathForPEM); + + await importAccountPage + .getByPlaceholder('Account name', { exact: true }) + .fill(ACCOUNT_NAMES.importedPemAccountName); + + await importAccountPage.getByRole('button', { name: 'Import' }).click(); + + await popupExpect( + importAccountPage.getByRole('heading', { + name: 'Your account was successfully imported' + }) + ).toBeVisible(); + + await importAccountPage.getByRole('button', { name: 'Done' }).click(); + + await popupPage.getByTestId('connection-status-modal').click(); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.importedPemAccountName) + ).toBeVisible(); + await popupExpect( + popupPage.getByText(IMPORTED_PEM_ACCOUNT.truncatedPublicKey) + ).toBeVisible(); + await popupExpect( + popupPage.getByText('Imported', { exact: true }) + ).toBeVisible(); + } + ); + popup( + 'should import account via .cer file', async ({ unlockVault, context, popupPage }) => { await unlockVault(); @@ -31,11 +87,11 @@ popup.describe('Popup UI: import account with file', () => { .click(); const fileChooser = await fileChooserPromise; - await fileChooser.setFiles(secretKeyPath); + await fileChooser.setFiles(secretKeyPathForCER); await importAccountPage .getByPlaceholder('Account name', { exact: true }) - .fill(ACCOUNT_NAMES.importedAccountName); + .fill(ACCOUNT_NAMES.importedCerAccountName); await importAccountPage.getByRole('button', { name: 'Import' }).click(); @@ -50,10 +106,10 @@ popup.describe('Popup UI: import account with file', () => { await popupPage.getByTestId('connection-status-modal').click(); await popupExpect( - popupPage.getByText(ACCOUNT_NAMES.importedAccountName) + popupPage.getByText(ACCOUNT_NAMES.importedCerAccountName) ).toBeVisible(); await popupExpect( - popupPage.getByText(IMPORTED_ACCOUNT.truncatedPublicKey) + popupPage.getByText(IMPORTED_CER_ACCOUNT.truncatedPublicKey) ).toBeVisible(); await popupExpect( popupPage.getByText('Imported', { exact: true }) diff --git a/e2e-tests/popup/rename-account/rename-account.spec.ts b/e2e-tests/popup/rename-account/rename-account.spec.ts index 2ab7f8b94..a295c9b91 100644 --- a/e2e-tests/popup/rename-account/rename-account.spec.ts +++ b/e2e-tests/popup/rename-account/rename-account.spec.ts @@ -1,5 +1,5 @@ -import { popup, popupExpect } from '../../fixtures'; import { ACCOUNT_NAMES } from '../../constants'; +import { popup, popupExpect } from '../../fixtures'; popup.describe('Popup UI: rename account', () => { popup( diff --git a/e2e-tests/popup/signature-request-scenarios/signature-request-scenarios.spec.ts b/e2e-tests/popup/signature-request-scenarios/signature-request-scenarios.spec.ts index 7c3ba2850..26707e9a3 100644 --- a/e2e-tests/popup/signature-request-scenarios/signature-request-scenarios.spec.ts +++ b/e2e-tests/popup/signature-request-scenarios/signature-request-scenarios.spec.ts @@ -1,10 +1,10 @@ -import { popup, popupExpect } from '../../fixtures'; import { DEFAULT_FIRST_ACCOUNT, NEW_VALIDATOR, PLAYGROUND_URL, VALIDATOR } from '../../constants'; +import { popup, popupExpect } from '../../fixtures'; popup.describe('Popup UI: signature request scenarios', () => { popup.beforeEach(async ({ connectAccounts, page }) => { diff --git a/jest.config.js b/jest.config.js index 6ed9233d0..6843c47f3 100644 --- a/jest.config.js +++ b/jest.config.js @@ -12,7 +12,7 @@ module.exports = { moduleNameMapper: { '^@src/(.*)$': '/src/$1' }, - setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'], + setupFilesAfterEnv: ['@testing-library/jest-dom'], coverageReporters: ['json', 'text'], coverageThreshold: { global: { diff --git a/jest.e2e.config.js b/jest.e2e.config.js index fc49abf8f..fcef5c7c0 100644 --- a/jest.e2e.config.js +++ b/jest.e2e.config.js @@ -11,6 +11,6 @@ module.exports = { moduleFileExtensions: ['js', 'ts'], modulePathIgnorePatterns: ['/.*/__mocks__', '/src'], testEnvironment: 'jsdom', - setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'], + setupFilesAfterEnv: ['@testing-library/jest-dom'], testTimeout: 1000 * 60 }; diff --git a/package-lock.json b/package-lock.json index 8948b1dab..dd0b8d344 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,15 @@ { "name": "Casper Wallet", - "version": "1.8.2", + "version": "1.8.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "Casper Wallet", - "version": "1.8.2", + "version": "1.8.1", "dependencies": { "@formatjs/intl": "2.6.2", "@hookform/resolvers": "2.9.10", - "@hot-loader/react-dom": "^17.0.1", "@lapo/asn1js": "1.2.4", "@lottiefiles/react-lottie-player": "3.5.3", "@make-software/ces-js-parser": "1.3.2", @@ -24,22 +23,21 @@ "casper-cep18-js-client": "1.0.2", "casper-js-sdk": "2.15.4", "date-fns": "^2.30.0", - "i18next": "^23.5.1", - "i18next-browser-languagedetector": "^6.1.5", - "i18next-http-backend": "^2.4.1", - "i18next-parser": "^6.3.0", + "i18next": "^23.11.0", + "i18next-browser-languagedetector": "^7.2.1", + "i18next-http-backend": "2.5.0", + "i18next-parser": "7.9.0", "lodash.throttle": "4.1.1", - "mac-scrollbar": "^0.10.3", + "mac-scrollbar": "^0.13.6", + "md5": "^2.3.0", "micro-aes-gcm": "0.3.3", "qrcode.react": "^3.1.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.0.2", "react-hook-form": "7.48.2", - "react-hot-loader": "4.13.1", - "react-i18next": "12.0.0", - "react-identicons": "^1.2.5", + "react-i18next": "14.1.0", "react-infinite-scroll-hook": "^4.1.1", - "react-inlinesvg": "^3.0.1", + "react-inlinesvg": "3.0.3", "react-loading-skeleton": "^3.3.1", "react-player": "^2.13.0", "react-query": "^3.39.3", @@ -57,25 +55,25 @@ "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/preset-env": "7.23.2", "@babel/preset-react": "7.18.6", + "@babel/preset-typescript": "^7.23.3", "@playwright/test": "^1.39.0", "@redux-devtools/cli": "^3.0.1", - "@testing-library/dom": "8.19.0", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^12.1.2", - "@testing-library/react-hooks": "^7.0.2", - "@testing-library/user-event": "^13.5.0", + "@redux-devtools/remote": "^0.9.1", + "@testing-library/dom": "9.3.4", + "@testing-library/jest-dom": "^6.4.2", + "@testing-library/react": "^14.2.1", + "@testing-library/user-event": "^14.5.2", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/big.js": "^6.1.6", "@types/chrome": "0.0.246", "@types/expect": "^24.3.0", "@types/jest": "29.2.3", "@types/lodash.throttle": "4.1.7", + "@types/md5": "^2.3.5", "@types/node": "^20.9.0", - "@types/react": "^17.0.33", - "@types/react-dom": "^17.0.10", - "@types/remote-redux-devtools": "^0.5.5", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.18", "@types/styled-components": "^5.1.26", - "@types/testing-library__react": "^10.2.0", "babel-eslint": "^10.1.0", "babel-loader": "9.1.0", "babel-preset-react-app": "^10.0.0", @@ -102,12 +100,11 @@ "jest": "29.3.1", "jest-environment-jsdom": "29.3.1", "lint-staged": "14.0.1", - "markdownlint": "0.26.2", + "markdownlint": "0.34.0", "markdownlint-cli": "0.32.2", "prettier": "3.1.0", - "remote-redux-devtools": "^0.5.16", "source-map-loader": "4.0.1", - "style-loader": "^3.3.1", + "style-loader": "^3.3.4", "terser-webpack-plugin": "5.3.6", "ts-jest": "29.1.1", "ts-loader": "9.4.2", @@ -142,7 +139,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -441,7 +437,6 @@ "version": "7.23.2", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -450,7 +445,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", - "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", @@ -479,8 +473,7 @@ "node_modules/@babel/core/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/@babel/eslint-parser": { "version": "7.17.0", @@ -585,7 +578,6 @@ "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.22.9", "@babel/helper-validator-option": "^7.22.15", @@ -601,7 +593,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "dependencies": { "yallist": "^3.0.2" } @@ -609,21 +600,20 @@ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", - "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", + "version": "7.23.10", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz", + "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -727,7 +717,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", @@ -758,7 +747,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -801,7 +789,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -852,7 +839,6 @@ "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -875,7 +861,6 @@ "version": "7.23.2", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", - "dev": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/traverse": "^7.23.2", @@ -1214,12 +1199,11 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1331,12 +1315,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.10.tgz", - "integrity": "sha512-xJefea1DWXW09pW4Tm9bjwVlPDyYA2it3fWlmEjpYz6alPvTUjL0EOzNzI/FEOyI3r4/J7uVH5UqKgl1TQ5hqQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1734,12 +1718,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", - "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -2172,14 +2156,15 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", - "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", + "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-typescript": "^7.16.7" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" }, "engines": { "node": ">=6.9.0" @@ -2435,14 +2420,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", - "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.16.7" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" }, "engines": { "node": ">=6.9.0" @@ -2600,9 +2587,9 @@ } }, "node_modules/@dnd-kit/accessibility": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz", - "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.0.tgz", + "integrity": "sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==", "dev": true, "dependencies": { "tslib": "^2.0.0" @@ -2612,13 +2599,13 @@ } }, "node_modules/@dnd-kit/core": { - "version": "6.0.8", - "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.8.tgz", - "integrity": "sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.1.0.tgz", + "integrity": "sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==", "dev": true, "dependencies": { - "@dnd-kit/accessibility": "^3.0.0", - "@dnd-kit/utilities": "^3.2.1", + "@dnd-kit/accessibility": "^3.1.0", + "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { @@ -2627,37 +2614,37 @@ } }, "node_modules/@dnd-kit/modifiers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-6.0.1.tgz", - "integrity": "sha512-rbxcsg3HhzlcMHVHWDuh9LCjpOVAgqbV78wLGI8tziXY3+qcMQ61qVXIvNKQFuhj75dSfD+o+PYZQ/NUk2A23A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-7.0.0.tgz", + "integrity": "sha512-BG/ETy3eBjFap7+zIti53f0PCLGDzNXyTmn6fSdrudORf+OH04MxrW4p5+mPu4mgMk9kM41iYONjc3DOUWTcfg==", "dev": true, "dependencies": { - "@dnd-kit/utilities": "^3.2.1", + "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { - "@dnd-kit/core": "^6.0.6", + "@dnd-kit/core": "^6.1.0", "react": ">=16.8.0" } }, "node_modules/@dnd-kit/sortable": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-7.0.2.tgz", - "integrity": "sha512-wDkBHHf9iCi1veM834Gbk1429bd4lHX4RpAwT0y2cHLf246GAvU2sVw/oxWNpPKQNQRQaeGXhAVgrOl1IT+iyA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-8.0.0.tgz", + "integrity": "sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==", "dev": true, "dependencies": { - "@dnd-kit/utilities": "^3.2.0", + "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { - "@dnd-kit/core": "^6.0.7", + "@dnd-kit/core": "^6.1.0", "react": ">=16.8.0" } }, "node_modules/@dnd-kit/utilities": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.1.tgz", - "integrity": "sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", "dev": true, "dependencies": { "tslib": "^2.0.0" @@ -2795,15 +2782,15 @@ "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" }, "node_modules/@emotion/react": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", - "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "version": "11.11.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.3.tgz", + "integrity": "sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==", "dev": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.2", + "@emotion/serialize": "^1.1.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", "@emotion/utils": "^1.2.1", "@emotion/weak-memoize": "^0.3.1", @@ -2819,9 +2806,9 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", - "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", "dev": true, "dependencies": { "@emotion/hash": "^0.9.1", @@ -2880,6 +2867,336 @@ "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==", "dev": true }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -3052,28 +3369,28 @@ ] }, "node_modules/@floating-ui/core": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", - "integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", "dev": true, "dependencies": { - "@floating-ui/utils": "^0.1.1" + "@floating-ui/utils": "^0.2.1" } }, "node_modules/@floating-ui/dom": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.2.tgz", - "integrity": "sha512-6ArmenS6qJEWmwzczWyhvrXRdI/rI78poBcW0h/456+onlabit+2G+QxHx5xTOX60NBJQXjsCLFbW2CmsXpUog==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.1.tgz", + "integrity": "sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==", "dev": true, "dependencies": { - "@floating-ui/core": "^1.4.1", - "@floating-ui/utils": "^0.1.1" + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.1" } }, "node_modules/@floating-ui/utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.2.tgz", - "integrity": "sha512-ou3elfqG/hZsbmF4bxeJhPHIf3G2pm0ujc39hYEZrfVqt7Vk/Zji6CXc3W0pmYM8BW1g40U+akTl9DKZhFhInQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==", "dev": true }, "node_modules/@fluent/syntax": { @@ -3237,19 +3554,6 @@ "react-hook-form": "^7.0.0" } }, - "node_modules/@hot-loader/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/@hot-loader/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-G2RZrFhsQClS+bdDh/Ojpk3SgocLPUGnvnJDTQYnmKSSwXtU+Yh+8QMs+Ia3zaAvBiOSpIIDSUxuN69cvKqrWg==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - }, - "peerDependencies": { - "react": "17.0.2" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -4192,7 +4496,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -4638,25 +4941,6 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true }, - "node_modules/@redux-devtools/chart-monitor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/chart-monitor/-/chart-monitor-4.0.0.tgz", - "integrity": "sha512-ZxcYQ5JKs3HGS4AO5fYFN5OKPQ8w41uTRA6fU15Wf5qqv6oHDmDycgTlx2KHNDxVBS0QXa7PS83qiwL1SmGZrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.6", - "@types/redux-devtools-themes": "^1.0.0", - "d3-state-visualizer": "^2.0.0", - "deepmerge": "^4.2.2", - "redux-devtools-themes": "^1.0.0" - }, - "peerDependencies": { - "@redux-devtools/core": "^3.13.1", - "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "redux": "^3.4.0 || ^4.0.0" - } - }, "node_modules/@redux-devtools/cli": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@redux-devtools/cli/-/cli-3.0.1.tgz", @@ -4695,10 +4979,46 @@ "node": "^16.13.0 || >= 18.12.0" } }, + "node_modules/@redux-devtools/cli/node_modules/@babel/code-frame": { + "version": "8.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.0-alpha.6.tgz", + "integrity": "sha512-w29LUiFqVMe+Ybp/+xtQKAp6rpxjHxtCW909I0OMHvFKzrGB0K+1yQGRzXhTqrd4f7ZRRgzkAxdr0EOEbHt3dA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^8.0.0-alpha.6", + "chalk": "^5.3.0" + }, + "engines": { + "node": "^16.20.0 || ^18.16.0 || >=20.0.0" + } + }, + "node_modules/@redux-devtools/cli/node_modules/@babel/helper-validator-identifier": { + "version": "8.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.0-alpha.6.tgz", + "integrity": "sha512-a0YnAx4TJCgds07M2v0A3WeyZUfls2YOgNHCb1akGKlz5KdmTCqf2N2hw86YhjY6oDqb6Omb8gFKz/3TOKRevQ==", + "dev": true, + "engines": { + "node": "^16.20.0 || ^18.16.0 || >=20.0.0" + } + }, + "node_modules/@redux-devtools/cli/node_modules/@babel/highlight": { + "version": "8.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-8.0.0-alpha.6.tgz", + "integrity": "sha512-YzJ5blZXak7Gk6ZgV9a4B9bAkGzl594ZxmBaFFZkstA5hE1iOBTlUW4tkGKz2uomL7FLLW4qHJF3QjQLHKi7iw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^8.0.0-alpha.6", + "chalk": "^5.3.0", + "js-tokens": "^8.0.0" + }, + "engines": { + "node": "^16.20.0 || ^18.16.0 || >=20.0.0" + } + }, "node_modules/@redux-devtools/cli/node_modules/@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -4747,42 +5067,211 @@ "styled-components": "^5.3.11" } }, + "node_modules/@redux-devtools/cli/node_modules/@redux-devtools/chart-monitor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/chart-monitor/-/chart-monitor-4.1.0.tgz", + "integrity": "sha512-fdW7DKEhCB9oumMTyhdrVGOgb/6lBioPveW3w0+u7MCZn2i32laZYzU9VT39sx+Fc2kwxzbYsLxFsU0tijGsXA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "@types/redux-devtools-themes": "^1.0.3", + "d3-state-visualizer": "^2.0.0", + "deepmerge": "^4.3.1", + "redux-devtools-themes": "^1.0.0" + }, + "peerDependencies": { + "@redux-devtools/core": "^3.0.0", + "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "redux": "^3.4.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@redux-devtools/cli/node_modules/@redux-devtools/core": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/core/-/core-3.14.0.tgz", + "integrity": "sha512-OMPflPPCXR9L1rpfd7gwY31/EuqPyE9Of/5wZgDDzeisaENY5h/EfnAjnHRKr7NIx/yUIUX2DJs8NpmUOnANMg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "@redux-devtools/instrument": "^2.2.0", + "@types/prop-types": "^15.7.10", + "lodash": "^4.17.21", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^0.14.9 || ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-redux": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "redux": "^3.5.2 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@redux-devtools/cli/node_modules/@redux-devtools/inspector-monitor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor/-/inspector-monitor-4.1.0.tgz", + "integrity": "sha512-ga0rBdb8LeB7mN+X+/Pb0rx+yTPOsSHFFVxgcWag7XsBu+dXtujlRsCM++6LX6GjJGNzZAUsG4ZI4Wt0dG2CQg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/modifiers": "^7.0.0", + "@dnd-kit/sortable": "^8.0.0", + "@dnd-kit/utilities": "^3.2.2", + "@types/lodash": "^4.14.201", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "dateformat": "^5.0.3", + "hex-rgba": "^1.0.2", + "immutable": "^4.3.4", + "javascript-stringify": "^2.1.0", + "jsondiffpatch": "^0.5.0", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0", + "lodash.debounce": "^4.0.8", + "prop-types": "^15.8.1", + "react-base16-styling": "^0.9.1", + "react-json-tree": "^0.18.0", + "redux-devtools-themes": "^1.0.0" + }, + "peerDependencies": { + "@redux-devtools/core": "^3.0.0", + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "redux": "^3.4.0 || ^4.0.0 || ^5.0.0" + } + }, "node_modules/@redux-devtools/cli/node_modules/@redux-devtools/inspector-monitor-test-tab": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor-test-tab/-/inspector-monitor-test-tab-2.0.0.tgz", - "integrity": "sha512-6hi7WqUc/pGO7UtdwCnQngSdijsxG34Ou00/Wuu/yyZfw8WU7jib21LVRiSpo8UFwSeSGkc4YYKgGmS+NpAW0A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor-test-tab/-/inspector-monitor-test-tab-2.1.0.tgz", + "integrity": "sha512-wQ8dnB1F7RZn4XFoKYVPUPt996CIGWG1/ndQwGkXPvHg+P32QHUHsrhR+QDpn6Z1dMamycDjqijS2KDkQA/MDg==", "dev": true, "dependencies": { - "@babel/runtime": "^7.22.10", - "@redux-devtools/ui": "^1.3.0", - "@types/prop-types": "^15.7.5", + "@babel/runtime": "^7.23.2", + "@redux-devtools/ui": "^1.3.1", + "@types/prop-types": "^15.7.10", "es6template": "^1.0.5", "javascript-stringify": "^2.1.0", "jsan": "^3.1.14", "object-path": "^0.11.8", "prop-types": "^15.8.1", - "react-icons": "^4.10.1", - "simple-diff": "^1.7.1" + "react-icons": "^4.11.0", + "simple-diff": "^1.7.2" }, "peerDependencies": { "@redux-devtools/inspector-monitor": "^4.0.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.26", + "@types/styled-components": "^5.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "redux": "^3.4.0 || ^4.0.0", - "styled-components": "^5.3.11" + "redux": "^3.4.0 || ^4.0.0 || ^5.0.0", + "styled-components": "^5.0.0" } }, - "node_modules/@redux-devtools/cli/node_modules/@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", + "node_modules/@redux-devtools/cli/node_modules/@redux-devtools/inspector-monitor-trace-tab": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor-trace-tab/-/inspector-monitor-trace-tab-2.1.0.tgz", + "integrity": "sha512-Sac8iyYahyrq3k76kty1ebMVCp7Q1ABdBdzj8vJ5FSiaXOKU+HY1y4YS6Fb9ra7Bj5udIqzr/zdxprdPc7Yatg==", "dev": true, "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "@babel/code-frame": "^8.0.0-alpha.4", + "@babel/runtime": "^7.23.2", + "@types/chrome": "^0.0.251", + "anser": "^2.1.1", + "html-entities": "^2.4.0", + "path-browserify": "^1.0.1", + "redux-devtools-themes": "^1.0.0", + "source-map": "^0.5.7" + }, + "peerDependencies": { + "@redux-devtools/inspector-monitor": "^4.0.0", + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "redux": "^3.4.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@redux-devtools/cli/node_modules/@redux-devtools/log-monitor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/log-monitor/-/log-monitor-4.1.0.tgz", + "integrity": "sha512-2danca7yfQnuyzYxUVsEontmcRfQLFZgU8M33690JfvHlUV1OYjkNhbwKkMEso5py8sTd2EgoC2PGySoyupbUg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "@types/lodash.debounce": "^4.0.9", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "lodash.debounce": "^4.0.8", + "prop-types": "^15.8.1", + "react-json-tree": "^0.18.0", + "redux-devtools-themes": "^1.0.0" + }, + "peerDependencies": { + "@redux-devtools/core": "^3.0.0", + "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "redux": "^3.4.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@redux-devtools/cli/node_modules/@redux-devtools/rtk-query-monitor": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/rtk-query-monitor/-/rtk-query-monitor-3.2.0.tgz", + "integrity": "sha512-Td7oZUAO/TyxillkC2E33vYqfKEDFilJfLHLg8Na7KdfG3Y0JR5qmu0xypZDODeEsA5teHpkMnhI3O9ew/JqdQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "@redux-devtools/ui": "^1.3.1", + "@types/lodash": "^4.14.201", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "hex-rgba": "^1.0.2", + "immutable": "^4.3.4", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0", + "lodash.debounce": "^4.0.8", + "prop-types": "^15.8.1", + "react-base16-styling": "^0.9.1", + "react-json-tree": "^0.18.0", + "redux-devtools-themes": "^1.0.0" + }, + "peerDependencies": { + "@redux-devtools/core": "^3.0.0", + "@reduxjs/toolkit": "^1.0.0 || ^2.0.0", + "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "@types/styled-components": "^5.0.0", + "react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "redux": "^3.4.0 || ^4.0.0 || ^5.0.0", + "styled-components": "^5.0.0" + } + }, + "node_modules/@redux-devtools/cli/node_modules/@redux-devtools/slider-monitor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/slider-monitor/-/slider-monitor-4.1.0.tgz", + "integrity": "sha512-p0jDgLcmuOQyJTlMAwjSZ8wxioqV802IXtm7BsxGq9021WsmyhEGRhqfu4XvXUt95sBHNsRsm9yE5XVTMmlAtw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "@redux-devtools/ui": "^1.3.1", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "prop-types": "^15.8.1", + "redux-devtools-themes": "^1.0.0" + }, + "peerDependencies": { + "@redux-devtools/core": "^3.0.0", + "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "@types/styled-components": "^5.0.0", + "react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "redux": "^3.4.0 || ^4.0.0 || ^5.0.0", + "styled-components": "^5.0.0" + } + }, + "node_modules/@redux-devtools/cli/node_modules/@types/chrome": { + "version": "0.0.251", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.251.tgz", + "integrity": "sha512-UF+yr0LEKWWGsKxQ5A3XOSF5SNoU1ctW3pXcWJPpT8OOUTEspYeaLU8spDKe+6xalXeMTS0TBrX1g0b6qlWmkw==", + "dev": true, + "dependencies": { + "@types/filesystem": "*", + "@types/har-format": "*" } }, "node_modules/@redux-devtools/cli/node_modules/body-parser": { @@ -4851,6 +5340,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@redux-devtools/cli/node_modules/js-tokens": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", + "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "dev": true + }, "node_modules/@redux-devtools/cli/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -4890,31 +5385,6 @@ "node": ">= 0.8" } }, - "node_modules/@redux-devtools/cli/node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@redux-devtools/cli/node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, "node_modules/@redux-devtools/cli/node_modules/react-redux": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz", @@ -4966,15 +5436,6 @@ "integrity": "sha512-MgUIvuca+90fBrCWY5LdlU9YUWjlkPFwdpvmomcwQEu3t2id/6YHdG2nhB6o7nhRp4ocfmcXQTh00r/tJtynSg==", "dev": true }, - "node_modules/@redux-devtools/cli/node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - } - }, "node_modules/@redux-devtools/cli/node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -5084,121 +5545,56 @@ } }, "node_modules/@redux-devtools/core": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@redux-devtools/core/-/core-3.13.1.tgz", - "integrity": "sha512-VZbma4b28D7dLn6rKTxx4r1KJrgiT2EQNF4vjkpTlXTu0cQcHkEcAO9ixMBj6rZGrT/jinCHq8gBy2bWgnDvcA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.3", - "@redux-devtools/instrument": "^2.1.0", - "@types/prop-types": "^15.7.5", - "lodash": "^4.17.21", - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "react": "^0.14.9 || ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", - "react-redux": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "redux": "^3.5.2 || ^4.0.0" - } - }, - "node_modules/@redux-devtools/inspector-monitor": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor/-/inspector-monitor-4.0.0.tgz", - "integrity": "sha512-P0xXjv/N02dPQAaa+fSY2de6adFP+QdGaJZN+raWbWAoIB4SMYuxOlsEBWdclbTTpFBqYp0azpLTfy1vJroRPg==", + "resolved": "https://registry.npmjs.org/@redux-devtools/core/-/core-4.0.0.tgz", + "integrity": "sha512-9smPIgjVxSwCmA35SOwy/ZmlVdKfrdWQHxZdBeXw3G4u+guCl7hBLaOqqUhgceKdsX0IkdIr0v5TLpm2gQT2oQ==", "dev": true, "dependencies": { - "@babel/runtime": "^7.22.10", - "@dnd-kit/core": "^6.0.8", - "@dnd-kit/modifiers": "^6.0.1", - "@dnd-kit/sortable": "^7.0.2", - "@dnd-kit/utilities": "^3.2.1", - "@types/lodash": "^4.14.197", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "dateformat": "^5.0.3", - "hex-rgba": "^1.0.2", - "immutable": "^4.3.2", - "javascript-stringify": "^2.1.0", - "jsondiffpatch": "^0.5.0", - "jss": "^10.10.0", - "jss-preset-default": "^10.10.0", - "lodash.debounce": "^4.0.8", - "prop-types": "^15.8.1", - "react-base16-styling": "^0.9.1", - "react-json-tree": "^0.18.0", - "redux-devtools-themes": "^1.0.0" - }, - "peerDependencies": { - "@redux-devtools/core": "^3.13.1", - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "redux": "^3.4.0 || ^4.0.0" - } - }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor-trace-tab/-/inspector-monitor-trace-tab-2.0.0.tgz", - "integrity": "sha512-F5yS0cWZqcxNekZ+63HvJJ8S6uoY045uEJHA/IjuffHpZcTfZJoqs0uBAzPrg+y+TlUyGQ8hlT6H+sSJS1KHdA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^8.0.0-alpha.2", - "@babel/runtime": "^7.22.10", - "@types/chrome": "^0.0.243", - "anser": "^2.1.1", - "html-entities": "^2.4.0", - "path-browserify": "^1.0.1", - "redux-devtools-themes": "^1.0.0", - "source-map": "^0.5.7" + "@babel/runtime": "^7.23.5", + "@redux-devtools/instrument": "^2.2.0", + "lodash": "^4.17.21" }, "peerDependencies": { - "@redux-devtools/inspector-monitor": "^4.0.0", - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "redux": "^3.4.0 || ^4.0.0" + "react": "^16.8.4 || ^17.0.0 || ^18.0.0", + "react-redux": "^7.0.0 || ^8.0.0 || ^9.0.0", + "redux": "^3.5.2 || ^4.0.0 || ^5.0.0" } }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/@babel/code-frame": { - "version": "8.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.0-alpha.2.tgz", - "integrity": "sha512-uM1On1MxYaZDFVq1gPbGJx1Rf0N+lwlPOCBHZPS8RNVfP9CAG05xzViguK45e16n4Wo6V3WfaTkdmbuNusBnJQ==", + "node_modules/@redux-devtools/core/node_modules/@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", "dev": true, "dependencies": { - "@babel/highlight": "^8.0.0-alpha.2", - "chalk": "^4.1.2" + "regenerator-runtime": "^0.14.0" }, "engines": { - "node": "^16.20.0 || ^18.16.0 || >=20.0.0" + "node": ">=6.9.0" } }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/@babel/helper-validator-identifier": { - "version": "8.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.0-alpha.2.tgz", - "integrity": "sha512-us66RLKkCzBzNJ1TVAHe2euihYrYaXxbuQ7yJogKdBKBZ0R7gHEpB+e0ylaMGsmLzqlpPUyWWcz3OPTCsq1FDw==", - "dev": true, - "engines": { - "node": "^16.20.0 || ^18.16.0 || >=20.0.0" - } + "node_modules/@redux-devtools/core/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/@babel/highlight": { - "version": "8.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-8.0.0-alpha.2.tgz", - "integrity": "sha512-V+G3EzQx895Dqbu4xroJo6kMLK6YQJLrMLGj2zjJShA5HNuBCTGgwBhL1BA8jixOfFA5/110QoCugKC39oWB8w==", + "node_modules/@redux-devtools/instrument": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/instrument/-/instrument-2.2.0.tgz", + "integrity": "sha512-HKaL+ghBQ4ZQkM/kEQIKx8dNwz4E1oeiCDfdQlpPXxEi/BrisyrFFncAXb1y2HIJsLV9zSvQUR2jRtMDWgfi8w==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^8.0.0-alpha.2", - "chalk": "^4.1.2", - "js-tokens": "^8.0.0" + "@babel/runtime": "^7.23.2", + "lodash": "^4.17.21" }, - "engines": { - "node": "^16.20.0 || ^18.16.0 || >=20.0.0" + "peerDependencies": { + "redux": "^3.4.0 || ^4.0.0 || ^5.0.0" } }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "node_modules/@redux-devtools/instrument/node_modules/@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -5207,277 +5603,233 @@ "node": ">=6.9.0" } }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/@types/chrome": { - "version": "0.0.243", - "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.243.tgz", - "integrity": "sha512-4PHv0kxxxpZFHWPBiJJ9TWH8kbx0567j1b2djnhpJjpiSGNI7UKkz7dSEECBtQ0B3N5nQTMwSB/5IopkWGAbEA==", - "dev": true, - "dependencies": { - "@types/filesystem": "*", - "@types/har-format": "*" - } - }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } + "node_modules/@redux-devtools/instrument/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@redux-devtools/remote": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@redux-devtools/remote/-/remote-0.9.1.tgz", + "integrity": "sha512-MvPs4wGVBOj0iOtSKYpNTg5d5SEJPT8e5q88KWMISVptazKMQL0JgQ2TrwPdKccNG0EjjuCDeOONCl09hcLqsQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" + "@babel/runtime": "^7.23.5", + "@redux-devtools/instrument": "^2.2.0", + "@redux-devtools/utils": "^3.0.0", + "jsan": "^3.1.14", + "querystring": "^0.2.1", + "rn-host-detect": "^1.2.0", + "socketcluster-client": "^17.2.2" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "redux": "^3.5.2 || ^4.0.0 || ^5.0.0" } }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@redux-devtools/remote/node_modules/@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "regenerator-runtime": "^0.14.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=6.9.0" } }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/@redux-devtools/remote/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/has-flag": { + "node_modules/@redux-devtools/remote/node_modules/sc-formatter": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/js-tokens": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.2.tgz", - "integrity": "sha512-Olnt+V7xYdvGze9YTbGFZIfQXuGV4R3nQwwl8BrtgaPE/wq8UFpUHWuTNc05saowhSr1ZO6tx+V6RjE9D5YQog==", - "dev": true - }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-4.0.0.tgz", + "integrity": "sha512-MgUIvuca+90fBrCWY5LdlU9YUWjlkPFwdpvmomcwQEu3t2id/6YHdG2nhB6o7nhRp4ocfmcXQTh00r/tJtynSg==", "dev": true }, - "node_modules/@redux-devtools/inspector-monitor-trace-tab/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@redux-devtools/remote/node_modules/socketcluster-client": { + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-17.2.2.tgz", + "integrity": "sha512-HIopjTj8p979N5klC7FeZSwu9rd805bFgFcyVX7Y8zPyjVHXHTfGrV/8vqzN2gpOwnnosWQ44ue0qGqovlxZrg==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "ag-channel": "^5.0.0", + "ag-request": "^1.0.0", + "async-stream-emitter": "^4.0.0", + "buffer": "^5.2.1", + "clone-deep": "^4.0.1", + "linked-list": "^0.1.0", + "sc-errors": "^2.0.1", + "sc-formatter": "^4.0.0", + "stream-demux": "^8.0.0", + "uuid": "^8.3.2", + "vinyl-buffer": "^1.0.1", + "ws": "^8.9.0" } }, - "node_modules/@redux-devtools/inspector-monitor/node_modules/@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "node_modules/@redux-devtools/remote/node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@redux-devtools/inspector-monitor/node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", - "dev": true - }, - "node_modules/@redux-devtools/instrument": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/instrument/-/instrument-2.1.0.tgz", - "integrity": "sha512-e8fo88kuq/zWqfNf6S/GNfaQMjF4WSPpucmYfRhzZyyXHC3PCLd/xgz7zooPErDh9QwUXK6sTVYvrkq7hPbsFA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.7", - "lodash": "^4.17.21" + "node": ">=10.0.0" }, "peerDependencies": { - "redux": "^3.4.0 || ^4.0.0" - } - }, - "node_modules/@redux-devtools/log-monitor": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@redux-devtools/log-monitor/-/log-monitor-4.0.2.tgz", - "integrity": "sha512-BaTAwadm/XzRfnN2+8t4mwdbOILWfwsvMfVPn5OuE+NFaUG9pDKGoHRPCdMBaRdggDqqb5nlMgRCVdHzYftgVw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.6", - "@types/lodash.debounce": "^4.0.7", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "lodash.debounce": "^4.0.8", - "prop-types": "^15.8.1", - "react-json-tree": "^0.18.0", - "redux-devtools-themes": "^1.0.0" + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" }, - "peerDependencies": { - "@redux-devtools/core": "^3.13.1", - "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "redux": "^3.4.0 || ^4.0.0" + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/@redux-devtools/rtk-query-monitor": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@redux-devtools/rtk-query-monitor/-/rtk-query-monitor-3.1.1.tgz", - "integrity": "sha512-A7kHvU0SY6iQeaLHq+Kcq8a4Z/NhLcwQ/DluP/E+6UU/OXbEtoPK7304qdFQtVG7HY7owdKQiJZrYns5Mi7ysw==", + "node_modules/@redux-devtools/serialize": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@redux-devtools/serialize/-/serialize-0.4.2.tgz", + "integrity": "sha512-YVqZCChJld5l3Ni2psEZ5loe9x5xpf9J4ckz+7OJdzCNsplC7vzjnkQbFxE6+ULZbywRVp+nSBslTXmaXqAw4A==", "dev": true, "dependencies": { - "@babel/runtime": "^7.20.6", - "@redux-devtools/ui": "^1.3.0", - "@types/lodash": "^4.14.191", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "hex-rgba": "^1.0.2", - "immutable": "^4.1.0", - "jss": "^10.9.2", - "jss-preset-default": "^10.9.2", - "lodash.debounce": "^4.0.8", - "prop-types": "^15.8.1", - "react-base16-styling": "^0.9.1", - "react-json-tree": "^0.18.0", - "redux-devtools-themes": "^1.0.0" + "@babel/runtime": "^7.23.2", + "jsan": "^3.1.14" }, "peerDependencies": { - "@redux-devtools/core": "^3.13.1", - "@reduxjs/toolkit": "^1.9.1", - "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.26", - "react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "redux": "^3.4.0 || ^4.0.0", - "styled-components": "^5.3.6" + "immutable": "^4.0.0" } }, - "node_modules/@redux-devtools/slider-monitor": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@redux-devtools/slider-monitor/-/slider-monitor-4.0.1.tgz", - "integrity": "sha512-pjHPYLG91GLRQVcNAIu3Colc6nIqR4mSQYN1MWUqP8nTAlkP1ihEN44KXxcnTUEzuSLRYm1YW3jsI5p4q3aXZA==", + "node_modules/@redux-devtools/serialize/node_modules/@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", "dev": true, "dependencies": { - "@babel/runtime": "^7.18.3", - "@redux-devtools/ui": "^1.3.0", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "prop-types": "^15.8.1", - "redux-devtools-themes": "^1.0.0" + "regenerator-runtime": "^0.14.0" }, - "peerDependencies": { - "@redux-devtools/core": "^3.13.1", - "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.25", - "react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "redux": "^3.4.0 || ^4.0.0", - "styled-components": "^5.3.5" + "engines": { + "node": ">=6.9.0" } }, + "node_modules/@redux-devtools/serialize/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, "node_modules/@redux-devtools/ui": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/ui/-/ui-1.3.0.tgz", - "integrity": "sha512-fj4zyQ08U2DnJAGL7xa1mqlQnBMbrlS1P/HI10Wz57+dgqP9fIzfKymtLEGOnJHZNkPpPNXG04FH4+AQQ1v3kw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.3", - "@rjsf/core": "^4.2.0", - "@types/base16": "^1.0.2", - "@types/codemirror": "^5.60.5", - "@types/json-schema": "^7.0.11", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "@types/simple-element-resize-detector": "^1.3.0", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@redux-devtools/ui/-/ui-1.3.1.tgz", + "integrity": "sha512-qtfau1zSmv6nSUrnesuxaos1V7r89HQV2Hq/thcRcyHd0Y0OYgpQlnwEK3wkK1esLU2BhEUUb85DC8IdJ3l6Sg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "@rjsf/core": "^4.2.3", + "@types/base16": "^1.0.5", + "@types/codemirror": "^5.60.13", + "@types/json-schema": "^7.0.15", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "@types/simple-element-resize-detector": "^1.3.3", "base16": "^1.0.0", - "codemirror": "^5.65.4", + "codemirror": "^5.65.15", "color": "^4.2.3", "prop-types": "^15.8.1", - "react-icons": "^4.3.1", - "react-select": "^5.3.2", + "react-icons": "^4.11.0", + "react-select": "^5.8.0", "redux-devtools-themes": "^1.0.0", "simple-element-resize-detector": "^1.3.0" }, "peerDependencies": { "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.25", + "@types/styled-components": "^5.0.0", "react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "styled-components": "^5.3.5" + "styled-components": "^5.0.0" } }, - "node_modules/@redux-devtools/ui/node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "node_modules/@redux-devtools/ui/node_modules/@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@redux-devtools/ui/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true }, - "node_modules/@redux-devtools/ui/node_modules/react-select": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.4.tgz", - "integrity": "sha512-NhuE56X+p9QDFh4BgeygHFIvJJszO1i1KSkg/JPcIJrbovyRtI+GuOEa4XzFCEpZRAEoEI8u/cAHK+jG/PgUzQ==", + "node_modules/@redux-devtools/utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/utils/-/utils-3.0.0.tgz", + "integrity": "sha512-m1AJoxQffm1/6m0qrkb7gW0FkmaAoi1/HJzmdkchAeA8sAJhzGOnXJEpsjmXPt5BIHxg0zsglA+5FsgGWXa97A==", "dev": true, "dependencies": { - "@babel/runtime": "^7.12.0", - "@emotion/cache": "^11.4.0", - "@emotion/react": "^11.8.1", - "@floating-ui/dom": "^1.0.1", - "@types/react-transition-group": "^4.4.0", - "memoize-one": "^6.0.0", - "prop-types": "^15.6.0", - "react-transition-group": "^4.3.0", - "use-isomorphic-layout-effect": "^1.1.2" + "@babel/runtime": "^7.23.5", + "@redux-devtools/core": "^4.0.0", + "@redux-devtools/serialize": "^0.4.2", + "@types/get-params": "^0.1.2", + "get-params": "^0.1.2", + "immutable": "^4.3.4", + "jsan": "^3.1.14", + "lodash": "^4.17.21", + "nanoid": "^5.0.4", + "redux": "^4.2.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@redux-devtools/core": "^4.0.0", + "immutable": "^4.3.4", + "redux": "^4.0.0 || ^5.0.0" } }, - "node_modules/@redux-devtools/ui/node_modules/react-select/node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "node_modules/@redux-devtools/utils/node_modules/@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", "dev": true, "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" + "regenerator-runtime": "^0.14.0" }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" + "engines": { + "node": ">=6.9.0" } }, + "node_modules/@redux-devtools/utils/node_modules/nanoid": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.4.tgz", + "integrity": "sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@redux-devtools/utils/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, "node_modules/@redux-saga/core": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.2.3.tgz", @@ -5530,13 +5882,13 @@ "integrity": "sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA==" }, "node_modules/@reduxjs/toolkit": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz", - "integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==", + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", + "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", "dev": true, "dependencies": { "immer": "^9.0.21", - "redux": "4.2.1", + "redux": "^4.2.1", "redux-thunk": "^2.4.2", "reselect": "^4.1.8" }, @@ -5685,22 +6037,22 @@ } }, "node_modules/@testing-library/dom": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", - "integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", + "lz-string": "^1.5.0", "pretty-format": "^27.0.2" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/@testing-library/dom/node_modules/ansi-styles": { @@ -5718,6 +6070,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, "node_modules/@testing-library/dom/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5774,25 +6135,48 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "5.16.5", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", - "integrity": "sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz", + "integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==", "dev": true, "dependencies": { - "@adobe/css-tools": "^4.0.1", + "@adobe/css-tools": "^4.3.2", "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", + "dom-accessibility-api": "^0.6.3", "lodash": "^4.17.15", "redent": "^3.0.0" }, "engines": { - "node": ">=8", + "node": ">=14", "npm": ">=6", "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/bun": "latest", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/bun": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } } }, "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { @@ -5841,6 +6225,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, "node_modules/@testing-library/jest-dom/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5863,62 +6253,30 @@ } }, "node_modules/@testing-library/react": { - "version": "12.1.5", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", - "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.2.1.tgz", + "integrity": "sha512-sGdjws32ai5TLerhvzThYFbpnF9XtL65Cjf+gB0Dhr29BGqK+mAeN7SURSdu+eqgET4ANcWoC7FQpkaiGvBr+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.0.0", - "@types/react-dom": "<18.0.0" + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" }, "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "<18.0.0", - "react-dom": "<18.0.0" - } - }, - "node_modules/@testing-library/react-hooks": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz", - "integrity": "sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5", - "@types/react": ">=16.9.0", - "@types/react-dom": ">=16.9.0", - "@types/react-test-renderer": ">=16.9.0", - "react-error-boundary": "^3.1.0" - }, - "engines": { - "node": ">=12" + "node": ">=14" }, "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0", - "react-test-renderer": ">=16.9.0" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-test-renderer": { - "optional": true - } + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5" - }, "engines": { - "node": ">=10", + "node": ">=12", "npm": ">=6" }, "peerDependencies": { @@ -6079,9 +6437,9 @@ "integrity": "sha512-PZffP/CqH9m2kovDSRQMfMMxUC3V98I7i7/caa0RB0/nvsXzYbL9bKyqZpNMFmLFGZslROlG1R60ONt7abrwlA==" }, "node_modules/@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true }, "node_modules/@types/babel__core": { @@ -6126,9 +6484,9 @@ } }, "node_modules/@types/base16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.2.tgz", - "integrity": "sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.5.tgz", + "integrity": "sha512-OzOWrTluG9cwqidEzC/Q6FAmIPcnZfm8BFRlIx0+UIUqnuAmi5OS88O0RpT3Yz6qdmqObvUhasrbNsCofE4W9A==", "dev": true }, "node_modules/@types/big.js": { @@ -6187,9 +6545,9 @@ } }, "node_modules/@types/codemirror": { - "version": "5.60.10", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.10.tgz", - "integrity": "sha512-ZTA3teiCWKT8HUUofqlGPlShu5ojdIajizsS0HpH6GL0/iEdjRt7fXbCLHHqKYP5k7dC/HnnWIjZAiELUwBdjQ==", + "version": "5.60.15", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", + "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", "dev": true, "dependencies": { "@types/tern": "*" @@ -6556,6 +6914,12 @@ "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==", "dev": true }, + "node_modules/@types/get-params": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/get-params/-/get-params-0.1.2.tgz", + "integrity": "sha512-ujqPyr1UDsOTDngJPV+WFbR0iHT5AfZKlNPMX6XOCnQcMhEqR+r64dVC/nwYCitqjR3DcpWofnOEAInUQmI/eA==", + "dev": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -6673,9 +7037,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/json5": { @@ -6694,14 +7058,14 @@ } }, "node_modules/@types/lodash": { - "version": "4.14.198", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", - "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==" + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==" }, "node_modules/@types/lodash.debounce": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.7.tgz", - "integrity": "sha512-X1T4wMZ+gT000M2/91SYj0d/7JfeNZ9PeeOldSNoE/lunLeQXKvkmIumI29IaKMotU/ln/McOIvgzZcQ/3TrSA==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz", + "integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==", "dev": true, "dependencies": { "@types/lodash": "*" @@ -6722,6 +7086,12 @@ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", "dev": true }, + "node_modules/@types/md5": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.5.tgz", + "integrity": "sha512-/i42wjYNgE6wf0j2bcTX6kuowmdL/6PE4IVitMpm2eYKBUuYCprdcWVK+xEF0gcV6ufMCRhtxmReGfc6hIK7Jw==", + "dev": true + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -6778,9 +7148,9 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/qs": { "version": "6.9.7", @@ -6795,9 +7165,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.45.tgz", - "integrity": "sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg==", + "version": "18.2.55", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.55.tgz", + "integrity": "sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -6805,50 +7175,32 @@ } }, "node_modules/@types/react-dom": { - "version": "17.0.17", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.17.tgz", - "integrity": "sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==", + "version": "18.2.18", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz", + "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==", "devOptional": true, - "dependencies": { - "@types/react": "^17" - } - }, - "node_modules/@types/react-test-renderer": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz", - "integrity": "sha512-C7/5FBJ3g3sqUahguGi03O79b8afNeSD6T8/GU50oQrJCU0bVCCGQHaGKUbg2Ce8VQEEqTw8/HiS6lXHHdgkdQ==", - "dev": true, "dependencies": { "@types/react": "*" } }, "node_modules/@types/react-transition-group": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", - "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "dev": true, "dependencies": { "@types/react": "*" } }, "node_modules/@types/redux-devtools-themes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/redux-devtools-themes/-/redux-devtools-themes-1.0.0.tgz", - "integrity": "sha512-ul3x0MYM5Nzj57Fh9wINyHFne8vZL04RC4nWAUWLYcL105vHoa/oJyopuKOrQmqVmhqmDiL4c9FfLbUmIB7TWQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/redux-devtools-themes/-/redux-devtools-themes-1.0.3.tgz", + "integrity": "sha512-KqiQ2+6VTb1Yn02+ZNQsB0XcoJTu/W4AhnIUaeTnkVFie5YWMoeSpW4IOFYJ2/HJ+wi1kLw+PHDgjZ3t+M6IRw==", "dev": true, "dependencies": { "@types/base16": "*" } }, - "node_modules/@types/remote-redux-devtools": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@types/remote-redux-devtools/-/remote-redux-devtools-0.5.5.tgz", - "integrity": "sha512-Xuya1TegRPAe92+nnEeYpfufE/mtfN99+GH272edaoWohbMA+yP6r+wYqK4sq/fvmoUPtPHtwZR2Mkk+6uHeBQ==", - "dev": true, - "dependencies": { - "redux": "^4.0.0" - } - }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -6899,9 +7251,9 @@ } }, "node_modules/@types/simple-element-resize-detector": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/simple-element-resize-detector/-/simple-element-resize-detector-1.3.0.tgz", - "integrity": "sha512-z89ForrCNg+4uwTHjwBCM9LjcsXYC/4O8u3tSi+82v2LCbfiYFpkjH/qQVkDewFBK6FUG7RRV7jw78EGs2maoQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/simple-element-resize-detector/-/simple-element-resize-detector-1.3.3.tgz", + "integrity": "sha512-igYpe5ApGMB7YGk2ZyyvrT1NwLYG7Q+8d78uskiS3qriHQa1fiFesibFTCDbGWhc9teD7RmGSuh9a1rzzXj9zg==", "dev": true }, "node_modules/@types/sockjs": { @@ -6936,33 +7288,14 @@ "integrity": "sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg==" }, "node_modules/@types/tern": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz", - "integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==", + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", + "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", "dev": true, "dependencies": { "@types/estree": "*" } }, - "node_modules/@types/testing-library__jest-dom": { - "version": "5.14.3", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz", - "integrity": "sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw==", - "dev": true, - "dependencies": { - "@types/jest": "*" - } - }, - "node_modules/@types/testing-library__react": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@types/testing-library__react/-/testing-library__react-10.2.0.tgz", - "integrity": "sha512-KbU7qVfEwml8G5KFxM+xEfentAAVj/SOQSjW0+HqzjPE0cXpt0IpSamfX4jGYCImznDHgQcfXBPajS7HjLZduw==", - "deprecated": "This is a stub types definition. testing-library__react provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "@testing-library/react": "*" - } - }, "node_modules/@types/tough-cookie": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", @@ -8750,9 +9083,9 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", + "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", "dev": true, "engines": { "node": ">= 0.4" @@ -9009,25 +9342,20 @@ } }, "node_modules/babel-plugin-styled-components": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz", - "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11", - "picomatch": "^2.3.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" }, "peerDependencies": { "styled-components": ">= 2" } }, - "node_modules/babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" - }, "node_modules/babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", @@ -9555,7 +9883,6 @@ "version": "4.22.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -9884,12 +10211,17 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", + "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "set-function-length": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9932,7 +10264,6 @@ "version": "1.0.30001547", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -10077,6 +10408,14 @@ "node": ">=6" } }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, "node_modules/cheerio": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", @@ -10536,9 +10875,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.15", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.15.tgz", - "integrity": "sha512-YC4EHbbwQeubZzxLl5G4nlbLc1T21QTrKGaOal/Pkm9dVDMZXMH7+ieSPEOZCtO9I68i8/oteJKOxzHC2zR+0g==", + "version": "5.65.16", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", + "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==", "dev": true }, "node_modules/collect-v8-coverage": { @@ -10682,12 +11021,6 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "node_modules/component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -11108,9 +11441,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.32.2.tgz", - "integrity": "sha512-Y2rxThOuNywTjnX/PgA5vWM6CZ9QB9sz9oGeCixV8MqXZO70z/5SHzf9EeBrEBK0PN36DnEBBu9O/aGWzKuMZQ==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.35.1.tgz", + "integrity": "sha512-zcIdi/CL3MWbBJYo5YCeVAAx+Sy9yJE9I3/u9LkFABwbeaPhTMRWraM8mYFp9jW5Z50hOy7FVzCc8dCrpZqtIQ==", "dev": true, "hasInstallScript": true, "funding": { @@ -11218,6 +11551,14 @@ "node": ">= 8" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, "node_modules/crypto-random-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", @@ -11992,6 +12333,44 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-equal/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -12223,13 +12602,14 @@ } }, "node_modules/define-data-property": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", - "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", + "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", "dependencies": { - "get-intrinsic": "^1.2.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.2", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -12440,11 +12820,6 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -12621,8 +12996,7 @@ "node_modules/electron-to-chromium": { "version": "1.4.551", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.551.tgz", - "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==", - "dev": true + "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==" }, "node_modules/electron/node_modules/@types/node": { "version": "18.18.9", @@ -12669,6 +13043,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, "engines": { "node": ">= 4" } @@ -12833,6 +13208,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/es-iterator-helpers": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", @@ -12937,11 +13346,46 @@ "sliced": "^1.0.1" } }, + "node_modules/esbuild": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -14128,7 +14572,8 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true }, "node_modules/fast-redact": { "version": "3.3.0", @@ -14434,9 +14879,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -14541,7 +14986,6 @@ "version": "11.1.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -14648,9 +15092,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, "node_modules/fs-tree-diff": { @@ -14850,7 +15294,6 @@ "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, "engines": { "node": ">=6.9.0" } @@ -14865,14 +15308,18 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15175,15 +15622,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "node_modules/global-agent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", @@ -15425,6 +15863,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -15450,11 +15889,11 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dependencies": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.2.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15483,12 +15922,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -15528,7 +15967,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -16018,9 +16456,9 @@ "dev": true }, "node_modules/i18next": { - "version": "23.5.1", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.5.1.tgz", - "integrity": "sha512-JelYzcaCoFDaa+Ysbfz2JsGAKkrHiMG6S61+HLBUEIPaF40WMwW9hCPymlQGrP+wWawKxKPuSuD71WZscCsWHg==", + "version": "23.11.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.0.tgz", + "integrity": "sha512-VwFtlgy2LDbY0Qs6VfekIm6mv5/JmSJrtBf4aszl7Vby8+GcBlri0/7dkMZXmzTfiBMPUPBOmYCdQK7K4emkGQ==", "funding": [ { "type": "individual", @@ -16036,17 +16474,33 @@ } ], "dependencies": { - "@babel/runtime": "^7.22.5" + "@babel/runtime": "^7.23.2" } }, "node_modules/i18next-browser-languagedetector": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-6.1.8.tgz", - "integrity": "sha512-Svm+MduCElO0Meqpj1kJAriTC6OhI41VhlT/A0UPjGoPZBhAHIaGE5EfsHlTpgdH09UVX7rcc72pSDDBeKSQQA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.2.1.tgz", + "integrity": "sha512-h/pM34bcH6tbz8WgGXcmWauNpQupCGr25XPp9cZwZInR9XHSjIFDYp1SIok7zSPsTOMxdvuLyu86V+g2Kycnfw==", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-browser-languagedetector/node_modules/@babel/runtime": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", "dependencies": { - "@babel/runtime": "^7.19.0" + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" } }, + "node_modules/i18next-browser-languagedetector/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/i18next-conv": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/i18next-conv/-/i18next-conv-14.0.0.tgz", @@ -16084,29 +16538,31 @@ } }, "node_modules/i18next-http-backend": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.4.1.tgz", - "integrity": "sha512-CZHzFGDvF8zN7ya1W2lHbgLj2ejPUvPD836+vA3eNXc9eKGUM3MSF6SA2TKBXKBZ2cNG3nxzycCXeM6n/46KWQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.0.tgz", + "integrity": "sha512-Z/aQsGZk1gSxt2/DztXk92DuDD20J+rNudT7ZCdTrNOiK8uQppfvdjq9+DFQfpAnFPn3VZS+KQIr1S/W1KxhpQ==", "dependencies": { "cross-fetch": "4.0.0" } }, "node_modules/i18next-parser": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-6.6.0.tgz", - "integrity": "sha512-yA3W6PL+7epCyUFTpUDdztKArfpeGMWRUOnB/4FZRodfXkjCIBcBg728h6b/lrBTbva4OlFjVgv1kCXbvZVRWQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-7.9.0.tgz", + "integrity": "sha512-yrPJhWGsDBx404T4KLMOTkTgAAEuHvjbxee3HnlqFHALWy/3BOY7or69CxsJOomN3wdrwgg8kWtfIUWR1BZ1nw==", "dependencies": { "@babel/runtime": "^7.15.4", "broccoli-plugin": "^4.0.7", "cheerio": "^1.0.0-rc.2", "colors": "1.4.0", - "commander": "~9.4.1", + "commander": "~10.0.0", "concat-stream": "~2.0.0", "eol": "^0.9.1", - "fs-extra": "^10.0.0", + "esbuild": "^0.17.0", + "fs-extra": "^11.1.0", "gulp-sort": "^2.0.0", - "i18next": "^21.2.0", + "i18next": "^22.0.4", "js-yaml": "4.1.0", + "lilconfig": "^2.0.6", "rsvp": "^4.8.2", "sort-keys": "^5.0.0", "through2": "~4.0.2", @@ -16133,30 +16589,17 @@ } }, "node_modules/i18next-parser/node_modules/commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/i18next-parser/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/i18next-parser/node_modules/i18next": { - "version": "21.10.0", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.10.0.tgz", - "integrity": "sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==", + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.5.1.tgz", + "integrity": "sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==", "funding": [ { "type": "individual", @@ -16172,7 +16615,7 @@ } ], "dependencies": { - "@babel/runtime": "^7.17.2" + "@babel/runtime": "^7.20.6" } }, "node_modules/i18next-parser/node_modules/replace-ext": { @@ -16199,9 +16642,9 @@ } }, "node_modules/i18next/node_modules/@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -16210,9 +16653,9 @@ } }, "node_modules/i18next/node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/iconv-lite": { "version": "0.4.24", @@ -16449,9 +16892,9 @@ } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", "dev": true, "optional": true }, @@ -16476,6 +16919,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -20061,7 +20520,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } @@ -20079,12 +20537,12 @@ "dev": true }, "node_modules/linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "dependencies": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" } }, "node_modules/lint-staged": { @@ -20377,6 +20835,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -20390,6 +20849,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, "engines": { "node": "*" } @@ -20664,18 +21124,18 @@ } }, "node_modules/lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "bin": { "lz-string": "bin/bin.js" } }, "node_modules/mac-scrollbar": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/mac-scrollbar/-/mac-scrollbar-0.10.3.tgz", - "integrity": "sha512-+dCARf54JUqeAWhjZE+cMBA9kLLIx1V7LRm3Fh27hAVX9J8ZqpSgXkfioFV218tivVFmusv/xHB1+6SgX0HZgg==" + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/mac-scrollbar/-/mac-scrollbar-0.13.6.tgz", + "integrity": "sha512-P0eNiCTExlmWBQ0FXalfXVh42eo9b0obnZIo1khZzyZX99frTsCmZwcbH0RWZZtNYtBZVd5f/7k4iLPou+skzg==" }, "node_modules/make-dir": { "version": "3.1.0", @@ -20758,25 +21218,26 @@ } }, "node_modules/markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "dependencies": { "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "bin": { - "markdown-it": "bin/markdown-it.js" + "markdown-it": "bin/markdown-it.mjs" } }, "node_modules/markdown-it/node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "engines": { "node": ">=0.12" @@ -20786,15 +21247,19 @@ } }, "node_modules/markdownlint": { - "version": "0.26.2", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", - "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz", + "integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==", "dev": true, "dependencies": { - "markdown-it": "13.0.1" + "markdown-it": "14.1.0", + "markdownlint-micromark": "0.1.9" }, "engines": { - "node": ">=14" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" } }, "node_modules/markdownlint-cli": { @@ -20839,6 +21304,18 @@ "node": "^12.20.0 || >=14" } }, + "node_modules/markdownlint-cli/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/markdownlint-cli/node_modules/glob": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", @@ -20858,6 +21335,49 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/markdownlint-cli/node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/markdownlint-cli/node_modules/markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdownlint-cli/node_modules/markdownlint": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", + "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", + "dev": true, + "dependencies": { + "markdown-it": "13.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/markdownlint-cli/node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "node_modules/markdownlint-cli/node_modules/minimatch": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", @@ -20870,6 +21390,24 @@ "node": ">=10" } }, + "node_modules/markdownlint-cli/node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/markdownlint-micromark": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz", + "integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, "node_modules/markdownlint-rule-helpers": { "version": "0.17.2", "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.2.tgz", @@ -20932,10 +21470,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, "node_modules/media-typer": { @@ -20962,12 +21510,12 @@ } }, "node_modules/memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "dependencies": { - "fs-monkey": "1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -21082,14 +21630,6 @@ "node": ">=4" } }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -21735,8 +22275,7 @@ "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" }, "node_modules/nopt": { "version": "5.0.0", @@ -21852,6 +22391,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -22650,8 +23205,7 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -23053,6 +23607,7 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, "engines": { "node": ">= 0.6.0" } @@ -23224,6 +23779,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pupa": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", @@ -23419,12 +23983,11 @@ } }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" @@ -23456,32 +24019,23 @@ } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.0" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.2.0" } }, - "node_modules/react-error-boundary": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", - "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", - "dev": true, + "node_modules/react-dom/node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "react": ">=16.13.1" + "loose-envify": "^1.1.0" } }, "node_modules/react-fast-compare": { @@ -23512,52 +24066,16 @@ "react": "^16.8.0 || ^17 || ^18" } }, - "node_modules/react-hot-loader": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.13.1.tgz", - "integrity": "sha512-ZlqCfVRqDJmMXTulUGic4lN7Ic1SXgHAFw7y/Jb7t25GBgTR0fYAJ8uY4mrpxjRyWGWmqw77qJQGnYbzCvBU7g==", - "dependencies": { - "fast-levenshtein": "^2.0.6", - "global": "^4.3.0", - "hoist-non-react-statics": "^3.3.0", - "loader-utils": "^2.0.3", - "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4", - "shallowequal": "^1.1.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "@types/react": "^15.0.0 || ^16.0.0 || ^17.0.0", - "react": "^15.0.0 || ^16.0.0 || ^17.0.0", - "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-hot-loader/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, "node_modules/react-i18next": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.0.0.tgz", - "integrity": "sha512-/O7N6aIEAl1FaWZBNvhdIo9itvF/MO/nRKr9pYqRc9LhuC1u21SlfwpiYQqvaeNSEW3g3qUXLREOWMt+gxrWbg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.0.tgz", + "integrity": "sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==", "dependencies": { - "@babel/runtime": "^7.14.5", + "@babel/runtime": "^7.23.9", "html-parse-stringify": "^3.0.1" }, "peerDependencies": { - "i18next": ">= 19.0.0", + "i18next": ">= 23.2.3", "react": ">= 16.8.0" }, "peerDependenciesMeta": { @@ -23569,6 +24087,22 @@ } } }, + "node_modules/react-i18next/node_modules/@babel/runtime": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/react-i18next/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/react-icons": { "version": "4.11.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz", @@ -23578,15 +24112,6 @@ "react": "*" } }, - "node_modules/react-identicons": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/react-identicons/-/react-identicons-1.2.5.tgz", - "integrity": "sha512-x7prkDoc2pD7wSl2C1pGxS+XAoSdq1ABWJWTBUimVTDVJArKOLd0B4wRUJpDm4r+9y7pgf8ylyPGsmlWSV5n2g==", - "peerDependencies": { - "react": "^17.0.1", - "react-dom": "^17.0.1" - } - }, "node_modules/react-infinite-scroll-hook": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/react-infinite-scroll-hook/-/react-infinite-scroll-hook-4.1.1.tgz", @@ -23602,9 +24127,9 @@ } }, "node_modules/react-inlinesvg": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/react-inlinesvg/-/react-inlinesvg-3.0.1.tgz", - "integrity": "sha512-cBfoyfseNI2PkDA7ZKIlDoHq0eMfpoC3DhKBQNC+/X1M4ZQB+aXW+YiNPUDDDKXUsGDUIZWWiZWNFeauDIVdoA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/react-inlinesvg/-/react-inlinesvg-3.0.3.tgz", + "integrity": "sha512-D9wqEyh1+ni07+CP2yaD9nSK11Y2ngd79xudEilX7YHKmUCeP1lXZqFvuLbdOo+m+oEjekd+c0DBc/bj93Lwqg==", "dependencies": { "exenv": "^1.2.2", "react-from-dom": "^0.6.2" @@ -23641,11 +24166,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, "node_modules/react-loading-skeleton": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz", @@ -23762,6 +24282,49 @@ "react-dom": ">=16.8" } }, + "node_modules/react-select": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz", + "integrity": "sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.1.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-select/node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "dev": true + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -23829,40 +24392,6 @@ "@babel/runtime": "^7.9.2" } }, - "node_modules/redux-devtools-core": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/redux-devtools-core/-/redux-devtools-core-0.2.1.tgz", - "integrity": "sha512-RAGOxtUFdr/1USAvxrWd+Gq/Euzgw7quCZlO5TgFpDfG7rB5tMhZUrNyBjpzgzL2yMk0eHnPYIGm7NkIfRzHxQ==", - "deprecated": "Package moved to @redux-devtools/app.", - "dev": true, - "dependencies": { - "get-params": "^0.1.2", - "jsan": "^3.1.13", - "lodash": "^4.17.11", - "nanoid": "^2.0.0", - "remotedev-serialize": "^0.1.8" - } - }, - "node_modules/redux-devtools-core/node_modules/nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==", - "dev": true - }, - "node_modules/redux-devtools-instrument": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/redux-devtools-instrument/-/redux-devtools-instrument-1.10.0.tgz", - "integrity": "sha512-X8JRBCzX2ADSMp+iiV7YQ8uoTNyEm0VPFPd4T854coz6lvRiBrFSqAr9YAS2n8Kzxx8CJQotR0QF9wsMM+3DvA==", - "deprecated": "Package moved to @redux-devtools/instrument.", - "dev": true, - "dependencies": { - "lodash": "^4.17.19", - "symbol-observable": "^1.2.0" - }, - "peerDependencies": { - "redux": "^3.4.0 || ^4.0.0" - } - }, "node_modules/redux-devtools-themes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redux-devtools-themes/-/redux-devtools-themes-1.0.0.tgz", @@ -24080,30 +24609,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/remote-redux-devtools": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/remote-redux-devtools/-/remote-redux-devtools-0.5.16.tgz", - "integrity": "sha512-xZ2D1VRIWzat5nsvcraT6fKEX9Cfi+HbQBCwzNnUAM8Uicm/anOc60XGalcaDPrVmLug7nhDl2nimEa3bL3K9w==", - "dev": true, - "dependencies": { - "jsan": "^3.1.13", - "querystring": "^0.2.0", - "redux-devtools-core": "^0.2.1", - "redux-devtools-instrument": "^1.9.4", - "rn-host-detect": "^1.1.5", - "socketcluster-client": "^14.2.1" - } - }, - "node_modules/remotedev-serialize": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/remotedev-serialize/-/remotedev-serialize-0.1.9.tgz", - "integrity": "sha512-5tFdZg9mSaAWTv6xmQ7HtHjKMLSFQFExEZOtJe10PLsv1wb7cy7kYHtBvTYRro27/3fRGEcQBRNKSaixOpb69w==", - "deprecated": "Package moved to @redux-devtools/serialize.", - "dev": true, - "dependencies": { - "jsan": "^3.1.13" - } - }, "node_modules/remove-accents": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", @@ -24644,36 +25149,12 @@ "node": ">=v12.22.7" } }, - "node_modules/sc-channel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sc-channel/-/sc-channel-1.2.0.tgz", - "integrity": "sha512-M3gdq8PlKg0zWJSisWqAsMmTVxYRTpVRqw4CWAdKBgAfVKumFcTjoCV0hYu7lgUXccCtCD8Wk9VkkE+IXCxmZA==", - "dev": true, - "dependencies": { - "component-emitter": "1.2.1" - } - }, "node_modules/sc-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-2.0.1.tgz", "integrity": "sha512-JoVhq3Ud+3Ujv2SIG7W0XtjRHsrNgl6iXuHHsh0s+Kdt5NwI6N2EGAZD4iteitdDv68ENBkpjtSvN597/wxPSQ==", "dev": true }, - "node_modules/sc-formatter": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-3.0.2.tgz", - "integrity": "sha512-9PbqYBpCq+OoEeRQ3QfFIGE6qwjjBcd2j7UjgDlhnZbtSnuGgHdcRklPKYGuYFH82V/dwd+AIpu8XvA1zqTd+A==", - "dev": true - }, - "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "node_modules/schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -24749,7 +25230,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -24973,6 +25453,22 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/set-function-name": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", @@ -25132,9 +25628,9 @@ "dev": true }, "node_modules/simple-diff": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/simple-diff/-/simple-diff-1.7.1.tgz", - "integrity": "sha512-adwK0aCHYSLEDOiAxb4TjGE3h2WGFox2Luzkqy9m68O/P2iEpZbcnFYKqrbWVgKXf/pUt+8yXvfSU38vXI8GSg==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/simple-diff/-/simple-diff-1.7.2.tgz", + "integrity": "sha512-7UPeBrh/I1zlY33vyUL5R0J1rP4HqP1zMpbuYw0+Lbq4OhWWadUi0dNziRMrQzjJsk2MoPwKDLHacjGpolUiqQ==", "dev": true }, "node_modules/simple-element-resize-detector": { @@ -25218,44 +25714,6 @@ "npm": ">= 3.0.0" } }, - "node_modules/socketcluster-client": { - "version": "14.3.2", - "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-14.3.2.tgz", - "integrity": "sha512-xDtgW7Ss0ARlfhx53bJ5GY5THDdEOeJnT+/C9Rmrj/vnZr54xeiQfrCZJbcglwe732nK3V+uZq87IvrRl7Hn4g==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "clone": "2.1.1", - "component-emitter": "1.2.1", - "linked-list": "0.1.0", - "querystring": "0.2.0", - "sc-channel": "^1.2.0", - "sc-errors": "^2.0.1", - "sc-formatter": "^3.0.1", - "uuid": "3.2.1", - "ws": "^7.5.0" - } - }, - "node_modules/socketcluster-client/node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/socketcluster-client/node_modules/uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/socketcluster-server": { "version": "17.4.1", "resolved": "https://registry.npmjs.org/socketcluster-server/-/socketcluster-server-17.4.1.tgz", @@ -25645,6 +26103,18 @@ "node": ">= 0.8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/stream-demux": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/stream-demux/-/stream-demux-8.1.0.tgz", @@ -25992,9 +26462,9 @@ } }, "node_modules/style-loader": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", "dev": true, "engines": { "node": ">= 12.13.0" @@ -27114,9 +27584,9 @@ } }, "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, "node_modules/unbox-primitive": { @@ -27292,7 +27762,6 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -28112,13 +28581,13 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", - "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "dependencies": { "colorette": "^2.0.10", - "memfs": "^3.4.1", + "memfs": "^3.4.3", "mime-types": "^2.1.31", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" @@ -28478,16 +28947,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -28756,9 +29225,9 @@ } }, "node_modules/ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "engines": { "node": ">=8.3.0" }, @@ -29026,7 +29495,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -29243,14 +29711,12 @@ "@babel/compat-data": { "version": "7.23.2", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", - "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", - "dev": true + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==" }, "@babel/core": { "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", - "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", @@ -29272,8 +29738,7 @@ "convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" } } }, @@ -29356,7 +29821,6 @@ "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", - "dev": true, "requires": { "@babel/compat-data": "^7.22.9", "@babel/helper-validator-option": "^7.22.15", @@ -29369,7 +29833,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "requires": { "yallist": "^3.0.2" } @@ -29377,23 +29840,22 @@ "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, "@babel/helper-create-class-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", - "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", + "version": "7.23.10", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz", + "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -29467,7 +29929,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", @@ -29488,8 +29949,7 @@ "@babel/helper-plugin-utils": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==" }, "@babel/helper-remap-async-to-generator": { "version": "7.22.20", @@ -29517,7 +29977,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, "requires": { "@babel/types": "^7.22.5" } @@ -29552,8 +30011,7 @@ "@babel/helper-validator-option": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", - "dev": true + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==" }, "@babel/helper-wrap-function": { "version": "7.22.20", @@ -29570,7 +30028,6 @@ "version": "7.23.2", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", - "dev": true, "requires": { "@babel/template": "^7.22.15", "@babel/traverse": "^7.23.2", @@ -29793,12 +30250,11 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -29874,12 +30330,12 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.10.tgz", - "integrity": "sha512-xJefea1DWXW09pW4Tm9bjwVlPDyYA2it3fWlmEjpYz6alPvTUjL0EOzNzI/FEOyI3r4/J7uVH5UqKgl1TQ5hqQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-syntax-unicode-sets-regex": { @@ -30127,12 +30583,12 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", - "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" } @@ -30403,14 +30859,15 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", - "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", + "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-typescript": "^7.16.7" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" } }, "@babel/plugin-transform-unicode-escapes": { @@ -30611,14 +31068,16 @@ } }, "@babel/preset-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", - "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.16.7" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" } }, "@babel/regjsgen": { @@ -30741,49 +31200,49 @@ "dev": true }, "@dnd-kit/accessibility": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz", - "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.0.tgz", + "integrity": "sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==", "dev": true, "requires": { "tslib": "^2.0.0" } }, "@dnd-kit/core": { - "version": "6.0.8", - "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.8.tgz", - "integrity": "sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.1.0.tgz", + "integrity": "sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==", "dev": true, "requires": { - "@dnd-kit/accessibility": "^3.0.0", - "@dnd-kit/utilities": "^3.2.1", + "@dnd-kit/accessibility": "^3.1.0", + "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" } }, "@dnd-kit/modifiers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-6.0.1.tgz", - "integrity": "sha512-rbxcsg3HhzlcMHVHWDuh9LCjpOVAgqbV78wLGI8tziXY3+qcMQ61qVXIvNKQFuhj75dSfD+o+PYZQ/NUk2A23A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-7.0.0.tgz", + "integrity": "sha512-BG/ETy3eBjFap7+zIti53f0PCLGDzNXyTmn6fSdrudORf+OH04MxrW4p5+mPu4mgMk9kM41iYONjc3DOUWTcfg==", "dev": true, "requires": { - "@dnd-kit/utilities": "^3.2.1", + "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" } }, "@dnd-kit/sortable": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-7.0.2.tgz", - "integrity": "sha512-wDkBHHf9iCi1veM834Gbk1429bd4lHX4RpAwT0y2cHLf246GAvU2sVw/oxWNpPKQNQRQaeGXhAVgrOl1IT+iyA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-8.0.0.tgz", + "integrity": "sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==", "dev": true, "requires": { - "@dnd-kit/utilities": "^3.2.0", + "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" } }, "@dnd-kit/utilities": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.1.tgz", - "integrity": "sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", "dev": true, "requires": { "tslib": "^2.0.0" @@ -30907,15 +31366,15 @@ "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" }, "@emotion/react": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", - "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "version": "11.11.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.3.tgz", + "integrity": "sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==", "dev": true, "requires": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.2", + "@emotion/serialize": "^1.1.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", "@emotion/utils": "^1.2.1", "@emotion/weak-memoize": "^0.3.1", @@ -30923,9 +31382,9 @@ } }, "@emotion/serialize": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", - "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", "dev": true, "requires": { "@emotion/hash": "^0.9.1", @@ -30984,6 +31443,138 @@ "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==", "dev": true }, + "@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "optional": true + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -31086,28 +31677,28 @@ "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==" }, "@floating-ui/core": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", - "integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", "dev": true, "requires": { - "@floating-ui/utils": "^0.1.1" + "@floating-ui/utils": "^0.2.1" } }, "@floating-ui/dom": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.2.tgz", - "integrity": "sha512-6ArmenS6qJEWmwzczWyhvrXRdI/rI78poBcW0h/456+onlabit+2G+QxHx5xTOX60NBJQXjsCLFbW2CmsXpUog==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.1.tgz", + "integrity": "sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==", "dev": true, "requires": { - "@floating-ui/core": "^1.4.1", - "@floating-ui/utils": "^0.1.1" + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.1" } }, "@floating-ui/utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.2.tgz", - "integrity": "sha512-ou3elfqG/hZsbmF4bxeJhPHIf3G2pm0ujc39hYEZrfVqt7Vk/Zji6CXc3W0pmYM8BW1g40U+akTl9DKZhFhInQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==", "dev": true }, "@fluent/syntax": { @@ -31246,16 +31837,6 @@ "integrity": "sha512-JIL1DgJIlH9yuxcNGtyhsWX/PgNltz+5Gr6+8SX9fhXc/hPbEIk6wPI82nhgvp3uUb6ZfAM5mqg/x7KR7NAb+A==", "requires": {} }, - "@hot-loader/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/@hot-loader/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-G2RZrFhsQClS+bdDh/Ojpk3SgocLPUGnvnJDTQYnmKSSwXtU+Yh+8QMs+Ia3zaAvBiOSpIIDSUxuN69cvKqrWg==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, "@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -31965,7 +32546,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, "requires": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -32317,19 +32897,6 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true }, - "@redux-devtools/chart-monitor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/chart-monitor/-/chart-monitor-4.0.0.tgz", - "integrity": "sha512-ZxcYQ5JKs3HGS4AO5fYFN5OKPQ8w41uTRA6fU15Wf5qqv6oHDmDycgTlx2KHNDxVBS0QXa7PS83qiwL1SmGZrA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.20.6", - "@types/redux-devtools-themes": "^1.0.0", - "d3-state-visualizer": "^2.0.0", - "deepmerge": "^4.2.2", - "redux-devtools-themes": "^1.0.0" - } - }, "@redux-devtools/cli": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@redux-devtools/cli/-/cli-3.0.1.tgz", @@ -32362,10 +32929,37 @@ "uuid": "^9.0.0" }, "dependencies": { + "@babel/code-frame": { + "version": "8.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.0-alpha.6.tgz", + "integrity": "sha512-w29LUiFqVMe+Ybp/+xtQKAp6rpxjHxtCW909I0OMHvFKzrGB0K+1yQGRzXhTqrd4f7ZRRgzkAxdr0EOEbHt3dA==", + "dev": true, + "requires": { + "@babel/highlight": "^8.0.0-alpha.6", + "chalk": "^5.3.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "8.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.0-alpha.6.tgz", + "integrity": "sha512-a0YnAx4TJCgds07M2v0A3WeyZUfls2YOgNHCb1akGKlz5KdmTCqf2N2hw86YhjY6oDqb6Omb8gFKz/3TOKRevQ==", + "dev": true + }, + "@babel/highlight": { + "version": "8.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-8.0.0-alpha.6.tgz", + "integrity": "sha512-YzJ5blZXak7Gk6ZgV9a4B9bAkGzl594ZxmBaFFZkstA5hE1iOBTlUW4tkGKz2uomL7FLLW4qHJF3QjQLHKi7iw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^8.0.0-alpha.6", + "chalk": "^5.3.0", + "js-tokens": "^8.0.0" + } + }, "@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", "dev": true, "requires": { "regenerator-runtime": "^0.14.0" @@ -32404,33 +32998,154 @@ "socketcluster-client": "^17.2.2" } }, + "@redux-devtools/chart-monitor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/chart-monitor/-/chart-monitor-4.1.0.tgz", + "integrity": "sha512-fdW7DKEhCB9oumMTyhdrVGOgb/6lBioPveW3w0+u7MCZn2i32laZYzU9VT39sx+Fc2kwxzbYsLxFsU0tijGsXA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.23.2", + "@types/redux-devtools-themes": "^1.0.3", + "d3-state-visualizer": "^2.0.0", + "deepmerge": "^4.3.1", + "redux-devtools-themes": "^1.0.0" + } + }, + "@redux-devtools/core": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/core/-/core-3.14.0.tgz", + "integrity": "sha512-OMPflPPCXR9L1rpfd7gwY31/EuqPyE9Of/5wZgDDzeisaENY5h/EfnAjnHRKr7NIx/yUIUX2DJs8NpmUOnANMg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.23.2", + "@redux-devtools/instrument": "^2.2.0", + "@types/prop-types": "^15.7.10", + "lodash": "^4.17.21", + "prop-types": "^15.8.1" + } + }, + "@redux-devtools/inspector-monitor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor/-/inspector-monitor-4.1.0.tgz", + "integrity": "sha512-ga0rBdb8LeB7mN+X+/Pb0rx+yTPOsSHFFVxgcWag7XsBu+dXtujlRsCM++6LX6GjJGNzZAUsG4ZI4Wt0dG2CQg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.23.2", + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/modifiers": "^7.0.0", + "@dnd-kit/sortable": "^8.0.0", + "@dnd-kit/utilities": "^3.2.2", + "@types/lodash": "^4.14.201", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "dateformat": "^5.0.3", + "hex-rgba": "^1.0.2", + "immutable": "^4.3.4", + "javascript-stringify": "^2.1.0", + "jsondiffpatch": "^0.5.0", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0", + "lodash.debounce": "^4.0.8", + "prop-types": "^15.8.1", + "react-base16-styling": "^0.9.1", + "react-json-tree": "^0.18.0", + "redux-devtools-themes": "^1.0.0" + } + }, "@redux-devtools/inspector-monitor-test-tab": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor-test-tab/-/inspector-monitor-test-tab-2.0.0.tgz", - "integrity": "sha512-6hi7WqUc/pGO7UtdwCnQngSdijsxG34Ou00/Wuu/yyZfw8WU7jib21LVRiSpo8UFwSeSGkc4YYKgGmS+NpAW0A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor-test-tab/-/inspector-monitor-test-tab-2.1.0.tgz", + "integrity": "sha512-wQ8dnB1F7RZn4XFoKYVPUPt996CIGWG1/ndQwGkXPvHg+P32QHUHsrhR+QDpn6Z1dMamycDjqijS2KDkQA/MDg==", "dev": true, "requires": { - "@babel/runtime": "^7.22.10", - "@redux-devtools/ui": "^1.3.0", - "@types/prop-types": "^15.7.5", + "@babel/runtime": "^7.23.2", + "@redux-devtools/ui": "^1.3.1", + "@types/prop-types": "^15.7.10", "es6template": "^1.0.5", "javascript-stringify": "^2.1.0", "jsan": "^3.1.14", "object-path": "^0.11.8", "prop-types": "^15.8.1", - "react-icons": "^4.10.1", - "simple-diff": "^1.7.1" + "react-icons": "^4.11.0", + "simple-diff": "^1.7.2" } }, - "@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", + "@redux-devtools/inspector-monitor-trace-tab": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor-trace-tab/-/inspector-monitor-trace-tab-2.1.0.tgz", + "integrity": "sha512-Sac8iyYahyrq3k76kty1ebMVCp7Q1ABdBdzj8vJ5FSiaXOKU+HY1y4YS6Fb9ra7Bj5udIqzr/zdxprdPc7Yatg==", + "dev": true, + "requires": { + "@babel/code-frame": "^8.0.0-alpha.4", + "@babel/runtime": "^7.23.2", + "@types/chrome": "^0.0.251", + "anser": "^2.1.1", + "html-entities": "^2.4.0", + "path-browserify": "^1.0.1", + "redux-devtools-themes": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "@redux-devtools/log-monitor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/log-monitor/-/log-monitor-4.1.0.tgz", + "integrity": "sha512-2danca7yfQnuyzYxUVsEontmcRfQLFZgU8M33690JfvHlUV1OYjkNhbwKkMEso5py8sTd2EgoC2PGySoyupbUg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.23.2", + "@types/lodash.debounce": "^4.0.9", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "lodash.debounce": "^4.0.8", + "prop-types": "^15.8.1", + "react-json-tree": "^0.18.0", + "redux-devtools-themes": "^1.0.0" + } + }, + "@redux-devtools/rtk-query-monitor": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/rtk-query-monitor/-/rtk-query-monitor-3.2.0.tgz", + "integrity": "sha512-Td7oZUAO/TyxillkC2E33vYqfKEDFilJfLHLg8Na7KdfG3Y0JR5qmu0xypZDODeEsA5teHpkMnhI3O9ew/JqdQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.23.2", + "@redux-devtools/ui": "^1.3.1", + "@types/lodash": "^4.14.201", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "hex-rgba": "^1.0.2", + "immutable": "^4.3.4", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0", + "lodash.debounce": "^4.0.8", + "prop-types": "^15.8.1", + "react-base16-styling": "^0.9.1", + "react-json-tree": "^0.18.0", + "redux-devtools-themes": "^1.0.0" + } + }, + "@redux-devtools/slider-monitor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/slider-monitor/-/slider-monitor-4.1.0.tgz", + "integrity": "sha512-p0jDgLcmuOQyJTlMAwjSZ8wxioqV802IXtm7BsxGq9021WsmyhEGRhqfu4XvXUt95sBHNsRsm9yE5XVTMmlAtw==", "dev": true, "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "@babel/runtime": "^7.23.2", + "@redux-devtools/ui": "^1.3.1", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "prop-types": "^15.8.1", + "redux-devtools-themes": "^1.0.0" + } + }, + "@types/chrome": { + "version": "0.0.251", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.251.tgz", + "integrity": "sha512-UF+yr0LEKWWGsKxQ5A3XOSF5SNoU1ctW3pXcWJPpT8OOUTEspYeaLU8spDKe+6xalXeMTS0TBrX1g0b6qlWmkw==", + "dev": true, + "requires": { + "@types/filesystem": "*", + "@types/har-format": "*" } }, "body-parser": { @@ -32480,6 +33195,12 @@ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true }, + "js-tokens": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", + "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -32510,25 +33231,6 @@ "unpipe": "1.0.0" } }, - "react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - } - }, "react-redux": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz", @@ -32555,15 +33257,6 @@ "integrity": "sha512-MgUIvuca+90fBrCWY5LdlU9YUWjlkPFwdpvmomcwQEu3t2id/6YHdG2nhB6o7nhRp4ocfmcXQTh00r/tJtynSg==", "dev": true }, - "scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0" - } - }, "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -32635,310 +33328,231 @@ } }, "@redux-devtools/core": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@redux-devtools/core/-/core-3.13.1.tgz", - "integrity": "sha512-VZbma4b28D7dLn6rKTxx4r1KJrgiT2EQNF4vjkpTlXTu0cQcHkEcAO9ixMBj6rZGrT/jinCHq8gBy2bWgnDvcA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.18.3", - "@redux-devtools/instrument": "^2.1.0", - "@types/prop-types": "^15.7.5", - "lodash": "^4.17.21", - "prop-types": "^15.8.1" - } - }, - "@redux-devtools/inspector-monitor": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor/-/inspector-monitor-4.0.0.tgz", - "integrity": "sha512-P0xXjv/N02dPQAaa+fSY2de6adFP+QdGaJZN+raWbWAoIB4SMYuxOlsEBWdclbTTpFBqYp0azpLTfy1vJroRPg==", + "resolved": "https://registry.npmjs.org/@redux-devtools/core/-/core-4.0.0.tgz", + "integrity": "sha512-9smPIgjVxSwCmA35SOwy/ZmlVdKfrdWQHxZdBeXw3G4u+guCl7hBLaOqqUhgceKdsX0IkdIr0v5TLpm2gQT2oQ==", "dev": true, "requires": { - "@babel/runtime": "^7.22.10", - "@dnd-kit/core": "^6.0.8", - "@dnd-kit/modifiers": "^6.0.1", - "@dnd-kit/sortable": "^7.0.2", - "@dnd-kit/utilities": "^3.2.1", - "@types/lodash": "^4.14.197", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "dateformat": "^5.0.3", - "hex-rgba": "^1.0.2", - "immutable": "^4.3.2", - "javascript-stringify": "^2.1.0", - "jsondiffpatch": "^0.5.0", - "jss": "^10.10.0", - "jss-preset-default": "^10.10.0", - "lodash.debounce": "^4.0.8", - "prop-types": "^15.8.1", - "react-base16-styling": "^0.9.1", - "react-json-tree": "^0.18.0", - "redux-devtools-themes": "^1.0.0" + "@babel/runtime": "^7.23.5", + "@redux-devtools/instrument": "^2.2.0", + "lodash": "^4.17.21" }, "dependencies": { "@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", "dev": true, "requires": { "regenerator-runtime": "^0.14.0" } }, "regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true } } }, - "@redux-devtools/inspector-monitor-trace-tab": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/inspector-monitor-trace-tab/-/inspector-monitor-trace-tab-2.0.0.tgz", - "integrity": "sha512-F5yS0cWZqcxNekZ+63HvJJ8S6uoY045uEJHA/IjuffHpZcTfZJoqs0uBAzPrg+y+TlUyGQ8hlT6H+sSJS1KHdA==", + "@redux-devtools/instrument": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/instrument/-/instrument-2.2.0.tgz", + "integrity": "sha512-HKaL+ghBQ4ZQkM/kEQIKx8dNwz4E1oeiCDfdQlpPXxEi/BrisyrFFncAXb1y2HIJsLV9zSvQUR2jRtMDWgfi8w==", "dev": true, "requires": { - "@babel/code-frame": "^8.0.0-alpha.2", - "@babel/runtime": "^7.22.10", - "@types/chrome": "^0.0.243", - "anser": "^2.1.1", - "html-entities": "^2.4.0", - "path-browserify": "^1.0.1", - "redux-devtools-themes": "^1.0.0", - "source-map": "^0.5.7" + "@babel/runtime": "^7.23.2", + "lodash": "^4.17.21" }, "dependencies": { - "@babel/code-frame": { - "version": "8.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.0-alpha.2.tgz", - "integrity": "sha512-uM1On1MxYaZDFVq1gPbGJx1Rf0N+lwlPOCBHZPS8RNVfP9CAG05xzViguK45e16n4Wo6V3WfaTkdmbuNusBnJQ==", + "@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", "dev": true, "requires": { - "@babel/highlight": "^8.0.0-alpha.2", - "chalk": "^4.1.2" + "regenerator-runtime": "^0.14.0" } }, - "@babel/helper-validator-identifier": { - "version": "8.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.0-alpha.2.tgz", - "integrity": "sha512-us66RLKkCzBzNJ1TVAHe2euihYrYaXxbuQ7yJogKdBKBZ0R7gHEpB+e0ylaMGsmLzqlpPUyWWcz3OPTCsq1FDw==", + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true - }, - "@babel/highlight": { - "version": "8.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-8.0.0-alpha.2.tgz", - "integrity": "sha512-V+G3EzQx895Dqbu4xroJo6kMLK6YQJLrMLGj2zjJShA5HNuBCTGgwBhL1BA8jixOfFA5/110QoCugKC39oWB8w==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^8.0.0-alpha.2", - "chalk": "^4.1.2", - "js-tokens": "^8.0.0" - } - }, + } + } + }, + "@redux-devtools/remote": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@redux-devtools/remote/-/remote-0.9.1.tgz", + "integrity": "sha512-MvPs4wGVBOj0iOtSKYpNTg5d5SEJPT8e5q88KWMISVptazKMQL0JgQ2TrwPdKccNG0EjjuCDeOONCl09hcLqsQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.23.5", + "@redux-devtools/instrument": "^2.2.0", + "@redux-devtools/utils": "^3.0.0", + "jsan": "^3.1.14", + "querystring": "^0.2.1", + "rn-host-detect": "^1.2.0", + "socketcluster-client": "^17.2.2" + }, + "dependencies": { "@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", "dev": true, "requires": { "regenerator-runtime": "^0.14.0" } }, - "@types/chrome": { - "version": "0.0.243", - "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.243.tgz", - "integrity": "sha512-4PHv0kxxxpZFHWPBiJJ9TWH8kbx0567j1b2djnhpJjpiSGNI7UKkz7dSEECBtQ0B3N5nQTMwSB/5IopkWGAbEA==", - "dev": true, - "requires": { - "@types/filesystem": "*", - "@types/har-format": "*" - } - }, - "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.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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==", + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true }, - "has-flag": { + "sc-formatter": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "js-tokens": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.2.tgz", - "integrity": "sha512-Olnt+V7xYdvGze9YTbGFZIfQXuGV4R3nQwwl8BrtgaPE/wq8UFpUHWuTNc05saowhSr1ZO6tx+V6RjE9D5YQog==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-4.0.0.tgz", + "integrity": "sha512-MgUIvuca+90fBrCWY5LdlU9YUWjlkPFwdpvmomcwQEu3t2id/6YHdG2nhB6o7nhRp4ocfmcXQTh00r/tJtynSg==", "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==", + "socketcluster-client": { + "version": "17.2.2", + "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-17.2.2.tgz", + "integrity": "sha512-HIopjTj8p979N5klC7FeZSwu9rd805bFgFcyVX7Y8zPyjVHXHTfGrV/8vqzN2gpOwnnosWQ44ue0qGqovlxZrg==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "ag-channel": "^5.0.0", + "ag-request": "^1.0.0", + "async-stream-emitter": "^4.0.0", + "buffer": "^5.2.1", + "clone-deep": "^4.0.1", + "linked-list": "^0.1.0", + "sc-errors": "^2.0.1", + "sc-formatter": "^4.0.0", + "stream-demux": "^8.0.0", + "uuid": "^8.3.2", + "vinyl-buffer": "^1.0.1", + "ws": "^8.9.0" } + }, + "ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "dev": true, + "requires": {} } } }, - "@redux-devtools/instrument": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/instrument/-/instrument-2.1.0.tgz", - "integrity": "sha512-e8fo88kuq/zWqfNf6S/GNfaQMjF4WSPpucmYfRhzZyyXHC3PCLd/xgz7zooPErDh9QwUXK6sTVYvrkq7hPbsFA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.16.7", - "lodash": "^4.17.21" - } - }, - "@redux-devtools/log-monitor": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@redux-devtools/log-monitor/-/log-monitor-4.0.2.tgz", - "integrity": "sha512-BaTAwadm/XzRfnN2+8t4mwdbOILWfwsvMfVPn5OuE+NFaUG9pDKGoHRPCdMBaRdggDqqb5nlMgRCVdHzYftgVw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.20.6", - "@types/lodash.debounce": "^4.0.7", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "lodash.debounce": "^4.0.8", - "prop-types": "^15.8.1", - "react-json-tree": "^0.18.0", - "redux-devtools-themes": "^1.0.0" - } - }, - "@redux-devtools/rtk-query-monitor": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@redux-devtools/rtk-query-monitor/-/rtk-query-monitor-3.1.1.tgz", - "integrity": "sha512-A7kHvU0SY6iQeaLHq+Kcq8a4Z/NhLcwQ/DluP/E+6UU/OXbEtoPK7304qdFQtVG7HY7owdKQiJZrYns5Mi7ysw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.20.6", - "@redux-devtools/ui": "^1.3.0", - "@types/lodash": "^4.14.191", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "hex-rgba": "^1.0.2", - "immutable": "^4.1.0", - "jss": "^10.9.2", - "jss-preset-default": "^10.9.2", - "lodash.debounce": "^4.0.8", - "prop-types": "^15.8.1", - "react-base16-styling": "^0.9.1", - "react-json-tree": "^0.18.0", - "redux-devtools-themes": "^1.0.0" - } - }, - "@redux-devtools/slider-monitor": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@redux-devtools/slider-monitor/-/slider-monitor-4.0.1.tgz", - "integrity": "sha512-pjHPYLG91GLRQVcNAIu3Colc6nIqR4mSQYN1MWUqP8nTAlkP1ihEN44KXxcnTUEzuSLRYm1YW3jsI5p4q3aXZA==", + "@redux-devtools/serialize": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@redux-devtools/serialize/-/serialize-0.4.2.tgz", + "integrity": "sha512-YVqZCChJld5l3Ni2psEZ5loe9x5xpf9J4ckz+7OJdzCNsplC7vzjnkQbFxE6+ULZbywRVp+nSBslTXmaXqAw4A==", "dev": true, "requires": { - "@babel/runtime": "^7.18.3", - "@redux-devtools/ui": "^1.3.0", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "prop-types": "^15.8.1", - "redux-devtools-themes": "^1.0.0" + "@babel/runtime": "^7.23.2", + "jsan": "^3.1.14" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + } } }, "@redux-devtools/ui": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@redux-devtools/ui/-/ui-1.3.0.tgz", - "integrity": "sha512-fj4zyQ08U2DnJAGL7xa1mqlQnBMbrlS1P/HI10Wz57+dgqP9fIzfKymtLEGOnJHZNkPpPNXG04FH4+AQQ1v3kw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.18.3", - "@rjsf/core": "^4.2.0", - "@types/base16": "^1.0.2", - "@types/codemirror": "^5.60.5", - "@types/json-schema": "^7.0.11", - "@types/prop-types": "^15.7.5", - "@types/redux-devtools-themes": "^1.0.0", - "@types/simple-element-resize-detector": "^1.3.0", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@redux-devtools/ui/-/ui-1.3.1.tgz", + "integrity": "sha512-qtfau1zSmv6nSUrnesuxaos1V7r89HQV2Hq/thcRcyHd0Y0OYgpQlnwEK3wkK1esLU2BhEUUb85DC8IdJ3l6Sg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.23.2", + "@rjsf/core": "^4.2.3", + "@types/base16": "^1.0.5", + "@types/codemirror": "^5.60.13", + "@types/json-schema": "^7.0.15", + "@types/prop-types": "^15.7.10", + "@types/redux-devtools-themes": "^1.0.3", + "@types/simple-element-resize-detector": "^1.3.3", "base16": "^1.0.0", - "codemirror": "^5.65.4", + "codemirror": "^5.65.15", "color": "^4.2.3", "prop-types": "^15.8.1", - "react-icons": "^4.3.1", - "react-select": "^5.3.2", + "react-icons": "^4.11.0", + "react-select": "^5.8.0", "redux-devtools-themes": "^1.0.0", "simple-element-resize-detector": "^1.3.0" }, "dependencies": { - "memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "dev": true + "@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.14.0" + } }, - "react-select": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.4.tgz", - "integrity": "sha512-NhuE56X+p9QDFh4BgeygHFIvJJszO1i1KSkg/JPcIJrbovyRtI+GuOEa4XzFCEpZRAEoEI8u/cAHK+jG/PgUzQ==", + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + } + } + }, + "@redux-devtools/utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@redux-devtools/utils/-/utils-3.0.0.tgz", + "integrity": "sha512-m1AJoxQffm1/6m0qrkb7gW0FkmaAoi1/HJzmdkchAeA8sAJhzGOnXJEpsjmXPt5BIHxg0zsglA+5FsgGWXa97A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.23.5", + "@redux-devtools/core": "^4.0.0", + "@redux-devtools/serialize": "^0.4.2", + "@types/get-params": "^0.1.2", + "get-params": "^0.1.2", + "immutable": "^4.3.4", + "jsan": "^3.1.14", + "lodash": "^4.17.21", + "nanoid": "^5.0.4", + "redux": "^4.2.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", "dev": true, "requires": { - "@babel/runtime": "^7.12.0", - "@emotion/cache": "^11.4.0", - "@emotion/react": "^11.8.1", - "@floating-ui/dom": "^1.0.1", - "@types/react-transition-group": "^4.4.0", - "memoize-one": "^6.0.0", - "prop-types": "^15.6.0", - "react-transition-group": "^4.3.0", - "use-isomorphic-layout-effect": "^1.1.2" - }, - "dependencies": { - "react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "dev": true, - "requires": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - } - } + "regenerator-runtime": "^0.14.0" } + }, + "nanoid": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.4.tgz", + "integrity": "sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true } } }, @@ -32990,13 +33604,13 @@ "integrity": "sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA==" }, "@reduxjs/toolkit": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz", - "integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==", + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", + "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", "dev": true, "requires": { "immer": "^9.0.21", - "redux": "4.2.1", + "redux": "^4.2.1", "redux-thunk": "^2.4.2", "reselect": "^4.1.8" }, @@ -33110,18 +33724,18 @@ } }, "@testing-library/dom": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", - "integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", + "lz-string": "^1.5.0", "pretty-format": "^27.0.2" }, "dependencies": { @@ -33134,6 +33748,15 @@ "color-convert": "^2.0.1" } }, + "aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "requires": { + "deep-equal": "^2.0.5" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -33177,18 +33800,17 @@ } }, "@testing-library/jest-dom": { - "version": "5.16.5", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", - "integrity": "sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz", + "integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==", "dev": true, "requires": { - "@adobe/css-tools": "^4.0.1", + "@adobe/css-tools": "^4.3.2", "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", + "dom-accessibility-api": "^0.6.3", "lodash": "^4.17.15", "redent": "^3.0.0" }, @@ -33227,6 +33849,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -33245,37 +33873,22 @@ } }, "@testing-library/react": { - "version": "12.1.5", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", - "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.0.0", - "@types/react-dom": "<18.0.0" - } - }, - "@testing-library/react-hooks": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz", - "integrity": "sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg==", + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.2.1.tgz", + "integrity": "sha512-sGdjws32ai5TLerhvzThYFbpnF9XtL65Cjf+gB0Dhr29BGqK+mAeN7SURSdu+eqgET4ANcWoC7FQpkaiGvBr+A==", "dev": true, "requires": { "@babel/runtime": "^7.12.5", - "@types/react": ">=16.9.0", - "@types/react-dom": ">=16.9.0", - "@types/react-test-renderer": ">=16.9.0", - "react-error-boundary": "^3.1.0" + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" } }, "@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", "dev": true, - "requires": { - "@babel/runtime": "^7.12.5" - } + "requires": {} }, "@tootallnate/once": { "version": "1.1.2", @@ -33405,9 +34018,9 @@ "integrity": "sha512-PZffP/CqH9m2kovDSRQMfMMxUC3V98I7i7/caa0RB0/nvsXzYbL9bKyqZpNMFmLFGZslROlG1R60ONt7abrwlA==" }, "@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true }, "@types/babel__core": { @@ -33452,9 +34065,9 @@ } }, "@types/base16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.2.tgz", - "integrity": "sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.5.tgz", + "integrity": "sha512-OzOWrTluG9cwqidEzC/Q6FAmIPcnZfm8BFRlIx0+UIUqnuAmi5OS88O0RpT3Yz6qdmqObvUhasrbNsCofE4W9A==", "dev": true }, "@types/big.js": { @@ -33513,9 +34126,9 @@ } }, "@types/codemirror": { - "version": "5.60.10", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.10.tgz", - "integrity": "sha512-ZTA3teiCWKT8HUUofqlGPlShu5ojdIajizsS0HpH6GL0/iEdjRt7fXbCLHHqKYP5k7dC/HnnWIjZAiELUwBdjQ==", + "version": "5.60.15", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", + "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", "dev": true, "requires": { "@types/tern": "*" @@ -33881,6 +34494,12 @@ "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==", "dev": true }, + "@types/get-params": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/get-params/-/get-params-0.1.2.tgz", + "integrity": "sha512-ujqPyr1UDsOTDngJPV+WFbR0iHT5AfZKlNPMX6XOCnQcMhEqR+r64dVC/nwYCitqjR3DcpWofnOEAInUQmI/eA==", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -33991,9 +34610,9 @@ } }, "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "@types/json5": { @@ -34012,14 +34631,14 @@ } }, "@types/lodash": { - "version": "4.14.198", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", - "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==" + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==" }, "@types/lodash.debounce": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.7.tgz", - "integrity": "sha512-X1T4wMZ+gT000M2/91SYj0d/7JfeNZ9PeeOldSNoE/lunLeQXKvkmIumI29IaKMotU/ln/McOIvgzZcQ/3TrSA==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz", + "integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==", "dev": true, "requires": { "@types/lodash": "*" @@ -34040,6 +34659,12 @@ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", "dev": true }, + "@types/md5": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.5.tgz", + "integrity": "sha512-/i42wjYNgE6wf0j2bcTX6kuowmdL/6PE4IVitMpm2eYKBUuYCprdcWVK+xEF0gcV6ufMCRhtxmReGfc6hIK7Jw==", + "dev": true + }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -34095,9 +34720,9 @@ "dev": true }, "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "@types/qs": { "version": "6.9.7", @@ -34112,9 +34737,9 @@ "dev": true }, "@types/react": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.45.tgz", - "integrity": "sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg==", + "version": "18.2.55", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.55.tgz", + "integrity": "sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -34122,50 +34747,32 @@ } }, "@types/react-dom": { - "version": "17.0.17", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.17.tgz", - "integrity": "sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==", + "version": "18.2.18", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz", + "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==", "devOptional": true, - "requires": { - "@types/react": "^17" - } - }, - "@types/react-test-renderer": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz", - "integrity": "sha512-C7/5FBJ3g3sqUahguGi03O79b8afNeSD6T8/GU50oQrJCU0bVCCGQHaGKUbg2Ce8VQEEqTw8/HiS6lXHHdgkdQ==", - "dev": true, "requires": { "@types/react": "*" } }, "@types/react-transition-group": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", - "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "dev": true, "requires": { "@types/react": "*" } }, "@types/redux-devtools-themes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/redux-devtools-themes/-/redux-devtools-themes-1.0.0.tgz", - "integrity": "sha512-ul3x0MYM5Nzj57Fh9wINyHFne8vZL04RC4nWAUWLYcL105vHoa/oJyopuKOrQmqVmhqmDiL4c9FfLbUmIB7TWQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/redux-devtools-themes/-/redux-devtools-themes-1.0.3.tgz", + "integrity": "sha512-KqiQ2+6VTb1Yn02+ZNQsB0XcoJTu/W4AhnIUaeTnkVFie5YWMoeSpW4IOFYJ2/HJ+wi1kLw+PHDgjZ3t+M6IRw==", "dev": true, "requires": { "@types/base16": "*" } }, - "@types/remote-redux-devtools": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@types/remote-redux-devtools/-/remote-redux-devtools-0.5.5.tgz", - "integrity": "sha512-Xuya1TegRPAe92+nnEeYpfufE/mtfN99+GH272edaoWohbMA+yP6r+wYqK4sq/fvmoUPtPHtwZR2Mkk+6uHeBQ==", - "dev": true, - "requires": { - "redux": "^4.0.0" - } - }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -34216,9 +34823,9 @@ } }, "@types/simple-element-resize-detector": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/simple-element-resize-detector/-/simple-element-resize-detector-1.3.0.tgz", - "integrity": "sha512-z89ForrCNg+4uwTHjwBCM9LjcsXYC/4O8u3tSi+82v2LCbfiYFpkjH/qQVkDewFBK6FUG7RRV7jw78EGs2maoQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/simple-element-resize-detector/-/simple-element-resize-detector-1.3.3.tgz", + "integrity": "sha512-igYpe5ApGMB7YGk2ZyyvrT1NwLYG7Q+8d78uskiS3qriHQa1fiFesibFTCDbGWhc9teD7RmGSuh9a1rzzXj9zg==", "dev": true }, "@types/sockjs": { @@ -34253,32 +34860,14 @@ "integrity": "sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg==" }, "@types/tern": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz", - "integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==", + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", + "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", "dev": true, "requires": { "@types/estree": "*" } }, - "@types/testing-library__jest-dom": { - "version": "5.14.3", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz", - "integrity": "sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw==", - "dev": true, - "requires": { - "@types/jest": "*" - } - }, - "@types/testing-library__react": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@types/testing-library__react/-/testing-library__react-10.2.0.tgz", - "integrity": "sha512-KbU7qVfEwml8G5KFxM+xEfentAAVj/SOQSjW0+HqzjPE0cXpt0IpSamfX4jGYCImznDHgQcfXBPajS7HjLZduw==", - "dev": true, - "requires": { - "@testing-library/react": "*" - } - }, "@types/tough-cookie": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", @@ -35633,9 +36222,9 @@ "dev": true }, "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", + "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", "dev": true }, "aws-sign2": { @@ -35822,22 +36411,17 @@ } }, "babel-plugin-styled-components": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz", - "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11", - "picomatch": "^2.3.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" } }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" - }, "babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", @@ -36260,7 +36844,6 @@ "version": "4.22.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", - "dev": true, "requires": { "caniuse-lite": "^1.0.30001541", "electron-to-chromium": "^1.4.535", @@ -36488,12 +37071,14 @@ } }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", + "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "set-function-length": "^1.2.0" } }, "callsites": { @@ -36526,8 +37111,7 @@ "caniuse-lite": { "version": "1.0.30001547", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", - "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==", - "dev": true + "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==" }, "caseless": { "version": "0.12.0", @@ -36635,6 +37219,11 @@ "integrity": "sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ==", "dev": true }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" + }, "cheerio": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", @@ -36976,9 +37565,9 @@ "dev": true }, "codemirror": { - "version": "5.65.15", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.15.tgz", - "integrity": "sha512-YC4EHbbwQeubZzxLl5G4nlbLc1T21QTrKGaOal/Pkm9dVDMZXMH7+ieSPEOZCtO9I68i8/oteJKOxzHC2zR+0g==", + "version": "5.65.16", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", + "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==", "dev": true }, "collect-v8-coverage": { @@ -37097,12 +37686,6 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -37418,9 +38001,9 @@ } }, "core-js-pure": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.32.2.tgz", - "integrity": "sha512-Y2rxThOuNywTjnX/PgA5vWM6CZ9QB9sz9oGeCixV8MqXZO70z/5SHzf9EeBrEBK0PN36DnEBBu9O/aGWzKuMZQ==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.35.1.tgz", + "integrity": "sha512-zcIdi/CL3MWbBJYo5YCeVAAx+Sy9yJE9I3/u9LkFABwbeaPhTMRWraM8mYFp9jW5Z50hOy7FVzCc8dCrpZqtIQ==", "dev": true }, "core-util-is": { @@ -37505,6 +38088,11 @@ "which": "^2.0.1" } }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" + }, "crypto-random-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", @@ -38077,6 +38665,40 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, + "deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -38231,13 +38853,14 @@ "dev": true }, "define-data-property": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", - "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", + "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", "requires": { - "get-intrinsic": "^1.2.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.2", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.1" } }, "define-lazy-prop": { @@ -38399,11 +39022,6 @@ "entities": "^2.0.0" } }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, "domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -38558,8 +39176,7 @@ "electron-to-chromium": { "version": "1.4.551", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.551.tgz", - "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==", - "dev": true + "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==" }, "elliptic": { "version": "6.5.4", @@ -38590,7 +39207,8 @@ "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true }, "encodeurl": { "version": "1.0.2", @@ -38727,6 +39345,36 @@ "which-typed-array": "^1.1.11" } }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, "es-iterator-helpers": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", @@ -38816,11 +39464,39 @@ "sliced": "^1.0.1" } }, + "esbuild": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "requires": { + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-goat": { "version": "4.0.0", @@ -39659,7 +40335,8 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true }, "fast-redact": { "version": "3.3.0", @@ -39904,9 +40581,9 @@ } }, "follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true }, "for-each": { @@ -39976,7 +40653,6 @@ "version": "11.1.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", - "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -40072,9 +40748,9 @@ } }, "fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, "fs-tree-diff": { @@ -40231,8 +40907,7 @@ "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 + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-caller-file": { "version": "2.0.5", @@ -40241,14 +40916,15 @@ "dev": true }, "get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-package-type": { @@ -40470,15 +41146,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "global-agent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", @@ -40674,6 +41341,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -40690,11 +41358,11 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "requires": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.2.2" } }, "has-proto": { @@ -40708,12 +41376,12 @@ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "requires": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" } }, "has-unicode": { @@ -40741,7 +41409,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, "requires": { "function-bind": "^1.1.2" } @@ -41122,34 +41789,49 @@ "dev": true }, "i18next": { - "version": "23.5.1", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.5.1.tgz", - "integrity": "sha512-JelYzcaCoFDaa+Ysbfz2JsGAKkrHiMG6S61+HLBUEIPaF40WMwW9hCPymlQGrP+wWawKxKPuSuD71WZscCsWHg==", + "version": "23.11.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.0.tgz", + "integrity": "sha512-VwFtlgy2LDbY0Qs6VfekIm6mv5/JmSJrtBf4aszl7Vby8+GcBlri0/7dkMZXmzTfiBMPUPBOmYCdQK7K4emkGQ==", "requires": { - "@babel/runtime": "^7.22.5" + "@babel/runtime": "^7.23.2" }, "dependencies": { "@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", "requires": { "regenerator-runtime": "^0.14.0" } }, "regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" } } }, "i18next-browser-languagedetector": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-6.1.8.tgz", - "integrity": "sha512-Svm+MduCElO0Meqpj1kJAriTC6OhI41VhlT/A0UPjGoPZBhAHIaGE5EfsHlTpgdH09UVX7rcc72pSDDBeKSQQA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.2.1.tgz", + "integrity": "sha512-h/pM34bcH6tbz8WgGXcmWauNpQupCGr25XPp9cZwZInR9XHSjIFDYp1SIok7zSPsTOMxdvuLyu86V+g2Kycnfw==", "requires": { - "@babel/runtime": "^7.19.0" + "@babel/runtime": "^7.23.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + } } }, "i18next-conv": { @@ -41182,29 +41864,31 @@ } }, "i18next-http-backend": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.4.1.tgz", - "integrity": "sha512-CZHzFGDvF8zN7ya1W2lHbgLj2ejPUvPD836+vA3eNXc9eKGUM3MSF6SA2TKBXKBZ2cNG3nxzycCXeM6n/46KWQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.0.tgz", + "integrity": "sha512-Z/aQsGZk1gSxt2/DztXk92DuDD20J+rNudT7ZCdTrNOiK8uQppfvdjq9+DFQfpAnFPn3VZS+KQIr1S/W1KxhpQ==", "requires": { "cross-fetch": "4.0.0" } }, "i18next-parser": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-6.6.0.tgz", - "integrity": "sha512-yA3W6PL+7epCyUFTpUDdztKArfpeGMWRUOnB/4FZRodfXkjCIBcBg728h6b/lrBTbva4OlFjVgv1kCXbvZVRWQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-7.9.0.tgz", + "integrity": "sha512-yrPJhWGsDBx404T4KLMOTkTgAAEuHvjbxee3HnlqFHALWy/3BOY7or69CxsJOomN3wdrwgg8kWtfIUWR1BZ1nw==", "requires": { "@babel/runtime": "^7.15.4", "broccoli-plugin": "^4.0.7", "cheerio": "^1.0.0-rc.2", "colors": "1.4.0", - "commander": "~9.4.1", + "commander": "~10.0.0", "concat-stream": "~2.0.0", "eol": "^0.9.1", - "fs-extra": "^10.0.0", + "esbuild": "^0.17.0", + "fs-extra": "^11.1.0", "gulp-sort": "^2.0.0", - "i18next": "^21.2.0", + "i18next": "^22.0.4", "js-yaml": "4.1.0", + "lilconfig": "^2.0.6", "rsvp": "^4.8.2", "sort-keys": "^5.0.0", "through2": "~4.0.2", @@ -41220,26 +41904,16 @@ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" }, "commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==" - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" }, "i18next": { - "version": "21.10.0", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.10.0.tgz", - "integrity": "sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==", + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.5.1.tgz", + "integrity": "sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==", "requires": { - "@babel/runtime": "^7.17.2" + "@babel/runtime": "^7.20.6" } }, "replace-ext": { @@ -41422,9 +42096,9 @@ "dev": true }, "ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", "dev": true, "optional": true }, @@ -41443,6 +42117,16 @@ "is-windows": "^1.0.1" } }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -44146,8 +44830,7 @@ "lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==" }, "lines-and-columns": { "version": "1.2.4", @@ -44162,12 +44845,12 @@ "dev": true }, "linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "requires": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" } }, "lint-staged": { @@ -44354,6 +45037,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -44363,7 +45047,8 @@ "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true } } }, @@ -44581,15 +45266,15 @@ } }, "lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true }, "mac-scrollbar": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/mac-scrollbar/-/mac-scrollbar-0.10.3.tgz", - "integrity": "sha512-+dCARf54JUqeAWhjZE+cMBA9kLLIx1V7LRm3Fh27hAVX9J8ZqpSgXkfioFV218tivVFmusv/xHB1+6SgX0HZgg==" + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/mac-scrollbar/-/mac-scrollbar-0.13.6.tgz", + "integrity": "sha512-P0eNiCTExlmWBQ0FXalfXVh42eo9b0obnZIo1khZzyZX99frTsCmZwcbH0RWZZtNYtBZVd5f/7k4iLPou+skzg==" }, "make-dir": { "version": "3.1.0", @@ -44660,33 +45345,35 @@ } }, "markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "requires": { "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "dependencies": { "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true } } }, "markdownlint": { - "version": "0.26.2", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", - "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz", + "integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==", "dev": true, "requires": { - "markdown-it": "13.0.1" + "markdown-it": "14.1.0", + "markdownlint-micromark": "0.1.9" } }, "markdownlint-cli": { @@ -44722,6 +45409,12 @@ "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", "dev": true }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, "glob": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", @@ -44735,6 +45428,43 @@ "once": "^1.3.0" } }, + "linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdownlint": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", + "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", + "dev": true, + "requires": { + "markdown-it": "13.0.1" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "minimatch": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", @@ -44743,9 +45473,21 @@ "requires": { "brace-expansion": "^2.0.1" } + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true } } }, + "markdownlint-micromark": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz", + "integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==", + "dev": true + }, "markdownlint-rule-helpers": { "version": "0.17.2", "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.2.tgz", @@ -44795,10 +45537,20 @@ "minimatch": "^3.0.2" } }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, "media-typer": { @@ -44819,12 +45571,12 @@ } }, "memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "requires": { - "fs-monkey": "1.0.3" + "fs-monkey": "^1.0.4" } }, "memoize-one": { @@ -44909,14 +45661,6 @@ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -45419,8 +46163,7 @@ "node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" }, "nopt": { "version": "5.0.0", @@ -45503,6 +46246,16 @@ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -46091,8 +46844,7 @@ "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "picomatch": { "version": "2.3.1", @@ -46362,7 +47114,8 @@ "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true }, "process-nextick-args": { "version": "2.0.1", @@ -46513,6 +47266,12 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true + }, "pupa": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", @@ -46655,12 +47414,11 @@ } }, "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "react-base16-styling": { @@ -46691,22 +47449,22 @@ } }, "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "requires": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, - "react-error-boundary": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", - "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5" + "scheduler": "^0.23.0" + }, + "dependencies": { + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "requires": { + "loose-envify": "^1.1.0" + } + } } }, "react-fast-compare": { @@ -46726,37 +47484,30 @@ "integrity": "sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A==", "requires": {} }, - "react-hot-loader": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.13.1.tgz", - "integrity": "sha512-ZlqCfVRqDJmMXTulUGic4lN7Ic1SXgHAFw7y/Jb7t25GBgTR0fYAJ8uY4mrpxjRyWGWmqw77qJQGnYbzCvBU7g==", + "react-i18next": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.0.tgz", + "integrity": "sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==", "requires": { - "fast-levenshtein": "^2.0.6", - "global": "^4.3.0", - "hoist-non-react-statics": "^3.3.0", - "loader-utils": "^2.0.3", - "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4", - "shallowequal": "^1.1.0", - "source-map": "^0.7.3" + "@babel/runtime": "^7.23.9", + "html-parse-stringify": "^3.0.1" }, "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==" + "@babel/runtime": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" } } }, - "react-i18next": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.0.0.tgz", - "integrity": "sha512-/O7N6aIEAl1FaWZBNvhdIo9itvF/MO/nRKr9pYqRc9LhuC1u21SlfwpiYQqvaeNSEW3g3qUXLREOWMt+gxrWbg==", - "requires": { - "@babel/runtime": "^7.14.5", - "html-parse-stringify": "^3.0.1" - } - }, "react-icons": { "version": "4.11.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz", @@ -46764,12 +47515,6 @@ "dev": true, "requires": {} }, - "react-identicons": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/react-identicons/-/react-identicons-1.2.5.tgz", - "integrity": "sha512-x7prkDoc2pD7wSl2C1pGxS+XAoSdq1ABWJWTBUimVTDVJArKOLd0B4wRUJpDm4r+9y7pgf8ylyPGsmlWSV5n2g==", - "requires": {} - }, "react-infinite-scroll-hook": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/react-infinite-scroll-hook/-/react-infinite-scroll-hook-4.1.1.tgz", @@ -46779,9 +47524,9 @@ } }, "react-inlinesvg": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/react-inlinesvg/-/react-inlinesvg-3.0.1.tgz", - "integrity": "sha512-cBfoyfseNI2PkDA7ZKIlDoHq0eMfpoC3DhKBQNC+/X1M4ZQB+aXW+YiNPUDDDKXUsGDUIZWWiZWNFeauDIVdoA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/react-inlinesvg/-/react-inlinesvg-3.0.3.tgz", + "integrity": "sha512-D9wqEyh1+ni07+CP2yaD9nSK11Y2ngd79xudEilX7YHKmUCeP1lXZqFvuLbdOo+m+oEjekd+c0DBc/bj93Lwqg==", "requires": { "exenv": "^1.2.2", "react-from-dom": "^0.6.2" @@ -46809,11 +47554,6 @@ "react-base16-styling": "^0.9.1" } }, - "react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, "react-loading-skeleton": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz", @@ -46872,6 +47612,43 @@ "react-router": "6.16.0" } }, + "react-select": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz", + "integrity": "sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.1.2" + }, + "dependencies": { + "memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "dev": true + } + } + }, + "react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -46924,37 +47701,6 @@ "@babel/runtime": "^7.9.2" } }, - "redux-devtools-core": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/redux-devtools-core/-/redux-devtools-core-0.2.1.tgz", - "integrity": "sha512-RAGOxtUFdr/1USAvxrWd+Gq/Euzgw7quCZlO5TgFpDfG7rB5tMhZUrNyBjpzgzL2yMk0eHnPYIGm7NkIfRzHxQ==", - "dev": true, - "requires": { - "get-params": "^0.1.2", - "jsan": "^3.1.13", - "lodash": "^4.17.11", - "nanoid": "^2.0.0", - "remotedev-serialize": "^0.1.8" - }, - "dependencies": { - "nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==", - "dev": true - } - } - }, - "redux-devtools-instrument": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/redux-devtools-instrument/-/redux-devtools-instrument-1.10.0.tgz", - "integrity": "sha512-X8JRBCzX2ADSMp+iiV7YQ8uoTNyEm0VPFPd4T854coz6lvRiBrFSqAr9YAS2n8Kzxx8CJQotR0QF9wsMM+3DvA==", - "dev": true, - "requires": { - "lodash": "^4.17.19", - "symbol-observable": "^1.2.0" - } - }, "redux-devtools-themes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redux-devtools-themes/-/redux-devtools-themes-1.0.0.tgz", @@ -47124,29 +47870,6 @@ } } }, - "remote-redux-devtools": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/remote-redux-devtools/-/remote-redux-devtools-0.5.16.tgz", - "integrity": "sha512-xZ2D1VRIWzat5nsvcraT6fKEX9Cfi+HbQBCwzNnUAM8Uicm/anOc60XGalcaDPrVmLug7nhDl2nimEa3bL3K9w==", - "dev": true, - "requires": { - "jsan": "^3.1.13", - "querystring": "^0.2.0", - "redux-devtools-core": "^0.2.1", - "redux-devtools-instrument": "^1.9.4", - "rn-host-detect": "^1.1.5", - "socketcluster-client": "^14.2.1" - } - }, - "remotedev-serialize": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/remotedev-serialize/-/remotedev-serialize-0.1.9.tgz", - "integrity": "sha512-5tFdZg9mSaAWTv6xmQ7HtHjKMLSFQFExEZOtJe10PLsv1wb7cy7kYHtBvTYRro27/3fRGEcQBRNKSaixOpb69w==", - "dev": true, - "requires": { - "jsan": "^3.1.13" - } - }, "remove-accents": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", @@ -47572,36 +48295,12 @@ "xmlchars": "^2.2.0" } }, - "sc-channel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sc-channel/-/sc-channel-1.2.0.tgz", - "integrity": "sha512-M3gdq8PlKg0zWJSisWqAsMmTVxYRTpVRqw4CWAdKBgAfVKumFcTjoCV0hYu7lgUXccCtCD8Wk9VkkE+IXCxmZA==", - "dev": true, - "requires": { - "component-emitter": "1.2.1" - } - }, "sc-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-2.0.1.tgz", "integrity": "sha512-JoVhq3Ud+3Ujv2SIG7W0XtjRHsrNgl6iXuHHsh0s+Kdt5NwI6N2EGAZD4iteitdDv68ENBkpjtSvN597/wxPSQ==", "dev": true }, - "sc-formatter": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-3.0.2.tgz", - "integrity": "sha512-9PbqYBpCq+OoEeRQ3QfFIGE6qwjjBcd2j7UjgDlhnZbtSnuGgHdcRklPKYGuYFH82V/dwd+AIpu8XvA1zqTd+A==", - "dev": true - }, - "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -47661,8 +48360,7 @@ "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" }, "semver-compare": { "version": "1.0.0", @@ -47851,6 +48549,19 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "requires": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + } + }, "set-function-name": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", @@ -47984,9 +48695,9 @@ "dev": true }, "simple-diff": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/simple-diff/-/simple-diff-1.7.1.tgz", - "integrity": "sha512-adwK0aCHYSLEDOiAxb4TjGE3h2WGFox2Luzkqy9m68O/P2iEpZbcnFYKqrbWVgKXf/pUt+8yXvfSU38vXI8GSg==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/simple-diff/-/simple-diff-1.7.2.tgz", + "integrity": "sha512-7UPeBrh/I1zlY33vyUL5R0J1rP4HqP1zMpbuYw0+Lbq4OhWWadUi0dNziRMrQzjJsk2MoPwKDLHacjGpolUiqQ==", "dev": true }, "simple-element-resize-detector": { @@ -48055,38 +48766,6 @@ "dev": true, "optional": true }, - "socketcluster-client": { - "version": "14.3.2", - "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-14.3.2.tgz", - "integrity": "sha512-xDtgW7Ss0ARlfhx53bJ5GY5THDdEOeJnT+/C9Rmrj/vnZr54xeiQfrCZJbcglwe732nK3V+uZq87IvrRl7Hn4g==", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "clone": "2.1.1", - "component-emitter": "1.2.1", - "linked-list": "0.1.0", - "querystring": "0.2.0", - "sc-channel": "^1.2.0", - "sc-errors": "^2.0.1", - "sc-formatter": "^3.0.1", - "uuid": "3.2.1", - "ws": "^7.5.0" - }, - "dependencies": { - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", - "dev": true - } - } - }, "socketcluster-server": { "version": "17.4.1", "resolved": "https://registry.npmjs.org/socketcluster-server/-/socketcluster-server-17.4.1.tgz", @@ -48395,6 +49074,15 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true }, + "stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "requires": { + "internal-slot": "^1.0.4" + } + }, "stream-demux": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/stream-demux/-/stream-demux-8.1.0.tgz", @@ -48659,9 +49347,9 @@ "dev": true }, "style-loader": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", "dev": true, "requires": {} }, @@ -49489,9 +50177,9 @@ } }, "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, "unbox-primitive": { @@ -49627,7 +50315,6 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -50279,13 +50966,13 @@ } }, "webpack-dev-middleware": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", - "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "requires": { "colorette": "^2.0.10", - "memfs": "^3.4.1", + "memfs": "^3.4.3", "mime-types": "^2.1.31", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" @@ -50487,16 +51174,16 @@ } }, "which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.1" } }, "wide-align": { @@ -50707,9 +51394,9 @@ } }, "ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "requires": {} }, "xcode-build-webpack-plugin": { diff --git a/package.json b/package.json index c89488acb..6b28a41ff 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Casper Wallet", "description": "Securely manage your CSPR tokens and interact with dapps with the self-custody wallet for the Casper blockchain.", - "version": "1.8.4", + "version": "1.9.0", "author": "MAKE LLC", "scripts": { "devtools:redux": "redux-devtools --hostname=localhost", @@ -54,7 +54,6 @@ "dependencies": { "@formatjs/intl": "2.6.2", "@hookform/resolvers": "2.9.10", - "@hot-loader/react-dom": "^17.0.1", "@lapo/asn1js": "1.2.4", "@lottiefiles/react-lottie-player": "3.5.3", "@make-software/ces-js-parser": "1.3.2", @@ -68,22 +67,21 @@ "casper-cep18-js-client": "1.0.2", "casper-js-sdk": "2.15.4", "date-fns": "^2.30.0", - "i18next": "^23.5.1", - "i18next-browser-languagedetector": "^6.1.5", - "i18next-http-backend": "^2.4.1", - "i18next-parser": "^6.3.0", + "i18next": "^23.11.0", + "i18next-browser-languagedetector": "^7.2.1", + "i18next-http-backend": "2.5.0", + "i18next-parser": "7.9.0", "lodash.throttle": "4.1.1", - "mac-scrollbar": "^0.10.3", + "mac-scrollbar": "^0.13.6", + "md5": "^2.3.0", "micro-aes-gcm": "0.3.3", "qrcode.react": "^3.1.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.0.2", "react-hook-form": "7.48.2", - "react-hot-loader": "4.13.1", - "react-i18next": "12.0.0", - "react-identicons": "^1.2.5", + "react-i18next": "14.1.0", "react-infinite-scroll-hook": "^4.1.1", - "react-inlinesvg": "^3.0.1", + "react-inlinesvg": "3.0.3", "react-loading-skeleton": "^3.3.1", "react-player": "^2.13.0", "react-query": "^3.39.3", @@ -101,25 +99,25 @@ "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/preset-env": "7.23.2", "@babel/preset-react": "7.18.6", + "@babel/preset-typescript": "^7.23.3", "@playwright/test": "^1.39.0", "@redux-devtools/cli": "^3.0.1", - "@testing-library/dom": "8.19.0", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^12.1.2", - "@testing-library/react-hooks": "^7.0.2", - "@testing-library/user-event": "^13.5.0", + "@redux-devtools/remote": "^0.9.1", + "@testing-library/dom": "9.3.4", + "@testing-library/jest-dom": "^6.4.2", + "@testing-library/react": "^14.2.1", + "@testing-library/user-event": "^14.5.2", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/big.js": "^6.1.6", "@types/chrome": "0.0.246", "@types/expect": "^24.3.0", "@types/jest": "29.2.3", "@types/lodash.throttle": "4.1.7", + "@types/md5": "^2.3.5", "@types/node": "^20.9.0", - "@types/react": "^17.0.33", - "@types/react-dom": "^17.0.10", - "@types/remote-redux-devtools": "^0.5.5", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.18", "@types/styled-components": "^5.1.26", - "@types/testing-library__react": "^10.2.0", "babel-eslint": "^10.1.0", "babel-loader": "9.1.0", "babel-preset-react-app": "^10.0.0", @@ -146,12 +144,11 @@ "jest": "29.3.1", "jest-environment-jsdom": "29.3.1", "lint-staged": "14.0.1", - "markdownlint": "0.26.2", + "markdownlint": "0.34.0", "markdownlint-cli": "0.32.2", "prettier": "3.1.0", - "remote-redux-devtools": "^0.5.16", "source-map-loader": "4.0.1", - "style-loader": "^3.3.1", + "style-loader": "^3.3.4", "terser-webpack-plugin": "5.3.6", "ts-jest": "29.1.1", "ts-loader": "9.4.2", diff --git a/src/apps/connect-to-app/index.html b/src/apps/connect-to-app/index.html index 33a2a39bc..cb259d35a 100644 --- a/src/apps/connect-to-app/index.html +++ b/src/apps/connect-to-app/index.html @@ -2,10 +2,6 @@ - diff --git a/src/apps/connect-to-app/index.tsx b/src/apps/connect-to-app/index.tsx index 0f66d017b..59b1b04df 100644 --- a/src/apps/connect-to-app/index.tsx +++ b/src/apps/connect-to-app/index.tsx @@ -1,10 +1,10 @@ import React, { Suspense, useState } from 'react'; -import { render } from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { Provider as ReduxProvider } from 'react-redux'; import { ThemeProvider } from 'styled-components'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { isSafariBuild } from '@src/utils'; +import { isSafariBuild, setCSPForSafari } from '@src/utils'; import { AppRouter } from '@connect-to-app/app-router'; @@ -25,6 +25,8 @@ import { GlobalStyle, darkTheme, lightTheme } from '@libs/ui'; const Tree = () => { const [state, setState] = useState(null); + setCSPForSafari(); + const isSystemDarkTheme = useSystemThemeDetector(); useSubscribeToRedux({ @@ -66,4 +68,7 @@ const Tree = () => { ); }; -render(, document.querySelector('#app-container')); +const container = document.querySelector('#app-container'); +const root = createRoot(container!); + +root.render(); diff --git a/src/apps/import-account-with-file/index.html b/src/apps/import-account-with-file/index.html index dcd288d48..0e090e7c8 100644 --- a/src/apps/import-account-with-file/index.html +++ b/src/apps/import-account-with-file/index.html @@ -2,10 +2,6 @@ - diff --git a/src/apps/import-account-with-file/index.tsx b/src/apps/import-account-with-file/index.tsx index 2061642ff..eeb5ef3f0 100644 --- a/src/apps/import-account-with-file/index.tsx +++ b/src/apps/import-account-with-file/index.tsx @@ -1,10 +1,10 @@ import React, { Suspense, useState } from 'react'; -import { render } from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { Provider as ReduxProvider } from 'react-redux'; import { ThemeProvider } from 'styled-components'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { isSafariBuild } from '@src/utils'; +import { isSafariBuild, setCSPForSafari } from '@src/utils'; import { createMainStoreReplica } from '@background/redux/get-main-store'; import { themeModeSettingChanged } from '@background/redux/settings/actions'; @@ -25,6 +25,8 @@ import { AppRouter } from './app-router'; const Tree = () => { const [state, setState] = useState(null); + setCSPForSafari(); + const isDarkTheme = useSystemThemeDetector(); useSubscribeToRedux({ @@ -64,4 +66,7 @@ const Tree = () => { ); }; -render(, document.querySelector('#app-container')); +const container = document.querySelector('#app-container'); +const root = createRoot(container!); + +root.render(); diff --git a/src/apps/import-account-with-file/pages/import-account-with-file-upload/content.tsx b/src/apps/import-account-with-file/pages/import-account-with-file-upload/content.tsx index c5aa892e7..6b96e9aae 100644 --- a/src/apps/import-account-with-file/pages/import-account-with-file-upload/content.tsx +++ b/src/apps/import-account-with-file/pages/import-account-with-file-upload/content.tsx @@ -51,7 +51,7 @@ export function ImportAccountWithFileUploadPageContent({ } suffixIcon={ isFileLoaded && ( diff --git a/src/apps/import-account-with-file/pages/import-account-with-file-upload/hooks/use-secret-key-file-reader.ts b/src/apps/import-account-with-file/pages/import-account-with-file-upload/hooks/use-secret-key-file-reader.ts index 4539daa7d..3f3646b93 100644 --- a/src/apps/import-account-with-file/pages/import-account-with-file-upload/hooks/use-secret-key-file-reader.ts +++ b/src/apps/import-account-with-file/pages/import-account-with-file-upload/hooks/use-secret-key-file-reader.ts @@ -66,7 +66,8 @@ export function useSecretKeyFileReader({ imported: true, name: name.trim(), publicKey: publicKeyHex, - secretKey: secretKeyBase64 + secretKey: secretKeyBase64, + hidden: false }); }; }, diff --git a/src/apps/import-account-with-file/pages/import-account-with-file-upload/index.tsx b/src/apps/import-account-with-file/pages/import-account-with-file-upload/index.tsx index 5650bb41b..38cca990e 100644 --- a/src/apps/import-account-with-file/pages/import-account-with-file-upload/index.tsx +++ b/src/apps/import-account-with-file/pages/import-account-with-file-upload/index.tsx @@ -59,10 +59,10 @@ export function ImportAccountWithFileUploadPage() { ) .test( 'fileType', - t('Please upload a PEM file containing private key.'), + t('Please upload a PEM or CER file containing a private key.'), filesArray => { if (filesArray != null && filesArray.length > 0) { - return /\.pem$/.test(filesArray[0].name); + return /\.pem$|\.cer$/.test(filesArray[0].name); } return false; } diff --git a/src/apps/onboarding/index.html b/src/apps/onboarding/index.html index 4cf06884f..6afaef1a3 100644 --- a/src/apps/onboarding/index.html +++ b/src/apps/onboarding/index.html @@ -2,10 +2,6 @@ - diff --git a/src/apps/onboarding/index.tsx b/src/apps/onboarding/index.tsx index ec9d58b04..a245e07ac 100644 --- a/src/apps/onboarding/index.tsx +++ b/src/apps/onboarding/index.tsx @@ -1,9 +1,10 @@ import React, { Suspense, useState } from 'react'; -import { render } from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { Provider as ReduxProvider } from 'react-redux'; import { ThemeProvider } from 'styled-components'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; +import { setCSPForSafari } from '@src/utils'; import { AppRouter } from '@onboarding/app-router'; @@ -18,6 +19,8 @@ import { GlobalStyle, lightTheme } from '@libs/ui'; const Tree = () => { const [state, setState] = useState(null); + setCSPForSafari(); + useSubscribeToRedux({ windowInitAction: onboardingAppInit, setPopupState: setState @@ -43,4 +46,7 @@ const Tree = () => { ); }; -render(, document.querySelector('#app-container')); +const container = document.querySelector('#app-container'); +const root = createRoot(container!); + +root.render(); diff --git a/src/apps/onboarding/pages/confirm-secret-phrase-success/content.tsx b/src/apps/onboarding/pages/confirm-secret-phrase-success/content.tsx index 6451ea71a..f198d56b2 100644 --- a/src/apps/onboarding/pages/confirm-secret-phrase-success/content.tsx +++ b/src/apps/onboarding/pages/confirm-secret-phrase-success/content.tsx @@ -17,11 +17,8 @@ export function ConfirmSecretPhraseSuccessPageContent() { { key: 2, value: t('Never share the phrase with anyone.') }, { key: 3, - value: ( - - Be careful of phishing! Casper Wallet will never spontaneously ask for - your secret phrase. - + value: t( + 'Be careful of phishing! Casper Wallet will never spontaneously ask for your secret phrase.' ) }, { diff --git a/src/apps/onboarding/pages/create-secret-phrase-confirmation/content.tsx b/src/apps/onboarding/pages/create-secret-phrase-confirmation/content.tsx index 1225cfe15..82d2df0ad 100644 --- a/src/apps/onboarding/pages/create-secret-phrase-confirmation/content.tsx +++ b/src/apps/onboarding/pages/create-secret-phrase-confirmation/content.tsx @@ -16,11 +16,8 @@ export function CreateSecretPhraseConfirmationPageContent() { { key: 2, value: t('Never share the phrase with anyone.') }, { key: 3, - value: ( - - Be careful of phishing! Casper Wallet will never spontaneously ask you - for your secret recovery phrase. - + value: t( + 'Be careful of phishing! Casper Wallet will never spontaneously ask you for your secret recovery phrase.' ) }, { diff --git a/src/apps/onboarding/pages/unlock-wallet/index.tsx b/src/apps/onboarding/pages/unlock-wallet/index.tsx index 7f49ca499..2e1e6bdce 100644 --- a/src/apps/onboarding/pages/unlock-wallet/index.tsx +++ b/src/apps/onboarding/pages/unlock-wallet/index.tsx @@ -90,10 +90,13 @@ export function UnlockWalletPage({ saveIsLoggedIn }: UnlockWalletPageProps) { register={register} errorMessage={errors.password?.message} > - - Please enter your password to unlock. You have{' '} - {{ retryLeft }} tries left. - + }} + /> )} renderFooter={() => ( diff --git a/src/apps/popup/app-router.tsx b/src/apps/popup/app-router.tsx index 2be979a48..5b6515491 100644 --- a/src/apps/popup/app-router.tsx +++ b/src/apps/popup/app-router.tsx @@ -7,20 +7,22 @@ import { useUserActivityTracker } from '@src/hooks/use-user-activity-tracker'; import { AccountSettingsPage } from '@popup/pages/account-settings'; import { ActivityDetailsPage } from '@popup/pages/activity-details'; import { AddContactPage } from '@popup/pages/add-contact'; +import { AllAccountsPage } from '@popup/pages/all-accounts'; import { BackupSecretPhrasePage } from '@popup/pages/backup-secret-phrase'; +import { BuyCSPRPage } from '@popup/pages/buy-cspr'; import { ChangePasswordPage } from '@popup/pages/change-password'; import { ConnectAnotherAccountPageContent } from '@popup/pages/connect-another-account'; import { ConnectedSitesPage } from '@popup/pages/connected-sites'; import { ContactDetailsPage } from '@popup/pages/contact-details'; import { ContactsBookPage } from '@popup/pages/contacts'; import { CreateAccountPage } from '@popup/pages/create-account'; -import { DownloadSecretKeysPage } from '@popup/pages/download-secret-keys'; -import { DownloadedSecretKeysPage } from '@popup/pages/downloaded-secret-keys'; +import { DownloadAccountKeysPage } from '@popup/pages/download-account-keys'; import { HomePageContent } from '@popup/pages/home'; import { ImportAccountFromTorusPage } from '@popup/pages/import-account-from-torus'; import { NavigationMenuPageContent } from '@popup/pages/navigation-menu'; import { NftDetailsPage } from '@popup/pages/nft-details'; import { NoConnectedAccountPageContent } from '@popup/pages/no-connected-account'; +import { RateAppPage } from '@popup/pages/rate-app'; import { ReceivePage } from '@popup/pages/receive'; import { RemoveAccountPageContent } from '@popup/pages/remove-account'; import { RenameAccountPageContent } from '@popup/pages/rename-account'; @@ -236,12 +238,8 @@ function AppRoutes() { element={} /> } - /> - } + path={RouterPath.DownloadAccountKeys} + element={} /> } /> } /> + } /> + } /> } /> + } /> ); } diff --git a/src/apps/popup/index.html b/src/apps/popup/index.html index c0fe67ddd..e8c8c960f 100644 --- a/src/apps/popup/index.html +++ b/src/apps/popup/index.html @@ -2,10 +2,6 @@ - diff --git a/src/apps/popup/index.tsx b/src/apps/popup/index.tsx index b985b4ada..cc051bf5f 100644 --- a/src/apps/popup/index.tsx +++ b/src/apps/popup/index.tsx @@ -1,11 +1,11 @@ import React, { Suspense, useState } from 'react'; -import { render } from 'react-dom'; +import { createRoot } from 'react-dom/client'; // skeleton styles import 'react-loading-skeleton/dist/skeleton.css'; import { Provider as ReduxProvider } from 'react-redux'; import { ThemeProvider } from 'styled-components'; -import { isSafariBuild } from '@src/utils'; +import { isSafariBuild, setCSPForSafari } from '@src/utils'; import { createMainStoreReplica } from '@background/redux/get-main-store'; import { themeModeSettingChanged } from '@background/redux/settings/actions'; @@ -26,6 +26,8 @@ import { AppRouter } from './app-router'; const Tree = () => { const [state, setState] = useState(null); + setCSPForSafari(); + const isSystemDarkTheme = useSystemThemeDetector(); useSubscribeToRedux({ @@ -67,4 +69,7 @@ const Tree = () => { ); }; -render(, document.querySelector('#app-container')); +const container = document.querySelector('#app-container'); +const root = createRoot(container!); + +root.render(); diff --git a/src/apps/popup/pages/account-settings/content.tsx b/src/apps/popup/pages/account-settings/content.tsx index 4ade6ebe9..0ba76b291 100644 --- a/src/apps/popup/pages/account-settings/content.tsx +++ b/src/apps/popup/pages/account-settings/content.tsx @@ -7,9 +7,12 @@ import { RootState } from 'typesafe-actions'; import { RouterPath, useTypedNavigate } from '@popup/router'; +import { dispatchToMainStore } from '@background/redux/utils'; +import { hideAccountFromListChange } from '@background/redux/vault/actions'; import { selectVaultAccount, - selectVaultImportedAccounts + selectVaultHiddenAccountsNames, + selectVaultImportedAccountNames } from '@background/redux/vault/selectors'; import { useFetchAccountInfo } from '@hooks/use-fetch-account-info'; @@ -83,13 +86,20 @@ export function AccountSettingsPageContent() { } interface AccountIconButtonProps { - type: 'rename' | 'remove'; + type: 'rename' | 'remove' | 'hide' | 'show'; } function AccountIconButton({ type }: AccountIconButtonProps) { const { accountName } = useParams(); const navigate = useTypedNavigate(); + const icons = { + remove: 'assets/icons/delete.svg', + rename: 'assets/icons/edit.svg', + show: 'assets/icons/show.svg', + hide: 'assets/icons/hide.svg' + }; + const handleNavigateToNextPage = useCallback(() => { if (!accountName) { return; @@ -102,10 +112,14 @@ function AccountIconButton({ type }: AccountIconButtonProps) { case 'rename': navigate(RouterPath.RenameAccount.replace(':accountName', accountName)); break; + case 'hide': + case 'show': + dispatchToMainStore(hideAccountFromListChange({ accountName })); + break; default: throw new Error('Not found'); } - }, [navigate, accountName, type]); + }, [accountName, type, navigate]); if (!accountName) { return null; @@ -115,33 +129,32 @@ function AccountIconButton({ type }: AccountIconButtonProps) { ); } const AccountSettingsActionsGroupContainer = styled.div` display: flex; - gap: 28px; + gap: 24px; `; export function AccountSettingsActionsGroup() { const { accountName } = useParams(); - const importedAccountNames = useSelector(selectVaultImportedAccounts).map( - a => a.name - ); + const importedAccountNames = useSelector(selectVaultImportedAccountNames); + const hiddenAccountsNames = useSelector(selectVaultHiddenAccountsNames); if (!accountName) { return null; } const isImportedAccount = importedAccountNames.includes(accountName); + const isAccountHidden = hiddenAccountsNames.includes(accountName); return ( + {isImportedAccount && } ); diff --git a/src/apps/popup/pages/account-settings/index.tsx b/src/apps/popup/pages/account-settings/index.tsx index f605b4a1a..2ae2cd487 100644 --- a/src/apps/popup/pages/account-settings/index.tsx +++ b/src/apps/popup/pages/account-settings/index.tsx @@ -17,7 +17,7 @@ import { HeaderSubmenuBarNavLink, PopupLayout } from '@libs/layout'; -import { Button, Link } from '@libs/ui/components'; +import { Button } from '@libs/ui/components'; import { AccountSettingsActionsGroup, @@ -58,17 +58,12 @@ export const AccountSettingsPage = () => { renderFooter={() => ( + + + ); +}; diff --git a/src/apps/popup/pages/buy-cspr/country.tsx b/src/apps/popup/pages/buy-cspr/country.tsx new file mode 100644 index 000000000..f02d848c7 --- /dev/null +++ b/src/apps/popup/pages/buy-cspr/country.tsx @@ -0,0 +1,129 @@ +import React, { useEffect, useState } from 'react'; +import { useForm, useWatch } from 'react-hook-form'; +import { Trans, useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { selectAccountBalance } from '@background/redux/account-info/selectors'; + +import { + ContentContainer, + ParagraphContainer, + SpacingSize +} from '@libs/layout'; +import { ResponseCountryPropsWithId } from '@libs/services/buy-cspr-service/types'; +import { + ActiveAccountPlate, + List, + Modal, + Typography +} from '@libs/ui/components'; +import { motesToCSPR } from '@libs/ui/utils'; + +import { CountryRow } from './components/country-row'; +import { ListRow } from './components/list-row'; +import { Switcher } from './components/switcher'; +import { sortCountries } from './utils'; + +interface CountryProps { + availableCountries: ResponseCountryPropsWithId[]; + setSelectedCountry: React.Dispatch< + React.SetStateAction + >; + selectedCountry: ResponseCountryPropsWithId; +} + +export const Country = ({ + availableCountries, + setSelectedCountry, + selectedCountry +}: CountryProps) => { + const [sortedCountries, setSortedCountries] = useState< + ResponseCountryPropsWithId[] + >([]); + const { t } = useTranslation(); + + const csprBalance = useSelector(selectAccountBalance); + + const balance = + csprBalance.liquidMotes && motesToCSPR(csprBalance.liquidMotes); + + const { register, control, setValue } = useForm(); + + const inputValue = useWatch({ + control: control, + name: 'countryNameSearch' + }); + + useEffect(() => { + const sortedCountries = sortCountries( + availableCountries, + selectedCountry.code + ).filter( + country => + country?.name.toLowerCase().includes(inputValue?.toLowerCase() || '') + ); + + setSortedCountries(sortedCountries); + }, [availableCountries, inputValue, selectedCountry]); + + return ( + + + + Pick country + + + + + + ( + + { + const isSelected = selectedCountry.code === country.code; + + return ( + + ) => { + if (isSelected) { + return; + } + setSelectedCountry(country); + closeModal(e); + }} + isSelected={isSelected} + /> + ); + }} + marginLeftForItemSeparatorLine={54} + /> + + )} + placement="fullBottom" + children={() => ( + setValue('countryNameSearch', '')} + /> + )} + loading={!sortedCountries.length} + /> + + ); +}; diff --git a/src/apps/popup/pages/buy-cspr/index.tsx b/src/apps/popup/pages/buy-cspr/index.tsx new file mode 100644 index 000000000..2391ee9cf --- /dev/null +++ b/src/apps/popup/pages/buy-cspr/index.tsx @@ -0,0 +1,352 @@ +import React, { useEffect, useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { RouterPath, useTypedNavigate } from '@popup/router'; + +import { selectVaultActiveAccount } from '@background/redux/vault/selectors'; + +import { + ErrorPath, + FooterButtonsContainer, + HeaderPopup, + HeaderSubmenuBarNavLink, + PopupLayout, + createErrorLocationState +} from '@libs/layout'; +import { + dispatchFetchOnRampOptionGet, + dispatchFetchOnRampOptionPost, + dispatchFetchOnRampSelectionPost +} from '@libs/services/buy-cspr-service'; +import { + ProviderProps, + ResponseCountryPropsWithId, + ResponseCurrencyProps, + SelectionPostRequestData +} from '@libs/services/buy-cspr-service/types'; +import { Button, Typography } from '@libs/ui/components'; + +import { Amount } from './amount'; +import { Country } from './country'; +import { NoProvider } from './no-provider'; +import { Provider } from './provider'; +import { BuyCSPRSteps } from './utils'; + +export const BuyCSPRPage = () => { + const [buyCSPRStep, setBuyCSPRStep] = useState(BuyCSPRSteps.Country); + const [availableCountries, setAvailableCountries] = useState< + ResponseCountryPropsWithId[] + >([]); + const [selectedCountry, setSelectedCountry] = + useState({ + id: 0, + name: '', + code: '' + }); + const [currencies, setCurrencies] = useState([]); + const [selectedCurrency, setSelectedCurrency] = + useState({ + id: 0, + code: '', + type_id: '', + rate: 0 + }); + const [defaultAmount, setDefaultAmount] = useState('0'); + const [fiatAmount, setFiatAmount] = useState(0); + const [availableProviders, setAvailableProviders] = useState( + [] + ); + const [selectedProvider, setSelectedProvider] = + useState(null); + const [loadingAvailableProviders, setLoadingAvailableProviders] = + useState(false); + const [loadingRedirectUrl, setLoadingRedirectUrl] = useState(false); + + const { t } = useTranslation(); + const navigate = useTypedNavigate(); + + const activeAccount = useSelector(selectVaultActiveAccount); + + useEffect(() => { + dispatchFetchOnRampOptionGet() + .then(({ payload }) => { + if ('countries' in payload) { + const countriesWithId = payload.countries.map((country, id) => ({ + id, + ...country + })); + + const defaultSelectedCountry = countriesWithId.find( + country => country.code === payload.defaultCountry + ); + + const defaultSelectedCurrency = payload.currencies.find( + currency => currency.code === payload.defaultCurrency + ); + + setAvailableCountries(countriesWithId); + setCurrencies(payload.currencies); + setSelectedCountry(defaultSelectedCountry!); + setSelectedCurrency(defaultSelectedCurrency!); + setDefaultAmount(payload.defaultAmount); + setFiatAmount(Number(payload.defaultAmount)); + } else { + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: t('Something went wrong'), + errorContentText: + payload.error.message || + t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + } + }) + .catch(error => { + console.error(error.message, 'countries request failed'); + + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: error.message || t('Something went wrong'), + errorContentText: + typeof error.data === 'string' + ? error.data + : t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + }); + }, [navigate, t]); + + const handleAmountSubmit = () => { + setLoadingAvailableProviders(true); + + dispatchFetchOnRampOptionPost({ + amount: fiatAmount, + country: selectedCountry.code, + fiatCurrency: selectedCurrency.code, + paymentCurrency: selectedCurrency.code + }) + .then(({ payload }) => { + if ('availableProviders' in payload) { + if (payload.availableProviders.length === 0) { + setBuyCSPRStep(BuyCSPRSteps.NoProvider); + } else { + setAvailableProviders(payload.availableProviders); + + if (payload.availableProviders.length === 1) { + setSelectedProvider(payload.availableProviders[0]); + } + + setBuyCSPRStep(BuyCSPRSteps.Provider); + } + } else { + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: t('Something went wrong'), + errorContentText: + payload.error.message || + t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + } + }) + .catch(error => { + console.error(error.message, 'available provider request failed'); + + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: error.message || t('Something went wrong'), + errorContentText: + typeof error.data === 'string' + ? error.data + : t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + }) + .finally(() => setLoadingAvailableProviders(false)); + }; + + const handleSubmit = () => { + setLoadingRedirectUrl(true); + if (activeAccount && selectedProvider) { + const data: SelectionPostRequestData = { + account: activeAccount.publicKey, + fiatCurrency: selectedCurrency.code, + cryptoAmount: null, + cryptoAsset: 'CSPR', + selectedOnrampProvider: selectedProvider.providerKey, + fiatAmount + }; + + dispatchFetchOnRampSelectionPost(data) + .then(({ payload }) => { + if ('location' in payload) { + window.open(payload.location, '_blank'); + } else { + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: t('Something went wrong'), + errorContentText: + payload.error.message || + t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + } + }) + .catch(error => { + console.error(error.message, 'provider selection request failed'); + + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: error.message || t('Something went wrong'), + errorContentText: + typeof error.data === 'string' + ? error.data + : t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + }) + .finally(() => setLoadingRedirectUrl(false)); + } + }; + + const content = { + [BuyCSPRSteps.Country]: ( + + ), + [BuyCSPRSteps.Amount]: ( + + ), + [BuyCSPRSteps.Provider]: ( + + ), + [BuyCSPRSteps.NoProvider]: ( + + ) + }; + + const headerButton = { + [BuyCSPRSteps.Country]: , + [BuyCSPRSteps.Amount]: ( + setBuyCSPRStep(BuyCSPRSteps.Country)} + /> + ), + [BuyCSPRSteps.Provider]: ( + setBuyCSPRStep(BuyCSPRSteps.Amount)} + /> + ), + [BuyCSPRSteps.NoProvider]: + }; + + const footerButton = { + [BuyCSPRSteps.Country]: ( + + ), + [BuyCSPRSteps.Amount]: ( + <> + + + ), + [BuyCSPRSteps.Provider]: ( + <> + {selectedProvider ? ( + + You’ll be taken to provider’s website + + ) : null} + + + ), + [BuyCSPRSteps.NoProvider]: ( + + ) + }; + + return ( + ( + headerButton[buyCSPRStep]} + /> + )} + renderContent={() => content[buyCSPRStep]} + renderFooter={() => ( + + {footerButton[buyCSPRStep]} + + )} + /> + ); +}; diff --git a/src/apps/popup/pages/buy-cspr/no-provider.tsx b/src/apps/popup/pages/buy-cspr/no-provider.tsx new file mode 100644 index 000000000..d77a47af1 --- /dev/null +++ b/src/apps/popup/pages/buy-cspr/no-provider.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { Trans, useTranslation } from 'react-i18next'; + +import { + ContentContainer, + IllustrationContainer, + ParagraphContainer, + SpacingSize +} from '@libs/layout'; +import { SvgIcon, Typography } from '@libs/ui/components'; + +interface NoProviderProps { + countryName: string; + currencyCode: string; +} + +export const NoProvider = ({ countryName, currencyCode }: NoProviderProps) => { + const { t } = useTranslation(); + + return ( + + + + + + + + No available provider + + + + + + }} + /> + + + + ); +}; diff --git a/src/apps/popup/pages/buy-cspr/provider.tsx b/src/apps/popup/pages/buy-cspr/provider.tsx new file mode 100644 index 000000000..555c09f29 --- /dev/null +++ b/src/apps/popup/pages/buy-cspr/provider.tsx @@ -0,0 +1,142 @@ +import React from 'react'; +import { Trans, useTranslation } from 'react-i18next'; +import styled from 'styled-components'; + +import { + AlignedSpaceBetweenFlexRow, + ContentContainer, + FlexColumn, + FlexRow, + LeftAlignedFlexColumn, + ParagraphContainer, + SpacingSize +} from '@libs/layout'; +import { ProviderProps } from '@libs/services/buy-cspr-service/types'; +import { Checkbox, Tile, Typography } from '@libs/ui/components'; + +const ProviderContainer = styled(Tile)` + margin-top: 16px; + + cursor: pointer; +`; + +const Container = styled(FlexRow)` + padding: 0 0 16px 16px; +`; + +const ImageContainer = styled.div` + padding-top: 16px; +`; + +const Image = styled.img` + width: 32px; + height: 32px; + border-radius: ${({ theme }) => theme.borderRadius.eight}px; +`; + +const CheckBoxContainer = styled(AlignedSpaceBetweenFlexRow)` + padding-top: 8px; + padding-right: 16px; +`; + +const DividerLine = styled.hr` + margin-top: 8px; + + border-width: 0; + height: 0.5px; + background-color: ${({ theme }) => theme.color.borderPrimary}; +`; + +interface ProviderPageProps { + availableProviders: ProviderProps[]; + setSelectedProviders: React.Dispatch< + React.SetStateAction + >; + selectedProviders: ProviderProps | null; +} + +export const Provider = ({ + availableProviders, + setSelectedProviders, + selectedProviders +}: ProviderPageProps) => { + const { t } = useTranslation(); + + return ( + + + + + {availableProviders.length === 1 + ? 'Review provider option' + : 'Pick provider'} + + + + + {availableProviders.map(provider => { + const isSelected = + selectedProviders?.providerKey === provider.providerKey; + return ( + { + if (isSelected) { + return; + } + setSelectedProviders(provider); + }} + > + + + {provider.providerName} + + + + + + + {provider.providerName} + + + Fees + {` ~ ${provider.fees}`} + + + + + + + + + + 1 CSPR + + + ~ + + + {provider.csprExchangeRate} + + + + + You’ll get: + + {`${provider.cryptoAmount} CSPR`} + + + + + + ); + })} + + ); +}; diff --git a/src/apps/popup/pages/buy-cspr/utils.ts b/src/apps/popup/pages/buy-cspr/utils.ts new file mode 100644 index 000000000..da2b677de --- /dev/null +++ b/src/apps/popup/pages/buy-cspr/utils.ts @@ -0,0 +1,45 @@ +import { + ResponseCountryPropsWithId, + ResponseCurrencyProps +} from '@libs/services/buy-cspr-service/types'; + +export enum BuyCSPRSteps { + Country = 'country', + Amount = 'amount', + Provider = 'provider', + NoProvider = 'no provider' +} + +export function sortCountries( + availableCountries: ResponseCountryPropsWithId[], + selectedCountryCode: string +): ResponseCountryPropsWithId[] { + const copiedCountries = [...availableCountries]; + + return copiedCountries.sort((a, b) => { + if (a.code === selectedCountryCode) { + return -1; + } + if (b.code === selectedCountryCode) { + return 1; + } + return 0; + }); +} + +export const sortCurrencies = ( + currencies: ResponseCurrencyProps[], + selectedCurrencyCode: string +) => { + const copiedCurrencies = [...currencies]; + + return copiedCurrencies.sort((a, b) => { + if (a.code === selectedCurrencyCode) { + return -1; + } + if (b.code === selectedCurrencyCode) { + return 1; + } + return 0; + }); +}; diff --git a/src/apps/popup/pages/contact-details/details.tsx b/src/apps/popup/pages/contact-details/details.tsx index a26076343..3655ce83b 100644 --- a/src/apps/popup/pages/contact-details/details.tsx +++ b/src/apps/popup/pages/contact-details/details.tsx @@ -36,7 +36,7 @@ export const ContactDetails = ({ contact }: ContactDetailsProps) => { - + {contact.name} { )} {!isDeleting && !isEditing && ( + ), + [DownloadAccountKeysSteps.Download]: ( + + ), + [DownloadAccountKeysSteps.Success]: ( + + ) + }; + + return ( + ( + headerButton[downloadAccountKeysStep]} + /> + )} + renderContent={() => content[downloadAccountKeysStep]} + renderFooter={() => ( + + {footerButton[downloadAccountKeysStep]} + + )} + /> + ); +}; diff --git a/src/apps/popup/pages/download-account-keys/instruction.tsx b/src/apps/popup/pages/download-account-keys/instruction.tsx new file mode 100644 index 000000000..187c2990c --- /dev/null +++ b/src/apps/popup/pages/download-account-keys/instruction.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { Trans, useTranslation } from 'react-i18next'; + +import { + ContentContainer, + ParagraphContainer, + SpacingSize +} from '@libs/layout'; +import { Tips, Typography } from '@libs/ui/components'; + +import { safetyTips } from './utils'; + +export const Instruction = () => { + const { t } = useTranslation(); + + return ( + + + + Please remember + + + + + + + Private key files are needed to recover access to your accounts. + + + + + + + ); +}; diff --git a/src/apps/popup/pages/downloaded-secret-keys/content.tsx b/src/apps/popup/pages/download-account-keys/success.tsx similarity index 80% rename from src/apps/popup/pages/downloaded-secret-keys/content.tsx rename to src/apps/popup/pages/download-account-keys/success.tsx index 9f4486cf1..34a3eb725 100644 --- a/src/apps/popup/pages/downloaded-secret-keys/content.tsx +++ b/src/apps/popup/pages/download-account-keys/success.tsx @@ -9,8 +9,9 @@ import { } from '@libs/layout'; import { SvgIcon, Typography } from '@libs/ui/components'; -export function DownloadedSecretKeysPageContent() { +export const Success = () => { const { t } = useTranslation(); + return ( @@ -23,18 +24,18 @@ export function DownloadedSecretKeysPageContent() { - Your secret key was downloaded + You downloaded account private key(s) - Keep your account secret key file safe and secure. Do not share it - with anyone. + Keep your account private key file(s) safe and secure. Do not share + it with anyone. ); -} +}; diff --git a/src/apps/popup/pages/download-account-keys/utils.ts b/src/apps/popup/pages/download-account-keys/utils.ts new file mode 100644 index 000000000..c6a246d1b --- /dev/null +++ b/src/apps/popup/pages/download-account-keys/utils.ts @@ -0,0 +1,45 @@ +export enum DownloadAccountKeysSteps { + Instruction = 'instruction', + Download = 'download', + Success = 'success' +} + +export const downloadFile = (content: Blob, filename: string): void => { + // allocation + const url = window.URL.createObjectURL(content); + + const downloadFileLink = document.createElement('a'); + downloadFileLink.href = url; + downloadFileLink.setAttribute('download', filename); + downloadFileLink.click(); + downloadFileLink.remove(); + + // cleanup + window.URL.revokeObjectURL(url); +}; + +export const safetyTips = [ + { + id: 1, + header: 'Save files in secure locations.', + icon: 'assets/icons/secure.svg' + }, + { + id: 2, + header: 'Never share files with anyone.', + icon: 'assets/icons/lock.svg' + }, + { + id: 3, + header: 'Be careful of phishing', + description: + 'Casper Wallet will never spontaneously ask you for your private key files.', + icon: 'assets/icons/error.svg' + }, + { + id: 4, + header: 'Casper Wallet can’t recover it', + description: 'Casper Wallet does not keep a copy of your secret phrase.', + icon: 'assets/icons/cross-in-circle.svg' + } +]; diff --git a/src/apps/popup/pages/download-secret-keys/index.tsx b/src/apps/popup/pages/download-secret-keys/index.tsx deleted file mode 100644 index 5512a7ed1..000000000 --- a/src/apps/popup/pages/download-secret-keys/index.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React from 'react'; -import { Trans, useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { RouterPath, useTypedNavigate } from '@popup/router'; - -import { - selectPasswordHash, - selectPasswordSaltHash -} from '@background/redux/keys/selectors'; -import { loginRetryCountReseted } from '@background/redux/login-retry-count/actions'; -import { dispatchToMainStore } from '@background/redux/utils'; -import { selectVaultImportedAccounts } from '@background/redux/vault/selectors'; - -import { createAsymmetricKey } from '@libs/crypto/create-asymmetric-key'; -import { - FooterButtonsContainer, - HeaderPopup, - HeaderSubmenuBarNavLink, - PopupLayout, - UnlockProtectedPageContent -} from '@libs/layout'; -import { Button } from '@libs/ui/components'; -import { calculateSubmitButtonDisabled } from '@libs/ui/forms/get-submit-button-state-from-validation'; -import { useUnlockWalletForm } from '@libs/ui/forms/unlock-wallet'; - -import { downloadFile } from './utils'; - -export function DownloadSecretKeysPage() { - const navigate = useTypedNavigate(); - const { t } = useTranslation(); - - const passwordHash = useSelector(selectPasswordHash); - const passwordSaltHash = useSelector(selectPasswordSaltHash); - - if (passwordHash == null || passwordSaltHash == null) { - throw Error("Password doesn't exist"); - } - - const { - register, - handleSubmit, - formState: { isDirty, errors } - } = useUnlockWalletForm(passwordHash, passwordSaltHash); - - const importedAccounts = useSelector(selectVaultImportedAccounts); - - if (importedAccounts.length === 0) { - // Redirect to error page? - throw new Error('There are no imported accounts!'); - } - - const onSubmit = () => { - dispatchToMainStore(loginRetryCountReseted()); - try { - importedAccounts.forEach(account => { - const asymmetricKey = createAsymmetricKey( - account.publicKey, - account.secretKey - ); - const file = asymmetricKey.exportPrivateKeyInPem(); - downloadFile( - new Blob([file], { type: 'text/plain;charset=utf-8' }), - `${account.name}_secret_key.pem` - ); - }); - } catch (e) { - // Redirect to error page? - console.error(e); - } - - navigate(RouterPath.DownloadedSecretKeys); - }; - - const isSubmitButtonDisabled = calculateSubmitButtonDisabled({ - isDirty - }); - - return ( - ( - ( - - )} - /> - )} - renderContent={() => ( - - )} - renderFooter={() => ( - - - - )} - /> - ); -} diff --git a/src/apps/popup/pages/download-secret-keys/utils.ts b/src/apps/popup/pages/download-secret-keys/utils.ts deleted file mode 100644 index 08ee5f1c4..000000000 --- a/src/apps/popup/pages/download-secret-keys/utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -export function downloadFile(content: Blob, filename: string): void { - // allocation - const url = window.URL.createObjectURL(content); - - const downloadFileLink = document.createElement('a'); - downloadFileLink.href = url; - downloadFileLink.setAttribute('download', filename); - downloadFileLink.click(); - downloadFileLink.remove(); - - // cleanup - window.URL.revokeObjectURL(url); -} diff --git a/src/apps/popup/pages/downloaded-secret-keys/index.tsx b/src/apps/popup/pages/downloaded-secret-keys/index.tsx deleted file mode 100644 index 2aab51143..000000000 --- a/src/apps/popup/pages/downloaded-secret-keys/index.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { Trans, useTranslation } from 'react-i18next'; - -import { RouterPath, useTypedNavigate } from '@popup/router'; - -import { - FooterButtonsContainer, - HeaderPopup, - HeaderSubmenuBarNavLink, - PopupLayout -} from '@libs/layout'; -import { Button } from '@libs/ui/components'; - -import { DownloadedSecretKeysPageContent } from './content'; - -export function DownloadedSecretKeysPage() { - const navigate = useTypedNavigate(); - const { t } = useTranslation(); - return ( - ( - ( - - )} - /> - )} - renderContent={() => } - renderFooter={() => ( - - - - )} - /> - ); -} diff --git a/src/apps/popup/pages/home/components/more-buttons-modal/index.tsx b/src/apps/popup/pages/home/components/more-buttons-modal/index.tsx index db7973e3c..46464c667 100644 --- a/src/apps/popup/pages/home/components/more-buttons-modal/index.tsx +++ b/src/apps/popup/pages/home/components/more-buttons-modal/index.tsx @@ -13,21 +13,13 @@ const MoreButton = styled(CenteredFlexColumn)` padding: 0 16px; `; -interface MoreButtonsModalProps { - handleBuyWithCSPR: () => void; -} - -export const MoreButtonsModal = ({ - handleBuyWithCSPR -}: MoreButtonsModalProps) => { +export const MoreButtonsModal = () => { const { t } = useTranslation(); return ( ( - - )} + renderContent={() => } children={() => ( diff --git a/src/apps/popup/pages/home/index.tsx b/src/apps/popup/pages/home/index.tsx index ddf15632e..64dfbf20c 100644 --- a/src/apps/popup/pages/home/index.tsx +++ b/src/apps/popup/pages/home/index.tsx @@ -1,14 +1,9 @@ -import React, { useCallback, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; -import { tabs } from 'webextension-polyfill'; -import { - HomePageTabName, - NetworkSetting, - getBuyWithTopperUrl -} from '@src/constants'; +import { HomePageTabName, NetworkSetting } from '@src/constants'; import { RouterPath, useTypedLocation, useTypedNavigate } from '@popup/router'; @@ -83,15 +78,6 @@ export function HomePageContent() { const casperToken = useCasperToken(); - const handleBuyWithCSPR = useCallback(() => { - if (activeAccount?.publicKey && network === NetworkSetting.Mainnet) { - tabs.create({ - url: getBuyWithTopperUrl(activeAccount.publicKey), - active: true - }); - } - }, [activeAccount?.publicKey, network]); - useEffect(() => { if (!state?.activeTabId) { const container = document.querySelector('#ms-container'); @@ -133,7 +119,7 @@ export function HomePageContent() { {network === NetworkSetting.Mainnet && ( navigate(RouterPath.BuyCSPR)} > + + + ), + [RateAppSteps.Rate]: ( + + ), + [RateAppSteps.Support]: ( + <> + + + + ) + }; + + /** + * Defines header buttons to be shown based on the current rate app step. + * The actions dispatch relevant actions to the Redux store and set the rate app step or navigation path accordingly. + */ + const headerButtons = { + [RateAppSteps.Navigation]: ( + { + const date = new Date(); // This will get current date + const datePlusOneMonth = date.setMonth(date.getMonth() + 1); //This will set a date 1 month ahead. + + dispatchToMainStore(ratedInStoreChanged(false)); + dispatchToMainStore(askForReviewAfterChanged(datePlusOneMonth)); + + navigate(RouterPath.Home); + }} + /> + ), + [RateAppSteps.Rate]: ( + setReviewStep(RateAppSteps.Navigation)} + /> + ), + [RateAppSteps.Support]: ( + setReviewStep(RateAppSteps.Navigation)} + /> + ) + }; + + /** + * Generates the page layout, including the header, main content and footer. + */ + return ( + ( + headerButtons[reviewStep]} + /> + )} + renderContent={() => content[reviewStep]} + renderFooter={() => ( + + {footerButtons[reviewStep]} + + )} + /> + ); +}; diff --git a/src/apps/popup/pages/rate-app/utils.ts b/src/apps/popup/pages/rate-app/utils.ts new file mode 100644 index 000000000..28be8e82a --- /dev/null +++ b/src/apps/popup/pages/rate-app/utils.ts @@ -0,0 +1,45 @@ +// Import necessary modules +import { Browser } from '@src/constants'; + +// Enum for different steps involved in a rate app +export enum RateAppSteps { + Navigation = 'navigation', // The navigation step in the rate app process + Rate = 'rate', // The main rate-writing step + Support = 'support' // The customer support step (if any) in the review process +} + +/** + * Function to identify the browser from the user agent. + * + * @returns {Browser | 'Unknown'} - The name of the browser the user is using. + */ +export const getBrowserFromUserAgent = (): Browser | 'Unknown' => { + const userAgent = navigator.userAgent; + + // Run regex tests on the userAgent to identify the browser + if (/chrome/i.test(userAgent) && !/edg/i.test(userAgent)) { + return Browser.Chrome; + } else if (/firefox/i.test(userAgent)) { + return Browser.Firefox; + } else if (/edg/i.test(userAgent)) { + return Browser.Edge; + } else if (/safari/i.test(userAgent) && !/chrome/i.test(userAgent)) { + return Browser.Safari; + } else { + // if the browser can't be identified, return 'Unknown' + return 'Unknown'; + } +}; + +// Map of rate app links for different browsers +export const RateAppLinks = { + [Browser.Chrome]: + 'https://chromewebstore.google.com/detail/casper-wallet/abkahkcbhngaebpcgfmhkoioedceoigp/reviews', + [Browser.Firefox]: + 'https://addons.mozilla.org/en-US/firefox/addon/casper-wallet/', + [Browser.Safari]: 'https://apps.apple.com/us/app/casper-wallet/id6446363274', + [Browser.Edge]: + 'https://microsoftedge.microsoft.com/addons/detail/casper-wallet/dfmbcapkkeejcpmfhpnglndfkgmalhik', + Unknown: + 'https://chromewebstore.google.com/detail/casper-wallet/abkahkcbhngaebpcgfmhkoioedceoigp/reviews' +}; diff --git a/src/apps/popup/pages/stakes/amount-step.tsx b/src/apps/popup/pages/stakes/amount-step.tsx index 49543ac35..afe66ba9f 100644 --- a/src/apps/popup/pages/stakes/amount-step.tsx +++ b/src/apps/popup/pages/stakes/amount-step.tsx @@ -5,7 +5,11 @@ import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; -import { AuctionManagerEntryPoint, STAKE_COST_MOTES } from '@src/constants'; +import { + AuctionManagerEntryPoint, + DELEGATION_MIN_AMOUNT_MOTES, + STAKE_COST_MOTES +} from '@src/constants'; import { selectAccountBalance, @@ -20,10 +24,14 @@ import { } from '@libs/layout'; import { Error, Input, Typography } from '@libs/ui/components'; import { StakeAmountFormValues } from '@libs/ui/forms/stakes-form'; -import { formatFiatAmount, motesToCSPR } from '@libs/ui/utils'; +import { + formatFiatAmount, + handleNumericInput, + motesToCSPR +} from '@libs/ui/utils'; -const StakeMaxButton = styled(AlignedFlexRow)` - cursor: pointer; +const StakeMaxButton = styled(AlignedFlexRow)<{ disabled?: boolean }>` + cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')}; `; interface AmountStepProps { @@ -42,6 +50,7 @@ export const AmountStep = ({ amountStepMaxAmountValue }: AmountStepProps) => { const [maxAmountMotes, setMaxAmountMotes] = useState('0'); + const [disabled, setDisabled] = useState(false); const { t } = useTranslation(); @@ -55,12 +64,25 @@ export const AmountStep = ({ csprBalance.liquidMotes == null ? '0' : Big(csprBalance.liquidMotes).sub(STAKE_COST_MOTES).toFixed(); + const minAmount = Big(STAKE_COST_MOTES) + .add(DELEGATION_MIN_AMOUNT_MOTES) + .toFixed(); + const hasEnoughBalance = + csprBalance.liquidMotes != null && + Big(csprBalance.liquidMotes).gte(minAmount); + + setDisabled(!hasEnoughBalance); setMaxAmountMotes(maxAmountMotes); break; } case AuctionManagerEntryPoint.undelegate: case AuctionManagerEntryPoint.redelegate: { + const hasEnoughBalance = + csprBalance.liquidMotes != null && + Big(csprBalance.liquidMotes).gte(STAKE_COST_MOTES); + + setDisabled(!hasEnoughBalance); setMaxAmountMotes(stakeAmountMotes); } } @@ -74,8 +96,6 @@ export const AmountStep = ({ trigger } = amountForm; - const { onChange: onChangeCSPRAmount } = register('amount'); - const amount = useWatch({ control, name: 'amount' @@ -87,36 +107,54 @@ export const AmountStep = ({ return ( <> + {disabled && ( + + + + )} { - // replace all non-numeric characters except decimal point - e.target.value = e.target.value.replace(/[^0-9.]/g, ''); - // regex replace decimal point from beginning of string - e.target.value = e.target.value.replace(/^\./, ''); - onChangeCSPRAmount(e); - }} + onKeyDown={handleNumericInput} + disabled={disabled} /> { + if (disabled) return; + setValue('amount', motesToCSPR(maxAmountMotes)); trigger('amount'); }} > - + {amountStepText} {amountStepMaxAmountValue && ( - + {amountStepMaxAmountValue} )} diff --git a/src/apps/popup/pages/stakes/content.tsx b/src/apps/popup/pages/stakes/content.tsx index eb2af77e7..2cc376506 100644 --- a/src/apps/popup/pages/stakes/content.tsx +++ b/src/apps/popup/pages/stakes/content.tsx @@ -44,6 +44,7 @@ interface DelegateStakePageContentProps { setStakeAmount: React.Dispatch>; validatorList: ValidatorResultWithId[] | null; undelegateValidatorList: ValidatorResultWithId[] | null; + loading: boolean; } export const StakesPageContent = ({ @@ -60,7 +61,8 @@ export const StakesPageContent = ({ stakeAmountMotes, setStakeAmount, validatorList, - undelegateValidatorList + undelegateValidatorList, + loading }: DelegateStakePageContentProps) => { const { t } = useTranslation(); @@ -87,6 +89,7 @@ export const StakesPageContent = ({ setValidator={setValidator} setStakeAmount={setStakeAmount} stakesType={stakesType} + loading={loading} /> ); diff --git a/src/apps/popup/pages/stakes/index.tsx b/src/apps/popup/pages/stakes/index.tsx index 96d65e579..ea1907278 100644 --- a/src/apps/popup/pages/stakes/index.tsx +++ b/src/apps/popup/pages/stakes/index.tsx @@ -7,34 +7,35 @@ import { STAKE_COST_MOTES, StakeSteps } from '@src/constants'; +import { fetchAndDispatchExtendedDeployInfo } from '@src/utils'; import { StakesPageContent } from '@popup/pages/stakes/content'; import { NoDelegations } from '@popup/pages/stakes/no-delegations'; import { useConfirmationButtonText } from '@popup/pages/stakes/utils'; import { RouterPath, useTypedLocation, useTypedNavigate } from '@popup/router'; -import { accountPendingTransactionsChanged } from '@background/redux/account-info/actions'; import { selectAccountBalance } from '@background/redux/account-info/selectors'; +import { + selectAskForReviewAfter, + selectRatedInStore +} from '@background/redux/rate-app/selectors'; import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors'; -import { dispatchToMainStore } from '@background/redux/utils'; import { selectVaultActiveAccount } from '@background/redux/vault/selectors'; import { createAsymmetricKey } from '@libs/crypto/create-asymmetric-key'; import { - CenteredFlexRow, - ContentContainer, ErrorPath, FooterButtonsContainer, HeaderPopup, HeaderSubmenuBarNavLink, - ParagraphContainer, PopupLayout, SpaceBetweenFlexRow, - SpacingSize, createErrorLocationState } from '@libs/layout'; -import { dispatchFetchExtendedDeploysInfo } from '@libs/services/account-activity-service'; -import { makeAuctionManagerDeploy } from '@libs/services/deployer-service'; +import { + makeAuctionManagerDeployAndSing, + sendSignDeploy +} from '@libs/services/deployer-service'; import { dispatchFetchAuctionValidatorsRequest, dispatchFetchValidatorsDetailsDataRequest @@ -76,6 +77,8 @@ export const StakesPage = () => { casperClarityApiUrl } = useSelector(selectApiConfigBasedOnActiveNetwork); const csprBalance = useSelector(selectAccountBalance); + const ratedInStore = useSelector(selectRatedInStore); + const askForReviewAfter = useSelector(selectAskForReviewAfter); const { t } = useTranslation(); const navigate = useTypedNavigate(); @@ -217,7 +220,7 @@ export const StakesPage = () => { }; }, [isSubmitButtonDisable, stakeStep]); - const submitStake = () => { + const submitStake = async () => { if (activeAccount) { const motesAmount = CSPRtoMotes(inputAmountCSPR); @@ -226,52 +229,59 @@ export const StakesPage = () => { activeAccount.secretKey ); - const deploy = makeAuctionManagerDeploy( + const signDeploy = await makeAuctionManagerDeployAndSing( stakesType, activeAccount.publicKey, validatorPublicKey, newValidatorPublicKey || null, motesAmount, networkName, - auctionManagerContractHash + auctionManagerContractHash, + nodeUrl, + [KEYS] ); - const signDeploy = deploy.sign([KEYS]); - - signDeploy.send(nodeUrl).then((deployHash: string) => { - if (deployHash) { - let triesLeft = 10; - const interval = setInterval(async () => { - const { payload: extendedDeployInfo } = - await dispatchFetchExtendedDeploysInfo(deployHash); - if (extendedDeployInfo) { - dispatchToMainStore( - accountPendingTransactionsChanged(extendedDeployInfo) - ); - clearInterval(interval); - } else if (triesLeft === 0) { - clearInterval(interval); - } - - triesLeft--; - // Note: this timeout is needed because the deploy is not immediately visible in the explorer - }, 2000); + sendSignDeploy(signDeploy, nodeUrl) + .then(resp => { + if ('result' in resp) { + fetchAndDispatchExtendedDeployInfo(resp.result.deploy_hash); + + setStakeStep(StakeSteps.Success); + } else { + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: + resp.error.message || t('Something went wrong'), + errorContentText: + resp.error.data || + t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + } + }) + .catch(error => { + console.error(error, 'staking request error'); - setStakeStep(StakeSteps.Success); - } else { navigate( ErrorPath, createErrorLocationState({ - errorHeaderText: t('Something went wrong'), - errorContentText: t( - 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' - ), + errorHeaderText: error.message || t('Something went wrong'), + errorContentText: + typeof error.data === 'string' + ? error.data + : t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), errorPrimaryButtonLabel: t('Close'), errorRedirectPath: RouterPath.Home }) ); - } - }); + }); } }; @@ -337,12 +347,26 @@ export const StakesPage = () => { case StakeSteps.Success: { return { onClick: () => { - navigate(RouterPath.Home, { - state: { - // set the active tab to deploys - activeTabId: HomePageTabsId.Deploys - } - }); + const currentDate = Date.now(); + + const shouldAskForReview = + askForReviewAfter == null || currentDate > askForReviewAfter; + + if (ratedInStore || !shouldAskForReview) { + const homeRoutesState = { + state: { + // set the active tab to deploys + activeTabId: HomePageTabsId.Deploys + } + }; + + // Navigate "Home" with the pre-defined state + navigate(RouterPath.Home, homeRoutesState); + } else { + // Navigate to "RateApp" when the application has not been rated in the store, + // and it's time to ask for a review. + navigate(RouterPath.RateApp); + } } }; } @@ -381,32 +405,10 @@ export const StakesPage = () => { const confirmButtonText = useConfirmationButtonText(stakesType); - if (loading) { - return ( - ( - - )} - renderContent={() => ( - - - - - Loading... - - - - - )} - /> - ); - } - if ( (stakesType === AuctionManagerEntryPoint.undelegate || stakesType === AuctionManagerEntryPoint.redelegate) && - undelegateValidatorList !== null && - undelegateValidatorList.length === 0 + (csprBalance.delegatedMotes == null || csprBalance.delegatedMotes === '0') ) { return ( { setStakeAmount={setStakeAmountMotes} validatorList={validatorList} undelegateValidatorList={undelegateValidatorList} + loading={loading} /> )} renderFooter={() => ( diff --git a/src/apps/popup/pages/stakes/redelegate-validator-dropdown-input.tsx b/src/apps/popup/pages/stakes/redelegate-validator-dropdown-input.tsx index 162d28c13..9750d797a 100644 --- a/src/apps/popup/pages/stakes/redelegate-validator-dropdown-input.tsx +++ b/src/apps/popup/pages/stakes/redelegate-validator-dropdown-input.tsx @@ -154,7 +154,7 @@ export const RedelegateValidatorDropdownInput = ({ ( diff --git a/src/apps/popup/pages/stakes/utils.ts b/src/apps/popup/pages/stakes/utils.ts index 57d2f53cb..3fec838e9 100644 --- a/src/apps/popup/pages/stakes/utils.ts +++ b/src/apps/popup/pages/stakes/utils.ts @@ -22,6 +22,34 @@ type StakeActionTextMap = Record< Omit >; +const stakeActionsTextMap: StakeActionTextMap = { + [AuctionManagerEntryPoint.delegate]: { + validatorStepHeaderText: 'Delegate', + amountStepHeaderText: 'Delegate amount', + confirmStepHeaderText: 'Confirm delegation', + successStepHeaderText: 'You’ve submitted a delegation', + amountStepText: 'Delegate max', + confirmStepText: 'You’ll delegate' + }, + [AuctionManagerEntryPoint.undelegate]: { + validatorStepHeaderText: 'Undelegate', + amountStepHeaderText: 'Undelegate amount', + confirmStepHeaderText: 'Confirm undelegation', + successStepHeaderText: 'You’ve submitted an undelegation', + amountStepText: 'Undelegate max:', + confirmStepText: 'You’ll undelegate' + }, + [AuctionManagerEntryPoint.redelegate]: { + validatorStepHeaderText: 'Redelegate', + amountStepHeaderText: 'Redelegate amount', + newValidatorStepHeaderText: 'Delegate', + confirmStepHeaderText: 'Confirm redelegation', + successStepHeaderText: 'You’ve submitted a redelegation', + amountStepText: 'Redelegate max:', + confirmStepText: 'You’ll redelegate' + } +}; + export const useFilteredValidators = ( inputValue: string | undefined, validatorList: ValidatorResultWithId[] | null @@ -56,34 +84,6 @@ export const useStakeActionTexts = ( stakesType: AuctionManagerEntryPoint, stakeAmountMotes?: string ) => { - const stakeActionsTextMap: StakeActionTextMap = { - [AuctionManagerEntryPoint.delegate]: { - validatorStepHeaderText: 'Delegate', - amountStepHeaderText: 'Delegate amount', - confirmStepHeaderText: 'Confirm delegation', - successStepHeaderText: 'You’ve submitted a delegation', - amountStepText: 'Delegate max', - confirmStepText: 'You’ll delegate' - }, - [AuctionManagerEntryPoint.undelegate]: { - validatorStepHeaderText: 'Undelegate', - amountStepHeaderText: 'Undelegate amount', - confirmStepHeaderText: 'Confirm undelegation', - successStepHeaderText: 'You’ve submitted an undelegation', - amountStepText: 'Undelegate max:', - confirmStepText: 'You’ll undelegate' - }, - [AuctionManagerEntryPoint.redelegate]: { - validatorStepHeaderText: 'Redelegate', - amountStepHeaderText: 'Redelegate amount', - newValidatorStepHeaderText: 'Delegate', - confirmStepHeaderText: 'Confirm redelegation', - successStepHeaderText: 'You’ve submitted a redelegation', - amountStepText: 'Redelegate max:', - confirmStepText: 'You’ll redelegate' - } - }; - const [state, setState] = useState({ ...stakeActionsTextMap[stakesType], amountStepMaxAmountValue: null @@ -94,13 +94,13 @@ export const useStakeActionTexts = ( stakeAmountMotes && formatNumber(motesToCSPR(stakeAmountMotes), { precision: { max: 4 } }); - setState(prevState => ({ - ...prevState, + setState({ + ...stakeActionsTextMap[stakesType], amountStepMaxAmountValue: stakesType !== AuctionManagerEntryPoint.delegate ? `${formattedAmountCSPR} CSPR` : null - })); + }); }, [stakeAmountMotes, stakesType]); return state; diff --git a/src/apps/popup/pages/stakes/validator-dropdown-input.tsx b/src/apps/popup/pages/stakes/validator-dropdown-input.tsx index cc6df0a51..d2ab05703 100644 --- a/src/apps/popup/pages/stakes/validator-dropdown-input.tsx +++ b/src/apps/popup/pages/stakes/validator-dropdown-input.tsx @@ -18,6 +18,7 @@ import { ValidatorResultWithId } from '@libs/services/validators-service/types'; import { Input, List, + Spinner, SvgIcon, Typography, ValidatorPlate @@ -34,6 +35,7 @@ interface ValidatorDropdownInputProps { setStakeAmount: React.Dispatch>; stakesType: AuctionManagerEntryPoint; undelegateValidatorList: ValidatorResultWithId[] | null; + loading: boolean; } export const ValidatorDropdownInput = ({ @@ -43,7 +45,8 @@ export const ValidatorDropdownInput = ({ setValidator, setStakeAmount, stakesType, - undelegateValidatorList + undelegateValidatorList, + loading }: ValidatorDropdownInputProps) => { const [isOpenValidatorPublicKeysList, setIsOpenValidatorPublicKeysList] = useState(true); @@ -114,9 +117,6 @@ export const ValidatorDropdownInput = ({ setLabel('From validator'); break; } - - default: - throw Error('fetch validator: unknown stakes type'); } }, [stakesType]); @@ -179,11 +179,12 @@ export const ValidatorDropdownInput = ({ {...register('validatorPublicKey')} autoComplete="off" /> - {isOpenValidatorPublicKeysList && ( + {loading && } + {isOpenValidatorPublicKeysList && !loading && ( ( diff --git a/src/apps/popup/pages/token-details/token.tsx b/src/apps/popup/pages/token-details/token.tsx index 0d0b95388..081d80b7c 100644 --- a/src/apps/popup/pages/token-details/token.tsx +++ b/src/apps/popup/pages/token-details/token.tsx @@ -4,7 +4,7 @@ import { useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; import styled from 'styled-components'; -import { NetworkSetting, getBuyWithTopperUrl } from '@src/constants'; +import { NetworkSetting } from '@src/constants'; import { formatErc20TokenBalance } from '@popup/pages/home/components/tokens-list/utils'; import { RouterPath, useTypedLocation, useTypedNavigate } from '@popup/router'; @@ -26,7 +26,6 @@ import { import { ContractPackageWithBalance } from '@libs/services/erc20-service'; import { Button, - Link, List, SvgIcon, TokenPlate, @@ -168,27 +167,19 @@ export const Token = ({ erc20Tokens }: TokenProps) => { Receive - {tokenName === 'Casper' && - network === NetworkSetting.Mainnet && - activeAccount?.publicKey && ( - - - - - Buy - - - - )} + {tokenName === 'Casper' && network === NetworkSetting.Mainnet && ( + navigate(RouterPath.BuyCSPR)} + > + + + Buy + + + )} )} marginLeftForItemSeparatorLine={16} diff --git a/src/apps/popup/pages/transfer-nft/index.tsx b/src/apps/popup/pages/transfer-nft/index.tsx index a9cd514b5..63b51b7ab 100644 --- a/src/apps/popup/pages/transfer-nft/index.tsx +++ b/src/apps/popup/pages/transfer-nft/index.tsx @@ -3,25 +3,28 @@ import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; -import { MapNFTTokenStandardToName } from '@src/utils'; +import { + MapNFTTokenStandardToName, + fetchAndDispatchExtendedDeployInfo +} from '@src/utils'; import { TransferNftContent } from '@popup/pages/transfer-nft/content'; import { getDefaultPaymentAmountBasedOnNftTokenStandard, - getRuntimeArgs, - signNftDeploy + getRuntimeArgs } from '@popup/pages/transfer-nft/utils'; import { RouterPath, useTypedNavigate } from '@popup/router'; -import { - accountPendingTransactionsChanged, - accountTrackingIdOfSentNftTokensChanged -} from '@background/redux/account-info/actions'; +import { accountTrackingIdOfSentNftTokensChanged } from '@background/redux/account-info/actions'; import { selectAccountBalance, selectAccountNftTokens } from '@background/redux/account-info/selectors'; import { selectAllPublicKeys } from '@background/redux/contacts/selectors'; +import { + selectAskForReviewAfter, + selectRatedInStore +} from '@background/redux/rate-app/selectors'; import { recipientPublicKeyAdded } from '@background/redux/recent-recipient-public-keys/actions'; import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors'; import { dispatchToMainStore } from '@background/redux/utils'; @@ -37,7 +40,10 @@ import { PopupLayout, createErrorLocationState } from '@libs/layout'; -import { dispatchFetchExtendedDeploysInfo } from '@libs/services/account-activity-service'; +import { + makeNFTDeployAndSign, + sendSignDeploy +} from '@libs/services/deployer-service'; import { Button, HomePageTabsId, @@ -59,6 +65,8 @@ export const TransferNftPage = () => { selectApiConfigBasedOnActiveNetwork ); const contactPublicKeys = useSelector(selectAllPublicKeys); + const ratedInStore = useSelector(selectRatedInStore); + const askForReviewAfter = useSelector(selectAskForReviewAfter); const { t } = useTranslation(); const navigate = useTypedNavigate(); @@ -133,58 +141,68 @@ export const TransferNftPage = () => { target: getRawPublicKey(recipientPublicKey) }; - const signDeploy = signNftDeploy( + const signDeploy = await makeNFTDeployAndSign( getRuntimeArgs(tokenStandard, args), CSPRtoMotes(paymentAmount), KEYS.publicKey, networkName, nftToken?.contract_package_hash!, + nodeUrl, [KEYS] ); - signDeploy.send(nodeUrl).then((deployHash: string) => { - dispatchToMainStore(recipientPublicKeyAdded(recipientPublicKey)); + sendSignDeploy(signDeploy, nodeUrl) + .then(resp => { + dispatchToMainStore(recipientPublicKeyAdded(recipientPublicKey)); - if (deployHash) { - dispatchToMainStore( - accountTrackingIdOfSentNftTokensChanged({ - trackingId: nftToken.tracking_id, - deployHash - }) - ); + if ('result' in resp) { + const deployHash = resp.result.deploy_hash; + + dispatchToMainStore( + accountTrackingIdOfSentNftTokensChanged({ + trackingId: nftToken.tracking_id, + deployHash + }) + ); + + fetchAndDispatchExtendedDeployInfo(deployHash); + + setShowSuccessScreen(true); + } else { + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: + resp.error.message || t('Something went wrong'), + errorContentText: + resp.error.data || + t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + } + }) + .catch(error => { + console.error(error, 'nft transfer request error'); - let triesLeft = 10; - const interval = setInterval(async () => { - const { payload: extendedDeployInfo } = - await dispatchFetchExtendedDeploysInfo(deployHash); - if (extendedDeployInfo) { - dispatchToMainStore( - accountPendingTransactionsChanged(extendedDeployInfo) - ); - clearInterval(interval); - } else if (triesLeft === 0) { - clearInterval(interval); - } - - triesLeft--; - // Note: this timeout is needed because the deploy is not immediately visible in the explorer - }, 2000); - - setShowSuccessScreen(true); - } else { navigate( ErrorPath, createErrorLocationState({ - errorHeaderText: t('Something went wrong'), - errorContentText: t( - 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' - ), + errorHeaderText: error.message || t('Something went wrong'), + errorContentText: + typeof error.data === 'string' + ? error.data + : t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), errorPrimaryButtonLabel: t('Close'), errorRedirectPath: RouterPath.Home }) ); - } - }); + }); } }; @@ -222,12 +240,26 @@ export const TransferNftPage = () => { color="primaryBlue" type="button" onClick={() => { - navigate(RouterPath.Home, { - state: { - // set the active tab to deploys - activeTabId: HomePageTabsId.Deploys - } - }); + const currentDate = Date.now(); + + const shouldAskForReview = + askForReviewAfter == null || + currentDate > askForReviewAfter; + + if (ratedInStore || !shouldAskForReview) { + const homeRoutesState = { + state: { + // set the active tab to deploys + activeTabId: HomePageTabsId.Deploys + } + }; + + // Navigate to "Home" with the pre-defined state + navigate(RouterPath.Home, homeRoutesState); + } else { + // Navigate to "RateApp" when the application has not been rated in the store, and it's time to ask for a review. + navigate(RouterPath.RateApp); + } }} > Done diff --git a/src/apps/popup/pages/transfer-nft/utils.ts b/src/apps/popup/pages/transfer-nft/utils.ts index 3a17db89f..7f62a4845 100644 --- a/src/apps/popup/pages/transfer-nft/utils.ts +++ b/src/apps/popup/pages/transfer-nft/utils.ts @@ -1,12 +1,4 @@ -import { - CLKeyParameters, - CLPublicKey, - CLValueBuilder, - DeployUtil, - Keys, - RuntimeArgs -} from 'casper-js-sdk'; -import { sub } from 'date-fns'; +import { CLKeyParameters, CLValueBuilder, RuntimeArgs } from 'casper-js-sdk'; import { NFT_CEP47_PAYMENT_AMOUNT_AVERAGE_MOTES, @@ -93,34 +85,3 @@ export const getRuntimeArgs = ( throw new Error('Unknown token standard.'); } }; - -export const signNftDeploy = ( - runtimeArgs: RuntimeArgs, - paymentAmount: string, - deploySender: CLPublicKey, - networkName: string, - contractPackageHash: string, - keys: Keys.AsymmetricKey[] -) => { - const hash = Uint8Array.from(Buffer.from(contractPackageHash, 'hex')); - - const deployParams = new DeployUtil.DeployParams( - deploySender, - networkName, - undefined, - undefined, - undefined, - sub(new Date(), { seconds: 2 }).getTime() - ); // https://github.com/casper-network/casper-node/issues/4152 - const session = - DeployUtil.ExecutableDeployItem.newStoredVersionContractByHash( - hash, - null, - 'transfer', - runtimeArgs - ); - const payment = DeployUtil.standardPayment(paymentAmount); - const deploy = DeployUtil.makeDeploy(deployParams, session, payment); - - return deploy.sign(keys); -}; diff --git a/src/apps/popup/pages/transfer/amount-step.tsx b/src/apps/popup/pages/transfer/amount-step.tsx index c68cf592c..9ed16698d 100644 --- a/src/apps/popup/pages/transfer/amount-step.tsx +++ b/src/apps/popup/pages/transfer/amount-step.tsx @@ -17,9 +17,13 @@ import { SpacingSize, VerticalSpaceContainer } from '@libs/layout'; -import { Checkbox, Input, Typography } from '@libs/ui/components'; +import { Checkbox, Error, Input, Typography } from '@libs/ui/components'; import { TransferAmountFormValues } from '@libs/ui/forms/transfer'; -import { formatFiatAmount, motesToCSPR } from '@libs/ui/utils'; +import { + formatFiatAmount, + handleNumericInput, + motesToCSPR +} from '@libs/ui/utils'; interface AmountStepProps { amountForm: UseFormReturn; @@ -63,7 +67,6 @@ export const AmountStep = ({ amountForm, symbol, isCSPR }: AmountStepProps) => { const { onChange: onChangeTransferIdMemo } = register('transferIdMemo'); const { onChange: onChangeCSPRAmount } = register('amount'); - const { onChange: onChangePaymentAmount } = register('paymentAmount'); const amount = useWatch({ control, @@ -94,14 +97,13 @@ export const AmountStep = ({ amountForm, symbol, isCSPR }: AmountStepProps) => { {isCSPR && disabled && ( - - - - You don't have enough CSPR to cover the transfer minimum amount - and the transaction fee. - - - + + + )} @@ -109,21 +111,19 @@ export const AmountStep = ({ amountForm, symbol, isCSPR }: AmountStepProps) => { label={amountLabel} rightLabel={fiatAmount} monotype + type="number" placeholder={t('0.00')} suffixText={symbol} {...register('amount')} disabled={isCSPR && disabled} onChange={e => { - // replace all non-numeric characters except decimal point - e.target.value = e.target.value.replace(/[^0-9.]/g, ''); - // regex replace decimal point from beginning of string - e.target.value = e.target.value.replace(/^\./, ''); onChangeCSPRAmount(e); if (isChecked) { setIsChecked(false); } }} + onKeyDown={handleNumericInput} error={!!errors?.amount} validationText={errors?.amount?.message} /> @@ -171,18 +171,12 @@ export const AmountStep = ({ amountForm, symbol, isCSPR }: AmountStepProps) => { label={paymentAmoutLabel} rightLabel={paymentFiatAmount} monotype + type="number" placeholder={t('Enter transaction fee')} suffixText={'CSPR'} {...register('paymentAmount')} - onChange={e => { - // replace all non-numeric characters except decimal point - e.target.value = e.target.value.replace(/[^0-9.]/g, ''); - // regex replace decimal point from beginning of string - e.target.value = e.target.value.replace(/^\./, ''); - - onChangePaymentAmount(e); - }} error={!!errors?.paymentAmount} + onKeyDown={handleNumericInput} validationText={ errors?.paymentAmount?.message || "You'll be charged this amount in CSPR as a transaction fee. You can change it at your discretion." diff --git a/src/apps/popup/pages/transfer/index.tsx b/src/apps/popup/pages/transfer/index.tsx index 815b8d159..ba5c7bb9c 100644 --- a/src/apps/popup/pages/transfer/index.tsx +++ b/src/apps/popup/pages/transfer/index.tsx @@ -1,6 +1,4 @@ -import { CEP18Client } from 'casper-cep18-js-client'; -import { CLPublicKey, DeployUtil } from 'casper-js-sdk'; -import { sub } from 'date-fns'; +import { DeployUtil } from 'casper-js-sdk'; import React, { useEffect, useMemo, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; @@ -11,18 +9,23 @@ import { TRANSFER_COST_MOTES } from '@src/constants'; import { useActiveAccountErc20Tokens } from '@src/hooks/use-active-account-erc20-tokens'; +import { fetchAndDispatchExtendedDeployInfo } from '@src/utils'; import { TransferPageContent } from '@popup/pages/transfer/content'; import { RouterPath, useTypedLocation, useTypedNavigate } from '@popup/router'; -import { accountPendingTransactionsChanged } from '@background/redux/account-info/actions'; import { selectAccountBalance } from '@background/redux/account-info/selectors'; import { selectAllPublicKeys } from '@background/redux/contacts/selectors'; +import { + selectAskForReviewAfter, + selectRatedInStore +} from '@background/redux/rate-app/selectors'; import { recipientPublicKeyAdded } from '@background/redux/recent-recipient-public-keys/actions'; import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors'; import { dispatchToMainStore } from '@background/redux/utils'; import { selectVaultActiveAccount } from '@background/redux/vault/selectors'; +import { createAsymmetricKey } from '@libs/crypto/create-asymmetric-key'; import { ErrorPath, FooterButtonsContainer, @@ -32,9 +35,11 @@ import { SpaceBetweenFlexRow, createErrorLocationState } from '@libs/layout'; -import { dispatchFetchExtendedDeploysInfo } from '@libs/services/account-activity-service'; -import { signAndDeploy } from '@libs/services/deployer-service'; -import { makeNativeTransferDeploy } from '@libs/services/transfer-service/transfer-service'; +import { + makeCep18TransferDeployAndSign, + makeNativeTransferDeployAndSign, + sendSignDeploy +} from '@libs/services/deployer-service'; import { Button, HomePageTabsId, Typography } from '@libs/ui/components'; import { calculateSubmitButtonDisabled } from '@libs/ui/forms/get-submit-button-state-from-validation'; import { useTransferForm } from '@libs/ui/forms/transfer'; @@ -42,8 +47,7 @@ import { CSPRtoMotes, divideErc20Balance, formatNumber, - motesToCSPR, - multiplyErc20Balance + motesToCSPR } from '@libs/ui/utils'; import { TransactionSteps, getIsErc20Transfer } from './utils'; @@ -74,6 +78,8 @@ export const TransferPage = () => { ); const csprBalance = useSelector(selectAccountBalance); const contactPublicKeys = useSelector(selectAllPublicKeys); + const ratedInStore = useSelector(selectRatedInStore); + const askForReviewAfter = useSelector(selectAskForReviewAfter); const { tokens } = useActiveAccountErc20Tokens(); @@ -169,141 +175,88 @@ export const TransferPage = () => { }; }, [isSubmitButtonDisable, transferStep]); - const onSubmitSending = () => { - if (activeAccount) { - const publicKeyFromHex = (publicKeyHex: string) => { - return CLPublicKey.fromHex(publicKeyHex); - }; + const sendDeploy = (signDeploy: DeployUtil.Deploy) => { + sendSignDeploy(signDeploy, nodeUrl) + .then(resp => { + dispatchToMainStore(recipientPublicKeyAdded(recipientPublicKey)); + + if ('result' in resp) { + fetchAndDispatchExtendedDeployInfo(resp.result.deploy_hash); + + setTransferStep(TransactionSteps.Success); + } else { + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: resp.error.message || t('Something went wrong'), + errorContentText: + resp.error.data || + t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + } + }) + .catch(error => { + console.error(error, 'transfer request error'); + + navigate( + ErrorPath, + createErrorLocationState({ + errorHeaderText: error.message || t('Something went wrong'), + errorContentText: + typeof error.data === 'string' + ? error.data + : t( + 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' + ), + errorPrimaryButtonLabel: t('Close'), + errorRedirectPath: RouterPath.Home + }) + ); + }); + }; + const onSubmitSending = async () => { + if (activeAccount) { + const KEYS = createAsymmetricKey( + activeAccount.publicKey, + activeAccount.secretKey + ); if (isErc20Transfer) { // ERC20 transfer - const cep18 = new CEP18Client(nodeUrl, networkName); - - cep18.setContractHash( - `hash-${tokenContractHash}`, - `hash-${tokenContractPackageHash}` - ); - - // create deploy - const tempDeploy = cep18.transfer( - { - recipient: publicKeyFromHex(recipientPublicKey), - amount: multiplyErc20Balance(amount, erc20Decimals) || '0' - }, - CSPRtoMotes(paymentAmount), - publicKeyFromHex(activeAccount.publicKey), - networkName - ); - - const deployParams = new DeployUtil.DeployParams( - publicKeyFromHex(activeAccount.publicKey), + const signDeploy = await makeCep18TransferDeployAndSign( + nodeUrl, networkName, - undefined, - undefined, - undefined, - sub(new Date(), { seconds: 2 }).getTime() // https://github.com/casper-network/casper-node/issues/4152 - ); - - const deploy = DeployUtil.makeDeploy( - deployParams, - tempDeploy.session, - tempDeploy.payment + tokenContractHash, + tokenContractPackageHash, + recipientPublicKey, + amount, + erc20Decimals, + paymentAmount, + activeAccount, + [KEYS] ); - signAndDeploy( - deploy, - activeAccount.publicKey, - activeAccount.secretKey, - nodeUrl - ).then(({ deploy_hash }) => { - dispatchToMainStore(recipientPublicKeyAdded(recipientPublicKey)); - - if (deploy_hash != null) { - let triesLeft = 10; - const interval = setInterval(async () => { - const { payload: extendedDeployInfo } = - await dispatchFetchExtendedDeploysInfo(deploy_hash); - if (extendedDeployInfo) { - dispatchToMainStore( - accountPendingTransactionsChanged(extendedDeployInfo) - ); - clearInterval(interval); - } else if (triesLeft === 0) { - clearInterval(interval); - } - - triesLeft--; - // Note: this timeout is needed because the deploy is not immediately visible in the explorer - }, 2000); - - setTransferStep(TransactionSteps.Success); - } else { - navigate( - ErrorPath, - createErrorLocationState({ - errorHeaderText: t('Something went wrong'), - errorContentText: t( - 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' - ), - errorPrimaryButtonLabel: t('Close'), - errorRedirectPath: RouterPath.Home - }) - ); - } - }); + sendDeploy(signDeploy); } else { // CSPR transfer const motesAmount = CSPRtoMotes(amount); - const deploy = makeNativeTransferDeploy( + const signDeploy = await makeNativeTransferDeployAndSign( activeAccount.publicKey, recipientPublicKey, motesAmount, networkName, + nodeUrl, + [KEYS], transferIdMemo ); - signAndDeploy( - deploy, - activeAccount.publicKey, - activeAccount.secretKey, - nodeUrl - ).then(({ deploy_hash }) => { - dispatchToMainStore(recipientPublicKeyAdded(recipientPublicKey)); - - if (deploy_hash != null) { - let triesLeft = 10; - const interval = setInterval(async () => { - const { payload: extendedDeployInfo } = - await dispatchFetchExtendedDeploysInfo(deploy_hash); - if (extendedDeployInfo) { - dispatchToMainStore( - accountPendingTransactionsChanged(extendedDeployInfo) - ); - clearInterval(interval); - } else if (triesLeft === 0) { - clearInterval(interval); - } - - triesLeft--; - // Note: this timeout is needed because the deploy is not immediately visible in the explorer - }, 2000); - - setTransferStep(TransactionSteps.Success); - } else { - navigate( - ErrorPath, - createErrorLocationState({ - errorHeaderText: t('Something went wrong'), - errorContentText: t( - 'Please check browser console for error details, this will be a valuable for our team to fix the issue.' - ), - errorPrimaryButtonLabel: t('Close'), - errorRedirectPath: RouterPath.Home - }) - ); - } - }); + sendDeploy(signDeploy); } } }; @@ -357,12 +310,25 @@ export const TransferPage = () => { case TransactionSteps.Success: { return { onClick: () => { - navigate(RouterPath.Home, { - state: { - // set the active tab to deploys - activeTabId: HomePageTabsId.Deploys - } - }); + const currentDate = Date.now(); + + const shouldAskForReview = + askForReviewAfter == null || currentDate > askForReviewAfter; + + if (ratedInStore || !shouldAskForReview) { + const homeRoutesState = { + state: { + // set the active tab to deploys + activeTabId: HomePageTabsId.Deploys + } + }; + + // Navigate to "Home" with the pre-defined state + navigate(RouterPath.Home, homeRoutesState); + } else { + // Navigate to "RateApp" when the application has not been rated in the store, and it's time to ask for a review. + navigate(RouterPath.RateApp); + } } }; } diff --git a/src/apps/popup/router/paths.ts b/src/apps/popup/router/paths.ts index d65652066..05dc4197b 100644 --- a/src/apps/popup/router/paths.ts +++ b/src/apps/popup/router/paths.ts @@ -12,8 +12,7 @@ export enum RouterPath { ConnectAnotherAccountByParams = '/connect-another-account/:targetAccountName', ConnectedSites = '/connected-sites', BackupSecretPhrase = '/backup-secret-phrase', - DownloadSecretKeys = '/download-secret-keys', - DownloadedSecretKeys = '/downloaded-secret-keys', + DownloadAccountKeys = '/download-account-keys', Transfer = '/transfer/:tokenContractPackageHash/:tokenContractHash', TransferNoParams = '/transfer', ActivityDetails = '/activity-details', @@ -29,5 +28,8 @@ export enum RouterPath { ContactList = '/contact-list', AddContact = '/add-contact', ContactDetails = '/contact-list/:contactName', - ImportAccountFromTorus = '/import-account-from-torus' + RateApp = '/rate-app', + AllAccountsList = '/accounts-list', + ImportAccountFromTorus = '/import-account-from-torus', + BuyCSPR = '/buy-cspr' } diff --git a/src/apps/signature-request/index.html b/src/apps/signature-request/index.html index ac4f929dc..514385ea9 100644 --- a/src/apps/signature-request/index.html +++ b/src/apps/signature-request/index.html @@ -2,10 +2,6 @@ - diff --git a/src/apps/signature-request/index.tsx b/src/apps/signature-request/index.tsx index 36705b948..2b9250d15 100644 --- a/src/apps/signature-request/index.tsx +++ b/src/apps/signature-request/index.tsx @@ -1,10 +1,10 @@ import React, { Suspense, useState } from 'react'; -import { render } from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { Provider as ReduxProvider } from 'react-redux/es/exports'; import { ThemeProvider } from 'styled-components'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { isSafariBuild } from '@src/utils'; +import { isSafariBuild, setCSPForSafari } from '@src/utils'; import { createMainStoreReplica } from '@background/redux/get-main-store'; import { themeModeSettingChanged } from '@background/redux/settings/actions'; @@ -25,6 +25,8 @@ import { AppRouter } from './app-router'; const Tree = () => { const [state, setState] = useState(null); + setCSPForSafari(); + const isSystemDarkTheme = useSystemThemeDetector(); useSubscribeToRedux({ @@ -66,4 +68,7 @@ const Tree = () => { ); }; -render(, document.querySelector('#app-container')); +const container = document.querySelector('#app-container'); +const root = createRoot(container!); + +root.render(); diff --git a/src/apps/signature-request/pages/sign-deploy/index.tsx b/src/apps/signature-request/pages/sign-deploy/index.tsx index d5c7e8c2c..3aaa56cb3 100644 --- a/src/apps/signature-request/pages/sign-deploy/index.tsx +++ b/src/apps/signature-request/pages/sign-deploy/index.tsx @@ -3,6 +3,8 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; +import { getSigningAccount } from '@src/utils'; + import { closeCurrentWindow } from '@background/close-current-window'; import { selectConnectedAccountNamesWithActiveOrigin, @@ -73,9 +75,8 @@ export function SignDeployPage() { // eslint-disable-next-line react-hooks/exhaustive-deps }, renderDeps); - const signingAccount = accounts.find( - a => a.publicKey === signingPublicKeyHex - ); + const signingAccount = getSigningAccount(accounts, signingPublicKeyHex); + // signing account should exist in wallet if (signingAccount == null) { const error = Error('No signing account'); diff --git a/src/apps/signature-request/pages/sign-message/index.tsx b/src/apps/signature-request/pages/sign-message/index.tsx index 827521aa7..5b3c7d069 100644 --- a/src/apps/signature-request/pages/sign-message/index.tsx +++ b/src/apps/signature-request/pages/sign-message/index.tsx @@ -2,6 +2,8 @@ import React, { useCallback, useEffect, useMemo } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; +import { getSigningAccount } from '@src/utils'; + import { closeCurrentWindow } from '@background/close-current-window'; import { selectConnectedAccountNamesWithActiveOrigin, @@ -51,9 +53,7 @@ export function SignMessagePage() { renderDeps ); - const signingAccount = accounts.find( - account => account.publicKey === signingPublicKeyHex - ); + const signingAccount = getSigningAccount(accounts, signingPublicKeyHex); // signing account should exist in wallet if (signingAccount == null) { diff --git a/src/assets/icons/accounts.svg b/src/assets/icons/accounts.svg new file mode 100644 index 000000000..8dd34ee74 --- /dev/null +++ b/src/assets/icons/accounts.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/arrows.svg b/src/assets/icons/arrows.svg new file mode 100644 index 000000000..d754fef0c --- /dev/null +++ b/src/assets/icons/arrows.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/cross-in-circle.svg b/src/assets/icons/cross-in-circle.svg new file mode 100644 index 000000000..56e7f1ae2 --- /dev/null +++ b/src/assets/icons/cross-in-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/placeholder-image-gray.svg b/src/assets/icons/placeholder-image-gray.svg new file mode 100644 index 000000000..d2e692d61 --- /dev/null +++ b/src/assets/icons/placeholder-image-gray.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/illustrations/chat.svg b/src/assets/illustrations/chat.svg new file mode 100644 index 000000000..3fd0033ca --- /dev/null +++ b/src/assets/illustrations/chat.svg @@ -0,0 +1,1060 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/illustrations/review.svg b/src/assets/illustrations/review.svg new file mode 100644 index 000000000..b7e3eb0eb --- /dev/null +++ b/src/assets/illustrations/review.svg @@ -0,0 +1,1039 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/illustrations/welcome-2.svg b/src/assets/illustrations/welcome-2.svg new file mode 100644 index 000000000..06be60c5f --- /dev/null +++ b/src/assets/illustrations/welcome-2.svg @@ -0,0 +1,935 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/background/background-events.ts b/src/background/background-events.ts index 60d1b9d16..7a27559f9 100644 --- a/src/background/background-events.ts +++ b/src/background/background-events.ts @@ -9,6 +9,9 @@ export const backgroundEvent = { }; export type BackgroundEvent = ActionType; +export type popupStateUpdated = ActionType< + typeof backgroundEvent.popupStateUpdated +>; export function isBackgroundEvent(action?: { type?: unknown; diff --git a/src/background/index.ts b/src/background/index.ts index 9d2c50ecd..4aa191a0b 100644 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -9,14 +9,28 @@ import { windows } from 'webextension-polyfill'; -import { getUrlOrigin, hasHttpPrefix } from '@src/utils'; +import { + getUrlOrigin, + hasHttpPrefix, + isEqualCaseInsensitive +} from '@src/utils'; + +import { CasperDeploy } from '@signature-request/pages/sign-deploy/deploy-types'; +import { + backgroundEvent, + popupStateUpdated +} from '@background/background-events'; import { WindowApp } from '@background/create-open-window'; import { disableOnboardingFlow, enableOnboardingFlow, openOnboardingUi } from '@background/open-onboarding-flow'; +import { + accountBalancesChanged, + accountBalancesReseted +} from '@background/redux/account-balances/actions'; import { accountBalanceChanged, accountCasperActivityChanged, @@ -49,6 +63,10 @@ import { CheckAccountNameIsTakenAction, CheckSecretKeyExistAction } from '@background/redux/import-account-actions-should-be-removed'; +import { + askForReviewAfterChanged, + ratedInStoreChanged +} from '@background/redux/rate-app/actions'; import { accountAdded, accountDisconnected, @@ -59,6 +77,7 @@ import { anotherAccountConnected, deployPayloadReceived, deploysReseted, + hideAccountFromListChange, secretPhraseCreated, siteConnected, siteDisconnected, @@ -98,8 +117,14 @@ import { fetchErc20TokenActivity } from '@libs/services/account-activity-service import { fetchAccountInfo } from '@libs/services/account-info'; import { fetchAccountBalance, + fetchAccountBalances, fetchCurrencyRate } from '@libs/services/balance-service'; +import { + fetchOnRampOptionGet, + fetchOnRampOptionPost, + fetchOnRampSelectionPost +} from '@libs/services/buy-cspr-service'; import { fetchErc20Tokens } from '@libs/services/erc20-service'; import { fetchNftTokens } from '@libs/services/nft-service'; import { @@ -271,7 +296,10 @@ tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => { // NOTE: if two events are send at the same time (same function) it must reuse the same store instance runtime.onMessage.addListener( - async (action: RootAction | SdkMethod | ServiceMessage, sender) => { + async ( + action: RootAction | SdkMethod | ServiceMessage | popupStateUpdated, + sender + ) => { const store = await getExistingMainStoreSingletonOrInit(); return new Promise(async (sendResponse, sendError) => { @@ -346,12 +374,32 @@ runtime.onMessage.addListener( return sendError(Error('Desploy json string parse error')); } + const deploy: CasperDeploy = deployJson.deploy; + + const isDeployAlreadySigningWithThisAccount = deploy.approvals.some( + approvals => + isEqualCaseInsensitive(approvals.signer, signingPublicKeyHex) + ); + + if (isDeployAlreadySigningWithThisAccount) { + return sendResponse( + sdkMethod.signResponse( + { + cancelled: true, + message: 'This deploy already sign by this account' + }, + { requestId: action.meta.requestId } + ) + ); + } + store.dispatch( deployPayloadReceived({ id: action.meta.requestId, json: deployJson }) ); + openWindow({ windowApp: WindowApp.SignatureRequestDeploy, searchParams: { @@ -531,6 +579,7 @@ runtime.onMessage.addListener( case getType(accountRemoved): case getType(accountRenamed): case getType(activeAccountChanged): + case getType(hideAccountFromListChange): case getType(activeTimeoutDurationSettingChanged): case getType(activeNetworkSettingChanged): case getType(vaultSettingsReseted): @@ -581,9 +630,17 @@ runtime.onMessage.addListener( case getType(contactEditingPermissionChanged): case getType(contactUpdated): case getType(contactsReseted): + case getType(ratedInStoreChanged): + case getType(askForReviewAfterChanged): + case getType(accountBalancesChanged): + case getType(accountBalancesReseted): store.dispatch(action); return sendResponse(undefined); + case getType(backgroundEvent.popupStateUpdated): + // do nothing + return; + // SERVICE MESSAGE HANDLERS case getType(serviceMessage.fetchBalanceRequest): { const { casperWalletApiUrl, casperClarityApiUrl } = @@ -611,6 +668,27 @@ runtime.onMessage.addListener( return; } + case getType(serviceMessage.fetchAccountBalancesRequest): { + const { casperWalletApiUrl } = selectApiConfigBasedOnActiveNetwork( + store.getState() + ); + + try { + const data = await fetchAccountBalances({ + accountHashes: action.payload.accountHashes, + casperWalletApiUrl + }); + + return sendResponse( + serviceMessage.fetchAccountBalancesResponse(data) + ); + } catch (error) { + console.error(error); + } + + return; + } + case getType(serviceMessage.fetchAccountInfoRequest): { const { casperClarityApiUrl } = selectApiConfigBasedOnActiveNetwork( store.getState() @@ -817,6 +895,48 @@ runtime.onMessage.addListener( return; } + case getType(serviceMessage.fetchOnRampGetOptionRequest): { + try { + const data = await fetchOnRampOptionGet(); + + return sendResponse( + serviceMessage.fetchOnRampGetOptionResponse(data) + ); + } catch (error) { + console.error(error); + } + + return; + } + + case getType(serviceMessage.fetchOnRampPostOptionRequest): { + try { + const data = await fetchOnRampOptionPost(action.payload); + + return sendResponse( + serviceMessage.fetchOnRampPostOptionResponse(data) + ); + } catch (error) { + console.error(error); + } + + return; + } + + case getType(serviceMessage.fetchOnRampPostSelectionRequest): { + try { + const data = await fetchOnRampSelectionPost(action.payload); + + return sendResponse( + serviceMessage.fetchOnRampPostSelectionResponse(data) + ); + } catch (error) { + console.error(error); + } + + return; + } + // TODO: All below should be removed when Import Account is integrated with window case 'check-secret-key-exist' as any: { const { secretKeyBase64 } = ( @@ -854,6 +974,9 @@ runtime.onMessage.addListener( ); } } else { + if (action === 'ping') { + return; + } throw Error('Background: Unknown message: ' + JSON.stringify(action)); } }); @@ -866,4 +989,4 @@ function ping() { // ping }); } -setInterval(ping, 5000); +setInterval(ping, 15000); diff --git a/src/background/redux/account-balances/actions.ts b/src/background/redux/account-balances/actions.ts new file mode 100644 index 000000000..e4926b171 --- /dev/null +++ b/src/background/redux/account-balances/actions.ts @@ -0,0 +1,11 @@ +import { createAction } from 'typesafe-actions'; + +import { AccountData } from '@libs/services/balance-service/types'; + +export const accountBalancesChanged = createAction('ACCOUNT_BALANCES_CHANGED')< + AccountData[] +>(); + +export const accountBalancesReseted = createAction( + 'ACCOUNT_BALANCES_RESETED' +)(); diff --git a/src/background/redux/account-balances/reducer.ts b/src/background/redux/account-balances/reducer.ts new file mode 100644 index 000000000..044e2af70 --- /dev/null +++ b/src/background/redux/account-balances/reducer.ts @@ -0,0 +1,13 @@ +import { createReducer } from 'typesafe-actions'; + +import { accountBalancesChanged, accountBalancesReseted } from './actions'; +import { AccountBalancesState } from './types'; + +const initialState = [] as AccountBalancesState; + +export const reducer = createReducer(initialState) + .handleAction(accountBalancesReseted, () => initialState) + .handleAction( + accountBalancesChanged, + (state, action: ReturnType) => action.payload + ); diff --git a/src/background/redux/account-balances/selectors.ts b/src/background/redux/account-balances/selectors.ts new file mode 100644 index 000000000..fcd061275 --- /dev/null +++ b/src/background/redux/account-balances/selectors.ts @@ -0,0 +1,4 @@ +import { RootState } from 'typesafe-actions'; + +export const selectAccountBalances = (state: RootState) => + state.accountBalances; diff --git a/src/background/redux/account-balances/types.ts b/src/background/redux/account-balances/types.ts new file mode 100644 index 000000000..f97a24ed1 --- /dev/null +++ b/src/background/redux/account-balances/types.ts @@ -0,0 +1,3 @@ +import { AccountData } from '@libs/services/balance-service/types'; + +export type AccountBalancesState = AccountData[]; diff --git a/src/background/redux/get-main-store.ts b/src/background/redux/get-main-store.ts index a30f3af64..5cd492c45 100644 --- a/src/background/redux/get-main-store.ts +++ b/src/background/redux/get-main-store.ts @@ -7,6 +7,7 @@ import { createStore } from '@background/redux/index'; import { KeysState } from '@background/redux/keys/types'; import { LoginRetryCountState } from '@background/redux/login-retry-count/reducer'; import { LoginRetryLockoutTimeState } from '@background/redux/login-retry-lockout-time/types'; +import { RateAppState } from '@background/redux/rate-app/types'; import { RecentRecipientPublicKeysState } from '@background/redux/recent-recipient-public-keys/types'; import { startBackground } from '@background/redux/sagas/actions'; import { SettingsState } from '@background/redux/settings/types'; @@ -20,6 +21,7 @@ export const LAST_ACTIVITY_TIME = 'j8d1dusn76EdD'; export const VAULT_SETTINGS = 'Nmxd8BZh93MHua'; export const RECENT_RECIPIENT_PUBLIC_KEYS = '7c2WyRuGhEtaDX'; export const CONTACTS_KEY = 'teuwe6zH3A72gc'; +export const RATE_APP = 'p4cGYubbwnd9ke'; type StorageState = { [VAULT_CIPHER_KEY]: string; @@ -30,6 +32,7 @@ type StorageState = { [VAULT_SETTINGS]: SettingsState; [RECENT_RECIPIENT_PUBLIC_KEYS]: RecentRecipientPublicKeysState; [CONTACTS_KEY]: ContactsState; + [RATE_APP]: RateAppState; }; // this needs to be private let storeSingleton: ReturnType; @@ -50,7 +53,9 @@ export const selectPopupState = (state: RootState): PopupState => { settings: state.settings, recentRecipientPublicKeys: state.recentRecipientPublicKeys, accountInfo: state.accountInfo, - contacts: state.contacts + contacts: state.contacts, + rateApp: state.rateApp, + accountBalances: state.accountBalances }; }; @@ -58,87 +63,95 @@ export const selectPopupState = (state: RootState): PopupState => { const isMockStateEnable = Boolean(process.env.MOCK_STATE); export async function getExistingMainStoreSingletonOrInit() { - // load selected state - const { - [VAULT_CIPHER_KEY]: vaultCipher, - [KEYS_KEY]: keys, - [LOGIN_RETRY_KEY]: loginRetryCount, - [LOGIN_RETRY_LOCKOUT_KEY]: loginRetryLockoutTime, - [LAST_ACTIVITY_TIME]: lastActivityTime, - [VAULT_SETTINGS]: settings, - [RECENT_RECIPIENT_PUBLIC_KEYS]: recentRecipientPublicKeys, - [CONTACTS_KEY]: contacts - } = (await storage.local.get([ - VAULT_CIPHER_KEY, - KEYS_KEY, - LOGIN_RETRY_KEY, - LOGIN_RETRY_LOCKOUT_KEY, - LAST_ACTIVITY_TIME, - VAULT_SETTINGS, - RECENT_RECIPIENT_PUBLIC_KEYS, - CONTACTS_KEY - ])) as StorageState; + try { + // load selected state + const { + [VAULT_CIPHER_KEY]: vaultCipher, + [KEYS_KEY]: keys, + [LOGIN_RETRY_KEY]: loginRetryCount, + [LOGIN_RETRY_LOCKOUT_KEY]: loginRetryLockoutTime, + [LAST_ACTIVITY_TIME]: lastActivityTime, + [VAULT_SETTINGS]: settings, + [RECENT_RECIPIENT_PUBLIC_KEYS]: recentRecipientPublicKeys, + [CONTACTS_KEY]: contacts, + [RATE_APP]: rateApp + } = (await storage.local.get([ + VAULT_CIPHER_KEY, + KEYS_KEY, + LOGIN_RETRY_KEY, + LOGIN_RETRY_LOCKOUT_KEY, + LAST_ACTIVITY_TIME, + VAULT_SETTINGS, + RECENT_RECIPIENT_PUBLIC_KEYS, + CONTACTS_KEY, + RATE_APP + ])) as StorageState; - if (storeSingleton == null) { - if (isMockStateEnable) { - const { initialStateForPopupTests } = await import( - /* webpackMode: "eager" */ '@src/fixtures' - ); - storeSingleton = createStore(initialStateForPopupTests as PopupState); - } else { - storeSingleton = createStore({ - vaultCipher, - keys, - loginRetryCount, - loginRetryLockoutTime, - lastActivityTime, - settings, - recentRecipientPublicKeys, - contacts - }); - } - // send start action - storeSingleton.dispatch(startBackground()); - // on updates propagate new state to replicas and also persist encrypted vault - storeSingleton.subscribe(() => { - const state = storeSingleton.getState(); + if (storeSingleton == null) { + if (isMockStateEnable) { + const { initialStateForPopupTests } = await import( + /* webpackMode: "eager" */ '@src/fixtures' + ); + storeSingleton = createStore(initialStateForPopupTests as PopupState); + } else { + storeSingleton = createStore({ + vaultCipher, + keys, + loginRetryCount, + loginRetryLockoutTime, + lastActivityTime, + settings, + recentRecipientPublicKeys, + contacts, + rateApp + }); + } + // send start action + storeSingleton.dispatch(startBackground()); + // on updates propagate new state to replicas and also persist encrypted vault + storeSingleton.subscribe(() => { + const state = storeSingleton.getState(); - // propagate state to replicas - const popupState = selectPopupState(state); - runtime.sendMessage(backgroundEvent.popupStateUpdated(popupState)); + // propagate state to replicas + const popupState = selectPopupState(state); + runtime.sendMessage(backgroundEvent.popupStateUpdated(popupState)); - // persist selected state - const { - vaultCipher, - keys, - loginRetryCount, - loginRetryLockoutTime, - lastActivityTime, - settings, - recentRecipientPublicKeys, - contacts - } = state; - storage.local - .set({ - [VAULT_CIPHER_KEY]: vaultCipher, - [KEYS_KEY]: keys, - [LOGIN_RETRY_KEY]: loginRetryCount, - [LOGIN_RETRY_LOCKOUT_KEY]: loginRetryLockoutTime, - [LAST_ACTIVITY_TIME]: lastActivityTime, - [VAULT_SETTINGS]: settings, - [RECENT_RECIPIENT_PUBLIC_KEYS]: recentRecipientPublicKeys, - [CONTACTS_KEY]: contacts - }) - .catch(e => { - console.error('Persist encrypted vault failed: ', e); - }); - }); + // persist selected state + const { + vaultCipher, + keys, + loginRetryCount, + loginRetryLockoutTime, + lastActivityTime, + settings, + recentRecipientPublicKeys, + contacts, + rateApp + } = state; + storage.local + .set({ + [VAULT_CIPHER_KEY]: vaultCipher, + [KEYS_KEY]: keys, + [LOGIN_RETRY_KEY]: loginRetryCount, + [LOGIN_RETRY_LOCKOUT_KEY]: loginRetryLockoutTime, + [LAST_ACTIVITY_TIME]: lastActivityTime, + [VAULT_SETTINGS]: settings, + [RECENT_RECIPIENT_PUBLIC_KEYS]: recentRecipientPublicKeys, + [CONTACTS_KEY]: contacts, + [RATE_APP]: rateApp + }) + .catch(e => { + console.error('Persist encrypted vault failed: ', e); + }); + }); + } + } catch (e) { + console.error('Failed to retrieve data from local storage: ', e); } return storeSingleton; } export function createMainStoreReplica(state: T) { - const store = createStore(state); - return store; + return createStore(state); } diff --git a/src/background/redux/index.ts b/src/background/redux/index.ts index 5795159e7..d4d01d3c7 100644 --- a/src/background/redux/index.ts +++ b/src/background/redux/index.ts @@ -1,19 +1,21 @@ +import { composeWithDevTools } from '@redux-devtools/remote'; import { applyMiddleware, // TODO: Move to actual `createStore` compose, legacy_createStore as createStoreRedux } from 'redux'; import createSagaMiddleware from 'redux-saga'; -import { composeWithDevTools } from 'remote-redux-devtools'; import { RootState } from 'typesafe-actions'; +import { isChromeBuild } from '@src/utils'; + import reduxAction from './redux-action'; import rootReducer from './root-reducer'; import rootSaga from './root-saga'; // export const composeEnhancers = compose; export const composeEnhancers = - process.env.NODE_ENV === 'development' + process.env.NODE_ENV === 'development' && isChromeBuild ? composeWithDevTools({ name: 'Casper Wallet', hostname: 'localhost', @@ -24,10 +26,12 @@ export const composeEnhancers = export const createStore = (initialState: Partial) => { const sagaMiddleware = createSagaMiddleware(); // configure middlewares - const middlewares: any[] = [sagaMiddleware]; + const middlewares = [sagaMiddleware]; // compose enhancers + // @ts-ignore const enhancer = composeEnhancers(applyMiddleware(...middlewares)); // create store + // @ts-ignore const store = createStoreRedux(rootReducer, initialState, enhancer); // run sagas sagaMiddleware.run(rootSaga); diff --git a/src/background/redux/rate-app/actions.ts b/src/background/redux/rate-app/actions.ts new file mode 100644 index 000000000..a8c9e6728 --- /dev/null +++ b/src/background/redux/rate-app/actions.ts @@ -0,0 +1,9 @@ +import { createAction } from 'typesafe-actions'; + +export const ratedInStoreChanged = createAction( + 'RATED_IN_STORE_CHANGED' +)(); + +export const askForReviewAfterChanged = createAction( + 'ASK_FOR_REVIEW_AFTER_CHANGED' +)(); diff --git a/src/background/redux/rate-app/reducer.ts b/src/background/redux/rate-app/reducer.ts new file mode 100644 index 000000000..3beb69c8e --- /dev/null +++ b/src/background/redux/rate-app/reducer.ts @@ -0,0 +1,38 @@ +import { createReducer } from 'typesafe-actions'; + +import { + askForReviewAfterChanged, + ratedInStoreChanged +} from '@background/redux/rate-app/actions'; +import { RateAppState } from '@background/redux/rate-app/types'; + +// Define the initial State for the Rate App +const initialState: RateAppState = { + ratedInStore: false, + askForReviewAfter: null +}; + +/** + * Reducer for handling changes related to Reviews + * + * @name reducer + * @function + * @returns {RateAppState} - The updated state + */ +export const reducer = createReducer(initialState) + // Handling action when InStore rating changes + .handleAction( + ratedInStoreChanged, + (state: RateAppState, action: ReturnType) => ({ + ...state, + ratedInStore: action.payload + }) + ) + // Handles the action triggered when the time period, after which a rate app request should be made, is updated. + .handleAction( + askForReviewAfterChanged, + (state, action: ReturnType) => ({ + ...state, + askForReviewAfter: action.payload + }) + ); diff --git a/src/background/redux/rate-app/selectors.ts b/src/background/redux/rate-app/selectors.ts new file mode 100644 index 000000000..b2affbf2b --- /dev/null +++ b/src/background/redux/rate-app/selectors.ts @@ -0,0 +1,7 @@ +import { RootState } from 'typesafe-actions'; + +export const selectRatedInStore = (state: RootState) => + state.rateApp.ratedInStore; + +export const selectAskForReviewAfter = (state: RootState) => + state.rateApp.askForReviewAfter; diff --git a/src/background/redux/rate-app/types.ts b/src/background/redux/rate-app/types.ts new file mode 100644 index 000000000..8b29e4d12 --- /dev/null +++ b/src/background/redux/rate-app/types.ts @@ -0,0 +1,27 @@ +/** + * Interface representing the structure of the RateAppState. + * + * @interface + * @exports + * @name RateAppState + */ +export interface RateAppState { + /** + * Indicates whether the application was rated in the store. + * + * @type {boolean} + * @name ratedInStore + */ + ratedInStore: boolean; + + /** + * Stores the timestamp after which the user + * will be asked for a rate app. + * + * Is null if the user has never been asked for a rate app. + * + * @type {number | null} + * @name askForReviewAfter + */ + askForReviewAfter: number | null; +} diff --git a/src/background/redux/redux-action.ts b/src/background/redux/redux-action.ts index c67f71a2c..719449aa5 100644 --- a/src/background/redux/redux-action.ts +++ b/src/background/redux/redux-action.ts @@ -1,5 +1,6 @@ import { ActionType } from 'typesafe-actions'; +import * as accountBalances from './account-balances/actions'; import * as accountInfo from './account-info/actions'; import * as activeOrigin from './active-origin/actions'; import * as contacts from './contacts/actions'; @@ -7,6 +8,7 @@ import * as keys from './keys/actions'; import * as lastActivityTime from './last-activity-time/actions'; import * as loginRetryCount from './login-retry-count/actions'; import * as loginRetryLockoutTime from './login-retry-lockout-time/actions'; +import * as rateApp from './rate-app/actions'; import * as recentRecipientPublicKeys from './recent-recipient-public-keys/actions'; import * as sagas from './sagas/actions'; import * as session from './session/actions'; @@ -29,7 +31,9 @@ const reduxAction = { settings, recentRecipientPublicKeys, accountInfo, - contacts + contacts, + rateApp, + accountBalances }; export type ReduxAction = ActionType; diff --git a/src/background/redux/root-reducer.ts b/src/background/redux/root-reducer.ts index d175d40ef..32b6cf81d 100644 --- a/src/background/redux/root-reducer.ts +++ b/src/background/redux/root-reducer.ts @@ -1,5 +1,6 @@ import { combineReducers } from 'redux'; +import { reducer as accountBalances } from './account-balances/reducer'; import { reducer as accountInfo } from './account-info/reducer'; import { reducer as activeOrigin } from './active-origin/reducer'; import { reducer as contacts } from './contacts/reducer'; @@ -7,6 +8,7 @@ import { reducer as keys } from './keys/reducer'; import { reducer as lastActivityTime } from './last-activity-time/reducer'; import { reducer as loginRetryCount } from './login-retry-count/reducer'; import { reducer as loginRetryLockoutTime } from './login-retry-lockout-time/reducer'; +import { reducer as rateApp } from './rate-app/reducer'; import { reducer as recentRecipientPublicKeys } from './recent-recipient-public-keys/reducer'; import { reducer as session } from './session/reducer'; import { reducer as settings } from './settings/reducer'; @@ -27,7 +29,9 @@ const rootReducer = combineReducers({ settings, recentRecipientPublicKeys, accountInfo, - contacts + contacts, + rateApp, + accountBalances }); export default rootReducer; diff --git a/src/background/redux/root-selector.ts b/src/background/redux/root-selector.ts index 0dda12bc2..580f082f7 100644 --- a/src/background/redux/root-selector.ts +++ b/src/background/redux/root-selector.ts @@ -9,3 +9,4 @@ export * from './vault-cipher/selectors'; export * from './windowManagement/selectors'; export * from './settings/selectors'; export * from './recent-recipient-public-keys/selectors'; +export * from './rate-app/selectors'; diff --git a/src/background/redux/sagas/onboarding-sagas.ts b/src/background/redux/sagas/onboarding-sagas.ts index cbcb9c52d..558276936 100644 --- a/src/background/redux/sagas/onboarding-sagas.ts +++ b/src/background/redux/sagas/onboarding-sagas.ts @@ -104,7 +104,8 @@ function* initVaultSaga(action: ReturnType) { const keyPair = deriveKeyPair(secretPhrase, 0); const account = { ...keyPair, - name: 'Account 1' + name: 'Account 1', + hidden: false }; yield put(secretPhraseCreated(secretPhrase)); diff --git a/src/background/redux/sagas/vault-sagas.ts b/src/background/redux/sagas/vault-sagas.ts index 5e4dd9823..55ec224f8 100644 --- a/src/background/redux/sagas/vault-sagas.ts +++ b/src/background/redux/sagas/vault-sagas.ts @@ -8,6 +8,7 @@ import { MapTimeoutDurationSettingToValue } from '@popup/constants'; +import { accountBalancesReseted } from '@background/redux/account-balances/actions'; import { loginRetryLockoutTimeReseted, loginRetryLockoutTimeSet @@ -120,6 +121,7 @@ function* lockVaultSaga() { yield put(vaultReseted()); yield put(deploysReseted()); yield put(accountInfoReset()); + yield put(accountBalancesReseted()); emitSdkEventToActiveTabs(() => { return sdkEvent.lockedEvent({ @@ -318,7 +320,8 @@ function* createAccountSaga(action: ReturnType) { const keyPair = deriveKeyPair(secretPhrase, accountCount); const account = { ...keyPair, - name + name, + hidden: false }; yield put(accountAdded(account)); diff --git a/src/background/redux/types.d.ts b/src/background/redux/types.d.ts index a620e4ea1..37eed11df 100644 --- a/src/background/redux/types.d.ts +++ b/src/background/redux/types.d.ts @@ -1,5 +1,6 @@ import { ActionType, StateType } from 'typesafe-actions'; +import { AccountBalancesState } from '@background/redux/account-balances/types'; import { AccountInfoState } from '@background/redux/account-info/types'; import { ActiveOriginState } from '@background/redux/active-origin/types'; import { ContactsState } from '@background/redux/contacts/types'; @@ -7,6 +8,7 @@ import { KeysState } from '@background/redux/keys/types'; import { LastActivityTimeState } from '@background/redux/last-activity-time/reducer'; import { LoginRetryCountState } from '@background/redux/login-retry-count/reducer'; import { LoginRetryLockoutTimeState } from '@background/redux/login-retry-lockout-time/types'; +import { RateAppState } from '@background/redux/rate-app/types'; import { RecentRecipientPublicKeysState } from '@background/redux/recent-recipient-public-keys/types'; import { SessionState } from '@background/redux/session/types'; import { SettingsState } from '@background/redux/settings/types'; @@ -45,4 +47,6 @@ export type PopupState = { recentRecipientPublicKeys: RecentRecipientPublicKeysState; accountInfo: AccountInfoState; contacts: ContactsState; + rateApp: RateAppState; + accountBalances: AccountBalancesState; }; diff --git a/src/background/redux/vault/actions.ts b/src/background/redux/vault/actions.ts index c89ba6e7a..52a5bbf7b 100644 --- a/src/background/redux/vault/actions.ts +++ b/src/background/redux/vault/actions.ts @@ -55,3 +55,9 @@ export const deployPayloadReceived = createAction('DEPLOY_PAYLOAD_RECEIVED')<{ id: string; json: string; }>(); + +export const hideAccountFromListChange = createAction( + 'HIDE_ACCOUNT_FROM_LIST_CHANGE' +)<{ + accountName: string; +}>(); diff --git a/src/background/redux/vault/reducer.ts b/src/background/redux/vault/reducer.ts index 654f489a3..2fb9f2770 100644 --- a/src/background/redux/vault/reducer.ts +++ b/src/background/redux/vault/reducer.ts @@ -10,6 +10,7 @@ import { anotherAccountConnected, deployPayloadReceived, deploysReseted, + hideAccountFromListChange, secretPhraseCreated, siteConnected, siteDisconnected, @@ -44,7 +45,7 @@ export const reducer = createReducer(initialState) secretPhrase, jsonById } - } + }: ReturnType ) => ({ accountNamesByOriginDict, siteNameByOriginDict, @@ -57,31 +58,43 @@ export const reducer = createReducer(initialState) ) .handleAction( secretPhraseCreated, - (state, action): State => ({ + (state, action: ReturnType): State => ({ ...state, secretPhrase: action.payload }) ) - .handleAction(accountAdded, (state, action): State => { - const account = action.payload; + .handleAction( + accountAdded, + (state, action: ReturnType): State => { + const account = action.payload; - return { - ...state, - accounts: [...state.accounts, account], - activeAccountName: account.name - }; - }) - .handleAction(accountImported, (state, { payload: account }): State => { - return { - ...state, - accounts: [...state.accounts, account], - activeAccountName: - state.accounts.length === 0 ? account.name : state.activeAccountName - }; - }) + return { + ...state, + accounts: [...state.accounts, account], + activeAccountName: account.name + }; + } + ) + .handleAction( + accountImported, + ( + state, + { payload: account }: ReturnType + ): State => { + return { + ...state, + accounts: [...state.accounts, account], + activeAccountName: + state.accounts.length === 0 ? account.name : state.activeAccountName + }; + } + ) .handleAction( accountRemoved, - (state, { payload: { accountName } }): State => { + ( + state, + { payload: { accountName } }: ReturnType + ): State => { const newAccounts = state.accounts.filter( account => account.name !== accountName ); @@ -115,7 +128,10 @@ export const reducer = createReducer(initialState) ) .handleAction( accountRenamed, - (state, { payload: { oldName, newName } }): State => { + ( + state, + { payload: { oldName, newName } }: ReturnType + ): State => { const newAccountNamesByOriginDict = Object.fromEntries( Object.keys(state.accountNamesByOriginDict).map(origin => [ origin, @@ -146,7 +162,12 @@ export const reducer = createReducer(initialState) ) .handleAction( siteConnected, - (state, { payload: { siteOrigin, accountNames, siteTitle } }) => ({ + ( + state, + { + payload: { siteOrigin, accountNames, siteTitle } + }: ReturnType + ) => ({ ...state, siteNameByOriginDict: { ...state?.siteNameByOriginDict, @@ -166,7 +187,12 @@ export const reducer = createReducer(initialState) ) .handleAction( anotherAccountConnected, - (state, { payload: { siteOrigin, accountName } }) => ({ + ( + state, + { + payload: { siteOrigin, accountName } + }: ReturnType + ) => ({ ...state, accountNamesByOriginDict: { ...state.accountNamesByOriginDict, @@ -182,7 +208,12 @@ export const reducer = createReducer(initialState) ) .handleAction( accountDisconnected, - (state, { payload: { siteOrigin, accountName } }) => { + ( + state, + { + payload: { siteOrigin, accountName } + }: ReturnType + ) => { const newAccountNamesByOriginDict = Object.fromEntries( Object.entries(state.accountNamesByOriginDict) // when last account for origin, remove group @@ -208,23 +239,63 @@ export const reducer = createReducer(initialState) }; } ) - .handleAction(siteDisconnected, (state, { payload: { siteOrigin } }) => ({ - ...state, - accountNamesByOriginDict: Object.fromEntries( - Object.entries(state.accountNamesByOriginDict).filter( - ([origin]) => origin !== siteOrigin + .handleAction( + siteDisconnected, + ( + state, + { payload: { siteOrigin } }: ReturnType + ) => ({ + ...state, + accountNamesByOriginDict: Object.fromEntries( + Object.entries(state.accountNamesByOriginDict).filter( + ([origin]) => origin !== siteOrigin + ) ) - ) - })) - .handleAction(activeAccountChanged, (state, { payload }) => ({ - ...state, - activeAccountName: payload - })) + }) + ) + .handleAction( + activeAccountChanged, + (state, { payload }: ReturnType) => ({ + ...state, + activeAccountName: payload + }) + ) .handleAction(deploysReseted, (): State => initialState) .handleAction( deployPayloadReceived, - (state, { payload }): State => ({ + (state, { payload }: ReturnType): State => ({ ...state, jsonById: { [payload.id]: payload.json } }) + ) + .handleAction( + hideAccountFromListChange, + ( + state, + { payload: { accountName } }: ReturnType + ) => { + const visibleAccounts = state.accounts.filter( + account => !account.hidden && account.name !== accountName + ); + + const newActiveAccount = + state.activeAccountName === accountName + ? (state.accounts.length > 1 && visibleAccounts[0].name) || null + : state.activeAccountName; + + return { + ...state, + activeAccountName: newActiveAccount, + accounts: state.accounts.map(account => { + if (account.name === accountName) { + return { + ...account, + hidden: !account.hidden + }; + } + + return account; + }) + }; + } ); diff --git a/src/background/redux/vault/selectors.ts b/src/background/redux/vault/selectors.ts index 6a344140b..514cf8841 100644 --- a/src/background/redux/vault/selectors.ts +++ b/src/background/redux/vault/selectors.ts @@ -1,10 +1,11 @@ import { createSelector } from 'reselect'; import { RootState } from 'typesafe-actions'; +import { selectAccountBalances } from '@background/redux/account-balances/selectors'; import { VaultState } from '@background/redux/vault/types'; import { SecretPhrase } from '@libs/crypto'; -import { Account } from '@libs/types/account'; +import { Account, AccountWithBalance } from '@libs/types/account'; import { selectActiveOrigin } from '../active-origin/selectors'; @@ -19,36 +20,83 @@ export const selectSecretPhrase = (state: RootState): null | SecretPhrase => export const selectVaultAccounts = (state: RootState): Account[] => state.vault.accounts; +export const selectVaultAccountsWithBalances = createSelector( + selectVaultAccounts, + selectAccountBalances, + (accounts, accountBalances): AccountWithBalance[] => + accounts.map(account => { + if (!accountBalances.length) { + return { + ...account, + balance: { + liquidMotes: null + } + }; + } + + const accountBalance = accountBalances.find( + ac => ac.public_key === account.publicKey + ); + + return { + ...account, + balance: { + liquidMotes: String(accountBalance?.balance || '0') + } + }; + }) +); + +export const selectVaultCountsOfAccounts = createSelector( + selectVaultAccountsWithBalances, + accounts => accounts.length +); + export const selectVaultHasAccounts = (state: RootState): boolean => state.vault.accounts.length > 0; export const selectVaultAccountsNames = createSelector( - selectVaultAccounts, + selectVaultAccountsWithBalances, accounts => accounts.map(account => account.name) ); export const selectVaultImportedAccounts = createSelector( - selectVaultAccounts, + selectVaultAccountsWithBalances, accounts => accounts.filter(account => account.imported) ); -export const selectVaultHasImportedAccount = createSelector( +export const selectVaultImportedAccountNames = createSelector( selectVaultImportedAccounts, - importedAccounts => importedAccounts.length > 0 + accounts => accounts.map(account => account.name) +); + +export const selectVaultVisibleAccounts = createSelector( + selectVaultAccountsWithBalances, + accounts => accounts.filter(account => !account.hidden) +); + +export const selectVaultHiddenAccounts = createSelector( + selectVaultAccountsWithBalances, + accounts => accounts.filter(account => account.hidden) +); + +export const selectVaultHiddenAccountsNames = createSelector( + selectVaultHiddenAccounts, + accounts => accounts.map(account => account.name) ); export const selectVaultDerivedAccounts = createSelector( - selectVaultAccounts, + selectVaultAccountsWithBalances, accounts => accounts.filter(account => !account.imported) ); export const selectVaultAccountsSecretKeysBase64 = createSelector( - selectVaultAccounts, + selectVaultAccountsWithBalances, accounts => accounts.map(account => account.secretKey) ); export const selectVaultAccount = createSelector( - selectVaultAccounts, + selectVaultAccountsWithBalances, (_: RootState, accountName: string) => accountName, (accounts, accountName) => accounts.find(account => account.name === accountName) @@ -58,14 +106,10 @@ export const selectVaultActiveAccountName = (state: RootState) => state.vault.activeAccountName; export const selectVaultActiveAccount = createSelector( - selectVaultAccounts, + selectVaultAccountsWithBalances, selectVaultActiveAccountName, (accounts, activeAccountName) => { - const activeAccount = accounts.find( - account => account.name === activeAccountName - ); - - return activeAccount; + return accounts.find(account => account.name === activeAccountName); } ); @@ -108,7 +152,8 @@ export const selectIsAccountConnected = createSelector( accountName: string | undefined ) => [origin, accountName], (accountNamesByOriginDict, [origin, accountName]) => { - const accountNames = origin && accountNamesByOriginDict[origin]; + const accountNames: '' | string[] | undefined = + origin && accountNamesByOriginDict[origin]; if (accountNames == null || !accountName) { return false; } @@ -128,7 +173,8 @@ export const selectIsActiveAccountConnectedWithActiveOrigin = createSelector( selectVaultActiveAccountName, selectAccountNamesByOriginDict, (origin, activeAccountName, accountNamesByOriginDict) => { - const accountNames = origin && accountNamesByOriginDict[origin]; + const accountNames: '' | string[] | null | undefined = + origin && accountNamesByOriginDict[origin]; if (accountNames == null || activeAccountName == null) { return false; } else { @@ -148,19 +194,19 @@ export const selectConnectedAccountNamesWithActiveOrigin = createSelector( export const selectConnectedAccountsWithActiveOrigin = createSelector( selectActiveOrigin, - selectVaultAccounts, + selectVaultAccountsWithBalances, selectConnectedAccountNamesWithActiveOrigin, - (origin, accounts, connectedAccountNamesWithOrigin): Account[] => { + (origin, accounts, connectedAccountNamesWithOrigin): AccountWithBalance[] => { return (connectedAccountNamesWithOrigin || []) .map(accountName => accounts.find(account => account.name === accountName) ) - .filter((account): account is Account => !!account); + .filter((account): account is AccountWithBalance => !!account); } ); export const selectUnconnectedAccountsWithActiveOrigin = createSelector( - selectVaultAccounts, + selectVaultAccountsWithBalances, selectConnectedAccountsWithActiveOrigin, (accounts, connectedAccountsToActiveTab) => accounts.filter( diff --git a/src/background/service-message.ts b/src/background/service-message.ts index 4d634cc60..ac056b819 100644 --- a/src/background/service-message.ts +++ b/src/background/service-message.ts @@ -6,7 +6,17 @@ import { TransferResult } from '@libs/services/account-activity-service/types'; import { AccountInfo } from '@libs/services/account-info/types'; -import { FetchBalanceResponse } from '@libs/services/balance-service/types'; +import { + AccountData, + FetchBalanceResponse +} from '@libs/services/balance-service/types'; +import { + GetOnRampResponse, + OptionsPostRequestData, + ResponseOnRampProps, + ResponseSelectionProps, + SelectionPostRequestData +} from '@libs/services/buy-cspr-service/types'; import { ContractPackageWithBalance } from '@libs/services/erc20-service/types'; import { NFTTokenResult } from '@libs/services/nft-service/types'; import { ErrorResponse, PaginatedResponse } from '@libs/services/types'; @@ -26,6 +36,14 @@ export const serviceMessage = { FetchBalanceResponse, Meta >(), + fetchAccountBalancesRequest: createAction('FETCH_ACCOUNT_BALANCES')< + { accountHashes: string }, + Meta + >(), + fetchAccountBalancesResponse: createAction('FETCH_ACCOUNT_BALANCES_RESPONSE')< + PaginatedResponse | ErrorResponse, + Meta + >(), fetchAccountInfoRequest: createAction('FETCH_ACCOUNT_INFO')< { accountHash: string }, Meta @@ -96,7 +114,25 @@ export const serviceMessage = { )<{ publicKey: string }, Meta>(), fetchValidatorsDetailsDataResponse: createAction( 'FETCH_VALIDATORS_DETAILS_DATA_RESPONSE' - ) | ErrorResponse, Meta>() + ) | ErrorResponse, Meta>(), + fetchOnRampGetOptionRequest: createAction( + 'FETCH_ON_RAMP_GET_OPTION_REQUEST' + )(), + fetchOnRampGetOptionResponse: createAction( + 'FETCH_ON_RAMP_GET_OPTION_RESPONSE' + )(), + fetchOnRampPostOptionRequest: createAction( + 'FETCH_ON_RAMP_POST_OPTION_REQUEST' + )(), + fetchOnRampPostOptionResponse: createAction( + 'FETCH_ON_RAMP_POST_OPTION_RESPONSE' + )(), + fetchOnRampPostSelectionRequest: createAction( + 'FETCH_ON_RAMP_POST_SELECTION_REQUEST' + )(), + fetchOnRampPostSelectionResponse: createAction( + 'FETCH_ON_RAMP_POST_SELECTION_RESPONSE' + )() }; export type ServiceMessage = ActionType; diff --git a/src/constants.ts b/src/constants.ts index 103b19538..b4e36d2c2 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -43,9 +43,6 @@ export const getContractNftUrl = ( tokenId: string ) => `${casperLiveUrl}/contracts/${contractHash}/nfts/${tokenId}`; -export const getBuyWithTopperUrl = (publicKey: string) => - `https://onramp-api.cspr.click/api/topper/bootstrap-token?account=${publicKey}&label=Your%20Public%20Key`; - export enum CasperLiveUrl { MainnetUrl = 'https://cspr.live', TestnetUrl = 'https://testnet.cspr.live' @@ -57,8 +54,8 @@ export enum CasperClarityApiUrl { } export enum CasperWalletApiUrl { - MainnetUrl = 'https://api.casperwallet.io', - TestnetUrl = 'https://cspr-wallet-api.dev.make.services' + MainnetUrl = 'https://api.mainnet.casperwallet.io', + TestnetUrl = 'https://api.testnet.casperwallet.io' } export enum NetworkSetting { @@ -69,7 +66,8 @@ export enum NetworkSetting { export enum Browser { Safari = 'safari', Chrome = 'chrome', - Firefox = 'firefox' + Firefox = 'firefox', + Edge = 'edge' } export enum TermsLink { @@ -78,10 +76,12 @@ export enum TermsLink { } export enum CasperNodeUrl { - MainnetUrl = 'https://casper-node-proxy.make.services/rpc', - TestnetUrl = 'https://casper-testnet-node-proxy.make.services/rpc' + MainnetUrl = 'https://node.cspr.cloud/rpc', + TestnetUrl = 'https://node.testnet.cspr.cloud/rpc' } +export const ReferrerUrl = 'https://casperwallet.io'; + export enum NetworkName { Mainnet = 'casper', Testnet = 'casper-test' diff --git a/src/content/sdk-method.ts b/src/content/sdk-method.ts index 1fc67e47e..53da3f1aa 100644 --- a/src/content/sdk-method.ts +++ b/src/content/sdk-method.ts @@ -41,7 +41,8 @@ export const sdkMethod = { Meta >(), signResponse: createAction('CasperWalletProvider:Sign:Response')< - { cancelled: true } | { cancelled: false; signatureHex: string }, + | { cancelled: true; message?: string } + | { cancelled: false; signatureHex: string }, Meta >(), signError: createAction('CasperWalletProvider:Sign:Error')(), diff --git a/src/content/sdk.ts b/src/content/sdk.ts index 798007061..ed80a15d3 100644 --- a/src/content/sdk.ts +++ b/src/content/sdk.ts @@ -11,6 +11,7 @@ import { export type SignatureResponse = | { cancelled: true; // if sign was cancelled + message?: string; } | { cancelled: false; // if sign was successfull diff --git a/src/declarative_net_request_rules.json b/src/declarative_net_request_rules.json index 3eadbf9da..c1e730cb4 100644 --- a/src/declarative_net_request_rules.json +++ b/src/declarative_net_request_rules.json @@ -30,7 +30,7 @@ ] }, "condition": { - "urlFilter": "https://cspr-wallet-api.dev.make.services" + "urlFilter": "https://api.testnet.casperwallet.io" } }, { @@ -47,7 +47,41 @@ ] }, "condition": { - "urlFilter": "https://api.casperwallet.io" + "urlFilter": "https://api.mainnet.casperwallet.io" + } + }, + { + "id": 4, + "priority": 1, + "action": { + "type": "modifyHeaders", + "requestHeaders": [ + { + "header": "Referer", + "operation": "set", + "value": "https://casperwallet.io" + } + ] + }, + "condition": { + "urlFilter": "https://node.testnet.cspr.cloud" + } + }, + { + "id": 5, + "priority": 1, + "action": { + "type": "modifyHeaders", + "requestHeaders": [ + { + "header": "Referer", + "operation": "set", + "value": "https://casperwallet.io" + } + ] + }, + "condition": { + "urlFilter": "https://node.cspr.cloud" } } ] diff --git a/src/fixtures/initial-state-for-popup-tests.ts b/src/fixtures/initial-state-for-popup-tests.ts index fcdde45fd..be820cd4d 100644 --- a/src/fixtures/initial-state-for-popup-tests.ts +++ b/src/fixtures/initial-state-for-popup-tests.ts @@ -54,13 +54,15 @@ export const initialStateForPopupTests: RootState = { publicKey: '0202b1943511b8c23b1b2b8ed7ddcedffcc7be70d9366a5005c7beab08a81b7ae633', secretKey: 'Go8sSp3u/hSaDFCjFK6wdM4VZuWjqxEaNB38RaZHLA0=', - name: 'Account 1' + name: 'Account 1', + hidden: false }, { publicKey: '0203b2e05f074452f5e69ba512310deceaca152ebd3394eadcec26c6e68e91aa7724', secretKey: 'TCDeehVWtWeWP2PM/UKh2gQ6hgUpZ6v1D6lzmonYpm4=', - name: 'Account 2' + name: 'Account 2', + hidden: false } ], accountNamesByOriginDict: {}, @@ -106,5 +108,10 @@ export const initialStateForPopupTests: RootState = { contacts: { contacts: [], lastModified: null - } + }, + rateApp: { + ratedInStore: false, + askForReviewAfter: null + }, + accountBalances: [] }; diff --git a/src/global.d.ts b/src/global.d.ts index 666127af3..7b0828bfa 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1 +1 @@ -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; diff --git a/src/hooks/use-copy-to-clipboard.ts b/src/hooks/use-copy-to-clipboard.ts index 99a06464d..b14f90e09 100644 --- a/src/hooks/use-copy-to-clipboard.ts +++ b/src/hooks/use-copy-to-clipboard.ts @@ -1,11 +1,11 @@ -import { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; export const useCopyToClipboard = (valueToCopy: string) => { const overlayTimeout = 2000; const [isClicked, setIsClicked] = useState(false); const handleCopyOnClick = useCallback( - async event => { + async (event: React.MouseEvent) => { event.stopPropagation(); if (isClicked) { diff --git a/src/hooks/use-fetch-account-balances.ts b/src/hooks/use-fetch-account-balances.ts new file mode 100644 index 000000000..791a51e66 --- /dev/null +++ b/src/hooks/use-fetch-account-balances.ts @@ -0,0 +1,60 @@ +import { useEffect, useRef } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { BALANCE_REFRESH_RATE } from '@src/constants'; + +import { useForceUpdate } from '@popup/hooks/use-force-update'; + +import { accountBalancesChanged } from '@background/redux/account-balances/actions'; +import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors'; +import { dispatchToMainStore } from '@background/redux/utils'; +import { selectVaultAccounts } from '@background/redux/vault/selectors'; + +import { getAccountHashFromPublicKey } from '@libs/entities/Account'; +import { dispatchFetchAccountBalances } from '@libs/services/balance-service'; + +export const useFetchAccountBalances = () => { + const effectTimeoutRef = useRef(); + const forceUpdate = useForceUpdate(); + const { t } = useTranslation(); + + const { casperClarityApiUrl } = useSelector( + selectApiConfigBasedOnActiveNetwork + ); + const accounts = useSelector(selectVaultAccounts); + + useEffect(() => { + const hashes = accounts.reduce( + (previousValue, currentValue, currentIndex) => { + const hash = getAccountHashFromPublicKey(currentValue.publicKey); + + return accounts.length === currentIndex + 1 + ? previousValue + `${hash}` + : previousValue + `${hash},`; + }, + '' + ); + + dispatchFetchAccountBalances(hashes) + .then(({ payload }) => { + if ('data' in payload) { + dispatchToMainStore(accountBalancesChanged(payload.data)); + } else { + dispatchToMainStore(accountBalancesChanged([])); + } + }) + .catch(error => { + console.error(t('Failed to fetch accounts balance'), error); + }); + + // will cause effect to run again after timeout + effectTimeoutRef.current = setTimeout(() => { + forceUpdate(); + }, BALANCE_REFRESH_RATE + 1); + + return () => { + clearTimeout(effectTimeoutRef.current); + }; + }, [casperClarityApiUrl, forceUpdate, accounts.length, accounts, t]); +}; diff --git a/src/hooks/use-fetch-account-deploys.ts b/src/hooks/use-fetch-account-deploys.ts index c27470dc5..b413de32b 100644 --- a/src/hooks/use-fetch-account-deploys.ts +++ b/src/hooks/use-fetch-account-deploys.ts @@ -121,7 +121,10 @@ export const useFetchAccountDeploys = () => { activeAccount?.publicKey, casperClarityApiUrl, forceUpdate, - isFirstPageLoad + isFirstPageLoad, + setLoading, + setIsFirstPageLoad, + setHasNextPage ]); const loadMoreDeploys = useCallback(() => { @@ -172,7 +175,10 @@ export const useFetchAccountDeploys = () => { accountDeploysCount, accountDeploysList?.length, accountDeploysPage, - activeAccount?.publicKey + activeAccount?.publicKey, + setLoading, + setHasNextPage, + setAccountDeploysPage ]); return { diff --git a/src/libs/layout/containers.ts b/src/libs/layout/containers.ts index f253395cd..11a224820 100644 --- a/src/libs/layout/containers.ts +++ b/src/libs/layout/containers.ts @@ -95,18 +95,24 @@ const getGapSize = (gap?: SpacingSize) => { interface FlexRowProps { gap?: SpacingSize; wrap?: 'wrap' | 'nowrap'; + flexGrow?: number; } export const FlexRow = styled.div` display: flex; gap: ${({ gap }) => getGapSize(gap)}; flex-wrap: ${({ wrap }) => wrap}; + flex-grow: ${({ flexGrow }) => flexGrow || 'inherit'}; `; export const AlignedFlexRow = styled(FlexRow)` align-items: center; `; +export const BaseLineFlexRow = styled(FlexRow)` + align-items: baseline; +`; + export const CenteredFlexRow = styled(AlignedFlexRow)` justify-content: center; `; diff --git a/src/libs/layout/header/header-data-updater.tsx b/src/libs/layout/header/header-data-updater.tsx index 4cf993233..76a57ef3a 100644 --- a/src/libs/layout/header/header-data-updater.tsx +++ b/src/libs/layout/header/header-data-updater.tsx @@ -1,11 +1,13 @@ import React from 'react'; +import { useFetchAccountBalances } from '@hooks/use-fetch-account-balances'; import { useFetchActiveAccountBalance } from '@hooks/use-fetch-active-account-balance'; import { useFetchErc20Tokens } from '@hooks/use-fetch-erc20-tokens'; export const HeaderDataUpdater: React.FC = () => { useFetchActiveAccountBalance(); useFetchErc20Tokens(); + useFetchAccountBalances(); return null; }; diff --git a/src/libs/layout/header/header-network-switcher.tsx b/src/libs/layout/header/header-network-switcher.tsx index 85b47868f..7c1a84866 100644 --- a/src/libs/layout/header/header-network-switcher.tsx +++ b/src/libs/layout/header/header-network-switcher.tsx @@ -107,6 +107,7 @@ export const HeaderNetworkSwitcher = () => { src="assets/icons/network.svg" size={16} color="contentOnFill" + dataTestId="network-switcher" /> {activeNetwork} diff --git a/src/libs/layout/unlock-protected-page-content/index.tsx b/src/libs/layout/unlock-protected-page-content/index.tsx index 866caea88..a96f2982c 100644 --- a/src/libs/layout/unlock-protected-page-content/index.tsx +++ b/src/libs/layout/unlock-protected-page-content/index.tsx @@ -63,9 +63,13 @@ export const UnlockProtectedPageContent = ({ - - You have {{ retryLeft }} tries left. - + }} + /> diff --git a/src/libs/layout/unlock-vault/index.tsx b/src/libs/layout/unlock-vault/index.tsx index 6ed361984..4d9eabde1 100644 --- a/src/libs/layout/unlock-vault/index.tsx +++ b/src/libs/layout/unlock-vault/index.tsx @@ -103,10 +103,23 @@ export function UnlockVaultPageContent() { /[A-Z]/.test(acc.publicKey) ); + // Mapping through vault accounts to update missing hidden property + const updatedVaultWithHiddenProp = vault.accounts.map(acc => { + // If the hidden property is undefined, set it to false + if (acc.hidden === undefined) { + return { + ...acc, + hidden: false + }; + } + + return acc; + }); + if (hasCheckSummedPublicKeys) { const updatedVault: VaultState = { ...vault, - accounts: vault.accounts.map(acc => ({ + accounts: updatedVaultWithHiddenProp.map(acc => ({ ...acc, publicKey: acc.publicKey.toLowerCase() })) @@ -123,7 +136,7 @@ export function UnlockVaultPageContent() { } else { dispatchToMainStore( unlockVault({ - vault, + vault: { ...vault, accounts: updatedVaultWithHiddenProp }, newKeyDerivationSaltHash, newVaultCipher, newEncryptionKeyHash diff --git a/src/libs/services/balance-service/balance-service.ts b/src/libs/services/balance-service/balance-service.ts index c21ef7d64..9b6660867 100644 --- a/src/libs/services/balance-service/balance-service.ts +++ b/src/libs/services/balance-service/balance-service.ts @@ -3,11 +3,20 @@ import { BALANCE_REFRESH_RATE, CURRENCY_REFRESH_RATE } from '@src/constants'; import { dispatchToMainStore } from '@background/redux/utils'; import { serviceMessage } from '@background/service-message'; -import { DataResponse, Payload } from '@libs/services/types'; +import { + DataResponse, + ErrorResponse, + PaginatedResponse, + Payload +} from '@libs/services/types'; import { queryClient } from '../query-client'; import { handleError, toJson } from '../utils'; -import { getAccountBalanceUrl, getCurrencyRateUrl } from './constants'; +import { + getAccountBalanceUrl, + getAccountBalancesUrl, + getCurrencyRateUrl +} from './constants'; import { AccountData, FetchBalanceResponse, @@ -48,11 +57,35 @@ export const accountBalanceRequest = ( .catch(handleError); }; +export const accountBalancesRequest = ( + accountHashes: string, + casperWalletApiUrl: string, + signal?: AbortSignal +): Promise | ErrorResponse> => + fetch( + getAccountBalancesUrl({ + accountHashes, + casperWalletApiUrl + }), + { + signal + } + ) + .then(toJson) + .catch(handleError); + export const dispatchFetchActiveAccountBalance = ( accountHash = '' ): Promise> => dispatchToMainStore(serviceMessage.fetchBalanceRequest({ accountHash })); +export const dispatchFetchAccountBalances = ( + accountHashes = '' +): Promise | ErrorResponse>> => + dispatchToMainStore( + serviceMessage.fetchAccountBalancesRequest({ accountHashes }) + ); + export const fetchAccountBalance = ({ accountHash, casperWalletApiUrl @@ -81,3 +114,19 @@ export const fetchCurrencyRate = ({ staleTime: CURRENCY_REFRESH_RATE } ); + +export const fetchAccountBalances = ({ + accountHashes, + casperWalletApiUrl +}: { + accountHashes: string; + casperWalletApiUrl: string; +}) => + queryClient.fetchQuery( + ['getAccountBalancesRequest', accountHashes, casperWalletApiUrl], + ({ signal }) => + accountBalancesRequest(accountHashes, casperWalletApiUrl, signal), + { + staleTime: BALANCE_REFRESH_RATE + } + ); diff --git a/src/libs/services/balance-service/constants.ts b/src/libs/services/balance-service/constants.ts index 9cfd61a53..44cc59b0a 100644 --- a/src/libs/services/balance-service/constants.ts +++ b/src/libs/services/balance-service/constants.ts @@ -3,6 +3,11 @@ interface GetAccountBalanceUrl { casperWalletApiUrl: string; } +interface GetAccountBalancesUrl { + accountHashes: string; + casperWalletApiUrl: string; +} + export const getCurrencyRateUrl = (casperClarityApiUrl: string) => `${casperClarityApiUrl}/rates/1/amount`; @@ -11,3 +16,9 @@ export const getAccountBalanceUrl = ({ casperWalletApiUrl }: GetAccountBalanceUrl) => `${casperWalletApiUrl}/accounts/${accountHash}?includes=delegated_balance,undelegating_balance`; + +export const getAccountBalancesUrl = ({ + accountHashes, + casperWalletApiUrl +}: GetAccountBalancesUrl) => + `${casperWalletApiUrl}/accounts?account_hash=${accountHashes}&page=1&page_size=100&includes=delegated_balance,undelegating_balance`; diff --git a/src/libs/services/buy-cspr-service/constants.ts b/src/libs/services/buy-cspr-service/constants.ts new file mode 100644 index 000000000..f1d4cf13f --- /dev/null +++ b/src/libs/services/buy-cspr-service/constants.ts @@ -0,0 +1,2 @@ +export const onRampOptionsUrl = 'https://onramp-api.cspr.click/api/options'; +export const onRampSelectionUrl = 'https://onramp-api.cspr.click/api/selection'; diff --git a/src/libs/services/buy-cspr-service/index.ts b/src/libs/services/buy-cspr-service/index.ts new file mode 100644 index 000000000..b0fc3452d --- /dev/null +++ b/src/libs/services/buy-cspr-service/index.ts @@ -0,0 +1,79 @@ +import { dispatchToMainStore } from '@background/redux/utils'; +import { serviceMessage } from '@background/service-message'; + +import { queryClient } from '@libs/services/query-client'; +import { ErrorResponse, Payload } from '@libs/services/types'; +import { handleError, toJson } from '@libs/services/utils'; + +import { onRampOptionsUrl, onRampSelectionUrl } from './constants'; +import { + GetOnRampResponse, + OptionsPostRequestData, + ResponseOnRampProps, + ResponseSelectionProps, + SelectionPostRequestData +} from './types'; + +export const onRampGetOptionRequest = ( + signal?: AbortSignal +): Promise => + fetch(onRampOptionsUrl, { signal }).then(toJson).catch(handleError); + +export const onRampPostOptionRequest = ( + data: OptionsPostRequestData, + signal?: AbortSignal +): Promise => + fetch(onRampOptionsUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + signal, + body: JSON.stringify(data) + }) + .then(toJson) + .catch(handleError); + +export const onRampPostSelectionRequest = ( + data: SelectionPostRequestData, + signal?: AbortSignal +): Promise => + fetch(onRampSelectionUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + signal, + body: JSON.stringify(data) + }) + .then(toJson) + .catch(handleError); + +export const fetchOnRampOptionGet = () => + queryClient.fetchQuery(['onRampGetOptionRequest'], ({ signal }) => + onRampGetOptionRequest(signal) + ); + +export const fetchOnRampOptionPost = (data: OptionsPostRequestData) => + queryClient.fetchQuery(['onRampPostOptionRequest', data], ({ signal }) => + onRampPostOptionRequest(data, signal) + ); + +export const fetchOnRampSelectionPost = (data: SelectionPostRequestData) => + queryClient.fetchQuery(['onRampPostSelectionRequest', data], ({ signal }) => + onRampPostSelectionRequest(data, signal) + ); + +export const dispatchFetchOnRampOptionGet = (): Promise< + Payload +> => dispatchToMainStore(serviceMessage.fetchOnRampGetOptionRequest()); + +export const dispatchFetchOnRampOptionPost = ( + data: OptionsPostRequestData +): Promise> => + dispatchToMainStore(serviceMessage.fetchOnRampPostOptionRequest(data)); + +export const dispatchFetchOnRampSelectionPost = ( + data: SelectionPostRequestData +): Promise> => + dispatchToMainStore(serviceMessage.fetchOnRampPostSelectionRequest(data)); diff --git a/src/libs/services/buy-cspr-service/types.ts b/src/libs/services/buy-cspr-service/types.ts new file mode 100644 index 000000000..3f2989407 --- /dev/null +++ b/src/libs/services/buy-cspr-service/types.ts @@ -0,0 +1,73 @@ +export interface GetOnRampResponse { + countries: ResponseCountryProps[]; + defaultCountry: string; + currencies: ResponseCurrencyProps[]; + defaultCurrency: string; + defaultAmount: string; +} + +export interface ResponseCountryProps { + name: string; + code: string; +} + +export interface ResponseCurrencyProps { + id: number; + code: string; + type_id: string; + rate: number; +} + +export interface ResponseOnRampProps { + availableProviders: ProviderProps[]; + currencies: CurrencyProps[]; + fiatAmount: number; + fiatCurrency: string; + cryptoAmount: number; + cryptoCurrency: string; + isCryptoChanged: boolean; +} + +export interface ProviderProps { + cryptoAmount: string; + cryptoCurrency: string; + fiatAmount: string; + fiatCurrency: string; + csprExchangeRate: string; + fees: string; + logoPNG: string; + logoSVG?: string; + providerKey: string; + providerName: string; +} + +export interface CurrencyProps { + value: string; + label: string; + rate: number; +} + +export interface OptionsPostRequestData { + amount: number; + country: string; + fiatCurrency: string; + paymentCurrency: string; +} + +export interface ResponseCountryPropsWithId extends ResponseCountryProps { + id: number; +} + +export interface ResponseSelectionProps { + provider: string; + location: string; +} + +export interface SelectionPostRequestData { + account: string; + fiatCurrency: string; + cryptoAmount: null; + cryptoAsset: string; + selectedOnrampProvider: string; + fiatAmount: number; +} diff --git a/src/libs/services/deployer-service/index.ts b/src/libs/services/deployer-service/index.ts index bef4c71fe..0d3ec53dd 100644 --- a/src/libs/services/deployer-service/index.ts +++ b/src/libs/services/deployer-service/index.ts @@ -1,21 +1,33 @@ +import { CEP18Client } from 'casper-cep18-js-client'; import { CLPublicKey, CLValueBuilder, - CasperServiceByJsonRPC, DeployUtil, + Keys, RuntimeArgs, decodeBase16 } from 'casper-js-sdk'; import { sub } from 'date-fns'; -import { AuctionManagerEntryPoint, STAKE_COST_MOTES } from '@src/constants'; +import { + AuctionManagerEntryPoint, + CasperNodeUrl, + NetworkName, + ReferrerUrl, + STAKE_COST_MOTES, + TRANSFER_COST_MOTES +} from '@src/constants'; -import { signDeploy } from '@libs/crypto'; import { getRawPublicKey } from '@libs/entities/Account'; +import { toJson } from '@libs/services/utils'; +import { Account } from '@libs/types/account'; +import { CSPRtoMotes, multiplyErc20Balance } from '@libs/ui/utils'; -import { RPCResponse } from './types'; - -const casperService = (url: string) => new CasperServiceByJsonRPC(url); +import { + ICasperNetworkSendDeployErrorResponse, + ICasperNetworkSendDeployResponse, + ICasperNodeStatusResponse +} from './types'; export const getAuctionManagerDeployCost = ( entryPoint: AuctionManagerEntryPoint @@ -31,42 +43,35 @@ export const getAuctionManagerDeployCost = ( } }; -export const signAndDeploy = ( - deploy: DeployUtil.Deploy, - senderPublicKeyHex: string, - senderSecretKeyHex: string, - url: string -): Promise => { - const signature = signDeploy( - deploy.hash, - senderPublicKeyHex, - senderSecretKeyHex - ); +export const getDateForDeploy = async (nodeUrl: CasperNodeUrl) => { + const defaultDate = sub(new Date(), { seconds: 2 }).getTime(); - const signedDeploy = DeployUtil.setSignature( - deploy, - signature, - CLPublicKey.fromHex(senderPublicKeyHex) - ); + try { + const casperNodeTimestamp: ICasperNodeStatusResponse = await fetch( + `${nodeUrl}/info_get_status`, + { + referrer: ReferrerUrl + } + ).then(toJson); - return casperService(url) - .deploy(signedDeploy) - .then(function (res) { - return res; - }) - .catch(error => { - throw error; - }); + return casperNodeTimestamp?.last_progress + ? new Date(casperNodeTimestamp?.last_progress).getTime() + : defaultDate; + } catch { + return defaultDate; + } }; -export const makeAuctionManagerDeploy = ( +export const makeAuctionManagerDeployAndSing = async ( contractEntryPoint: AuctionManagerEntryPoint, delegatorPublicKeyHex: string, validatorPublicKeyHex: string, redelegateValidatorPublicKeyHex: string | null, amountMotes: string, - networkName: string, - auctionManagerContractHash: string + networkName: NetworkName, + auctionManagerContractHash: string, + nodeUrl: CasperNodeUrl, + keys: Keys.AsymmetricKey[] ) => { const hash = decodeBase16(auctionManagerContractHash); @@ -85,14 +90,16 @@ export const makeAuctionManagerDeploy = ( }) }); + const date = await getDateForDeploy(nodeUrl); + const deployParams = new DeployUtil.DeployParams( delegatorPublicKey, networkName, undefined, undefined, undefined, - sub(new Date(), { seconds: 2 }).getTime() - ); // https://github.com/casper-network/casper-node/issues/4152 + date // https://github.com/casper-network/casper-node/issues/4152 + ); const session = DeployUtil.ExecutableDeployItem.newStoredContractByHash( hash, @@ -104,5 +111,156 @@ export const makeAuctionManagerDeploy = ( const payment = DeployUtil.standardPayment(deployCost); - return DeployUtil.makeDeploy(deployParams, session, payment); + const deploy = DeployUtil.makeDeploy(deployParams, session, payment); + + return deploy.sign(keys); +}; + +export const makeNativeTransferDeployAndSign = async ( + senderPublicKeyHex: string, + recipientPublicKeyHex: string, + amountMotes: string, + networkName: NetworkName, + nodeUrl: CasperNodeUrl, + keys: Keys.AsymmetricKey[], + transferIdMemo?: string +) => { + const senderPublicKey = CLPublicKey.fromHex(senderPublicKeyHex); + const recipientPublicKey = CLPublicKey.fromHex(recipientPublicKeyHex); + + const date = await getDateForDeploy(nodeUrl); + + const deployParams = new DeployUtil.DeployParams( + senderPublicKey, + networkName, + undefined, + undefined, + undefined, + date // https://github.com/casper-network/casper-node/issues/4152 + ); + + const session = + DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId( + amountMotes, + recipientPublicKey, + undefined, + transferIdMemo || undefined + ); + + const payment = DeployUtil.standardPayment(TRANSFER_COST_MOTES); + + const deploy = DeployUtil.makeDeploy(deployParams, session, payment); + + return deploy.sign(keys); +}; + +export const makeCep18TransferDeployAndSign = async ( + nodeUrl: CasperNodeUrl, + networkName: NetworkName, + tokenContractHash: string | undefined, + tokenContractPackageHash: string | undefined, + recipientPublicKey: string, + amount: string, + erc20Decimals: number | null, + paymentAmount: string, + activeAccount: Account, + keys: Keys.AsymmetricKey[] +) => { + const cep18 = new CEP18Client(nodeUrl, networkName); + + const date = await getDateForDeploy(nodeUrl); + + cep18.setContractHash( + `hash-${tokenContractHash}`, + `hash-${tokenContractPackageHash}` + ); + + // create deploy + const tempDeploy = cep18.transfer( + { + recipient: getRawPublicKey(recipientPublicKey), + amount: multiplyErc20Balance(amount, erc20Decimals) || '0' + }, + CSPRtoMotes(paymentAmount), + getRawPublicKey(activeAccount.publicKey), + networkName + ); + + const deployParams = new DeployUtil.DeployParams( + getRawPublicKey(activeAccount.publicKey), + networkName, + undefined, + undefined, + undefined, + date // https://github.com/casper-network/casper-node/issues/4152 + ); + + const deploy = DeployUtil.makeDeploy( + deployParams, + tempDeploy.session, + tempDeploy.payment + ); + + return deploy.sign(keys); +}; + +export const makeNFTDeployAndSign = async ( + runtimeArgs: RuntimeArgs, + paymentAmount: string, + deploySender: CLPublicKey, + networkName: NetworkName, + contractPackageHash: string, + nodeUrl: CasperNodeUrl, + keys: Keys.AsymmetricKey[] +) => { + const hash = Uint8Array.from(Buffer.from(contractPackageHash, 'hex')); + + const date = await getDateForDeploy(nodeUrl); + + const deployParams = new DeployUtil.DeployParams( + deploySender, + networkName, + undefined, + undefined, + undefined, + date // https://github.com/casper-network/casper-node/issues/4152 + ); + const session = + DeployUtil.ExecutableDeployItem.newStoredVersionContractByHash( + hash, + null, + 'transfer', + runtimeArgs + ); + const payment = DeployUtil.standardPayment(paymentAmount); + const deploy = DeployUtil.makeDeploy(deployParams, session, payment); + + return deploy.sign(keys); +}; + +export const sendSignDeploy = ( + deploy: DeployUtil.Deploy, + nodeUrl: CasperNodeUrl +): Promise< + ICasperNetworkSendDeployResponse | ICasperNetworkSendDeployErrorResponse +> => { + const oneMegaByte = 1048576; + const size = DeployUtil.deploySizeInBytes(deploy); + + if (size > oneMegaByte) { + throw new Error( + `Deploy can not be send, because it's too large: ${size} bytes. Max size is 1 megabyte.` + ); + } + + return fetch(nodeUrl, { + method: 'POST', + referrer: ReferrerUrl, + body: JSON.stringify({ + jsonrpc: '2.0', + method: 'account_put_deploy', + params: [DeployUtil.deployToJson(deploy).deploy], + id: new Date().getTime() + }) + }).then(toJson); }; diff --git a/src/libs/services/deployer-service/types.ts b/src/libs/services/deployer-service/types.ts index f9c26287d..22cebb357 100644 --- a/src/libs/services/deployer-service/types.ts +++ b/src/libs/services/deployer-service/types.ts @@ -2,3 +2,32 @@ export interface RPCResponse { api_version: string; deploy_hash: string; } + +export interface RPCErrorResponse { + code: number; + message: string; + data: string | any; +} + +export interface ICasperNodeStatusResponse { + last_progress: string; +} + +export interface ICasperNetworkSendDeployResponse { + jsonrpc: '2.0'; + id: number; + result: { + api_version: string; + deploy_hash: string; + }; +} + +export interface ICasperNetworkSendDeployErrorResponse { + error: { + code: number; + data: string; + message: string; + }; + id: number; + jsonrpc: string; +} diff --git a/src/libs/services/transfer-service/transfer-service.ts b/src/libs/services/transfer-service/transfer-service.ts deleted file mode 100644 index 59eb3d293..000000000 --- a/src/libs/services/transfer-service/transfer-service.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { CLPublicKey, DeployUtil } from 'casper-js-sdk'; -import { sub } from 'date-fns'; - -import { NetworkName, TRANSFER_COST_MOTES } from '@src/constants'; - -export const makeNativeTransferDeploy = ( - senderPublicKeyHex: string, - recipientPublicKeyHex: string, - amountMotes: string, - networkName: NetworkName, - transferIdMemo?: string -) => { - const senderPublicKey = CLPublicKey.fromHex(senderPublicKeyHex); - const recipientPublicKey = CLPublicKey.fromHex(recipientPublicKeyHex); - - const deployParams = new DeployUtil.DeployParams( - senderPublicKey, - networkName, - undefined, - undefined, - undefined, - sub(new Date(), { seconds: 2 }).getTime() // https://github.com/casper-network/casper-node/issues/4152 - ); - - const session = - DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId( - amountMotes, - recipientPublicKey, - undefined, - transferIdMemo || undefined - ); - - const payment = DeployUtil.standardPayment(TRANSFER_COST_MOTES); - - return DeployUtil.makeDeploy(deployParams, session, payment); -}; diff --git a/src/libs/services/types.ts b/src/libs/services/types.ts index 337575ce0..61206325d 100644 --- a/src/libs/services/types.ts +++ b/src/libs/services/types.ts @@ -16,5 +16,7 @@ export interface DataResponse { export interface ErrorResponse { error: { message: string; + description: string; + code: string; }; } diff --git a/src/libs/types/account.ts b/src/libs/types/account.ts index d96d1366a..70c9c1f9a 100644 --- a/src/libs/types/account.ts +++ b/src/libs/types/account.ts @@ -5,8 +5,15 @@ export interface KeyPair { export interface Account extends KeyPair { name: string; imported?: boolean; + hidden: boolean; } -export interface AccountListRows extends Account { +export interface AccountWithBalance extends Account { + balance: { + liquidMotes: string | null; + }; +} + +export interface AccountListRows extends AccountWithBalance { id: string; } diff --git a/src/libs/ui/components/account-list/account-list-item.tsx b/src/libs/ui/components/account-list/account-list-item.tsx new file mode 100644 index 000000000..e3cf14b06 --- /dev/null +++ b/src/libs/ui/components/account-list/account-list-item.tsx @@ -0,0 +1,123 @@ +import React from 'react'; +import styled from 'styled-components'; + +import { + AlignedSpaceBetweenFlexRow, + FlexColumn, + SpacingSize +} from '@libs/layout'; +import { AccountListRows } from '@libs/types/account'; +import { + AccountActionsMenuPopover, + Avatar, + Hash, + HashVariant, + Typography +} from '@libs/ui/components'; +import { formatNumber, motesToCSPR } from '@libs/ui/utils'; + +const ListItemContainer = styled(FlexColumn)` + min-height: 68px; + height: 100%; + + padding: 16px 8px 16px 16px; +`; + +const ClickableContainer = styled(FlexColumn)` + flex-grow: 1; + + cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')}; +`; + +const Balance = styled(Typography)` + min-width: 0; + flex-grow: 1; + flex-basis: auto; + text-align: right; +`; + +const AccountName = styled(Typography)` + flex-shrink: 0; +`; + +interface AccountListItemProps { + account: AccountListRows; + onClick?: ( + event: React.MouseEvent, + accountName: string + ) => void; + isConnected: boolean; + isActiveAccount: boolean; + showHideAccountItem?: boolean; + closeModal?: (e: React.MouseEvent) => void; +} + +export const AccountListItem = ({ + account, + onClick, + isActiveAccount, + isConnected, + showHideAccountItem, + closeModal +}: AccountListItemProps) => { + const accountBalance = + account.balance?.liquidMotes != null + ? formatNumber(motesToCSPR(account.balance.liquidMotes), { + precision: { max: 0 } + }) + : '-'; + + return ( + + + + { + onClick(event, account.name); + } + : undefined + } + > + + + {account.name} + + + {accountBalance} + + + + + + CSPR + + + + + + + ); +}; diff --git a/src/libs/ui/components/account-list/account-list.tsx b/src/libs/ui/components/account-list/account-list.tsx index db7dbc823..7566c47aa 100644 --- a/src/libs/ui/components/account-list/account-list.tsx +++ b/src/libs/ui/components/account-list/account-list.tsx @@ -9,47 +9,19 @@ import { RouterPath, useTypedNavigate } from '@popup/router'; import { WindowApp } from '@background/create-open-window'; import { selectConnectedAccountNamesWithActiveOrigin, - selectVaultAccounts, - selectVaultActiveAccountName + selectVaultActiveAccountName, + selectVaultVisibleAccounts } from '@background/redux/vault/selectors'; import { useWindowManager } from '@hooks/use-window-manager'; import { getAccountHashFromPublicKey } from '@libs/entities/Account'; -import { - AlignedFlexRow, - CenteredFlexRow, - FlexColumn, - LeftAlignedFlexColumn, - SpacingSize -} from '@libs/layout'; +import { CenteredFlexRow, SpacingSize } from '@libs/layout'; import { AccountListRows } from '@libs/types/account'; -import { - AccountActionsMenuPopover, - Avatar, - Button, - Hash, - HashVariant, - List, - Typography -} from '@libs/ui/components'; +import { Button, List } from '@libs/ui/components'; import { sortAccounts } from '@libs/ui/components/account-list/utils'; -const ListItemContainer = styled(FlexColumn)` - min-height: 68px; - height: 100%; - - padding: 16px 8px 16px 16px; -`; - -const ListItemClickableContainer = styled(AlignedFlexRow)` - width: 100%; - cursor: pointer; -`; - -const AccountNameWithHashListItemContainer = styled(LeftAlignedFlexColumn)` - width: 100%; -`; +import { AccountListItem } from './account-list-item'; const ButtonContainer = styled(CenteredFlexRow)` padding: 16px; @@ -68,7 +40,7 @@ export const AccountList = ({ closeModal }: AccountListProps) => { const navigate = useTypedNavigate(); const { openWindow } = useWindowManager(); - const accounts = useSelector(selectVaultAccounts); + const visibleAccounts = useSelector(selectVaultVisibleAccounts); const activeAccountName = useSelector(selectVaultActiveAccountName); const connectedAccountNames = @@ -76,7 +48,7 @@ export const AccountList = ({ closeModal }: AccountListProps) => { useEffect(() => { const accountListRows = sortAccounts( - accounts, + visibleAccounts, activeAccountName, connectedAccountNames ).map(account => ({ @@ -87,8 +59,8 @@ export const AccountList = ({ closeModal }: AccountListProps) => { setAccountListRows(accountListRows); // We need to sort the account list only on the component mount and when new accounts are added - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [accounts]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [visibleAccounts]); return ( { const isActiveAccount = activeAccountName === account.name; return ( - - - { - changeActiveAccount(account.name); - closeModal(event); - }} - gap={SpacingSize.Medium} - > - - - - {account.name} - - - - - - - + { + changeActiveAccount(account.name); + closeModal(event); + }} + /> ); }} marginLeftForItemSeparatorLine={70} diff --git a/src/libs/ui/components/account-list/utils.test.ts b/src/libs/ui/components/account-list/utils.test.ts index 4608d69fe..dcba7f69c 100644 --- a/src/libs/ui/components/account-list/utils.test.ts +++ b/src/libs/ui/components/account-list/utils.test.ts @@ -6,31 +6,51 @@ describe('sortAccount()', () => { name: 'Test user 1', publicKey: '02026360f7ea7ce2ab573c732252e166bff086fe69d5d892b31f22fb80d910bde63b', - secretKey: 'FXYT1tqA5j89+P4Aw/VMDRZSrH5byyBvcan2CRLMnEE=' + secretKey: 'FXYT1tqA5j89+P4Aw/VMDRZSrH5byyBvcan2CRLMnEE=', + hidden: false, + balance: { + liquidMotes: null + } }, { name: 'Test user 2', publicKey: '01f9631111f51219ac0b96ce69ffd9f8fc274a744a8e3e77cd7b18f8b5d4bcf39a', - secretKey: '0Z4EkL1TStnELE1QL2IgtjiOem3mjMp4WHOX91Er6Lc=' + secretKey: '0Z4EkL1TStnELE1QL2IgtjiOem3mjMp4WHOX91Er6Lc=', + hidden: false, + balance: { + liquidMotes: null + } }, { name: 'Test user 3', publicKey: '020373098cf279f55b501a16642e18ecfe4691ce795213060f28c86bf485f16528da', - secretKey: 'nWbsCkonqeWOeT1S9clhyFlb5HfN5blktdZbJCmK5qE=' + secretKey: 'nWbsCkonqeWOeT1S9clhyFlb5HfN5blktdZbJCmK5qE=', + hidden: false, + balance: { + liquidMotes: null + } }, { name: 'Test user 4', publicKey: '01d302c4a8e9687f0ed0ffa5f9cd29cb5109af526cd72da5a0db9c321fc990bee0', - secretKey: '09+B7ceHs72J8YdNxCPzxuo3g6MJPTVZcr30PiSZoPE=' + secretKey: '09+B7ceHs72J8YdNxCPzxuo3g6MJPTVZcr30PiSZoPE=', + hidden: false, + balance: { + liquidMotes: null + } }, { name: 'Test user 5', publicKey: '01f33224e945e601fec597b711abe1966abeddb41881954d281c99634df2698a7b', - secretKey: 'KrwMFnKWZ4ASavxhzJ59g/+6KkZHXatLl6G3DzJ6uLA=' + secretKey: 'KrwMFnKWZ4ASavxhzJ59g/+6KkZHXatLl6G3DzJ6uLA=', + hidden: false, + balance: { + liquidMotes: null + } } ]; @@ -42,31 +62,51 @@ describe('sortAccount()', () => { name: 'Test user 3', publicKey: '020373098cf279f55b501a16642e18ecfe4691ce795213060f28c86bf485f16528da', - secretKey: 'nWbsCkonqeWOeT1S9clhyFlb5HfN5blktdZbJCmK5qE=' + secretKey: 'nWbsCkonqeWOeT1S9clhyFlb5HfN5blktdZbJCmK5qE=', + hidden: false, + balance: { + liquidMotes: null + } }, { name: 'Test user 1', publicKey: '02026360f7ea7ce2ab573c732252e166bff086fe69d5d892b31f22fb80d910bde63b', - secretKey: 'FXYT1tqA5j89+P4Aw/VMDRZSrH5byyBvcan2CRLMnEE=' + secretKey: 'FXYT1tqA5j89+P4Aw/VMDRZSrH5byyBvcan2CRLMnEE=', + hidden: false, + balance: { + liquidMotes: null + } }, { name: 'Test user 5', publicKey: '01f33224e945e601fec597b711abe1966abeddb41881954d281c99634df2698a7b', - secretKey: 'KrwMFnKWZ4ASavxhzJ59g/+6KkZHXatLl6G3DzJ6uLA=' + secretKey: 'KrwMFnKWZ4ASavxhzJ59g/+6KkZHXatLl6G3DzJ6uLA=', + hidden: false, + balance: { + liquidMotes: null + } }, { name: 'Test user 2', publicKey: '01f9631111f51219ac0b96ce69ffd9f8fc274a744a8e3e77cd7b18f8b5d4bcf39a', - secretKey: '0Z4EkL1TStnELE1QL2IgtjiOem3mjMp4WHOX91Er6Lc=' + secretKey: '0Z4EkL1TStnELE1QL2IgtjiOem3mjMp4WHOX91Er6Lc=', + hidden: false, + balance: { + liquidMotes: null + } }, { name: 'Test user 4', publicKey: '01d302c4a8e9687f0ed0ffa5f9cd29cb5109af526cd72da5a0db9c321fc990bee0', - secretKey: '09+B7ceHs72J8YdNxCPzxuo3g6MJPTVZcr30PiSZoPE=' + secretKey: '09+B7ceHs72J8YdNxCPzxuo3g6MJPTVZcr30PiSZoPE=', + hidden: false, + balance: { + liquidMotes: null + } } ]; diff --git a/src/libs/ui/components/account-list/utils.ts b/src/libs/ui/components/account-list/utils.ts index 7b777e8fb..d794b7637 100644 --- a/src/libs/ui/components/account-list/utils.ts +++ b/src/libs/ui/components/account-list/utils.ts @@ -1,7 +1,7 @@ -import { Account } from '@libs/types/account'; +import { Account, AccountWithBalance } from '@libs/types/account'; export function sortAccounts( - accounts: Account[], + accounts: AccountWithBalance[], activeAccountName: string | null, connectedAccountNames: string[] ) { diff --git a/src/libs/ui/components/account-popover/account-popover.tsx b/src/libs/ui/components/account-popover/account-popover.tsx index 27f17b3e4..4cd600ef4 100644 --- a/src/libs/ui/components/account-popover/account-popover.tsx +++ b/src/libs/ui/components/account-popover/account-popover.tsx @@ -9,6 +9,8 @@ import { RouterPath, useTypedNavigate } from '@popup/router'; import { selectActiveOrigin } from '@background/redux/active-origin/selectors'; import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors'; +import { dispatchToMainStore } from '@background/redux/utils'; +import { hideAccountFromListChange } from '@background/redux/vault/actions'; import { selectConnectedAccountNamesWithActiveOrigin, selectIsAnyAccountConnectedWithActiveOrigin @@ -21,10 +23,12 @@ import { Popover } from '@libs/ui/components/popover/popover'; interface AccountActionsMenuPopoverProps { account: Account; onClick?: (e: React.MouseEvent) => void; + showHideAccountItem?: boolean; } export const AccountActionsMenuPopover = ({ account, - onClick + onClick, + showHideAccountItem }: AccountActionsMenuPopoverProps) => { const navigate = useTypedNavigate(); const { t } = useTranslation(); @@ -124,6 +128,33 @@ export const AccountActionsMenuPopover = ({ View on CSPR.live + {showHideAccountItem && ( + { + dispatchToMainStore( + hideAccountFromListChange({ accountName: account.name }) + ); + }} + > + + + {account.hidden ? ( + Show in list + ) : ( + Hide from list + )} + + + )} { diff --git a/src/libs/ui/components/active-account-plate/active-account-plate.tsx b/src/libs/ui/components/active-account-plate/active-account-plate.tsx index 7c2230d12..f638d7ae4 100644 --- a/src/libs/ui/components/active-account-plate/active-account-plate.tsx +++ b/src/libs/ui/components/active-account-plate/active-account-plate.tsx @@ -34,7 +34,7 @@ const NameContainer = styled(SpaceBetweenFlexColumn)` max-width: 120px; `; -export const Container = styled(TileContainer)` +const Container = styled(TileContainer)` margin-top: 8px; `; diff --git a/src/libs/ui/components/avatar/avatar.tsx b/src/libs/ui/components/avatar/avatar.tsx index b4d883b15..da5ac598e 100644 --- a/src/libs/ui/components/avatar/avatar.tsx +++ b/src/libs/ui/components/avatar/avatar.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import Identicon from 'react-identicons'; import { useSelector } from 'react-redux'; import styled, { DefaultTheme, useTheme } from 'styled-components'; @@ -16,33 +15,7 @@ import { CenteredFlexRow, SpacingSize } from '@libs/layout'; -import { SvgIcon } from '@libs/ui/components'; - -const RoundedIdenticon = styled(Identicon)( - ({ - theme, - displayContext, - isActiveAccount, - isConnected - }: { - theme: DefaultTheme; - displayContext?: 'header' | 'accountList'; - isActiveAccount?: boolean; - isConnected?: boolean; - }) => ({ - borderRadius: theme.borderRadius.base, - - ...(displayContext === 'accountList' && { - border: isActiveAccount - ? `3px solid ${ - isConnected - ? theme.color.contentPositive - : theme.color.contentDisabled - }` - : `3px solid ${theme.color.backgroundPrimary}` - }) - }) -); +import { Identicon, SvgIcon } from '@libs/ui/components'; const IconHashWrapper = styled(CenteredFlexRow)(({ theme }) => ({ color: theme.color.contentOnFill, @@ -71,6 +44,7 @@ interface AvatarTypes { isConnected?: boolean; displayContext?: 'header' | 'accountList'; isActiveAccount?: boolean; + borderRadius?: number; } export const Avatar = ({ @@ -80,7 +54,8 @@ export const Avatar = ({ withConnectedStatus, isConnected, displayContext, - isActiveAccount + isActiveAccount, + borderRadius }: AvatarTypes) => { const theme = useTheme(); @@ -104,13 +79,14 @@ export const Avatar = ({ if (withConnectedStatus && isConnected !== undefined) { return ( - - ); diff --git a/src/libs/ui/components/checkbox/checkbox.tsx b/src/libs/ui/components/checkbox/checkbox.tsx index 2d4c1e765..e6d20a501 100644 --- a/src/libs/ui/components/checkbox/checkbox.tsx +++ b/src/libs/ui/components/checkbox/checkbox.tsx @@ -10,7 +10,7 @@ const StyledFlexRow = styled(FlexRow)<{ checked?: boolean; disabled?: boolean; }>(({ theme, checked, disabled }) => ({ - cursor: 'pointer', + cursor: disabled ? 'default' : 'pointer', width: 'fit-content', pointerEvents: 'auto', svg: { diff --git a/src/libs/ui/components/contacts-plate/contacts-plate.tsx b/src/libs/ui/components/contacts-plate/contacts-plate.tsx index 2cd02452c..6ecae6148 100644 --- a/src/libs/ui/components/contacts-plate/contacts-plate.tsx +++ b/src/libs/ui/components/contacts-plate/contacts-plate.tsx @@ -27,7 +27,7 @@ export const ContactsPlate = ({ publicKey, name }: ContactsPlateProps) => { navigate(RouterPath.ContactDetails.replace(':contactName', name)); }} > - + {name} ( + ({ + theme, + displayContext, + isActiveAccount, + isConnected, + size, + borderRadius + }) => ({ + borderRadius: borderRadius ? borderRadius : theme.borderRadius.base, + + width: size, + height: size, + + ...(displayContext === 'accountList' && { + border: isActiveAccount + ? `3px solid ${ + isConnected + ? theme.color.contentPositive + : theme.color.contentDisabled + }` + : `3px solid ${theme.color.backgroundPrimary}` + }) + }) +); + +interface IdenticonProps { + background: string; + count?: number; + padding?: number; + size: number; + value: string; + displayContext?: 'header' | 'accountList'; + isActiveAccount?: boolean; + isConnected?: boolean; + borderRadius?: number; +} +export const Identicon = ({ + background, + count = 5, + value, + size, + padding = 0, + displayContext, + isActiveAccount, + isConnected, + borderRadius +}: IdenticonProps) => { + const canvas = useRef(null); + + useEffect(() => { + const hash = md5(value); + const block = Math.floor(size / count); + const hashColor = hash.slice(0, 6); + + if (canvas && canvas.current) { + canvas.current.width = block * count + padding; + canvas.current.height = block * count + padding; + const arr = hash.split('').map(el => { + const element = parseInt(el, 16); + + return element < 8 ? 0 : 1; + }); + + const map = []; + + map[0] = map[4] = arr.slice(0, 5); + map[1] = map[3] = arr.slice(5, 10); + map[2] = arr.slice(10, 15); + + const ctx = canvas.current.getContext('2d'); + + if (ctx) { + ctx.imageSmoothingEnabled = false; + ctx.clearRect(0, 0, canvas.current.width, canvas.current.height); + + map.forEach((row, i) => { + row.forEach((el, j) => { + if (el) { + ctx.fillStyle = '#' + hashColor; + ctx.fillRect( + block * i + padding, + block * j + padding, + block - padding, + block - padding + ); + } else { + ctx.fillStyle = background; + ctx.fillRect( + block * i + padding, + block * j + padding, + block - padding, + block - padding + ); + } + }); + }); + } + } + }, [background, count, padding, size, value]); + + return ( + + ); +}; diff --git a/src/libs/ui/components/index.ts b/src/libs/ui/components/index.ts index b3f95dfbb..3b2070954 100644 --- a/src/libs/ui/components/index.ts +++ b/src/libs/ui/components/index.ts @@ -49,3 +49,6 @@ export * from './validator-plate/validator-plate'; export * from './error/error'; export * from './contacts-plate/contacts-plate'; export * from './theme-switcher/theme-switcher'; +export * from './identicon/identicon'; +export * from './spinner/spinner'; +export * from './tips/tips'; diff --git a/src/libs/ui/components/list/list.tsx b/src/libs/ui/components/list/list.tsx index 2309e5d19..f5ef9365a 100644 --- a/src/libs/ui/components/list/list.tsx +++ b/src/libs/ui/components/list/list.tsx @@ -80,6 +80,7 @@ interface ListProps { stickyHeader?: boolean; maxHeight?: number; borderRadius?: 'base'; + height?: number; } export function List({ @@ -95,7 +96,8 @@ export function List({ contentTop = SpacingSize.XL, stickyHeader, maxHeight, - borderRadius + borderRadius, + height }: ListProps) { const separatorLine = marginLeftForHeaderSeparatorLine || marginLeftForHeaderSeparatorLine === 0 @@ -135,8 +137,8 @@ export function List({ {renderHeader()} )} - {maxHeight ? ( - + {maxHeight || height ? ( + diff --git a/src/libs/ui/components/modal/modal.tsx b/src/libs/ui/components/modal/modal.tsx index 3caca7c3a..73f08b69f 100644 --- a/src/libs/ui/components/modal/modal.tsx +++ b/src/libs/ui/components/modal/modal.tsx @@ -1,5 +1,5 @@ import React, { MouseEvent, useRef, useState } from 'react'; -import styled from 'styled-components'; +import styled, { keyframes } from 'styled-components'; import { useClickAway } from '@hooks/use-click-away'; @@ -10,6 +10,26 @@ const ChildrenContainer = styled(AlignedFlexRow)` cursor: pointer; `; +const slideInFromBottom = keyframes` + from { + transform: translateY(100%); + } + + to { + transform: translateY(0); + } +`; + +const slideOutToBottom = keyframes` + from { + transform: translateY(0); + } + + to { + transform: translateY(100%); + } +`; + const ModalContainer = styled.div<{ placement: 'top' | 'bottom' | 'fullBottom'; }>(({ theme, placement }) => ({ @@ -45,6 +65,14 @@ const ModalContainer = styled.div<{ : `${theme.borderRadius.twelve}px` })); +const ModalEnterFromBottom = styled(ModalContainer)` + animation: ${slideInFromBottom} 0.5s linear forwards; +`; + +const ModalExitToBottom = styled(ModalContainer)` + animation: ${slideOutToBottom} 0.5s linear forwards; +`; + interface RenderChildrenProps { isOpen: boolean; } @@ -58,35 +86,72 @@ export interface ModalProps extends BaseProps { renderContent: (renderProps: RenderContentProps) => React.ReactNode | string; dataTestId?: string; placement: 'top' | 'bottom' | 'fullBottom'; + loading?: boolean; + childrenFlexGrow?: number; } export const Modal = ({ children, renderContent, placement, - dataTestId + dataTestId, + loading, + childrenFlexGrow }: ModalProps) => { const [isOpen, setIsOpen] = useState(false); + const [isExiting, setIsExiting] = useState(false); const childrenContainerRef = useRef(null); const { ref: clickAwayRef } = useClickAway({ callback: event => { event.stopPropagation(); - isOpen && setIsOpen(false); + setIsExiting(true); + + if (placement === 'top') { + setIsOpen(false); + setIsExiting(false); + } else { + // After animation completes, set isOpen to false + setTimeout(() => { + setIsOpen(false); + setIsExiting(false); + }, 500); + } } }); const closeModal = (e: MouseEvent) => { e.stopPropagation(); - setIsOpen(false); + setIsExiting(true); + + if (placement === 'top') { + setIsOpen(false); + setIsExiting(false); + } else { + // After animation completes, set isOpen to false + setTimeout(() => { + setIsOpen(false); + setIsExiting(false); + }, 500); + } }; + let ModalComponent; + + if (placement === 'top') { + ModalComponent = ModalContainer; + } else { + ModalComponent = isExiting ? ModalExitToBottom : ModalEnterFromBottom; + } + return ( <> { + if (loading) return; event.stopPropagation(); setIsOpen(true); }} @@ -96,9 +161,9 @@ export const Modal = ({ {isOpen && ( - + {renderContent({ closeModal })} - + )} diff --git a/src/libs/ui/components/password-inputs/password-inputs.tsx b/src/libs/ui/components/password-inputs/password-inputs.tsx index e277dd28f..53bd6e32e 100644 --- a/src/libs/ui/components/password-inputs/password-inputs.tsx +++ b/src/libs/ui/components/password-inputs/password-inputs.tsx @@ -37,20 +37,25 @@ export const PasswordInputs = ({ {needToAddMoreCharacters <= 0 ? ( - - Your password length is -{' '} - - {{ passwordLength }} characters. - - + , + nt: + }} + /> ) : ( - - You need to add at least{' '} - - {{ needToAddMoreCharacters }} characters - {' '} - more. - + , + nt: + }} + /> )} diff --git a/src/libs/ui/components/secret-phrase-words-view/word-tag.tsx b/src/libs/ui/components/secret-phrase-words-view/word-tag.tsx index 757551001..06393aa61 100644 --- a/src/libs/ui/components/secret-phrase-words-view/word-tag.tsx +++ b/src/libs/ui/components/secret-phrase-words-view/word-tag.tsx @@ -68,7 +68,9 @@ export function WordTag({ {index + 1} )} - {value} + + {value} + ); } diff --git a/src/libs/ui/components/spinner/spinner.tsx b/src/libs/ui/components/spinner/spinner.tsx new file mode 100644 index 000000000..999d4f5ef --- /dev/null +++ b/src/libs/ui/components/spinner/spinner.tsx @@ -0,0 +1,215 @@ +import React from 'react'; +import styled, { DefaultTheme, keyframes } from 'styled-components'; + +import { CenteredFlexRow } from '@libs/layout'; +import { hexToRGBA } from '@libs/ui/utils'; + +const spin = (theme: DefaultTheme) => keyframes` + 0%, + 100% { + box-shadow: 0 -2.6em 0 0 ${ + theme.color.contentSecondary + }, 1.8em -1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 2.5em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.75em 1.75em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 0 2.5em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em 1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -2.6em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.5' + )}, -1.8em -1.8em 0 0 ${hexToRGBA(theme.color.contentSecondary, '0.7')}; + } + 12.5% { + box-shadow: 0 -2.6em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.7' + )}, 1.8em -1.8em 0 0 ${ + theme.color.contentOnFill + }, 2.5em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.75em 1.75em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 0 2.5em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em 1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -2.6em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em -1.8em 0 0 ${hexToRGBA(theme.color.contentSecondary, '0.5')}; + } + 25% { + box-shadow: 0 -2.6em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.5' + )}, 1.8em -1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.7' + )}, 2.5em 0 0 0 ${ + theme.color.contentOnFill + }, 1.75em 1.75em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 0 2.5em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em 1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -2.6em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em -1.8em 0 0 ${hexToRGBA(theme.color.contentSecondary, '0.2')}; + } + 37.5% { + box-shadow: 0 -2.6em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.8em -1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.5' + )}, 2.5em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.7' + )}, 1.75em 1.75em 0 0 ${ + theme.color.contentOnFill + }, 0 2.5em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em 1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -2.6em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em -1.8em 0 0 ${hexToRGBA(theme.color.contentSecondary, '0.2')}; + } + 50% { + box-shadow: 0 -2.6em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.8em -1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 2.5em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.5' + )}, 1.75em 1.75em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.7' + )}, 0 2.5em 0 0 ${ + theme.color.contentOnFill + }, -1.8em 1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -2.6em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em -1.8em 0 0 ${hexToRGBA(theme.color.contentSecondary, '0.2')}; + } + 62.5% { + box-shadow: 0 -2.6em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.8em -1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 2.5em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.75em 1.75em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.5' + )}, 0 2.5em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.7' + )}, -1.8em 1.8em 0 0 ${ + theme.color.contentOnFill + }, -2.6em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em -1.8em 0 0 ${hexToRGBA(theme.color.contentSecondary, '0.2')}; + } + 75% { + box-shadow: 0 -2.6em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.8em -1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 2.5em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.75em 1.75em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 0 2.5em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.5' + )}, -1.8em 1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.7' + )}, -2.6em 0 0 0 ${ + theme.color.contentOnFill + }, -1.8em -1.8em 0 0 ${hexToRGBA(theme.color.contentSecondary, '0.2')}; + } + 87.5% { + box-shadow: 0 -2.6em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.8em -1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 2.5em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 1.75em 1.75em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, 0 2.5em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.2' + )}, -1.8em 1.8em 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.5' + )}, -2.6em 0 0 0 ${hexToRGBA( + theme.color.contentSecondary, + '0.7' + )}, -1.8em -1.8em 0 0 ${theme.color.contentOnFill}; + } +`; + +const SpinnerWrapper = styled(CenteredFlexRow)` + margin-top: 30px; +`; + +const SpinnerCircle = styled.div` + font-size: 5px; + width: 1em; + height: 1em; + border-radius: 50%; + position: relative; + text-indent: -9999em; + animation: ${props => spin(props.theme)} 1.1s infinite ease; + transform: translateZ(0); +`; + +export const Spinner = () => ( + + + +); diff --git a/src/libs/ui/components/tips/tips.tsx b/src/libs/ui/components/tips/tips.tsx new file mode 100644 index 000000000..a69ba8ec7 --- /dev/null +++ b/src/libs/ui/components/tips/tips.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import styled from 'styled-components'; + +import { + AlignedFlexRow, + LeftAlignedFlexColumn, + SpacingSize +} from '@libs/layout'; +import { List, SvgIcon, Typography } from '@libs/ui/components'; + +const ItemContainer = styled(AlignedFlexRow)<{ withDescription: boolean }>` + padding: ${({ withDescription }) => (withDescription ? '8px 16px' : '16px')}; +`; + +type ListType = { + id: number; + header: string; + description?: string; + icon?: string; +}; +interface TipsProps { + label?: string; + list: ListType[]; + contentTop?: SpacingSize; +} + +export const Tips = ({ list, label, contentTop }: TipsProps) => ( + ( + + + + {header} + {description && ( + + {description} + + )} + + + )} + marginLeftForItemSeparatorLine={54} + /> +); diff --git a/src/libs/ui/components/typography/typography.tsx b/src/libs/ui/components/typography/typography.tsx index 2df0dc34e..c1f03e74f 100644 --- a/src/libs/ui/components/typography/typography.tsx +++ b/src/libs/ui/components/typography/typography.tsx @@ -35,6 +35,8 @@ export interface BodyStylesProps extends BaseProps { fontSize?: CSPRSize; ellipsis?: boolean; overflowWrap?: boolean; + translate?: 'yes' | 'no'; + textAlign?: 'center' | 'left' | 'right' | 'inherit'; } export const getFontSizeBasedOnTextLength = (length: number) => { @@ -63,7 +65,8 @@ function getBodyStyles( noWrap = false, wordBreak = false, ellipsis = false, - overflowWrap = false + overflowWrap = false, + textAlign }: BodyStylesProps ): CSSObject { return { @@ -92,6 +95,9 @@ function getBodyStyles( }), ...(overflowWrap && { overflowWrap: 'break-word' + }), + ...(textAlign && { + textAlign: textAlign }) }; } diff --git a/src/libs/ui/forms/buy-cspr.ts b/src/libs/ui/forms/buy-cspr.ts new file mode 100644 index 000000000..5122bec6a --- /dev/null +++ b/src/libs/ui/forms/buy-cspr.ts @@ -0,0 +1,28 @@ +import * as Yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup/dist/yup'; +import { UseFormProps, useForm } from 'react-hook-form'; + +import { useBuyCSPRKeyRule } from '@libs/ui/forms/form-validation-rules'; + +export type BuyCSPRFormValues = { + fiatAmount: string; + casperAmount: string; +}; + +export const useBuyCSPR = (defaultAmount: string) => { + const buyCSPRSchema = Yup.object().shape({ + fiatAmount: useBuyCSPRKeyRule(), + casperAmount: Yup.string() + }); + + const buyFromOptions: UseFormProps = { + reValidateMode: 'onChange', + mode: 'onChange', + resolver: yupResolver(buyCSPRSchema), + defaultValues: { + fiatAmount: defaultAmount + } + }; + + return useForm(buyFromOptions); +}; diff --git a/src/libs/ui/forms/form-validation-rules.ts b/src/libs/ui/forms/form-validation-rules.ts index 2db7dd951..0e5f3a20e 100644 --- a/src/libs/ui/forms/form-validation-rules.ts +++ b/src/libs/ui/forms/form-validation-rules.ts @@ -508,3 +508,21 @@ export const useTorusSecretKeyRule = () => { message: t('This secret key doesn’t look right') }); }; + +export const useBuyCSPRKeyRule = () => { + const { t } = useTranslation(); + + return Yup.string() + .required(t('Amount is required')) + .test({ + name: 'validU64', + test: csprAmountInputValue => { + if (csprAmountInputValue) { + return isValidU64(csprAmountInputValue); + } + + return false; + }, + message: t(`Amount is invalid`) + }); +}; diff --git a/src/libs/ui/utils/formatters.ts b/src/libs/ui/utils/formatters.ts index 100dab299..ce3919771 100644 --- a/src/libs/ui/utils/formatters.ts +++ b/src/libs/ui/utils/formatters.ts @@ -174,7 +174,16 @@ export const motesToCurrency = ( throw new Error('motesToCurrency: the CSPR rate cannot be zero'); } - return Big(motes).div(MOTES_PER_CSPR_RATE).mul(currencyPerCsprRate).toFixed(); + const amount = Big(motes).div(MOTES_PER_CSPR_RATE).mul(currencyPerCsprRate); + + const billion = new Big(10).pow(9); + + if (amount.gte(billion)) { + // If the value is greater than or equal to 10^9, return one billion string. + return '1000000000'; + } + + return amount.toFixed(); }; export function snakeAndKebabToCamel(str: string): string { @@ -190,7 +199,7 @@ export function capitalizeString(str: string): string { } export const formatCurrency = ( - value: number | string, + value: string, code: string, { precision @@ -198,12 +207,16 @@ export const formatCurrency = ( precision?: number; } = {} ): string => { - return intl.formatNumber(value as number, { + const formattedValue = intl.formatNumber(Number(value), { style: 'currency', currency: code, minimumFractionDigits: precision, maximumFractionDigits: precision }); + // Check if the original value is '1000000000' + // If yes, append a '+' sign to the end of the formatted value + // Otherwise, return the formatted value as is + return value === '1000000000' ? `${formattedValue}+` : formattedValue; }; export const formatFiatAmount = ( @@ -223,3 +236,24 @@ export const formatFiatAmount = ( } ); }; + +/** + * This function is an event handler for the onKeyDown event for HTML input elements of type "number". + * It prevents the user from entering 'e', 'E', '+', and '-' in the input field. + * These are valid inputs for the HTML input type "number" because they are used in scientific notation. + * For instance, a user could enter "1e-10" (0.0000000001), which is a valid number but might not be + * desirable for a form input because it's an unexpected format. + * Addition symbol '+' and minus '-' are also valid inputs for the HTML input type "number". + * If you want to allow these symbols but restrict 'e', 'E', you need to remove them from the included list. + * + * @param {React.KeyboardEvent} event - The Keyboard event object from React. + * This object contains various properties related to the keydown event, + * including info about which key is pressed, whether shift/ctrl/etc. keys are held down, + * what the target element is, and many others. + */ +export const handleNumericInput = (event: KeyboardEvent) => { + // Prevent 'e' (and '+', '-') from being entered into a number input field + if (['e', 'E', '+', '-'].includes(event.key)) { + event.preventDefault(); + } +}; diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 187e86c25..ef32d6b2b 100755 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -1,6 +1,5 @@ { "manifest_version": 2, - "content_security_policy": "default-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; script-src 'self'; style-src 'unsafe-inline'; img-src https: data:; media-src https: data:; connect-src https://event-store-api-clarity-testnet.make.services https://event-store-api-clarity-mainnet.make.services https://casper-assets.s3.amazonaws.com/ https://image-proxy-cdn.make.services/ https://casper-testnet-node-proxy.make.services/rpc https://casper-node-proxy.make.services/rpc https://cspr-wallet-api.dev.make.services/ https://api.casperwallet.io/", "icons": { "16": "logo16.png", "64": "logo64.png", @@ -14,10 +13,11 @@ "declarativeNetRequest", "https://image-proxy-cdn.make.services/*", "https://casper-assets.s3.amazonaws.com/*", - "https://casper-testnet-node-proxy.make.services/*", - "https://casper-node-proxy.make.services/*", - "https://cspr-wallet-api.dev.make.services/*", - "https://api.casperwallet.io/*" + "https://node.cspr.cloud/*", + "https://node.testnet.cspr.cloud/*", + "https://api.testnet.casperwallet.io/*", + "https://api.mainnet.casperwallet.io/*", + "https://onramp-api.cspr.click/api/*" ], "declarative_net_request": { "rule_resources": [ diff --git a/src/manifest.v2.safari.json b/src/manifest.v2.safari.json index d2a173734..0096f88dd 100644 --- a/src/manifest.v2.safari.json +++ b/src/manifest.v2.safari.json @@ -13,8 +13,11 @@ "tabs", "declarativeNetRequest", "https://image-proxy-cdn.make.services/*", - "https://cspr-wallet-api.dev.make.services/*", - "https://api.casperwallet.io/*" + "https://api.testnet.casperwallet.io/*", + "https://api.mainnet.casperwallet.io/*", + "https://onramp-api.cspr.click/api/*", + "https://node.testnet.cspr.cloud/*", + "https://node.cspr.cloud/*" ], "declarative_net_request": { "rule_resources": [ diff --git a/src/manifest.v3.json b/src/manifest.v3.json index e1765dfbe..b2b5122f5 100644 --- a/src/manifest.v3.json +++ b/src/manifest.v3.json @@ -1,8 +1,5 @@ { "manifest_version": 3, - "content_security_policy": { - "extension_pages": "default-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; script-src 'self'; style-src 'unsafe-inline'; img-src https: data:; media-src https: data:; connect-src https://event-store-api-clarity-testnet.make.services https://event-store-api-clarity-mainnet.make.services https://casper-assets.s3.amazonaws.com/ https://image-proxy-cdn.make.services/ https://casper-testnet-node-proxy.make.services/rpc https://casper-node-proxy.make.services/rpc https://cspr-wallet-api.dev.make.services/ https://api.casperwallet.io/" - }, "icons": { "16": "logo16.png", "64": "logo64.png", @@ -27,8 +24,10 @@ }, "host_permissions": [ "https://image-proxy-cdn.make.services/*", - "https://cspr-wallet-api.dev.make.services/*", - "https://api.casperwallet.io/*" + "https://api.testnet.casperwallet.io/*", + "https://api.mainnet.casperwallet.io/*", + "https://node.cspr.cloud/*", + "https://node.testnet.cspr.cloud/*" ], "background": { "service_worker": "./background.bundle.js" diff --git a/src/utils.ts b/src/utils.ts index 36612086c..8d7d48efa 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,12 +4,17 @@ import { runtime } from 'webextension-polyfill'; import { Browser, NFT_TOKENS_REFRESH_RATE } from '@src/constants'; +import { accountPendingTransactionsChanged } from '@background/redux/account-info/actions'; +import { dispatchToMainStore } from '@background/redux/utils'; + +import { dispatchFetchExtendedDeploysInfo } from '@libs/services/account-activity-service'; import { NFTTokenMetadata, NFTTokenMetadataEntry, NFTTokenResult } from '@libs/services/nft-service'; import { queryClient } from '@libs/services/query-client'; +import { Account } from '@libs/types/account'; interface ImageProxyUrlProps { ttl: string; @@ -29,6 +34,7 @@ export const getUrlOrigin = (url: string | undefined) => { export const isSafariBuild = process.env.BROWSER === Browser.Safari; export const isFirefoxBuild = process.env.BROWSER === Browser.Firefox; +export const isChromeBuild = process.env.BROWSER === Browser.Chrome; export const isValidU64 = (value?: string): boolean => { if (!value) { @@ -334,3 +340,54 @@ export const findMediaPreview = (metadata: NFTTokenMetadataEntry): boolean => { return hasImageExtension || knownImageKey; }; + +export const isEqualCaseInsensitive = (key1: string, key2: string) => { + return key1.toLowerCase() === key2.toLowerCase(); +}; + +export const getSigningAccount = ( + accounts: Account[], + signingPublicKeyHex: string +) => + accounts.find(account => + isEqualCaseInsensitive(account.publicKey, signingPublicKeyHex) + ); + +export const setCSPForSafari = () => { + if (isSafariBuild) { + const metaTag = document.querySelector('[http-equiv]'); + + if (metaTag == null) { + const meta = document.createElement('meta'); + + meta.setAttribute('http-equiv', 'Content-Security-Policy'); + meta.setAttribute( + 'content', + `default-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; script-src 'self'; style-src 'unsafe-inline'; img-src https: data:; media-src https: data:; connect-src https://event-store-api-clarity-testnet.make.services https://event-store-api-clarity-mainnet.make.services https://casper-assets.s3.amazonaws.com/ https://image-proxy-cdn.make.services/ https://node.cspr.cloud/ https://node.testnet.cspr.cloud/ https://api.testnet.casperwallet.io/ https://api.mainnet.casperwallet.io/ https://onramp-api.cspr.click/api/` + ); + + document.getElementsByTagName('head')[0].appendChild(meta); + } + } +}; + +export const fetchAndDispatchExtendedDeployInfo = (deployHash: string) => { + let triesLeft = 10; + + const interval = setInterval(async () => { + const { payload: extendedDeployInfo } = + await dispatchFetchExtendedDeploysInfo(deployHash); + + if (extendedDeployInfo) { + dispatchToMainStore( + accountPendingTransactionsChanged(extendedDeployInfo) + ); + clearInterval(interval); + } else if (triesLeft === 0) { + clearInterval(interval); + } + + triesLeft--; + // Note: this timeout is needed because the deploy is not immediately visible in the explorer + }, 2000); +}; diff --git a/webpack.config.js b/webpack.config.js index 1a16e80e6..d3306dbfc 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -27,7 +27,8 @@ const { isChrome, isSafari, ExtensionBuildPath, - ManifestPath + ManifestPath, + isFirefox } = require('./constants'); const isDev = env.NODE_ENV === 'development'; @@ -37,9 +38,7 @@ const buildDir = isChrome ? ExtensionBuildPath.Chrome : ExtensionBuildPath.Firefox; -const alias = { - 'react-dom': '@hot-loader/react-dom' -}; +const alias = {}; // load the secrets const secretsPath = path.join(__dirname, 'secrets.' + env.NODE_ENV + '.js'); @@ -61,6 +60,25 @@ if (fileSystem.existsSync(secretsPath)) { alias['secrets'] = secretsPath; } +const getCSP = () => { + const csp = + "default-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; script-src 'self'; style-src 'unsafe-inline'; img-src https: data:; media-src https: data:; connect-src https://event-store-api-clarity-testnet.make.services https://event-store-api-clarity-mainnet.make.services https://casper-assets.s3.amazonaws.com/ https://image-proxy-cdn.make.services/ https://node.cspr.cloud/ https://node.testnet.cspr.cloud/ https://api.testnet.casperwallet.io/ https://api.mainnet.casperwallet.io/ https://onramp-api.cspr.click/api/"; + + if (isFirefox) { + return csp; + } + + if (isChrome) { + return isDev + ? { + extension_pages: `${csp} ws://localhost:8000/socketcluster/ ws://localhost:3001/ws` + } + : { + extension_pages: csp + }; + } +}; + const options = { experiments: { topLevelAwait: true @@ -193,15 +211,7 @@ const options = { version_name: pkg.version + ` (${commitHash.slice(0, 7)})`, author: pkg.author, description: pkg.description, - ...(isDev - ? isChrome - ? { - content_security_policy: {} - } - : { - content_security_policy: '' - } - : {}) + content_security_policy: getCSP() }; // Removing the key from manifest for Chrome production build if (isChrome && !isDev) { diff --git a/xcode-project/Casper Wallet/Casper Wallet.xcodeproj/project.pbxproj b/xcode-project/Casper Wallet/Casper Wallet.xcodeproj/project.pbxproj index 806c4fa3d..2489edc7d 100644 --- a/xcode-project/Casper Wallet/Casper Wallet.xcodeproj/project.pbxproj +++ b/xcode-project/Casper Wallet/Casper Wallet.xcodeproj/project.pbxproj @@ -564,7 +564,7 @@ CODE_SIGN_ENTITLEMENTS = "Casper Wallet/Casper Wallet.entitlements"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 51; + CURRENT_PROJECT_VERSION = 56; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "Casper Wallet/Info.plist"; @@ -578,7 +578,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = 1.8.4; + MARKETING_VERSION = 1.9.0; OTHER_LDFLAGS = ( "-framework", SafariServices, @@ -601,7 +601,7 @@ CODE_SIGN_ENTITLEMENTS = "Casper Wallet/Casper Wallet.entitlements"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 51; + CURRENT_PROJECT_VERSION = 56; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "Casper Wallet/Info.plist"; @@ -615,7 +615,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = 1.8.4; + MARKETING_VERSION = 1.9.0; OTHER_LDFLAGS = ( "-framework", SafariServices,