diff --git a/.eslintrc.json b/.eslintrc.json index 30608aba..7b7ea1a3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -27,6 +27,7 @@ "quotes": ["error", "single"], "no-duplicate-imports": "error", "react/prop-types": 0, + "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }] }, diff --git a/.gitignore b/.gitignore index ed41a1ca..e7451e7d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,6 @@ build-storybook.log # local-testnet /local-testnet/testnet-data +/local-testnet/bls_to_execution_changes /out .env diff --git a/package.json b/package.json index 79ab05b2..0e112502 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@types/node": "^16.7.13", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", + "@uiw/react-textarea-code-editor": "^2.1.1", "autoprefixer": "^9", "axios": "^0.27.2", "bootstrap-icons": "^1.9.1", diff --git a/src/api/beacon.ts b/src/api/beacon.ts index 4f31c99b..a630256e 100644 --- a/src/api/beacon.ts +++ b/src/api/beacon.ts @@ -29,3 +29,9 @@ export const fetchValidatorMetrics = async ( await axios.post(`${protocol}://${address}:${port}/lighthouse/ui/validator_metrics`, { indices, }) + +export const broadcastBlsChange = async ({ protocol, address, port }: Endpoint, data: any) => + await axios.post( + `${protocol}://${address}:${port}/eth/v1/beacon/pool/bls_to_execution_changes`, + data, + ) diff --git a/src/components/BlsExecutionModal/BlsExecutionModal.tsx b/src/components/BlsExecutionModal/BlsExecutionModal.tsx new file mode 100644 index 00000000..8d1ed5f0 --- /dev/null +++ b/src/components/BlsExecutionModal/BlsExecutionModal.tsx @@ -0,0 +1,116 @@ +import RodalModal from '../RodalModal/RodalModal' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { beaconNodeEndpoint, isBlsExecutionModal, isProcessBls } from '../../recoil/atoms' +import useMediaQuery from '../../hooks/useMediaQuery' +import Typography from '../Typography/Typography' +import CodeInput from '../CodeInput/CodeInput' +import ValidatorDisclosure from '../Disclosures/ValidatorDisclosure' +import { useState } from 'react' +import { MOCK_BLS_JSON, WithdrawalInfoLink } from '../../constants/constants' +import GradientHeader from '../GradientHeader/GradientHeader' +import { ButtonFace } from '../Button/Button' +import { useTranslation, Trans } from 'react-i18next' +import { broadcastBlsChange } from '../../api/beacon' +import { toast } from 'react-toastify' +import axios, { AxiosError } from 'axios' +import useLocalStorage from '../../hooks/useLocalStorage' +import { Storage } from '../../constants/enums' + +const BlsExecutionModal = () => { + const { t } = useTranslation() + const beaconEndpoint = useRecoilValue(beaconNodeEndpoint) + const [isModal, toggleModal] = useRecoilState(isBlsExecutionModal) + const isTablet = useMediaQuery('(max-width: 1024px)') + const [blsJson, setJson] = useState(MOCK_BLS_JSON) + const setIsProcess = useSetRecoilState(isProcessBls) + const [, storeIsBlsProcessing] = useLocalStorage(Storage.BLS_PROCESSING, false) + + const closeModal = () => toggleModal(false) + const setJsonValue = (value: string) => setJson(value) + + const handleError = (code?: number) => { + let message = t('error.unknownError', { type: 'BEACON' }) + + if (code === 400) { + message = t('error.executionFailure') + } + + toast.error(message, { + position: 'top-right', + autoClose: 5000, + theme: 'colored', + hideProgressBar: true, + closeOnClick: true, + pauseOnHover: true, + }) + } + + const submitChange = async () => { + try { + const { status } = await broadcastBlsChange(beaconEndpoint, blsJson) + + if (status != 200) { + handleError(status) + return + } + + setIsProcess(true) + storeIsBlsProcessing(true) + } catch (e) { + if (axios.isAxiosError(e)) { + const axiosError = e as AxiosError + + handleError(axiosError.response?.status) + } + } + } + + return ( + +
+ +
+ + +
+
+ {' ---'} +
+ + {t('blsExecution.modal.description')} + + + + + + + +
+ {isModal && ( +
+ +
+ )} +
+
+ ) +} + +export default BlsExecutionModal diff --git a/src/components/CodeInput/CodeInput.tsx b/src/components/CodeInput/CodeInput.tsx new file mode 100644 index 00000000..ca2b1710 --- /dev/null +++ b/src/components/CodeInput/CodeInput.tsx @@ -0,0 +1,31 @@ +import CodeEditor from '@uiw/react-textarea-code-editor' +import { FC } from 'react' + +export interface CodeInputProps { + onChange: (value: string) => void + value: string + placeholder?: string +} + +const CodeInput: FC = ({ onChange, value, placeholder }) => { + return ( +
+ onChange(evn.target.value)} + padding={15} + style={{ + fontSize: 12, + fontFamily: + 'ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace', + }} + /> +
+ ) +} + +export default CodeInput diff --git a/src/components/Disclosures/ValidatorDisclosure.tsx b/src/components/Disclosures/ValidatorDisclosure.tsx index 6182ac66..dfebb80c 100644 --- a/src/components/Disclosures/ValidatorDisclosure.tsx +++ b/src/components/Disclosures/ValidatorDisclosure.tsx @@ -1,12 +1,14 @@ -import React, { useState } from 'react' -import ViewDisclosures from '../ViewDisclosures/ViewDisclosures' +import React, { FC, useState } from 'react' +import ViewDisclosures, { ViewDisclosuresProps } from '../ViewDisclosures/ViewDisclosures' import DisclosureModal from '../DisclosureModal/DisclosureModal' import validatorDisclosure from '../../assets/images/validatorDisclosure.png' import Typography from '../Typography/Typography' import { useTranslation } from 'react-i18next' import useUiMode from '../../hooks/useUiMode' -const ValidatorDisclosure = () => { +type ValidatorDisclosureProps = Omit + +const ValidatorDisclosure: FC = (props) => { const { t } = useTranslation() const { mode } = useUiMode() const [isOpen, toggleModal] = useState(false) @@ -16,7 +18,7 @@ const ValidatorDisclosure = () => { return ( <> - + = ({ className, title }) => { + const classes = addClassString('w-full h-36 relative', [className]) + + return ( +
+
+
+ {title && ( +
+ + {title} + +
+ )} +
+ ) +} + +export default GradientHeader diff --git a/src/components/SessionAuthModal/SessionAuthModal.tsx b/src/components/SessionAuthModal/SessionAuthModal.tsx index 389c49b9..4d09fa46 100644 --- a/src/components/SessionAuthModal/SessionAuthModal.tsx +++ b/src/components/SessionAuthModal/SessionAuthModal.tsx @@ -64,6 +64,7 @@ const SessionAuthModal: FC = ({ const handleError = () => { playErrorAnim() + setPassword('') setCount((prevState) => prevState + 1) } @@ -86,6 +87,7 @@ const SessionAuthModal: FC = ({ return } setCount(0) + setPassword('') onSuccess(token) } catch (e) { handleError() @@ -129,9 +131,14 @@ const SessionAuthModal: FC = ({ ) + const closeAuthModal = () => { + onClose?.() + setPassword('') + } + return ( <> - +
= ({
{children} = ({ isConversionRequired }) => { + const { t } = useTranslation() + const isProcessing = useRecoilValue(isProcessBls) + const warningClasses = addClassString('w-full flex items-center px-6 py-8 rounded', [ + isProcessing && 'bg-dark500', + !isProcessing && 'bg-lightError', + ]) + const warningIconBackgroundClasses = addClassString( + 'rounded-full mr-14 flex-shrink-0 flex items-center justify-center h-12 w-12', + [isProcessing && 'bg-dark400', !isProcessing && 'bg-lightError200'], + ) + const warningIconClasses = addClassString('text-2xl', [ + isProcessing && 'bi-hourglass-split text-dark600', + !isProcessing && 'bi-exclamation-triangle-fill text-error', + ]) + const toggleBlsModal = useSetRecoilState(isBlsExecutionModal) + const { closeModal } = useContext(ValidatorModalContext) + const viewBlsModal = () => { + closeModal() + setTimeout(() => { + toggleBlsModal(true) + }, 200) + } + + return ( + + ) +} + +export default ValidatorActions diff --git a/src/components/ValidatorModal/ValidatorModal.tsx b/src/components/ValidatorModal/ValidatorModal.tsx index d4c740ec..54a16d98 100644 --- a/src/components/ValidatorModal/ValidatorModal.tsx +++ b/src/components/ValidatorModal/ValidatorModal.tsx @@ -1,19 +1,44 @@ -import { useState } from 'react' +import { createContext, Dispatch, SetStateAction, useEffect, useState } from 'react' import ValidatorDetails from './views/ValidatorDetails' import { useRecoilValue, useSetRecoilState } from 'recoil' import Spinner from '../Spinner/Spinner' import { selectValidatorDetail } from '../../recoil/selectors/selectValidatorDetails' -import { validatorIndex } from '../../recoil/atoms' +import { isProcessBls, validatorIndex } from '../../recoil/atoms' import useMediaQuery from '../../hooks/useMediaQuery' import RodalModal from '../RodalModal/RodalModal' +import { Storage, ValidatorModalView } from '../../constants/enums' +import useLocalStorage from '../../hooks/useLocalStorage' + +export interface ValidatorModalContextProps { + setView: Dispatch> + closeModal: () => void +} + +export const ValidatorModalContext = createContext({ + setView: () => {}, + closeModal: () => {}, +}) const ValidatorModal = () => { const setValidatorIndex = useSetRecoilState(validatorIndex) const validator = useRecoilValue(selectValidatorDetail) - const [view] = useState('') + const [view, setView] = useState(ValidatorModalView.DETAILS) const isTablet = useMediaQuery('(max-width: 1024px)') + const setIsProcess = useSetRecoilState(isProcessBls) + const [isProcessing] = useLocalStorage(Storage.BLS_PROCESSING, false) - const closeModal = () => setValidatorIndex(undefined) + useEffect(() => { + if (isProcessing) { + setIsProcess(true) + } + }, [isProcessing]) + + const closeModal = () => { + setValidatorIndex(undefined) + setTimeout(() => { + setView(ValidatorModalView.DETAILS) + }, 1000) + } const renderContent = () => { switch (view) { @@ -32,7 +57,9 @@ const ValidatorModal = () => { onClose={closeModal} > {validator ? ( - renderContent() + + {renderContent()} + ) : (
diff --git a/src/components/ValidatorModal/views/ValidatorDetails.tsx b/src/components/ValidatorModal/views/ValidatorDetails.tsx index 43f24ce3..1a96cebd 100644 --- a/src/components/ValidatorModal/views/ValidatorDetails.tsx +++ b/src/components/ValidatorModal/views/ValidatorDetails.tsx @@ -1,7 +1,7 @@ -import { useRecoilValue, useSetRecoilState } from 'recoil' -import { validatorIndex, validatorMetrics } from '../../../recoil/atoms' +import { useRecoilValue } from 'recoil' +import { validatorMetrics } from '../../../recoil/atoms' import { selectValidatorDetail } from '../../../recoil/selectors/selectValidatorDetails' -import { useEffect, useMemo } from 'react' +import { useMemo } from 'react' import Typography from '../../Typography/Typography' import { selectEthExchangeRates } from '../../../recoil/selectors/selectEthExchangeRates' import { formatLocalCurrency } from '../../../utilities/formatLocalCurrency' @@ -11,25 +11,26 @@ import ValidatorIncomeSummary from '../../ValidatorIncomeSummary/ValidatorIncome import StatusIcon from '../../StatusIcon/StatusIcon' import ValidatorStatusProgress from '../../ValidatorStatusProgress/ValidatorStatusProgress' import ValidatorGraffitiInput from '../../ValidatorGraffitiInput/ValidatorGraffitiInput' -import ValidatorCardAction from '../ValidatorCardAction' import ValidatorDetailTable from '../../ValidatorDetailTable/ValidatorDetailTable' import ValidatorInfoCard from '../../ValidatorInfoCard/ValidatorInfoCard' -import DisabledTooltip from '../../DisabledTooltip/DisabledTooltip' import useValidatorGraffiti from '../../../hooks/useValidatorGraffiti' import ValidatorDisclosure from '../../Disclosures/ValidatorDisclosure' import BeaconChaLink from '../../BeaconChaLink/BeaconChaLink' import getAvgEffectivenessStatus from '../../../utilities/getAvgEffectivenessStatus' import EffectivenessBreakdown from '../../EffectivenessBreakdown/EffectivenessBreakdown' import toFixedIfNecessary from '../../../utilities/toFixedIfNecessary' +import isBlsAddress from '../../../utilities/isBlsAddress' +import ValidatorActions from '../ValidatorActions' const ValidatorDetails = () => { const { t } = useTranslation() - const setValidatorIndex = useSetRecoilState(validatorIndex) const validator = useRecoilValue(selectValidatorDetail) const metrics = useRecoilValue(validatorMetrics) - const { index, balance, status } = validator || {} + const { index, balance, status, withdrawalAddress } = validator || {} const { rates } = useRecoilValue(selectEthExchangeRates) + const isBls = Boolean(withdrawalAddress && isBlsAddress(withdrawalAddress)) + const avgTargetEffectiveness = useMemo(() => { if (!metrics || !index) return @@ -60,14 +61,8 @@ const ValidatorDetails = () => { const usdBalance = (balance || 0) * (rates['USD'] || 0) - useEffect(() => { - return () => { - setValidatorIndex(undefined) - } - }, []) - return validator ? ( -
+
@@ -152,47 +147,7 @@ const ValidatorDetails = () => {
-
- {t('validatorManagement.title')} -
- - - - - - - - - - - - - - - - - - -
-
+
diff --git a/src/components/ValidatorTable/ValidatorRow.tsx b/src/components/ValidatorTable/ValidatorRow.tsx index 7cbeeef3..11cb60b6 100644 --- a/src/components/ValidatorTable/ValidatorRow.tsx +++ b/src/components/ValidatorTable/ValidatorRow.tsx @@ -7,13 +7,15 @@ import formatEthAddress from '../../utilities/formatEthAddress' import { TableView } from './ValidatorTable' import ValidatorActionIcon from '../ValidatorActionIcon/ValidatorActionIcon' import { useRecoilValue, useSetRecoilState } from 'recoil' -import { dashView, validatorIndex } from '../../recoil/atoms' +import { dashView, isProcessBls, validatorIndex } from '../../recoil/atoms' import { ContentView } from '../../constants/enums' import StatusIcon from '../StatusIcon/StatusIcon' import formatBalanceColor from '../../utilities/formatBalanceColor' import IdenticonIcon from '../IdenticonIcon/IdenticonIcon' import DisabledTooltip from '../DisabledTooltip/DisabledTooltip' import { selectBeaconChaBaseUrl } from '../../recoil/selectors/selectBeaconChaBaseUrl' +import isBlsAddress from '../../utilities/isBlsAddress' +import Tooltip from '../ToolTip/Tooltip' export interface ValidatorRowProps { validator: ValidatorInfo @@ -23,22 +25,40 @@ export interface ValidatorRowProps { const ValidatorRow: FC = ({ validator, view }) => { const { t } = useTranslation() const setDashView = useSetRecoilState(dashView) + const isProcessing = useRecoilValue(isProcessBls) const setValidatorIndex = useSetRecoilState(validatorIndex) - const { name, pubKey, index, balance, rewards, status } = validator + const { name, pubKey, index, balance, rewards, status, withdrawalAddress } = validator const rewardColor = formatBalanceColor(rewards) const baseUrl = useRecoilValue(selectBeaconChaBaseUrl) + const isConversionRequired = isBlsAddress(withdrawalAddress) + const viewValidator = () => { setValidatorIndex(index) setDashView(ContentView.VALIDATORS) } + const renderAvatar = () => { + if (isConversionRequired) { + return ( + +
+ + {isConversionRequired && !isProcessing && ( + + )} +
+
+ ) + } + + return + } + return ( -
- -
+
{renderAvatar()}
diff --git a/src/components/ViewDisclosures/ViewDisclosures.tsx b/src/components/ViewDisclosures/ViewDisclosures.tsx index b4a6e0f5..d29ae99f 100644 --- a/src/components/ViewDisclosures/ViewDisclosures.tsx +++ b/src/components/ViewDisclosures/ViewDisclosures.tsx @@ -1,25 +1,74 @@ import Typography from '../Typography/Typography' import { useTranslation } from 'react-i18next' -import { FC } from 'react' +import { FC, useState } from 'react' +import Button, { ButtonFace } from '../Button/Button' +import SessionAuthModal from '../SessionAuthModal/SessionAuthModal' export interface ViewDisclosuresProps { onClick?: () => void + onAccept?: () => void + ctaText?: string + isSensitive?: boolean + ctaType?: ButtonFace } -const ViewDisclosures: FC = ({ onClick }) => { +const ViewDisclosures: FC = ({ + onClick, + onAccept, + ctaText, + ctaType, + isSensitive, +}) => { const { t } = useTranslation() + const [isSessionModal, toggleAuthModal] = useState(false) + + const closeAuthModal = () => toggleAuthModal(false) + const openAuthModal = () => toggleAuthModal(true) + + const onSuccessAuth = () => { + closeAuthModal() + onAccept?.() + } + + const renderCta = () => { + if (!onAccept || !ctaText) return null + + if (isSensitive) { + return ( + + + + ) + } + + return ( + + ) + } + return ( -
- - - {t('viewDisclosures')} - +
+
+ + + {t('viewDisclosures')} + +
+ {renderCta()}
) } diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 8016a222..ec6a8787 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -197,6 +197,7 @@ export const LighthouseBookUrl = 'https://lighthouse-book.sigmaprime.io/' export const SigPGithubUrl = 'https://github.com/sigp' export const SigPTwitter = 'https://twitter.com/sigp_io' export const SigPIoUrl = 'https://sigmaprime.io/' +export const WithdrawalInfoLink = 'https://launchpad.ethereum.org/en/withdrawals' export const DEFAULT_VALIDATOR_COUNT = { active_exiting: 0, @@ -232,3 +233,19 @@ export const REQUIRED_VALIDATOR_VERSION = { export const DEFAULT_MAX_NETWORK_ERROR = 3 export const MAX_SESSION_UNLOCK_ATTEMPTS = 3 + +export const MOCK_BLS_JSON = `[ + { + "message": { + "validator_index": "0", + "from_bls_pubkey": "your-pub-key", + "to_execution_address": "your-execution-address" + }, + "signature": "your-signature", + "metadata": { + "network_name": "network", + "genesis_validators_root": "genesis-validators-root", + "deposit_cli_version": "x.x.x" + } + } +]` diff --git a/src/constants/enums.ts b/src/constants/enums.ts index 31ebdd37..4c011b89 100644 --- a/src/constants/enums.ts +++ b/src/constants/enums.ts @@ -53,6 +53,7 @@ export enum SetupSteps { export enum Storage { UI = 'UI', CURRENCY = 'CURRENCY', + BLS_PROCESSING = 'BLS_PROCESSING', } export enum ApiType { @@ -64,3 +65,7 @@ export enum Network { Goerli = 'Goerli', Mainnet = 'Mainnet', } + +export enum ValidatorModalView { + DETAILS = 'DETAILS', +} diff --git a/src/locales/translations/en-US.json b/src/locales/translations/en-US.json index 90d39a4f..5d39b9e7 100644 --- a/src/locales/translations/en-US.json +++ b/src/locales/translations/en-US.json @@ -244,6 +244,7 @@ "numberRequired": "Password must contain at least one number", "specialCharRequired": "Password must contain at least one special character" }, + "executionFailure": "Execution broadcast failed. Please ensure all fields and signature are valid.", "networkError": "{{type}} NODE NETWORK ERROR: Make sure your IP is correct and/or CORS is correctly configured. Use --http-allow-origin in {{type}} config", "unknownError": "Unknown {{type}} NODE error.", "validatorInfo": "Error Loading Validator Info...", @@ -350,5 +351,21 @@ "passwordPrompt": "To ensure the safety of your account, password authentication is required to complete this action. Please confirm your password to proceed. Please be aware that you have a maximum of three attempts.", "failedResponse": "Authentication failed. Please return to the configuration settings to re-enter your validator credentials.", "configSettings": "Configuration Settings" + }, + "blsExecution": { + "tooltip": "Validator requires BLS to Execution address conversion", + "warning": { + "text": "This validator is using old BLS withdrawal credentials. It will not receive regular partial withdrawals and cannot be exited. Please convert the withdrawal address to an execution address.", + "learnMore": "Learn more about BLS to Execution here.", + "cta": "Convert withdrawal address.", + "processingText": "The BLS execution change has been processed but may take some time to be executed by the beacon node. Kindly wait until the validator status reflects the changes. Thank you for your understanding." + }, + "modal": { + "title": "BLS to Execution Change", + "subTitle": "Validator <0> Update", + "cta": "Execution Change", + "description": "Please enter your BLS Change JSON. Submitting this request will allow the beacon node to voluntarily deposit partial rewards and execute validator exits to a designated withdrawal address. This action is sensitive, please exercise caution and ensure that you have access to your withdrawal address before proceeding.", + "followLink": "For additional information, please follow the <0>link." + } } } \ No newline at end of file diff --git a/src/mocks/validatorResults.ts b/src/mocks/validatorResults.ts index 1740f75b..1777a72a 100644 --- a/src/mocks/validatorResults.ts +++ b/src/mocks/validatorResults.ts @@ -227,6 +227,7 @@ export const mockValidatorInfo = { rewards: 1000000, slashed: false, status: 'active_ongoing' as ValidatorStatus, + withdrawalAddress: 'mock-address', processed: 1, missed: 0, attested: 0, diff --git a/src/recoil/atoms.ts b/src/recoil/atoms.ts index a473d1fc..176d1409 100644 --- a/src/recoil/atoms.ts +++ b/src/recoil/atoms.ts @@ -164,3 +164,13 @@ export const sessionAuthErrorCount = atom({ key: 'sessionAuthErrorCount', default: 0, }) + +export const isBlsExecutionModal = atom({ + key: 'isBlsExecutionModal', + default: false, +}) + +export const isProcessBls = atom({ + key: 'isProcessBls', + default: false, +}) diff --git a/src/recoil/selectors/selectValidatorInfos.ts b/src/recoil/selectors/selectValidatorInfos.ts index 0f34a61c..c234f661 100644 --- a/src/recoil/selectors/selectValidatorInfos.ts +++ b/src/recoil/selectors/selectValidatorInfos.ts @@ -27,6 +27,7 @@ export const selectValidatorInfos = selector({ rewards: Number(formatUnits(balance, 'gwei')) - initialEthDeposit, index: Number(index), slashed: validator.slashed, + withdrawalAddress: validator.withdrawal_credentials, status: status, processed: 0, missed: 0, diff --git a/src/types/validator.ts b/src/types/validator.ts index a3348ed3..6949f8b0 100644 --- a/src/types/validator.ts +++ b/src/types/validator.ts @@ -25,6 +25,7 @@ export type ValidatorInfo = { pubKey: string rewards: number slashed: boolean + withdrawalAddress: string status: ValidatorStatus processed: number missed: number diff --git a/src/utilities/isBlsAddress.ts b/src/utilities/isBlsAddress.ts new file mode 100644 index 00000000..d7a4e9b1 --- /dev/null +++ b/src/utilities/isBlsAddress.ts @@ -0,0 +1,3 @@ +const isBlsAddress = (address: string) => address.indexOf('0x00') === 0 + +export default isBlsAddress diff --git a/src/views/DashBoard/Content/Validators.tsx b/src/views/DashBoard/Content/Validators.tsx index 8fc54b2a..ab00792a 100644 --- a/src/views/DashBoard/Content/Validators.tsx +++ b/src/views/DashBoard/Content/Validators.tsx @@ -14,6 +14,7 @@ import ValidatorModal from '../../../components/ValidatorModal/ValidatorModal' import useValidatorCachePolling from '../../../hooks/useValidatorCachePolling' import DisabledTooltip from '../../../components/DisabledTooltip/DisabledTooltip' import useValidatorMetrics from '../../../hooks/useValidatorMetrics' +import BlsExecutionModal from '../../../components/BlsExecutionModal/BlsExecutionModal' const Sync = () => { useValidatorInfoPolling() @@ -33,6 +34,7 @@ const Validators = () => { return ( <> {isReady && } +
diff --git a/tailwind.config.js b/tailwind.config.js index ae368a8f..5ac951fd 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -36,6 +36,8 @@ module.exports = { success: '#2ED47A', warning: '#FFB800', error: '#FF4D00', + lightError: '#FFDDE8', + lightError200: '#FFB7B3', }, backgroundImage: { lighthouse: 'url(\'./assets/images/lightHouseBg.png\')', diff --git a/yarn.lock b/yarn.lock index d525dcf9..eacde62d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1141,7 +1141,7 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.0", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.0", "@babel/runtime@^7.9.2": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== @@ -4586,6 +4586,11 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== +"@types/parse5@^6.0.0": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb" + integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g== + "@types/prettier@^2.1.5": version "2.7.2" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" @@ -4596,6 +4601,11 @@ resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601" integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ== +"@types/prismjs@^1.0.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.0.tgz#a1c3809b0ad61c62cac6d4e0c56d610c910b7654" + integrity sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ== + "@types/prop-types@*": version "15.7.5" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" @@ -4896,6 +4906,15 @@ "@typescript-eslint/types" "5.53.0" eslint-visitor-keys "^3.3.0" +"@uiw/react-textarea-code-editor@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@uiw/react-textarea-code-editor/-/react-textarea-code-editor-2.1.1.tgz#59a7e0c8b04d7aa36f4997a81dbbbb9004d324e3" + integrity sha512-vFUb58Dj8SCAcAL264ik6rFMzHmOAI4TG8BInu9avCdJ1ugRhrwD+RA7FKQN2xAoBokF9JJacyTqx+EUXIOg2g== + dependencies: + "@babel/runtime" "^7.18.6" + rehype "~12.0.1" + rehype-prism-plus "1.5.0" + "@webassemblyjs/ast@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" @@ -6153,6 +6172,11 @@ bail@^1.0.0: resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== +bail@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" + integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -6773,6 +6797,11 @@ ccount@^1.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -6813,21 +6842,41 @@ char-regex@^2.0.0: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.1.tgz#6dafdb25f9d3349914079f010ba8d0e6ff9cd01e" integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + character-entities-legacy@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + character-entities@^1.0.0: version "1.2.4" resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== +character-entities@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" + integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== + character-reference-invalid@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== +character-reference-invalid@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" + integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== + chart.js@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.2.1.tgz#d2bd5c98e9a0ae35408975b638f40513b067ba1d" @@ -7167,6 +7216,11 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + commander@2, commander@^2.15.1, commander@^2.19.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -8090,6 +8144,13 @@ decimal.js@^10.2.1, decimal.js@^10.4.2: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== +decode-named-character-reference@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" + integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== + dependencies: + character-entities "^2.0.0" + decode-uri-component@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" @@ -10762,11 +10823,31 @@ hast-util-from-parse5@^6.0.0: vfile-location "^3.2.0" web-namespaces "^1.0.0" +hast-util-from-parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz#aecfef73e3ceafdfa4550716443e4eb7b02e22b0" + integrity sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw== + dependencies: + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.0" + hastscript "^7.0.0" + property-information "^6.0.0" + vfile "^5.0.0" + vfile-location "^4.0.0" + web-namespaces "^2.0.0" + hast-util-parse-selector@^2.0.0: version "2.2.5" resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== +hast-util-parse-selector@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz#25ab00ae9e75cbc62cf7a901f68a247eade659e2" + integrity sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA== + dependencies: + "@types/hast" "^2.0.0" + hast-util-raw@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" @@ -10783,6 +10864,40 @@ hast-util-raw@6.0.1: xtend "^4.0.0" zwitch "^1.0.0" +hast-util-raw@^7.0.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-7.2.3.tgz#dcb5b22a22073436dbdc4aa09660a644f4991d99" + integrity sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg== + dependencies: + "@types/hast" "^2.0.0" + "@types/parse5" "^6.0.0" + hast-util-from-parse5 "^7.0.0" + hast-util-to-parse5 "^7.0.0" + html-void-elements "^2.0.0" + parse5 "^6.0.0" + unist-util-position "^4.0.0" + unist-util-visit "^4.0.0" + vfile "^5.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + +hast-util-to-html@^8.0.0: + version "8.0.4" + resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz#0269ef33fa3f6599b260a8dc94f733b8e39e41fc" + integrity sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA== + dependencies: + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.0" + ccount "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-raw "^7.0.0" + hast-util-whitespace "^2.0.0" + html-void-elements "^2.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + stringify-entities "^4.0.0" + zwitch "^2.0.4" + hast-util-to-parse5@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" @@ -10794,6 +10909,30 @@ hast-util-to-parse5@^6.0.0: xtend "^4.0.0" zwitch "^1.0.0" +hast-util-to-parse5@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz#c49391bf8f151973e0c9adcd116b561e8daf29f3" + integrity sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^2.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + +hast-util-to-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz#b008b0a4ea472bf34dd390b7eea1018726ae152a" + integrity sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A== + dependencies: + "@types/hast" "^2.0.0" + +hast-util-whitespace@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz#0ec64e257e6fc216c7d14c8a1b74d27d650b4557" + integrity sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng== + hastscript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" @@ -10805,6 +10944,17 @@ hastscript@^6.0.0: property-information "^5.0.0" space-separated-tokens "^1.0.0" +hastscript@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-7.2.0.tgz#0eafb7afb153d047077fa2a833dc9b7ec604d10b" + integrity sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^3.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -10913,6 +11063,11 @@ html-void-elements@^1.0.0: resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== +html-void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f" + integrity sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A== + html-webpack-plugin@^4.0.0: version "4.5.2" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12" @@ -11292,6 +11447,11 @@ is-alphabetical@1.0.4, is-alphabetical@^1.0.0: resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== +is-alphabetical@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" + integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== + is-alphanumerical@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" @@ -11300,6 +11460,14 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" +is-alphanumerical@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" + integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== + dependencies: + is-alphabetical "^2.0.0" + is-decimal "^2.0.0" + is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" @@ -11406,6 +11574,11 @@ is-decimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== +is-decimal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" + integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -11503,6 +11676,11 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== +is-hexadecimal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" + integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -11593,6 +11771,11 @@ is-plain-obj@^3.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== +is-plain-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + is-plain-object@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" @@ -15168,6 +15351,20 @@ parse-entities@^2.0.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" +parse-entities@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.1.tgz#4e2a01111fb1c986549b944af39eeda258fc9e4e" + integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== + dependencies: + "@types/unist" "^2.0.0" + character-entities "^2.0.0" + character-entities-legacy "^3.0.0" + character-reference-invalid "^2.0.0" + decode-named-character-reference "^1.0.0" + is-alphanumerical "^2.0.0" + is-decimal "^2.0.0" + is-hexadecimal "^2.0.0" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -15193,6 +15390,11 @@ parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-numeric-range@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz#7c63b61190d61e4d53a1197f0c83c47bb670ffa3" + integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ== + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -16273,6 +16475,11 @@ property-information@^5.0.0, property-information@^5.3.0: dependencies: xtend "^4.0.0" +property-information@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.2.0.tgz#b74f522c31c097b5149e3c3cb8d7f3defd986a1d" + integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg== + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -16838,6 +17045,16 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +refractor@^4.7.0: + version "4.8.1" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-4.8.1.tgz#fbdd889333a3d86c9c864479622855c9b38e9d42" + integrity sha512-/fk5sI0iTgFYlmVGYVew90AoYnNMP6pooClx/XKqyeeCQXrL0Kvgn8V0VEht5ccdljbzzF1i3Q213gcntkRExg== + dependencies: + "@types/hast" "^2.0.0" + "@types/prismjs" "^1.0.0" + hastscript "^7.0.0" + parse-entities "^4.0.0" + regenerate-unicode-properties@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" @@ -16908,6 +17125,47 @@ regjsparser@^0.9.1: dependencies: jsesc "~0.5.0" +rehype-parse@^8.0.0, rehype-parse@^8.0.2: + version "8.0.4" + resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-8.0.4.tgz#3d17c9ff16ddfef6bbcc8e6a25a99467b482d688" + integrity sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg== + dependencies: + "@types/hast" "^2.0.0" + hast-util-from-parse5 "^7.0.0" + parse5 "^6.0.0" + unified "^10.0.0" + +rehype-prism-plus@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/rehype-prism-plus/-/rehype-prism-plus-1.5.0.tgz#113aae19687c0f8faf6f5fb16964ff1527d130d7" + integrity sha512-KNJYMQHqN+53ZbT5Pa/lO7uorMpBIR3x9RjFeG1lPlQherZDZiPqyOFS464L4BniZ4VG5PnG5DXVqjGtwxWJew== + dependencies: + hast-util-to-string "^2.0.0" + parse-numeric-range "^1.3.0" + refractor "^4.7.0" + rehype-parse "^8.0.2" + unist-util-filter "^4.0.0" + unist-util-visit "^4.0.0" + +rehype-stringify@^9.0.0: + version "9.0.3" + resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-9.0.3.tgz#70e3bd6d4d29e7acf36b802deed350305d2c3c17" + integrity sha512-kWiZ1bgyWlgOxpqD5HnxShKAdXtb2IUljn3hQAhySeak6IOQPPt6DeGnsIh4ixm7yKJWzm8TXFuC/lPfcWHJqw== + dependencies: + "@types/hast" "^2.0.0" + hast-util-to-html "^8.0.0" + unified "^10.0.0" + +rehype@~12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/rehype/-/rehype-12.0.1.tgz#68a317662576dcaa2565a3952e149d6900096bf6" + integrity sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw== + dependencies: + "@types/hast" "^2.0.0" + rehype-parse "^8.0.0" + rehype-stringify "^9.0.0" + unified "^10.0.0" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" @@ -17861,6 +18119,11 @@ space-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== + spawn-command@^0.0.2-1: version "0.0.2-1" resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" @@ -18221,6 +18484,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-entities@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.3.tgz#cfabd7039d22ad30f3cc435b0ca2c1574fc88ef8" + integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + stringify-object@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" @@ -18869,6 +19140,11 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== +trough@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" + integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== + tryer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" @@ -19086,6 +19362,19 @@ unified@9.2.0: trough "^1.0.0" vfile "^4.0.0" +unified@^10.0.0: + version "10.1.2" + resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df" + integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== + dependencies: + "@types/unist" "^2.0.0" + bail "^2.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^4.0.0" + trough "^2.0.0" + vfile "^5.0.0" + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -19136,6 +19425,15 @@ unist-builder@2.0.3, unist-builder@^2.0.0: resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== +unist-util-filter@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/unist-util-filter/-/unist-util-filter-4.0.1.tgz#fd885dd48adaad345de5f5dc706ec4ff44a8d074" + integrity sha512-RynicUM/vbOSTSiUK+BnaK9XMfmQUh6gyi7L6taNgc7FIf84GukXVV3ucGzEN/PhUUkdP5hb1MmXc+3cvPUm5Q== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + unist-util-visit-parents "^5.0.0" + unist-util-generated@^1.0.0: version "1.1.6" resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" @@ -19146,11 +19444,25 @@ unist-util-is@^4.0.0: resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== +unist-util-is@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.2.1.tgz#b74960e145c18dcb6226bc57933597f5486deae9" + integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw== + dependencies: + "@types/unist" "^2.0.0" + unist-util-position@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== +unist-util-position@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.4.tgz#93f6d8c7d6b373d9b825844645877c127455f037" + integrity sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-remove-position@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" @@ -19172,6 +19484,13 @@ unist-util-stringify-position@^2.0.0: dependencies: "@types/unist" "^2.0.2" +unist-util-stringify-position@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz#03ad3348210c2d930772d64b489580c13a7db39d" + integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-visit-parents@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" @@ -19180,6 +19499,14 @@ unist-util-visit-parents@^3.0.0: "@types/unist" "^2.0.0" unist-util-is "^4.0.0" +unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1: + version "5.1.3" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz#b4520811b0ca34285633785045df7a8d6776cfeb" + integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + unist-util-visit@2.0.3, unist-util-visit@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" @@ -19189,6 +19516,15 @@ unist-util-visit@2.0.3, unist-util-visit@^2.0.0: unist-util-is "^4.0.0" unist-util-visit-parents "^3.0.0" +unist-util-visit@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.2.tgz#125a42d1eb876283715a3cb5cceaa531828c72e2" + integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + unist-util-visit-parents "^5.1.1" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -19407,6 +19743,14 @@ vfile-location@^3.0.0, vfile-location@^3.2.0: resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== +vfile-location@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-4.1.0.tgz#69df82fb9ef0a38d0d02b90dd84620e120050dd0" + integrity sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw== + dependencies: + "@types/unist" "^2.0.0" + vfile "^5.0.0" + vfile-message@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" @@ -19415,6 +19759,14 @@ vfile-message@^2.0.0: "@types/unist" "^2.0.0" unist-util-stringify-position "^2.0.0" +vfile-message@^3.0.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.4.tgz#15a50816ae7d7c2d1fa87090a7f9f96612b59dea" + integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^3.0.0" + vfile@^4.0.0: version "4.2.1" resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" @@ -19425,6 +19777,16 @@ vfile@^4.0.0: unist-util-stringify-position "^2.0.0" vfile-message "^2.0.0" +vfile@^5.0.0: + version "5.3.7" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.7.tgz#de0677e6683e3380fafc46544cfe603118826ab7" + integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^3.0.0" + vfile-message "^3.0.0" + vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" @@ -19539,6 +19901,11 @@ web-namespaces@^1.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== +web-namespaces@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" + integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== + web-vitals@^2.1.0: version "2.1.4" resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.4.tgz#76563175a475a5e835264d373704f9dde718290c" @@ -20356,3 +20723,8 @@ zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== + +zwitch@^2.0.0, zwitch@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==