diff --git a/.eslintignore b/.eslintignore index 4cc1ec2..b518474 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,11 @@ **/node_modules/* **/out/* -**/.next/* \ No newline at end of file +**/.next/* + +node_modules +.next +build + +next.config.js +postcss.config.js +tailwind.config.js \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 53d57ec..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,35 +0,0 @@ -module.exports = { - env: { - browser: true, - es2021: true, - }, - extends: [ - 'plugin:react/recommended', - 'standard-with-typescript', - 'plugin:@next/next/recommended', - ], - overrides: [], - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: 'tsconfig.json', - }, - plugins: ['react'], - rules: { - // React scope no longer necessary with new JSX transform\ - 'multiline-ternary': ['error', 'never'], - 'react/react-in-jsx-scope': 'off', - '@typescript-eslint/no-misused-promises': [ - 'error', - { - checksVoidReturn: false, - }, - ], - // Allow .js files to use JSX syntax - 'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }], - '@typescript-eslint/no-floating-promises': 'off', - '@typescript-eslint/prefer-nullish-coalescing': 'off', - '@typescript-eslint/strict-boolean-expressions': 'off', - 'react/no-unescaped-entities': 'off', - }, -} diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..4043f24 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,47 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint", + "import", + "react", + "react-hooks", + "destructuring" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react/recommended", + "plugin:@next/next/recommended", + "plugin:prettier/recommended" + ], + "overrides": [], + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "project": true, + "tsconfigRootDir": "__dirname" + }, + "rules": { + // React scope no longer necessary with new JSX transform\ + "react/react-in-jsx-scope": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/no-misused-promises": [ + "error", + { + "checksVoidReturn": false + } + ], + // Allow .js files to use JSX syntax + "react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }], + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/prefer-nullish-coalescing": "off", + "@typescript-eslint/strict-boolean-expressions": "off", + "react/no-unescaped-entities": "off" + }, + "root": true +} diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..25d2235 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname "$0")/_/husky.sh" + +npx lint-staged \ No newline at end of file diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 0000000..28a0c5c --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,4 @@ +{ + "*.{ts,tsx}": ["eslint --fix --quiet"], + "*.{ts,tsx,json}": ["prettier --write"] +} diff --git a/.prettierignore b/.prettierignore index 14fabc9..b2fd786 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,5 @@ node_modules .next yarn.lock package-lock.json -public \ No newline at end of file +public +build \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 75a894a..0000000 --- a/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "semi": false, - "singleQuote": true, - "printWidth": 100 -} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..9908b8b --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "semi": true, + "tabWidth": 2, + "singleQuote": true, + "jsxBracketSameLine": true +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3c0091e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Next.js: debug server-side", + "type": "node-terminal", + "request": "launch", + "command": "npm run dev" + }, + { + "name": "Next.js: chrome debug client-side", + "type": "chrome", + "request": "launch", + "url": "http://localhost:3000" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..59f51db --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact" + ] +} diff --git a/components/Chart.tsx b/components/Chart.tsx deleted file mode 100644 index d663279..0000000 --- a/components/Chart.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { curveCardinal } from '@visx/curve' -import { - AnimatedGrid, - XYChart, - Tooltip, - Axis, - AnimatedAreaSeries, - AnimatedAreaStack, - buildChartTheme -} from '@visx/xychart' -import dayjs from 'dayjs' -import { DailyIntervalType } from '../types' -import isMobile from 'is-mobile' - -const monthsShort = [ - 'Jan', - 'Feb', - 'Mar', - 'Apr', - 'May', - 'Jun', - 'Jul', - 'Aug', - 'Sep', - 'Oct', - 'Nov', - 'Dec' -] -interface ChartProps { - data: DailyIntervalType[] -} - -const customTheme = buildChartTheme({ - backgroundColor: '#fff', - colors: ['rgba(0, 169, 187, 0.5)'], - gridColor: '#00A9BB', - tickLength: 8, - gridColorDark: '' -}) - -const Chart = ({ data }: ChartProps): JSX.Element => { - const IsMobile = isMobile() - return ( -
- - `${monthsShort[dayjs(d).month()]} ${dayjs(d).year()}`} - /> - - - - - - d.date} - yAccessor={(d) => d.count} - fillOpacity={0.3} - /> - - - ( -
-
Swaps
- -
- {dayjs(tooltipData.nearestDatum.datum.date.split('T')[0]).format( - 'dddd, YYYY MMMM DD' - )} -
-
Count: {tooltipData.nearestDatum.datum.count}
-
- )} - /> -
-
-
- ) -} - -export default Chart diff --git a/components/ChartBox.tsx b/components/ChartBox.tsx deleted file mode 100644 index 8010b70..0000000 --- a/components/ChartBox.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from 'react' -import { AmountConverter } from '../utils/amountConverter' -import { SummaryType } from '../types' -import Chart from './Chart' - -interface PropsType { - summary: SummaryType -} - -const ChartBox: React.FC = ({ summary }) => { - return ( -
-
-

Swaps

- - -
-
-
-

- {AmountConverter(summary.connectedWallets)} -

-

Total Wallets Connected

-
-
-

- {AmountConverter(summary.totalTxVolumeUSD)} -

-

Total Swap Volume

-
-
-

- {AmountConverter(summary.totalTxCount)} -

-

Total Swap

-
-
-

- {AmountConverter(summary.supportedDexes)} -

-

Supported Dexes

-
-
-

- {AmountConverter(summary.supportedChains)} -

-

Supported Chain

-
-
-

- {AmountConverter(summary.supportedBridges)} -

-

Supported Bridges

-
-
-
- ) -} - -export default ChartBox diff --git a/components/Layout.tsx b/components/Layout.tsx deleted file mode 100644 index a12c14a..0000000 --- a/components/Layout.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import Head from 'next/head' -import Navbar from './Navbar' - -interface PropsType { - children: React.ReactNode - pageTitle: string -} - -const Layout: React.FC = ({ children, pageTitle }: PropsType) => ( -
- - {`${pageTitle} | Rango Scanner`} - - -
{children}
-
-) - -export default Layout diff --git a/components/MakeColumns.tsx b/components/MakeColumns.tsx deleted file mode 100644 index bb00513..0000000 --- a/components/MakeColumns.tsx +++ /dev/null @@ -1,146 +0,0 @@ -/* eslint-disable @next/next/no-img-element */ -import { columns, makeColumnsTypes } from './Table' -import Tooltip from './Tooltip' -import Image from 'next/image' -import doubleArrow from '../public/img/doubleArrow.svg' -import dayjs from 'dayjs' -import relativeTime from 'dayjs/plugin/relativeTime' -import { CapitalizeFirstLetter } from '../utils/capitalizeFirstLetter' -import { StepSummary } from '../types' -import copy from '../public/img/copy.svg' -import React from 'react' -import { CopyText } from 'utils/copyText' - -dayjs.extend(relativeTime) -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type - -interface StepProps { - image: string - symbol: string - name: string - blockchainLogo: string - blockchain: string - amount: number -} -const StepComponent = ({ - image, - name, - blockchainLogo, - blockchain, - symbol, - amount -}: StepProps): JSX.Element => ( -
-
- {name - {blockchain} -
- -

- {parseFloat(Number(amount).toFixed(2))} {symbol} -

-
-) -const renderRoute = ({ - steps, - sourceAmount -}: { - steps: StepSummary[] - sourceAmount: number -}): JSX.Element => ( -
- {steps.map((step, index) => ( - - {index === 0 && ( - <> - - route - - )} - - {steps.length - 1 !== index && route} - - ))} -
-) - -export const makeColumns: ({ onClick }: makeColumnsTypes) => columns[] = ({ onClick }) => [ - { - title: 'Request ID', - key: 'requestId', - classNameColBody: 'lg:!font-bold text-primary', - render: (text) => ( -
- - -
- ) - }, - { - title: 'Route', - key: 'stepsSummary', - render: (_, item: any) => - renderRoute({ steps: item.stepsSummary, sourceAmount: item.sourceAmount }), - hiddenTitle: true, - classNameColBody: 'lg:!flex-auto lg:w-60', - classNameColHead: 'lg:!flex-auto lg:w-60' - }, - - { - title: 'Time', - key: 'transactionTime', - render: (text) => dayjs(text).fromNow() - }, - { - title: 'Status', - key: 'status', - render: (text) =>

{CapitalizeFirstLetter(text)}

- }, - { - title: '', - key: 'destination', - hiddenTitle: true, - - render: (_, item: any) => ( - - ) - } -] diff --git a/components/Navbar/Menu.tsx b/components/Navbar/Menu.tsx deleted file mode 100644 index 55dcaa1..0000000 --- a/components/Navbar/Menu.tsx +++ /dev/null @@ -1,141 +0,0 @@ -/* eslint-disable @typescript-eslint/explicit-function-return-type */ -import { LegacyRef, useEffect, useRef, useState } from 'react' -import burger_menu from '../../public/img/burger-menu.svg' -import arrow_down from '../../public/img/arrow_down.svg' -import dashboard from '../../public/img/dashboard.svg' -import resource from '../../public/img/resource.svg' -import arrow_up from '../../public/img/arrow_up.svg' -import logo from '../../public/img/logo.png' -import Image from 'next/image' -import Link from 'next/link' - -const links: Array<{ location: string, title: string, id: number }> = [ - { - location: 'https://app.rango.exchange/', - title: 'Rango App', - id: 1 - }, - { - location: 'https://docs.rango.exchange/integration-guide/overview', - title: 'Rango SDK Doc', - id: 2 - }, - { - location: 'https://rango.exchange/docs/rango-whitepaper.pdf', - title: 'White Paper', - id: 3 - } -] - -const Menu: React.FC = () => { - const [isOpen, setIsOpen] = useState(false) - const [isOpenSubmenu, setIsOpenSubmenu] = useState(false) - - const menuRef = useRef() - - useEffect(() => { - const checkIfClickedOutside = (e: any) => { - // If the menu is open and the clicked target is not within the menu, - // then close the menu - if (isOpen && menuRef.current && !menuRef.current.contains(e.target)) { - closeMenu() - } - } - - document.addEventListener('mousedown', checkIfClickedOutside) - - return () => { - // Cleanup the event listener - document.removeEventListener('mousedown', checkIfClickedOutside) - } - }, [isOpen]) - - const closeMenu = (): void => setIsOpen(false) - return ( - <> -
}> - -
- Rango logo - - dashboard Rango scanner - Dashboard - -
setIsOpenSubmenu(!isOpenSubmenu)} - > -
- resource Rango scanner -

- Resources -

-
- {isOpenSubmenu ? ( - arrow up - ) : ( - arrow down - )} -
- -
-
- {links.map((link) => ( -

- - {link.title} - -

- ))} -
-
-
- -
- - ) -} - -export default Menu diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx deleted file mode 100644 index 1c867b3..0000000 --- a/components/Navbar/index.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import { ChangeEvent, KeyboardEvent, useState } from 'react' -import search from '../../public/img/search.svg' -import clear from '../../public/img/clear.svg' -import logo from '../../public/img/logo.png' -import desktopLogo from '../../public/img/rango.svg' - -import { useRouter } from 'next/router' -import Image from 'next/image' -import Link from 'next/link' -import Menu from './Menu' - -interface PropsType { - hasSearch?: boolean -} - -const Navbar: React.FC = ({ hasSearch }: PropsType) => { - const router = useRouter() - const [showSearchInput, setShowSearchInput] = useState(false) - const [query, setQuery] = useState('') - - const handleKeyPress = (e: KeyboardEvent): void => { - if (e.code === 'Enter') { - const query = (e.target as HTMLTextAreaElement).value - setShowSearchInput(false) - router.push({ - pathname: '/search', - query: { query } - }) - } - } - const onChangeQuery = (e: ChangeEvent): void => { - setQuery(e.target.value) - } - - const handleOnClick = (): void => { - router.push({ - pathname: '/search', - query: { query } - }) - } - - return ( -
- - Rango logo - Rango logo - - - -
- {hasSearch && ( -
- - search - {query && ( - - )} -
- )} -
- -
-
-
- ) -} - -export default Navbar diff --git a/components/NotFoundAnything.tsx b/components/NotFoundAnything.tsx deleted file mode 100644 index 54e4da3..0000000 --- a/components/NotFoundAnything.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import notfound from '../public/img/notfound.svg' -import Image from 'next/image' - -const NotFoundAnything: React.FC = () => ( -
-

- Oops! We couldn't find what you are looking for. -

-

- Please enter an address, transaction hash, block height or hash. -

- Not Found -
-) -export default NotFoundAnything diff --git a/components/SearchBox.tsx b/components/SearchBox.tsx deleted file mode 100644 index 82185f4..0000000 --- a/components/SearchBox.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import Image from 'next/image' -import { useRouter } from 'next/router' -import search from '../public/img/search.svg' -import { FormEvent, MouseEvent, useState } from 'react' - -const SearchBox: React.FC = () => { - const [query, setQuery] = useState('') - const router = useRouter() - const onSubmit = (e: FormEvent | MouseEvent): void => { - e.preventDefault() - if (query) { - router.push({ - pathname: '/search', - query: { query } - }) - } - } - - return ( -
-

- Rango Swap Search -

- -
- setQuery(e.target.value)} - /> - -
-
- ) -} - -export default SearchBox diff --git a/components/Table.tsx b/components/Table.tsx deleted file mode 100644 index eae7f01..0000000 --- a/components/Table.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { useMemo } from 'react' - -export interface columns { - title: string - key: string - render?: (text: string, item: any, index: number) => JSX.Element | string - classNameColBody?: string - classNameColHead?: string - hiddenTitle?: boolean -} -export interface makeColumnsTypes { - onClick: (id: string) => void -} - -interface PropsType { - makeColumns: ({ onClick }: makeColumnsTypes) => columns[] - data: any[] - onClick: (id: string) => void -} -const Table: React.FC = ({ makeColumns, data, onClick }: PropsType) => { - const columns: columns[] = useMemo(() => makeColumns({ onClick }), [makeColumns, onClick]) - - return ( -
-
-
- {columns.map((col) => ( -
- {col.title} -
- ))} -
- {data.map((item, key) => ( -
- {columns.map((row) => ( -
- {!row.hiddenTitle && ( -
{row.title}
- )} - - {row.render ? row.render(item[row.key], item, key) : item[row.key]} -
- ))} -
- ))} -
-
- ) -} - -export default Table diff --git a/components/Tooltip.tsx b/components/Tooltip.tsx deleted file mode 100644 index 738fb10..0000000 --- a/components/Tooltip.tsx +++ /dev/null @@ -1,12 +0,0 @@ -interface PropsType { - label: string -} -const Tooltip: React.FC = ({ label }: { label: string }) => { - return ( - - {label} - - ) -} - -export default Tooltip diff --git a/components/TxDetails.tsx b/components/TxDetails.tsx deleted file mode 100644 index 4a309da..0000000 --- a/components/TxDetails.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* eslint-disable @next/next/no-img-element */ -import React from 'react' -import { DetailsType } from '../types' -import dayjs from 'dayjs' -import utc from 'dayjs/plugin/utc' -import { CapitalizeFirstLetter } from '../utils/capitalizeFirstLetter' -import { SecondsTohms } from 'utils/secondsTohms' -import Image from 'next/image' -import copy from '../public/img/copy.svg' -import { CopyText } from '../utils/copyText' - -dayjs.extend(utc) - -interface PropsType { - details: DetailsType -} -interface DetailPropType { - title: string - value: string - className?: string - image?: string - onClick?: React.MouseEventHandler - hasCopyButton?: boolean -} -const Detail = ({ - title, - value, - className, - image, - onClick, - hasCopyButton -}: DetailPropType): JSX.Element => ( -
-

{title}

-
- {image && {value}} - - {hasCopyButton && ( - - )} -
-
-) -const TxDetails: React.FC = ({ details }) => { - return ( -
-

Swap Details

- - window.open(details.sourceWalletAddress, '_blank')} - /> - - window.open(details.destinationWalletAddress, '_blank')} - /> - - - -
- ) -} - -export default TxDetails diff --git a/components/TxSteps/Step.tsx b/components/TxSteps/Step.tsx deleted file mode 100644 index e3a00af..0000000 --- a/components/TxSteps/Step.tsx +++ /dev/null @@ -1,281 +0,0 @@ -import React, { useState } from 'react' -import { StepType } from '../../types' -import Image from 'next/image' -import { STATUS } from '../../constant' -import { CapitalizeFirstLetter } from '../../utils/capitalizeFirstLetter' -import { SecondsTohms } from 'utils/secondsTohms' -import { CopyText } from '../../utils/copyText' -import copy from '../../public/img/copy.svg' - -interface PropsType { - step: StepType - index: number -} - -interface DetailPropType { - title: string - value: string - className?: string - chain?: string - image?: string - onClick?: React.MouseEventHandler - hasCopyButton?: boolean -} -const Detail = ({ - title, - value, - chain, - className, - onClick, - hasCopyButton -}: DetailPropType): JSX.Element => ( -
  • -
    - - {title}: - - - {hasCopyButton && ( - - )} -
    -
  • -) - -const Step: React.FC = ({ step, index }) => { - const [isOpen, setIsOpen] = useState(false) - - return ( -
    -
    setIsOpen(false)} - className={`lg:hidden mt-3 ${ - isOpen ? `border rounded-md mt-0 px-2.5 py-1.5 bg-neutral-100 absolute z-10 -top-4 left-5 right-5 border-${step.status}` : '' - } cursor-pointer`} - > -
    -

    Step {index + 1}:

    - -

    - Status:{' '} - - {CapitalizeFirstLetter(STATUS[step.status])} - -

    -
    -
    - -
    !isOpen && setIsOpen(true)} - className={`relative border border-neutral-600 rounded-md p-5 lg:p-6 mt-1 ${ - isOpen ? 'mt-7' : 'cursor-pointer' - }`} - > -
    isOpen && setIsOpen(false)} - className={`flex items-center justify-between ${ - isOpen ? 'cursor-pointer lg:bg-neutral-100 lg:absolute lg:-top-6 lg:left-2 mt-3 lg:mt-0' : '' - }`} - > - {!isOpen &&
    } - {isOpen && ( - - )} -

    - - Step {index + 1}: - {' '} - From {step.fromAsset.symbol} (On{' '} - {step.fromAsset.blockchain}) To {step.toAsset.symbol}{' '} - (On {step.toAsset.blockchain}) Via {step.swapperId} -

    - - -
    - - {isOpen && ( -
    -

    - {step.fromAmount} {step.fromAsset.symbol}{' '} - (On {step.fromAsset.blockchain}) To{' '} - {step.toAmount} {step.toAsset.symbol}{' '} - ({step.toAsset.blockchain}) -

    -
      - - - { - e.stopPropagation() - window.open(step.sourceWalletAddress, '_blank') - }} - /> - { - e.stopPropagation() - window.open(step.destinationWalletAddress, '_blank') - }} - /> -
    -
    - {/*

    Chain Switch: successfully

    */} - -
    -
    - {/*
    - info -

    - Do Not Worry:{' '} - Your Funds Are Safe. Your Funds Are Still In Your wallet -

    -
    */} - {step.generatedTxId.length ? ( -
    - {/*

    - Details: Your Swap Failed Because The Anysawp Needs At Least - 1000 USD Coin To Perform The Bridging -

    */} -

    - {/* {step.explorerUrls.length ? ( - <> - e.stopPropagation()} - className="text-primary" - href={step.explorerUrls[step.explorerUrls.length - 1].url} - > - View {CapitalizeFirstLetter(STATUS[step.status])} Swap - {' '} - -{' '} - - ) : ( - '' - )} */} - - { - e.stopPropagation() - console.log(step) - - CopyText(step.generatedTxId[0]) - }} - className="text-primary cursor-pointer" - > - Copy Swap Hash - -

    -
    - ) : ( - '' - )} -
    -
    - )} -
    -
    - ) -} - -export default Step diff --git a/components/TxSteps/index.tsx b/components/TxSteps/index.tsx deleted file mode 100644 index b588d35..0000000 --- a/components/TxSteps/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import group from '../../public/img/group.svg' -import { StepType } from '../../types' -import Image from 'next/image' -import React from 'react' -import Step from './Step' - -interface PropsType { - steps: StepType[] -} - -const TxSteps: React.FC = ({ steps }) => - steps.length > 0 ? ( -
    -
    - steps -

    Swap Steps

    -
    - {steps.map((step: StepType, key: number) => ( -
    - -
    - ))} -
    - ) : ( -
    - ) - -export default TxSteps diff --git a/components/common/Button/Button.types.ts b/components/common/Button/Button.types.ts new file mode 100644 index 0000000..836a29c --- /dev/null +++ b/components/common/Button/Button.types.ts @@ -0,0 +1,12 @@ +import type { HTMLAttributes } from 'react'; + +type ButtonOnclick = Pick, 'onClick'>; + +export type ButtonProps = ButtonOnclick & { + className?: string; +}; + +export interface LinkButtonProps { + href: string; + className?: string; +} diff --git a/components/common/Button/LinkButton.tsx b/components/common/Button/LinkButton.tsx new file mode 100644 index 0000000..4589d0c --- /dev/null +++ b/components/common/Button/LinkButton.tsx @@ -0,0 +1,35 @@ +/* eslint-disable @typescript-eslint/restrict-plus-operands */ +import Link from 'next/link'; +import { LinkButtonProps } from './Button.types'; +import { PropsWithChildren } from 'react'; + +export function LinkButton(props: PropsWithChildren) { + const onClick = (e: React.MouseEvent) => { + const btn = e.currentTarget; + const circle = document.createElement('span'); + const diameter = Math.max(btn.clientWidth, btn.clientHeight); + const radius = diameter / 2; + circle.style.width = circle.style.height = `${diameter}px`; + circle.style.left = `${e.clientX - (btn.offsetLeft + radius)}px`; + circle.style.top = `${e.clientY - (btn.offsetTop + radius)}px`; + circle.classList.add('ripple'); + const ripple = btn.getElementsByClassName('ripple')[0]; + + if (ripple) { + ripple.remove(); + } + + btn.appendChild(circle); + }; + return ( + + {props.children} + + ); +} diff --git a/components/common/Button/index.tsx b/components/common/Button/index.tsx new file mode 100644 index 0000000..738afc9 --- /dev/null +++ b/components/common/Button/index.tsx @@ -0,0 +1,34 @@ +/* eslint-disable @typescript-eslint/restrict-plus-operands */ +import { ButtonProps } from './Button.types'; +import { PropsWithChildren } from 'react'; + +export function Button(props: PropsWithChildren) { + const handleClick = (e: React.MouseEvent) => { + const btn = e.currentTarget; + const circle = document.createElement('span'); + const diameter = Math.max(btn.clientWidth, btn.clientHeight); + const radius = diameter / 2; + circle.style.width = circle.style.height = `${diameter}px`; + circle.style.left = `${e.clientX - (btn.offsetLeft + radius)}px`; + circle.style.top = `${e.clientY - (btn.offsetTop + radius)}px`; + circle.classList.add('ripple'); + const ripple = btn.getElementsByClassName('ripple')[0]; + + if (ripple) { + ripple.remove(); + } + + btn.appendChild(circle); + if (props.onClick) props.onClick(e); + }; + + return ( + + ); +} diff --git a/components/common/ButtonCopyIcon/ButtonCopyIcon.type.ts b/components/common/ButtonCopyIcon/ButtonCopyIcon.type.ts new file mode 100644 index 0000000..6bf56d5 --- /dev/null +++ b/components/common/ButtonCopyIcon/ButtonCopyIcon.type.ts @@ -0,0 +1,10 @@ +import type { HTMLAttributes } from 'react'; + +type ButtonOnclick = Pick, 'onClick'>; + +export type PropsType = ButtonOnclick & { + text: string; + className?: string; + hasTooltip?: boolean; + tooltipText?: string; +}; diff --git a/components/common/ButtonCopyIcon/index.tsx b/components/common/ButtonCopyIcon/index.tsx new file mode 100644 index 0000000..b9209e5 --- /dev/null +++ b/components/common/ButtonCopyIcon/index.tsx @@ -0,0 +1,48 @@ +import { CopyIcon, CheckIcon } from 'components/icons'; +import { PropsType } from './ButtonCopyIcon.type'; +import { CopyText } from 'utils/copyText'; +import { useState } from 'react'; +import Tooltip from '../Tooltip'; + +function ButtonCopyIcon(props: PropsType) { + const { + text, + className, + hasTooltip = true, + tooltipText = 'Copied To Clipboard', + } = props; + const [copied, setCopied] = useState(false); + + const handleClick = (e: React.MouseEvent) => { + e.stopPropagation(); + if (text && !copied) { + CopyText(text); + setCopied(true); + setTimeout(() => setCopied(false), 3000); + } + }; + + return ( + + ); +} + +export default ButtonCopyIcon; diff --git a/components/common/Footer/Footer.helper.ts b/components/common/Footer/Footer.helper.ts new file mode 100644 index 0000000..454211c --- /dev/null +++ b/components/common/Footer/Footer.helper.ts @@ -0,0 +1,95 @@ +import { + DiscordIcon, + GithubIcon, + MediumIcon, + TelegramIcon, + TwitterIcon, + YoutubeIcon, +} from 'components/icons'; +import { ListItemProps } from './Footer.type'; + +export const products: ListItemProps[] = [ + { + location: 'https://app.rango.exchange/', + title: 'DApp', + openInNewTab: true, + }, + { + location: './apis', + title: 'SDK', + openInNewTab: false, + }, + { + location: './apis', + title: 'API', + openInNewTab: false, + }, + { + location: './widget', + title: 'Widget', + openInNewTab: false, + }, +]; + +export const documentation: ListItemProps[] = [ + { + location: 'https://docs.rango.exchange/integration-quick-start/overview', + title: 'SDK Docs', + openInNewTab: true, + }, + { + location: 'https://rango-api.readme.io/reference', + title: 'API Reference', + openInNewTab: true, + }, + { + location: 'https://docs.rango.exchange/widget-integration/overview', + title: 'Widget Docs', + openInNewTab: true, + }, + { + location: 'https://playground.rango.exchange/', + title: 'Widget Playground', + openInNewTab: true, + }, +]; + +export const socialMedia: ListItemProps[] = [ + { + location: 'https://discord.com/invite/q3EngGyTrZ', + title: 'Discord', + openInNewTab: true, + icon: DiscordIcon, + }, + { + location: 'https://twitter.com/RangoExchange', + title: 'Twitter', + openInNewTab: true, + icon: TwitterIcon, + }, + { + location: 'https://t.me/rangoexchange', + title: 'Telegram', + openInNewTab: true, + icon: TelegramIcon, + }, + { + location: 'https://medium.com/@rangoexchange', + title: 'Medium', + openInNewTab: true, + icon: MediumIcon, + }, + + { + location: 'https://www.youtube.com/@rangoexchange', + title: 'YouTube', + openInNewTab: true, + icon: YoutubeIcon, + }, + { + location: 'https://github.com/rango-exchange', + title: 'GitHub', + openInNewTab: true, + icon: GithubIcon, + }, +]; diff --git a/components/common/Footer/Footer.type.ts b/components/common/Footer/Footer.type.ts new file mode 100644 index 0000000..0026c1e --- /dev/null +++ b/components/common/Footer/Footer.type.ts @@ -0,0 +1,8 @@ +import { SvgIconProps } from '../SvgIcon'; + +export interface ListItemProps { + location: string; + openInNewTab: boolean; + title: string; + icon?: React.ComponentType; +} diff --git a/components/common/Footer/ListItem.tsx b/components/common/Footer/ListItem.tsx new file mode 100644 index 0000000..d551f74 --- /dev/null +++ b/components/common/Footer/ListItem.tsx @@ -0,0 +1,20 @@ +import Link from 'next/link'; +import { ListItemProps } from './Footer.type'; + +function ListItem(props: ListItemProps) { + const { title, openInNewTab, location, icon: Icon } = props; + return ( +
  • + {Icon && } + + {title} + +
  • + ); +} + +export default ListItem; diff --git a/components/common/Footer/index.tsx b/components/common/Footer/index.tsx new file mode 100644 index 0000000..1b9581f --- /dev/null +++ b/components/common/Footer/index.tsx @@ -0,0 +1,81 @@ +import { documentation, products, socialMedia } from './Footer.helper'; +import ListItem from './ListItem'; +import { LinkButton } from 'components/common/Button/LinkButton'; + +function Footer() { + return ( +
    +
    +
    +
    + Start secure swaps across blockchains +
    +
    + Swap across 64+ blockchains and 100+ DEX/Bridge Protocols in a + simple UI +
    + + Open App + +
    +
    +
    +
    +
    +
    +

    + About Rango +

    +

    + Rango is a cutting-edge routing and aggregation protocol for all + cross-chain and on-chain swaps, aggregating bridges and DEXs in + crypto world. You can swap native assets like Bitcoin, Ethereum, + Matic, ... to each other in a decentralized manner. +

    +
    +
    +
    +

    + Products +

    +
      + {products.map((link, index) => ( + + ))} +
    +
    +
    +

    + Documentation +

    +
      + {documentation.map((link, index) => ( + + ))} +
    +
    +
    +
    +

    + Social Media +

    +
      + {socialMedia.map((link, index) => ( + + ))} +
    +
    +
    +
    +
    + + + Copyright © 2023 Rango Exchange. All rights reserved. + +
    + ); +} + +export default Footer; diff --git a/components/common/IconStatus/IconStatus.helper.ts b/components/common/IconStatus/IconStatus.helper.ts new file mode 100644 index 0000000..92a6634 --- /dev/null +++ b/components/common/IconStatus/IconStatus.helper.ts @@ -0,0 +1,29 @@ +import { FailIcon, RunningIcon, SuccessIcon } from 'components/icons'; +import { StatusInfoType } from './IconStatus.type'; + +export const StatusInfo: StatusInfoType = { + running: { + title: 'Running', + color: 'text-running', + backgroundColor: 'bg-backgroundRunning', + icon: RunningIcon, + }, + failed: { + title: 'Failed', + color: 'text-failed', + backgroundColor: 'bg-backgroundFailed', + icon: FailIcon, + }, + success: { + title: 'Complete', + color: 'text-success', + backgroundColor: 'bg-backgroundSuccess', + icon: SuccessIcon, + }, + unknown: { + title: 'Running', + color: 'text-running', + backgroundColor: 'bg-backgroundRunning', + icon: RunningIcon, + }, +}; diff --git a/components/common/IconStatus/IconStatus.type.ts b/components/common/IconStatus/IconStatus.type.ts new file mode 100644 index 0000000..5cf1e02 --- /dev/null +++ b/components/common/IconStatus/IconStatus.type.ts @@ -0,0 +1,16 @@ +import { SwapStatus } from 'types'; +import { SvgIconProps } from '../SvgIcon'; + +export interface PropsType { + status: SwapStatus; + hasTitle?: boolean; +} + +export type StatusInfoType = { + [key in SwapStatus]: { + title: string; + color: string; + backgroundColor: string; + icon: React.ComponentType; + }; +}; diff --git a/components/common/IconStatus/index.tsx b/components/common/IconStatus/index.tsx new file mode 100644 index 0000000..1b96362 --- /dev/null +++ b/components/common/IconStatus/index.tsx @@ -0,0 +1,22 @@ +import { PropsType } from './IconStatus.type'; +import { StatusInfo } from './IconStatus.helper'; + +function IconStatus(props: PropsType) { + const { status, hasTitle } = props; + const statusInfo = StatusInfo[status]; + const { color, icon: StatusIcon, title } = statusInfo; + + return ( + <> + + {hasTitle &&
    {title}
    } + + ); +} + +export default IconStatus; diff --git a/components/common/Layout/Layout.type.ts b/components/common/Layout/Layout.type.ts new file mode 100644 index 0000000..2761653 --- /dev/null +++ b/components/common/Layout/Layout.type.ts @@ -0,0 +1,3 @@ +export interface LayoutProps { + title: string; +} diff --git a/components/common/Layout/index.tsx b/components/common/Layout/index.tsx new file mode 100644 index 0000000..bd08d3d --- /dev/null +++ b/components/common/Layout/index.tsx @@ -0,0 +1,27 @@ +import Head from 'next/head'; +import { PropsWithChildren } from 'react'; +import Navbar from '../Navbar'; +import { LayoutProps } from './Layout.type'; +import Footer from '../Footer'; + +function Layout(props: PropsWithChildren) { + return ( +
    + + {props.title} + + +
    + {props.children} +
    + +
    +
    + ); +} + +export default Layout; diff --git a/components/Loading.tsx b/components/common/Loading.tsx similarity index 94% rename from components/Loading.tsx rename to components/common/Loading.tsx index 34359dd..c02e2ae 100644 --- a/components/Loading.tsx +++ b/components/common/Loading.tsx @@ -4,13 +4,12 @@ const Loading: React.FC = () => ( style={{ margin: 'auto', display: 'block', - shapeRendering: 'auto' + shapeRendering: 'auto', }} width={90} height={90} viewBox="0 0 100 100" - preserveAspectRatio="xMidYMid" - > + preserveAspectRatio="xMidYMid"> ( /> -) -export default Loading +); +export default Loading; diff --git a/components/common/Navbar/DesktopNavbar.tsx b/components/common/Navbar/DesktopNavbar.tsx new file mode 100644 index 0000000..3eee7fd --- /dev/null +++ b/components/common/Navbar/DesktopNavbar.tsx @@ -0,0 +1,70 @@ +import { useState } from 'react'; +import Image from 'next/image'; +import Link from 'next/link'; +import coloredLogo from 'public/logo.svg'; +import rangoLogo from 'public/logo-with-text.svg'; +import Menu from './Menu'; +import { DeviceProps } from './Navbar.type'; + +function DesktopNavbar(props: DeviceProps) { + const { links, renderChildren, theme, className } = props; + const [showSubMenu, setShowSubMenu] = useState(0); + + return ( + + ); +} + +export default DesktopNavbar; diff --git a/components/common/Navbar/Menu.tsx b/components/common/Navbar/Menu.tsx new file mode 100644 index 0000000..55bef35 --- /dev/null +++ b/components/common/Navbar/Menu.tsx @@ -0,0 +1,57 @@ +import Link from 'next/link'; +import { MenuProps } from './Navbar.type'; + +function Menu(props: MenuProps) { + const { subMenu, showSubMenu, title, theme } = props; + return ( +
    +
    + {title} + + + +
    + + {showSubMenu && ( +
      + {subMenu.map((item, index) => { + const { icon: Icon } = item; + return ( +
    • + + + {item.title} + +
    • + ); + })} +
    + )} +
    + ); +} + +export default Menu; diff --git a/components/common/Navbar/MobileMenu.tsx b/components/common/Navbar/MobileMenu.tsx new file mode 100644 index 0000000..765be01 --- /dev/null +++ b/components/common/Navbar/MobileMenu.tsx @@ -0,0 +1,157 @@ +import { useEffect, useState } from 'react'; +import Image from 'next/image'; +import Link from 'next/link'; + +import rangoLogo from 'public/logo.svg'; +import { MobileMenuProps } from './Navbar.type'; +import { useRouter } from 'next/router'; + +const CLOSED_DELAY = 300; +const OPEN_DELAY = 10; + +function MobileMenu(props: MobileMenuProps) { + const { links, showMenu, onClose } = props; + const [showSubMenu, setShowSubMenu] = useState(0); + const { pathname } = useRouter(); + const [active, setActive] = useState(false); + const [isMount, setIsMount] = useState(false); + const handleBackDropClick = (event: React.MouseEvent) => { + if (event.target === event.currentTarget) { + onClose(); + } + }; + + useEffect(() => { + if (showMenu) { + setIsMount(true); + setTimeout(() => { + setActive(true); + }, OPEN_DELAY); + } else { + setActive(false); + setTimeout(() => { + setIsMount(false); + }, CLOSED_DELAY); + } + }, [showMenu]); + return ( + <> + {isMount && ( + <> +
    +
    + +
    + + )} + + ); +} + +export default MobileMenu; diff --git a/components/common/Navbar/MobileNavbar.tsx b/components/common/Navbar/MobileNavbar.tsx new file mode 100644 index 0000000..33f594f --- /dev/null +++ b/components/common/Navbar/MobileNavbar.tsx @@ -0,0 +1,74 @@ +import Image from 'next/image'; +import Link from 'next/link'; +import coloredLogo from 'public/logo.svg'; +import rangoLogo from 'public/logo-with-text.svg'; +import { DeviceProps } from './Navbar.type'; +import MobileMenu from './MobileMenu'; +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/router'; + +function MobileNavbar(props: DeviceProps) { + const { theme, renderChildren, links, className } = props; + + const [showMenu, setShowMenu] = useState(false); + + const { pathname } = useRouter(); + + useEffect(() => { + setShowMenu(false); + }, [pathname]); + + useEffect(() => { + if (showMenu) { + document.body.style.overflow = 'hidden'; + } + return () => { + document.body.style.overflow = 'unset'; + }; + }, [showMenu]); + + return ( +
    + {renderChildren ? ( + <> + + Rango logo + + + setShowMenu(false)} + showMenu={showMenu} + links={links} + /> + +
    + +
    + + ) : null} +
    + ); +} + +export default MobileNavbar; diff --git a/components/common/Navbar/Navbar.helper.ts b/components/common/Navbar/Navbar.helper.ts new file mode 100644 index 0000000..dc591fb --- /dev/null +++ b/components/common/Navbar/Navbar.helper.ts @@ -0,0 +1,55 @@ +import { + AffiliateIcon, + ApiManagementIcon, + DocsIcon, + WidgetIcon, +} from 'components/icons'; +import { LinkTypes, MenuTypes } from './Navbar.type'; + +export const links: Array = [ + { + location: '/', + title: 'Home', + id: 1, + type: 'link', + openInNewTab: false, + }, + { + location: 'https://app.rango.exchange', + title: 'Rango App', + id: 2, + type: 'link', + openInNewTab: true, + }, + { + title: 'Resources', + type: 'menu', + id: 3, + subMenu: [ + { + title: 'API/SDK', + location: 'https://rango-api.readme.io/reference/meta', + openInNewTab: true, + icon: ApiManagementIcon, + }, + { + title: 'Widget', + location: 'https://docs.rango.exchange/widget-integration/overview', + openInNewTab: true, + icon: WidgetIcon, + }, + { + title: 'Affiliate', + location: 'https://rango.exchange/affiliate', + openInNewTab: true, + icon: AffiliateIcon, + }, + { + title: 'Docs', + location: 'https://docs.rango.exchange', + openInNewTab: true, + icon: DocsIcon, + }, + ], + }, +]; diff --git a/components/common/Navbar/Navbar.type.ts b/components/common/Navbar/Navbar.type.ts new file mode 100644 index 0000000..9b2a218 --- /dev/null +++ b/components/common/Navbar/Navbar.type.ts @@ -0,0 +1,43 @@ +import { SvgIconProps } from '../SvgIcon'; + +export interface LinkTypes { + location: string; + title: string; + openInNewTab: boolean; + type: 'link'; + id: number; +} + +export type MenuTypes = Pick & { + subMenu: SubMenuTypes[]; + type: 'menu'; +}; + +export type SubMenuTypes = Pick< + LinkTypes, + 'location' | 'title' | 'openInNewTab' +> & { icon: React.ComponentType }; + +export interface NavbarProps { + theme: 'dark' | 'light'; +} + +export interface DeviceProps { + className: string; + renderChildren: boolean; + links: Array; + theme: 'dark' | 'light'; +} + +export interface MenuProps { + subMenu: SubMenuTypes[]; + showSubMenu: boolean; + title: string; + theme: 'dark' | 'light'; +} + +export interface MobileMenuProps { + showMenu: boolean; + links: Array; + onClose: () => void; +} diff --git a/components/common/Navbar/index.tsx b/components/common/Navbar/index.tsx new file mode 100644 index 0000000..5438980 --- /dev/null +++ b/components/common/Navbar/index.tsx @@ -0,0 +1,44 @@ +import { Media } from '../media'; +import DesktopNavbar from './DesktopNavbar'; +import { links } from './Navbar.helper'; +import MobileNavbar from './MobileNavbar'; +import { NavbarProps } from './Navbar.type'; + +function Navbar(props: NavbarProps) { + const { theme } = props; + + return ( +
    +
    + + {(className, renderChildren) => ( + + )} + + + {(className, renderChildren) => ( + + )} + +
    +
    + ); +} + +export default Navbar; diff --git a/components/common/SearchBox/SearchInput.tsx b/components/common/SearchBox/SearchInput.tsx new file mode 100644 index 0000000..9d2f447 --- /dev/null +++ b/components/common/SearchBox/SearchInput.tsx @@ -0,0 +1,43 @@ +import { useRouter } from 'next/router'; +import { FormEvent, MouseEvent, useState } from 'react'; +import { Button } from '../Button'; +import { SearchIcon } from 'components/icons'; + +function SearchInput() { + const [query, setQuery] = useState(''); + const router = useRouter(); + const onSubmit = ( + e: FormEvent | MouseEvent, + ) => { + e.preventDefault(); + if (query) { + router.push({ + pathname: '/search', + query: { query }, + }); + } + }; + + return ( +
    +
    + + setQuery(e.target.value)} + /> +
    + + +
    + ); +} + +export default SearchInput; diff --git a/components/common/SearchBox/index.tsx b/components/common/SearchBox/index.tsx new file mode 100644 index 0000000..36b8b90 --- /dev/null +++ b/components/common/SearchBox/index.tsx @@ -0,0 +1,18 @@ +import SearchInput from './SearchInput'; + +function SearchBox() { + return ( +
    +

    + Rango Swaps Explorer +

    +

    + Track all transactions on Rango + Exchange +

    + +
    + ); +} + +export default SearchBox; diff --git a/components/common/SvgIcon/SvgIcon.tsx b/components/common/SvgIcon/SvgIcon.tsx new file mode 100644 index 0000000..a483391 --- /dev/null +++ b/components/common/SvgIcon/SvgIcon.tsx @@ -0,0 +1,17 @@ +import type { SvgIconPropsWithChildren } from './SvgIcon.types'; + +import React from 'react'; + +export function SvgIcon(props: SvgIconPropsWithChildren) { + const { size = '1em', color, children, className } = props; + const originalSvgProps = children?.props; + const commonProps = { + ...originalSvgProps, + width: size, + height: size, + color, + className, + }; + + return {children?.props.children}; +} diff --git a/components/common/SvgIcon/SvgIcon.types.ts b/components/common/SvgIcon/SvgIcon.types.ts new file mode 100644 index 0000000..1b5f98f --- /dev/null +++ b/components/common/SvgIcon/SvgIcon.types.ts @@ -0,0 +1,8 @@ +export interface SvgIconProps { + size?: string; + color?: string; + className?: string; +} +export type SvgIconPropsWithChildren = SvgIconProps & { + children?: React.ReactElement; +}; diff --git a/components/common/SvgIcon/index.ts b/components/common/SvgIcon/index.ts new file mode 100644 index 0000000..89c76f6 --- /dev/null +++ b/components/common/SvgIcon/index.ts @@ -0,0 +1,2 @@ +export { SvgIcon } from './SvgIcon'; +export type { SvgIconPropsWithChildren, SvgIconProps } from './SvgIcon.types'; diff --git a/components/common/Table/Table.helper.ts b/components/common/Table/Table.helper.ts new file mode 100644 index 0000000..3444c6a --- /dev/null +++ b/components/common/Table/Table.helper.ts @@ -0,0 +1,36 @@ +import { ColumnType } from './Table.type'; +import AmountCell from './cells/AmountCell'; +import RequestIDCell from './cells/RequestIDCell'; +import StatusCell from './cells/StatusCell'; +import TokenCell from './cells/TokenCell'; + +export const columns: ColumnType[] = [ + { + id: 1, + title: 'Request ID', + component: RequestIDCell, + }, + { + id: 2, + title: 'Source Transaction', + tokenType: 'source', + component: TokenCell, + }, + { + id: 3, + title: 'Destination Transaction', + tokenType: 'destination', + component: TokenCell, + }, + { + id: 4, + title: 'Amount', + component: AmountCell, + }, + + { + id: 5, + title: 'Status', + component: StatusCell, + }, +]; diff --git a/components/common/Table/Table.type.ts b/components/common/Table/Table.type.ts new file mode 100644 index 0000000..fdc3c97 --- /dev/null +++ b/components/common/Table/Table.type.ts @@ -0,0 +1,23 @@ +import { SwapType } from 'types'; + +export interface TableProps { + data: SwapType[]; +} + +export interface TableBodyProps { + data: SwapType[]; +} + +export interface CellProps { + swapItem: SwapType; + column: ColumnType; +} + +export type TokenType = 'source' | 'destination'; + +export interface ColumnType { + id: number; + title: string; + tokenType?: TokenType; + component?: React.ComponentType; +} diff --git a/components/common/Table/TableBody.tsx b/components/common/Table/TableBody.tsx new file mode 100644 index 0000000..5db12e5 --- /dev/null +++ b/components/common/Table/TableBody.tsx @@ -0,0 +1,39 @@ +/* eslint-disable @typescript-eslint/restrict-template-expressions */ +import { TableBodyProps } from './Table.type'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import { columns } from './Table.helper'; +import Link from 'next/link'; + +dayjs.extend(utc); + +function TableBody(props: TableBodyProps) { + const { data } = props; + return ( +
    + {data.map((item) => { + const { requestId } = item; + return ( +
    + {columns.map((col) => { + const CellComponent = col.component; + return CellComponent ? ( + + ) : null; + })} + + + Detail + +
    + ); + })} +
    + ); +} + +export default TableBody; diff --git a/components/common/Table/TableHead.tsx b/components/common/Table/TableHead.tsx new file mode 100644 index 0000000..a64a1dc --- /dev/null +++ b/components/common/Table/TableHead.tsx @@ -0,0 +1,19 @@ +import { columns } from './Table.helper'; + +function TableHead() { + return ( +
    + {columns.map((col, index) => ( +
    + {col.title} +
    + ))} +
    + ); +} + +export default TableHead; diff --git a/components/common/Table/cells/AmountCell.tsx b/components/common/Table/cells/AmountCell.tsx new file mode 100644 index 0000000..dbe2208 --- /dev/null +++ b/components/common/Table/cells/AmountCell.tsx @@ -0,0 +1,49 @@ +import { GassIcon } from 'components/icons'; +import { CellProps } from '../Table.type'; +import { getPercentageChange } from 'utils/amountConverter'; + +function AmountCell(props: CellProps) { + const { swapItem, column } = props; + const { stepsSummary } = swapItem; + const fromToken = stepsSummary.length ? stepsSummary[0]?.fromToken : null; + const toToken = stepsSummary.length + ? stepsSummary[stepsSummary.length - 1]?.toToken + : null; + + const usdFromAmount = fromToken?.price + ? fromToken.price * fromToken.realAmount + : null; + const usdToAmount = toToken?.price + ? toToken.price * + (toToken.realAmount ? toToken.realAmount : toToken.expectedAmount) + : null; + + const changePercentage = getPercentageChange(usdFromAmount, usdToAmount); + const gasFee = stepsSummary.reduce((acc, cur) => { + if (cur?.feeUsd) return acc + cur.feeUsd; + return acc; + }, 0); + + return ( +
    +
    + {column.title} +
    +
    + + {usdToAmount && `~$${usdToAmount.toFixed(2)}`} + + {changePercentage ? `(${changePercentage}%)` : ''} +
    +
    + + Fee : + {`$${ + gasFee ? gasFee.toFixed(2) : '--' + }`} +
    +
    + ); +} + +export default AmountCell; diff --git a/components/common/Table/cells/RequestIDCell.tsx b/components/common/Table/cells/RequestIDCell.tsx new file mode 100644 index 0000000..2966e5e --- /dev/null +++ b/components/common/Table/cells/RequestIDCell.tsx @@ -0,0 +1,44 @@ +import { useRouter } from 'next/router'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import { CellProps } from '../Table.type'; +import ButtonCopyIcon from 'components/common/ButtonCopyIcon'; + +dayjs.extend(utc); + +function RequestIDCell(props: CellProps) { + const { swapItem, column } = props; + const { requestId, transactionTime } = swapItem; + + const router = useRouter(); + + const handleSwapDetails = (id: string) => { + router.push(`/swap/${id}`); + }; + + return ( +
    +
    {column.title}
    +
    + + +
    +
    + {dayjs + .utc(transactionTime) + .local() + .format('DD MMMM YYYY | HH:mm') + .toString()} +
    +
    + ); +} + +export default RequestIDCell; diff --git a/components/common/Table/cells/StatusCell.tsx b/components/common/Table/cells/StatusCell.tsx new file mode 100644 index 0000000..372dfde --- /dev/null +++ b/components/common/Table/cells/StatusCell.tsx @@ -0,0 +1,30 @@ +import { StepsIcon } from 'components/icons'; +import { CellProps } from '../Table.type'; +import IconStatus from 'components/common/IconStatus'; + +function StatusCell(props: CellProps) { + const { swapItem, column } = props; + const { status, stepsSummary } = swapItem; + const successStep = stepsSummary.filter( + (item) => item.status === 'success', + ).length; + + return ( +
    +
    + {column.title} +
    +
    + +
    + {stepsSummary?.length && ( +
    + + {`${successStep}/${stepsSummary.length}`} +
    + )} +
    + ); +} + +export default StatusCell; diff --git a/components/common/Table/cells/TokenCell.tsx b/components/common/Table/cells/TokenCell.tsx new file mode 100644 index 0000000..f76d8b2 --- /dev/null +++ b/components/common/Table/cells/TokenCell.tsx @@ -0,0 +1,65 @@ +/* eslint-disable @next/next/no-img-element */ +import { CellProps } from '../Table.type'; + +function TokenCell(props: CellProps) { + const { swapItem, column } = props; + const { stepsSummary } = swapItem; + const firstStep = stepsSummary.length ? stepsSummary[0] : null; + const lastStep = stepsSummary.length + ? stepsSummary[stepsSummary.length - 1] + : null; + + const token = + column.tokenType === 'destination' + ? lastStep?.toToken + : firstStep?.fromToken; + + const { blockchain, blockchainLogo, logo, name, symbol } = token || {}; + + return ( + <> + {column.tokenType === 'source' ? ( +
    + ) : ( +
    + )} +
    +
    + {name + {blockchain} +
    +
    +
    + + {`${!token?.realAmount ? '~' : ''}${parseFloat( + Number(token?.realAmount || token?.expectedAmount).toFixed(3), + )}`} + + + {symbol || name} + +
    +
    + {blockchain} +
    +
    +
    + + ); +} + +export default TokenCell; diff --git a/components/common/Table/index.tsx b/components/common/Table/index.tsx new file mode 100644 index 0000000..40782d2 --- /dev/null +++ b/components/common/Table/index.tsx @@ -0,0 +1,16 @@ +import { TableProps } from './Table.type'; +import TableHead from './TableHead'; +import TableBody from './TableBody'; + +function Table(props: TableProps) { + const { data } = props; + + return ( +
    + + +
    + ); +} + +export default Table; diff --git a/components/common/Tooltip/Tooltip.type.ts b/components/common/Tooltip/Tooltip.type.ts new file mode 100644 index 0000000..0f731ca --- /dev/null +++ b/components/common/Tooltip/Tooltip.type.ts @@ -0,0 +1,4 @@ +export interface PropsType { + placement?: 'left' | 'top' | 'bottom' | 'right'; + label: string; +} diff --git a/components/common/Tooltip/index.tsx b/components/common/Tooltip/index.tsx new file mode 100644 index 0000000..c8ee041 --- /dev/null +++ b/components/common/Tooltip/index.tsx @@ -0,0 +1,26 @@ +import React, { PropsWithChildren, useState } from 'react'; +import { PropsType } from './Tooltip.type'; + +const Tooltip = (props: PropsWithChildren) => { + const { label, children } = props; + const [isTooltipVisible, setTooltipVisible] = useState(false); + + return ( +
    setTooltipVisible(true)} + onMouseLeave={() => setTooltipVisible(false)}> + {children} + {isTooltipVisible && ( +
    + {label} +
    + )} +
    + ); +}; + +export default Tooltip; diff --git a/components/common/media.tsx b/components/common/media.tsx new file mode 100644 index 0000000..c4e3028 --- /dev/null +++ b/components/common/media.tsx @@ -0,0 +1,9 @@ +import { createMedia } from '@artsy/fresnel'; + +const ExampleAppMedia = createMedia({ + breakpoints: { xs: 0, sm: 640, md: 1024, lg: 1280 }, +}); + +export const mediaStyles = ExampleAppMedia.createMediaStyle(); + +export const { Media, MediaContextProvider } = ExampleAppMedia; diff --git a/components/detail/SwapDetailSummary/SwapDetail.helper.ts b/components/detail/SwapDetailSummary/SwapDetail.helper.ts new file mode 100644 index 0000000..4a108a7 --- /dev/null +++ b/components/detail/SwapDetailSummary/SwapDetail.helper.ts @@ -0,0 +1,82 @@ +import { ColumnType } from './SwapDetail.type'; +import SwapDetailValue from './SwapDetailValue'; +import SwapDetailAddress from './SwapDetailAddress'; +import SwapDetailChain from './SwapDetailChain'; +import SwapDetailMobileToken from './SwapDetailMobileToken'; +import SwapDetailMobileValue from './SwapDetailMobileValue'; + +export const DesktopColumns: ColumnType[] = [ + { + id: 1, + title: 'Swap Status', + component: SwapDetailValue, + }, + { + id: 2, + title: 'Input Amount', + component: SwapDetailValue, + }, + { + id: 3, + title: 'Output Amount', + component: SwapDetailValue, + }, + { + id: 4, + title: 'Source Address', + component: SwapDetailAddress, + }, + { + id: 5, + title: 'Source Token', + component: SwapDetailChain, + }, + { + id: 6, + title: 'Destination Address', + component: SwapDetailAddress, + }, + { + id: 7, + title: 'Destination Token', + component: SwapDetailChain, + }, + { + id: 8, + title: 'Duration', + component: SwapDetailValue, + }, + { + id: 9, + title: 'Initiation Date And Time', + component: SwapDetailValue, + }, +]; + +export const mobileColumns: ColumnType[] = [ + { + id: 1, + title: 'Swap Status', + component: SwapDetailMobileValue, + }, + { + id: 2, + title: 'input', + component: SwapDetailMobileToken, + }, + { + id: 3, + title: 'output', + component: SwapDetailMobileToken, + }, + { + id: 4, + title: 'Initiation Date And Time', + component: SwapDetailMobileValue, + }, + { + id: 5, + title: 'Duration', + component: SwapDetailMobileValue, + }, +]; diff --git a/components/detail/SwapDetailSummary/SwapDetail.type.ts b/components/detail/SwapDetailSummary/SwapDetail.type.ts new file mode 100644 index 0000000..0670725 --- /dev/null +++ b/components/detail/SwapDetailSummary/SwapDetail.type.ts @@ -0,0 +1,17 @@ +import { DetailsType } from 'types'; + +export interface PropsType { + details: DetailsType; + id: string; +} + +export interface ColumnType { + id: number; + title: string; + component?: React.ComponentType; +} + +export interface SwapDetailItem { + details: DetailsType; + column: ColumnType; +} diff --git a/components/detail/SwapDetailSummary/SwapDetailAddress.tsx b/components/detail/SwapDetailSummary/SwapDetailAddress.tsx new file mode 100644 index 0000000..e3937c6 --- /dev/null +++ b/components/detail/SwapDetailSummary/SwapDetailAddress.tsx @@ -0,0 +1,25 @@ +import { SwapDetailItem } from './SwapDetail.type'; +import ButtonCopyIcon from 'components/common/ButtonCopyIcon'; + +function SwapDetailAddress(props: SwapDetailItem) { + const { details, column } = props; + const { sourceWallet, destinationWallet } = details; + + const wallet = + column.title === 'Source Address' ? sourceWallet : destinationWallet; + + const handleClick = () => { + if (wallet?.explorer) window.open(wallet.explorer, '_blank'); + }; + + return ( +
    + + +
    + ); +} + +export default SwapDetailAddress; diff --git a/components/detail/SwapDetailSummary/SwapDetailChain.tsx b/components/detail/SwapDetailSummary/SwapDetailChain.tsx new file mode 100644 index 0000000..d0776f8 --- /dev/null +++ b/components/detail/SwapDetailSummary/SwapDetailChain.tsx @@ -0,0 +1,39 @@ +/* eslint-disable @next/next/no-img-element */ +import { SwapDetailItem } from './SwapDetail.type'; + +function SwapDetailChain(props: SwapDetailItem) { + const { details, column } = props; + const { from, to } = details; + + const token = column.title === 'Source Token' ? from : to; + const { blockchain, symbol, blockchainLogo, logo, name } = token; + + return ( +
    +
    + {name + {blockchain} +
    +
    +
    + {symbol || name} +
    +
    {blockchain}
    +
    +
    + ); +} + +export default SwapDetailChain; diff --git a/components/detail/SwapDetailSummary/SwapDetailMobileToken.tsx b/components/detail/SwapDetailSummary/SwapDetailMobileToken.tsx new file mode 100644 index 0000000..707855c --- /dev/null +++ b/components/detail/SwapDetailSummary/SwapDetailMobileToken.tsx @@ -0,0 +1,99 @@ +/* eslint-disable @next/next/no-img-element */ +import ButtonCopyIcon from 'components/common/ButtonCopyIcon'; +import { SwapDetailItem } from './SwapDetail.type'; + +function SwapDetailMobileToken(props: SwapDetailItem) { + const { details, column } = props; + const { steps, sourceWallet, destinationWallet } = details; + + const from = steps?.length ? steps[0].from : null; + const to = steps?.length ? steps[steps.length - 1].to : null; + const token = column.title === 'input' ? from : to; + const { + blockchain, + symbol, + blockchainLogo, + logo, + name, + realAmount, + expectedAmount, + } = token || {}; + + const wallet = column.title === 'input' ? sourceWallet : destinationWallet; + + const handleClick = () => { + if (wallet?.explorer) window.open(wallet.explorer, '_blank'); + }; + + return ( +
    +
    +
    + {column.title === 'input' ? 'Input Amount' : 'Output Amount'} +
    + {column.title === 'input' && ( +
    {`${realAmount} ${symbol}`}
    + )} + + {column.title === 'output' && ( + <> + {isNaN(Number(realAmount)) ? ( +
    {`Est. ~${expectedAmount} ${symbol}`}
    + ) : ( +
    {`${realAmount} ${symbol}`}
    + )} + + )} +
    + +
    + +
    +
    + {column.title === 'input' ? 'Source Address' : 'Destination Address '} +
    +
    + + +
    +
    + +
    + +
    +
    + {column.title === 'input' ? 'Source Token' : 'Destination Token '} +
    + +
    +
    + {name + {blockchain} +
    +
    + {symbol || name} +
    +
    {blockchain}
    +
    +
    +
    + ); +} + +export default SwapDetailMobileToken; diff --git a/components/detail/SwapDetailSummary/SwapDetailMobileValue.tsx b/components/detail/SwapDetailSummary/SwapDetailMobileValue.tsx new file mode 100644 index 0000000..8458dd3 --- /dev/null +++ b/components/detail/SwapDetailSummary/SwapDetailMobileValue.tsx @@ -0,0 +1,59 @@ +import { SecondsTohms } from 'utils/secondsTohms'; +import { SwapDetailItem } from './SwapDetail.type'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import IconStatus from 'components/common/IconStatus'; +import { StepsIcon } from 'components/icons'; + +dayjs.extend(utc); + +function SwapDetailMobileValue(props: SwapDetailItem) { + const { details, column } = props; + const { estimatedTimeInSeconds, status, steps, creationDate } = details; + const successStep = steps.filter((item) => item.status === 'success').length; + + return ( + <> +
    +
    {column.title}
    + {column.title === 'Swap Status' && ( +
    +
    + +
    + | + {steps?.length && ( +
    + + {`${successStep}/${steps.length}`} +
    + )} +
    + )} + {column.title === 'Initiation Date And Time' && creationDate && ( +
    + {dayjs + .utc(creationDate) + .local() + .format('MMMM DD, YYYY | HH:mm:ss') + .toString()} +
    + )} + {column.title === 'Duration' && ( +
    + {`Est. ~${ + estimatedTimeInSeconds + ? SecondsTohms(estimatedTimeInSeconds) + : '--' + }`} +
    + )} +
    + {column.title === 'Initiation Date And Time' && ( +
    + )} + + ); +} + +export default SwapDetailMobileValue; diff --git a/components/detail/SwapDetailSummary/SwapDetailValue.tsx b/components/detail/SwapDetailSummary/SwapDetailValue.tsx new file mode 100644 index 0000000..45d4fad --- /dev/null +++ b/components/detail/SwapDetailSummary/SwapDetailValue.tsx @@ -0,0 +1,62 @@ +import { SecondsTohms } from 'utils/secondsTohms'; +import { SwapDetailItem } from './SwapDetail.type'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import IconStatus from 'components/common/IconStatus'; +import { StepsIcon } from 'components/icons'; + +dayjs.extend(utc); + +function SwapDetailValue(props: SwapDetailItem) { + const { details, column } = props; + const { estimatedTimeInSeconds, status, steps, creationDate } = details; + const from = steps?.length ? steps[0].from : null; + const to = steps?.length ? steps[steps.length - 1].to : null; + const successStep = steps.filter((item) => item.status === 'success').length; + + return ( +
    + {column.title === 'Swap Status' && ( +
    +
    + +
    + {steps?.length && ( +
    + + {`${successStep}/${steps.length}`} +
    + )} +
    + )} + {column.title === 'Input Amount' && from && ( + {`${from?.realAmount} ${from?.symbol}`} + )} + {column.title === 'Output Amount' && + to && + (isNaN(to.realAmount) ? ( + {`Est. ~${to?.expectedAmount} ${to?.symbol}`} + ) : ( + {`${to.realAmount} ${to?.symbol}`} + ))} + {column.title === 'Duration' && ( + + {`Est. ~${ + estimatedTimeInSeconds ? SecondsTohms(estimatedTimeInSeconds) : '--' + }`} + + )} + {column.title === 'Initiation Date And Time' && creationDate && ( + + {dayjs + .utc(creationDate) + .local() + .format('MMMM DD, YYYY | HH:mm:ss') + .toString()} + + )} +
    + ); +} + +export default SwapDetailValue; diff --git a/components/detail/SwapDetailSummary/index.tsx b/components/detail/SwapDetailSummary/index.tsx new file mode 100644 index 0000000..6507e3a --- /dev/null +++ b/components/detail/SwapDetailSummary/index.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import { DesktopColumns, mobileColumns } from './SwapDetail.helper'; +import { PropsType } from './SwapDetail.type'; +import ButtonCopyIcon from 'components/common/ButtonCopyIcon'; + +function SwapDetailSummary(props: PropsType) { + const { details, id } = props; + const { from, to } = details; + + return ( +
    +

    + Swap Details +

    +

    + {`Swap from ${from.symbol} (on ${from.blockchain}) to ${to.symbol} (on ${to.blockchain})`} +

    +
    + + Request ID : + +
    + + {`${id.slice(0, 20)}...`} + + + {id} + + +
    +
    +
    +
    + {mobileColumns.map((col) => { + const DetailValueComponent = col.component; + return ( + DetailValueComponent && ( + + ) + ); + })} +
    +
    + {DesktopColumns.map((col, index) => { + const DetailValueComponent = col.component; + const { title, id } = col; + return ( + <> +
    +
    + {`${title} : `} +
    + {DetailValueComponent && ( + + )} +
    + {index !== DesktopColumns.length - 1 && ( +
    + )} + + ); + })} +
    +
    + ); +} + +export default SwapDetailSummary; diff --git a/components/detail/SwapSteps/SwapStepAddress.tsx b/components/detail/SwapSteps/SwapStepAddress.tsx new file mode 100644 index 0000000..d4b72a8 --- /dev/null +++ b/components/detail/SwapSteps/SwapStepAddress.tsx @@ -0,0 +1,30 @@ +import { SwapStepItemValueProps } from './SwapSteps.type'; +import ButtonCopyIcon from 'components/common/ButtonCopyIcon'; + +function SwapStepAddress(props: SwapStepItemValueProps) { + const { step, column } = props; + const { sourceWallet, destinationWallet } = step; + + const wallet = + column.title === 'Step Source Wallet' ? sourceWallet : destinationWallet; + const { address, explorer } = wallet; + const handleClick = (e: React.MouseEvent) => { + e.stopPropagation(); + if (explorer) window.open(explorer, '_blank'); + }; + + return ( + address && ( +
    + + +
    + ) + ); +} + +export default SwapStepAddress; diff --git a/components/detail/SwapSteps/SwapStepChainAmount.tsx b/components/detail/SwapSteps/SwapStepChainAmount.tsx new file mode 100644 index 0000000..1a86ed0 --- /dev/null +++ b/components/detail/SwapSteps/SwapStepChainAmount.tsx @@ -0,0 +1,26 @@ +/* eslint-disable @next/next/no-img-element */ +import React from 'react'; +import { SwapStepChainLogoProps } from './SwapSteps.type'; + +function SwapStepChainAmount(props: SwapStepChainLogoProps) { + const { token, firstStep } = props; + const { symbol, name, realAmount, expectedAmount } = token; + return ( + <> + {firstStep && `${realAmount.toFixed(2)} ${symbol}`} + {!firstStep && ( + <> + {isNaN(realAmount) + ? `Est. ~${expectedAmount.toFixed(2)} ${symbol || name}` + : `${realAmount.toFixed( + 2, + )} ${symbol} (Est. ~${expectedAmount.toFixed(2)} ${ + symbol || name + })`} + + )} + + ); +} + +export default SwapStepChainAmount; diff --git a/components/detail/SwapSteps/SwapStepChainLogo.tsx b/components/detail/SwapSteps/SwapStepChainLogo.tsx new file mode 100644 index 0000000..e3ce07e --- /dev/null +++ b/components/detail/SwapSteps/SwapStepChainLogo.tsx @@ -0,0 +1,25 @@ +/* eslint-disable @next/next/no-img-element */ +import React from 'react'; +import { SwapStepChainLogoProps } from './SwapSteps.type'; + +function SwapStepChainLogo(props: SwapStepChainLogoProps) { + const { token } = props; + const { symbol, logo, blockchainLogo, name, blockchain } = token; + + return ( +
    + {symbol + {blockchain} +
    + ); +} + +export default SwapStepChainLogo; diff --git a/components/detail/SwapSteps/SwapStepItem.tsx b/components/detail/SwapSteps/SwapStepItem.tsx new file mode 100644 index 0000000..d13e1ea --- /dev/null +++ b/components/detail/SwapSteps/SwapStepItem.tsx @@ -0,0 +1,78 @@ +import React, { useState } from 'react'; +import { SwapStepItemProps } from './SwapSteps.type'; +import TransactionURL from './TransactionURL'; +import SwapStepItemExpanded from './SwapStepItemExpanded'; +import { BorderColor } from './SwapSteps.helper'; +import { ChevronDownIcon, ChevronUpIcon, NextIcon } from 'components/icons'; +import SwapStepChainLogo from './SwapStepChainLogo'; +import SwapStepChainAmount from './SwapStepChainAmount'; +import SwapStepSwapper from './SwapStepSwapper'; + +function SwapStepItem(props: SwapStepItemProps) { + const { step, firstStep, lastStep } = props; + const { from, to, status, explorerUrls } = step; + const [isOpen, setIsOpen] = useState(false); + const borderColor = BorderColor[status]; + + return ( + <> +
    setIsOpen(!isOpen)} + className={`py-15 px-10 md:p-25 w-full cursor-pointer rounded-soft md:rounded-normal border-solid ${borderColor} border`}> +
    + + +
    +
    +
    +
    + + + + +
    +
    +
    + + + + +
    +
    +
    + + + + + + + + + +
    + + +
    +
    + {!lastStep && ( +
    + )} + + ); +} + +export default SwapStepItem; diff --git a/components/detail/SwapSteps/SwapStepItemExpanded.tsx b/components/detail/SwapSteps/SwapStepItemExpanded.tsx new file mode 100644 index 0000000..5e19c11 --- /dev/null +++ b/components/detail/SwapSteps/SwapStepItemExpanded.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { SwapStepItemExpandedProps } from './SwapSteps.type'; +import { columns } from './SwapSteps.helper'; + +function SwapStepItemExpanded(props: SwapStepItemExpandedProps) { + const { step, open, firstStep } = props; + const { from, to } = step; + const { + symbol: fromSymbol, + name: fromName, + blockchain: fromBlockchain, + } = from; + const { symbol: toSymbol, name: toName, blockchain: toBlockchain } = to; + + return ( +
    +
    + {`Swap from ${fromSymbol || fromName} (on ${fromBlockchain}) to ${ + toSymbol || toName + } (on ${toBlockchain})`} +
    + +
    + {columns.map((col, index) => { + const StepValueComponent = col.component; + const { title, id } = col; + return ( + <> +
    +
    + {`${title} : `} +
    + {StepValueComponent && ( + + )} +
    + {index !== columns.length - 1 && ( +
    + )} + + ); + })} +
    +
    + ); +} + +export default SwapStepItemExpanded; diff --git a/components/detail/SwapSteps/SwapStepSwapper.tsx b/components/detail/SwapSteps/SwapStepSwapper.tsx new file mode 100644 index 0000000..87c18ca --- /dev/null +++ b/components/detail/SwapSteps/SwapStepSwapper.tsx @@ -0,0 +1,51 @@ +/* eslint-disable @next/next/no-img-element */ +import React from 'react'; +import { SwapStepItemProps } from './SwapSteps.type'; +import { InternalPathType } from 'types'; +import { BorderColor } from './SwapSteps.helper'; + +function SwapStepSwapper(props: SwapStepItemProps) { + const { step } = props; + const { from, to, swapper, internalPath, status } = step; + + const swappers: InternalPathType[] = [...internalPath]; + if (!swappers.length) swappers.push({ from, swapper, to }); + + return ( +
    + {swappers.map((swapperItem, index) => { + const { + from: internalFrom, + to: internalTo, + swapper: internalSwapper, + } = swapperItem; + const borderColor = BorderColor[status]; + + return ( + <> + {index !== 0 && ( +
    + )} +
    + {internalSwapper?.swapperTitle} +
    + {internalSwapper?.swapperType === 'DEX' + ? `Swap on ${internalFrom?.blockchain} via ${internalSwapper?.swapperTitle}` + : `Bridge from ${internalFrom?.blockchain} to ${internalTo?.blockchain} via ${internalSwapper?.swapperTitle}`} +
    +
    + + ); + })} +
    + ); +} + +export default SwapStepSwapper; diff --git a/components/detail/SwapSteps/SwapStepValue.tsx b/components/detail/SwapSteps/SwapStepValue.tsx new file mode 100644 index 0000000..c7e655e --- /dev/null +++ b/components/detail/SwapSteps/SwapStepValue.tsx @@ -0,0 +1,67 @@ +import { SecondsTohms } from 'utils/secondsTohms'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import { SwapStepItemValueProps } from './SwapSteps.type'; + +dayjs.extend(utc); + +function SwapStepValue(props: SwapStepItemValueProps) { + const { step, column, firstStep } = props; + const { + to, + from, + estimatedTimeInSeconds, + executionTimeInSeconds, + startTime, + } = step; + + return ( +
    + {column.title === 'Output Amount' && + (isNaN(to?.realAmount) ? ( + {`Est. ~${to.expectedAmount} ${to?.symbol}`} + ) : ( + <> + {`${to.realAmount} ${to?.symbol}`} + {`(Est. ~${to.expectedAmount} ${to?.symbol})`} + + ))} + {column.title === 'Input Amount' && + (isNaN(from?.realAmount) ? ( + {`Est. ~${from.expectedAmount} ${from?.symbol}`} + ) : ( + <> + {`${from.realAmount} ${from?.symbol}`} + {!firstStep && ( + {`(Est. ~${from.expectedAmount} ${from?.symbol})`} + )} + + ))} + + {column.title === 'Step Duration' && + (executionTimeInSeconds ? ( + <> + + {SecondsTohms(executionTimeInSeconds)} + + + {`(Est. ~${SecondsTohms(estimatedTimeInSeconds)})`} + + + ) : ( + + {`Est. ~${SecondsTohms(estimatedTimeInSeconds)}`} + + ))} + + {column.title === 'Step Start Time' && ( + + {startTime && + dayjs.utc(startTime).local().format('HH:mm:ss').toString()} + + )} +
    + ); +} + +export default SwapStepValue; diff --git a/components/detail/SwapSteps/SwapSteps.helper.ts b/components/detail/SwapSteps/SwapSteps.helper.ts new file mode 100644 index 0000000..c4ae24d --- /dev/null +++ b/components/detail/SwapSteps/SwapSteps.helper.ts @@ -0,0 +1,43 @@ +import SwapStepAddress from './SwapStepAddress'; +import SwapStepValue from './SwapStepValue'; +import { ColumnType } from './SwapSteps.type'; + +export const columns: ColumnType[] = [ + { + id: 1, + title: 'Input Amount', + component: SwapStepValue, + }, + { + id: 2, + title: 'Output Amount', + component: SwapStepValue, + }, + { + id: 3, + title: 'Step Source Wallet', + component: SwapStepAddress, + }, + { + id: 4, + title: 'Step Destination Wallet', + component: SwapStepAddress, + }, + { + id: 5, + title: 'Step Start Time', + component: SwapStepValue, + }, + { + id: 6, + title: 'Step Duration', + component: SwapStepValue, + }, +]; + +export const BorderColor = { + running: 'border-running', + failed: 'border-failed', + success: 'border-success', + unknown: '', +}; diff --git a/components/detail/SwapSteps/SwapSteps.type.ts b/components/detail/SwapSteps/SwapSteps.type.ts new file mode 100644 index 0000000..9afdf3b --- /dev/null +++ b/components/detail/SwapSteps/SwapSteps.type.ts @@ -0,0 +1,45 @@ +import { AssetType, ExplorerUrlsType, StepType, SwapStatus } from 'types'; + +export interface PropsType { + steps: StepType[]; +} + +export interface SwapStepItemProps { + step: StepType; + firstStep?: boolean; + lastStep?: boolean; +} + +export interface SwapStepChainLogoProps { + token: AssetType; + firstStep?: boolean; +} + +export interface SwapStepItemExpandedProps { + step: StepType; + open: boolean; + firstStep?: boolean; +} + +export interface TransactionURLProps { + status: SwapStatus; + explorerUrls: ExplorerUrlsType[]; +} + +export interface TransactionURLItemProps { + url: string; + description: string; + transactionStatus: SwapStatus; +} + +export interface ColumnType { + id: number; + title: string; + component?: React.ComponentType; +} + +export interface SwapStepItemValueProps { + step: StepType; + column: ColumnType; + firstStep?: boolean; +} diff --git a/components/detail/SwapSteps/TransactionURL.tsx b/components/detail/SwapSteps/TransactionURL.tsx new file mode 100644 index 0000000..d115652 --- /dev/null +++ b/components/detail/SwapSteps/TransactionURL.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import IconStatus from 'components/common/IconStatus'; +import { TransactionURLProps } from './SwapSteps.type'; +import { SwapStatus } from 'types'; +import ButtonCopyIcon from 'components/common/ButtonCopyIcon'; +import { LinkIcon } from 'components/icons'; +import TransactionURLMobileItem from './TransactionURLMobileItem'; + +function TransactionURL(props: TransactionURLProps) { + const { explorerUrls, status } = props; + const handleLink = (value: string) => { + if (value) window.open(value, '_blank'); + }; + + return ( + <> + {explorerUrls.map((exploreItem, index) => { + const { description, url } = exploreItem; + const transactionStatus: SwapStatus = + index === explorerUrls.length - 1 ? status : 'success'; + return ( + <> + +
    +
    + + + {description || 'Swap transaction'} + +
    +
    + + +
    +
    + + ); + })} + + ); +} + +export default TransactionURL; diff --git a/components/detail/SwapSteps/TransactionURLMobileItem.tsx b/components/detail/SwapSteps/TransactionURLMobileItem.tsx new file mode 100644 index 0000000..d745592 --- /dev/null +++ b/components/detail/SwapSteps/TransactionURLMobileItem.tsx @@ -0,0 +1,96 @@ +import React, { useEffect, useRef, useState } from 'react'; +import IconStatus from 'components/common/IconStatus'; +import { TransactionURLItemProps } from './SwapSteps.type'; +import { CopyIcon, InfoIcon, LinkIcon, MoreIcon } from 'components/icons'; +import { CopyText } from 'utils/copyText'; + +function TransactionURLMobileItem(props: TransactionURLItemProps) { + const { description, url, transactionStatus } = props; + const [open, setOpen] = useState(false); + const ref = useRef(null); + + const handleCopy = ( + e: React.MouseEvent, + text: string, + ) => { + e.stopPropagation(); + if (text) { + CopyText(text); + setOpen(false); + } + }; + + const handleLink = ( + e: React.MouseEvent, + value: string, + ) => { + if (e) e.stopPropagation(); + setOpen(false); + if (value) window.open(value, '_blank'); + }; + + const handleOpen = (e: React.MouseEvent) => { + if (e) e.stopPropagation(); + setOpen(open ? false : true); + }; + + useEffect(() => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function handleClickOutside(event: any) { + if (ref?.current && !ref.current.contains(event.target)) { + setOpen(false); + } + } + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [ref]); + + return ( +
    +
    + + + {description || 'Swap transaction'} + +
    +
    + + {open && ( +
    + + + +
    + )} +
    +
    + ); +} + +export default TransactionURLMobileItem; diff --git a/components/detail/SwapSteps/index.tsx b/components/detail/SwapSteps/index.tsx new file mode 100644 index 0000000..744f6c3 --- /dev/null +++ b/components/detail/SwapSteps/index.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { PropsType } from './SwapSteps.type'; +import SwapStepItem from './SwapStepItem'; +import { StepType } from 'types'; + +function SwapSteps(props: PropsType) { + const { steps } = props; + return ( +
    +

    + Swap Steps +

    +
    + {steps.map((step: StepType, key: number) => ( + + ))} +
    +
    + ); +} + +export default SwapSteps; diff --git a/components/home/ChartBox/Chart.helper.ts b/components/home/ChartBox/Chart.helper.ts new file mode 100644 index 0000000..43d5aa8 --- /dev/null +++ b/components/home/ChartBox/Chart.helper.ts @@ -0,0 +1,43 @@ +import { buildChartTheme } from '@visx/xychart'; +import { DaysFilter } from './Chart.type'; + +export const daysFilter: DaysFilter[] = [ + { days: 7, hasPrevious: true, name: 'Week' }, + { days: 30, hasPrevious: true, name: 'Month' }, + { days: 90, hasPrevious: false, name: 'Season' }, +]; + +export const monthsShort = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', +]; + +export function getDayOfMonth(dateString: string) { + const date = new Date(dateString); + const monthName = date.toLocaleDateString('en-US', { month: 'short' }); + const dayNumber = date.getDate(); + + return `${dayNumber} ${monthName}`; +} + +export function getRoundedCount(count: number) { + return Math.ceil(count / 1000) * 1000; +} + +export const customTheme = buildChartTheme({ + backgroundColor: '#fff', + colors: ['#469BF5'], + gridColor: '#469BF5', + tickLength: 8, + gridColorDark: '', +}); diff --git a/components/home/ChartBox/Chart.tsx b/components/home/ChartBox/Chart.tsx new file mode 100644 index 0000000..c2d939e --- /dev/null +++ b/components/home/ChartBox/Chart.tsx @@ -0,0 +1,117 @@ +import { curveCardinal } from '@visx/curve'; +import { + AnimatedAxis, + AnimatedGrid, + AnimatedLineSeries, + XYChart, + Tooltip, +} from '@visx/xychart'; +import { customTheme, daysFilter, getDayOfMonth } from './Chart.helper'; +import { CustomTick } from './CustomTick'; +import { ChartProps } from './Chart.type'; +import isMobile from 'is-mobile'; + +const Chart = (props: ChartProps) => { + const IsMobile = isMobile({ tablet: true }); + const { data, days } = props; + const currentFilter = daysFilter.find((item) => item.days === days); + const currentPeriod = currentFilter?.hasPrevious + ? data.slice(days * -1).map((item) => ({ ...item })) + : null; + const prevPeriod = currentFilter?.hasPrevious + ? data.slice(days * -2, days * -1).map((item) => ({ ...item })) + : null; + + // Update the date property of each item in prevWeek with the corresponding item from deepCopyCurrentWeek + if (prevPeriod && currentPeriod) + prevPeriod.forEach((item, index) => { + prevPeriod[index].date = currentPeriod[index]?.date; + }); + + return ( +
    + + ( + + )} + orientation="bottom" + hideTicks + numTicks={IsMobile ? 3 : 7} + tickFormat={(d) => getDayOfMonth(d)} + /> + } + /> + + + {days === 90 && ( + d.date} + yAccessor={(d) => d.count} + /> + )} + + {days !== 90 && currentPeriod && prevPeriod && ( + <> + d.date} + yAccessor={(d) => d.count} + /> + d.date} + yAccessor={(d) => d.count} + /> + + )} + + ( +
    + {tooltipData.nearestDatum.datum.count} +
    + )} + /> +
    +
    + ); +}; + +export default Chart; diff --git a/components/home/ChartBox/Chart.type.ts b/components/home/ChartBox/Chart.type.ts new file mode 100644 index 0000000..1df90f3 --- /dev/null +++ b/components/home/ChartBox/Chart.type.ts @@ -0,0 +1,25 @@ +import { DailyIntervalType } from 'types'; + +import { TickRendererProps } from '@visx/axis'; + +export interface PropsType { + data: DailyIntervalType[]; +} +export interface ChartProps { + data: DailyIntervalType[]; + days: number; +} + +export type ValidDaysFilter = 7 | 30 | 90; +export type validFilterName = 'Week' | 'Month' | 'Season'; +export interface DaysFilter { + days: ValidDaysFilter; + hasPrevious: boolean; + name: validFilterName; +} + +export type CustomTickProps = TickRendererProps & { + dxValue?: number; +}; + +export type WeekFilter = 'current' | 'prev'; diff --git a/components/home/ChartBox/CustomTick.tsx b/components/home/ChartBox/CustomTick.tsx new file mode 100644 index 0000000..6c6a30d --- /dev/null +++ b/components/home/ChartBox/CustomTick.tsx @@ -0,0 +1,18 @@ +import { CustomTickProps } from './Chart.type'; + +export function CustomTick(props: CustomTickProps) { + const { formattedValue, dxValue = 0 } = props; + + return ( + + + {formattedValue} + + + ); +} diff --git a/components/home/ChartBox/index.tsx b/components/home/ChartBox/index.tsx new file mode 100644 index 0000000..b07d433 --- /dev/null +++ b/components/home/ChartBox/index.tsx @@ -0,0 +1,64 @@ +import { PropsType, ValidDaysFilter } from './Chart.type'; +import { useState } from 'react'; +import { daysFilter } from './Chart.helper'; +import dynamic from 'next/dynamic'; + +const Chart = dynamic(() => import('components/home/ChartBox/Chart'), { + ssr: false, +}); + +function ChartBox(props: PropsType) { + const { data } = props; + const [currentDays, setCurrentDays] = useState(7); + + return ( +
    +
    +
    + {daysFilter.map((filterItem) => { + return ( + + ); + })} +
    + + {daysFilter.map((filterItem) => { + if (!filterItem.hasPrevious || filterItem.days !== currentDays) + return null; + return ( +
    +
    + + + {`Current ${filterItem.name}`} + +
    +
    + + + {`Previous ${filterItem.name}`} + +
    +
    + ); + })} +
    + +
    + ); +} + +export default ChartBox; diff --git a/components/home/Summary/Summary.type.ts b/components/home/Summary/Summary.type.ts new file mode 100644 index 0000000..d55c62d --- /dev/null +++ b/components/home/Summary/Summary.type.ts @@ -0,0 +1,10 @@ +import { SummaryType } from 'types'; + +export interface SummaryProps { + summary: SummaryType; +} + +export interface SummaryItemProps { + value: number; + title: string; +} diff --git a/components/home/Summary/SummaryItem.tsx b/components/home/Summary/SummaryItem.tsx new file mode 100644 index 0000000..7911478 --- /dev/null +++ b/components/home/Summary/SummaryItem.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { SummaryItemProps } from './Summary.type'; +import { AmountConverter } from 'utils/amountConverter'; + +function SummaryItem(props: SummaryItemProps) { + const { value, title } = props; + return ( +
    +

    {title}

    +

    + {AmountConverter(value)} +

    +
    + ); +} + +export default SummaryItem; diff --git a/components/home/Summary/index.tsx b/components/home/Summary/index.tsx new file mode 100644 index 0000000..cfea929 --- /dev/null +++ b/components/home/Summary/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { SummaryProps } from './Summary.type'; +import SummaryItem from './SummaryItem'; + +function Summary(props: SummaryProps) { + const { summary } = props; + return ( +
    + + + + + + +
    + ); +} + +export default Summary; diff --git a/components/icons/Affiliate.tsx b/components/icons/Affiliate.tsx new file mode 100644 index 0000000..24914fc --- /dev/null +++ b/components/icons/Affiliate.tsx @@ -0,0 +1,24 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgAffiliate(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + , + ); +} +export default SvgAffiliate; diff --git a/components/icons/ApiManagement.tsx b/components/icons/ApiManagement.tsx new file mode 100644 index 0000000..9de1198 --- /dev/null +++ b/components/icons/ApiManagement.tsx @@ -0,0 +1,34 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgApiManagement(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + , + ); +} +export default SvgApiManagement; diff --git a/components/icons/Check.tsx b/components/icons/Check.tsx new file mode 100644 index 0000000..29eeff7 --- /dev/null +++ b/components/icons/Check.tsx @@ -0,0 +1,18 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgCheck(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + , + ); +} +export default SvgCheck; diff --git a/components/icons/ChevronDown.tsx b/components/icons/ChevronDown.tsx new file mode 100644 index 0000000..fc7c9ff --- /dev/null +++ b/components/icons/ChevronDown.tsx @@ -0,0 +1,21 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgChevronDown(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgChevronDown; diff --git a/components/icons/ChevronRight.tsx b/components/icons/ChevronRight.tsx new file mode 100644 index 0000000..ef63a77 --- /dev/null +++ b/components/icons/ChevronRight.tsx @@ -0,0 +1,21 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgChevronRight(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgChevronRight; diff --git a/components/icons/ChevronUp.tsx b/components/icons/ChevronUp.tsx new file mode 100644 index 0000000..53265f6 --- /dev/null +++ b/components/icons/ChevronUp.tsx @@ -0,0 +1,21 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgChevronUp(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgChevronUp; diff --git a/components/icons/Close.tsx b/components/icons/Close.tsx new file mode 100644 index 0000000..bd8117b --- /dev/null +++ b/components/icons/Close.tsx @@ -0,0 +1,26 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgClose(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + , + ); +} +export default SvgClose; diff --git a/components/icons/Copy.tsx b/components/icons/Copy.tsx new file mode 100644 index 0000000..c7ba745 --- /dev/null +++ b/components/icons/Copy.tsx @@ -0,0 +1,17 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgCopy(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + , + ); +} +export default SvgCopy; diff --git a/components/icons/Discord.tsx b/components/icons/Discord.tsx new file mode 100644 index 0000000..197459f --- /dev/null +++ b/components/icons/Discord.tsx @@ -0,0 +1,17 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgDiscord(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + , + ); +} +export default SvgDiscord; diff --git a/components/icons/Docs.tsx b/components/icons/Docs.tsx new file mode 100644 index 0000000..ff423b6 --- /dev/null +++ b/components/icons/Docs.tsx @@ -0,0 +1,24 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgDocs(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + , + ); +} +export default SvgDocs; diff --git a/components/icons/Fail.tsx b/components/icons/Fail.tsx new file mode 100644 index 0000000..46abb69 --- /dev/null +++ b/components/icons/Fail.tsx @@ -0,0 +1,22 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgFail(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + , + ); +} +export default SvgFail; diff --git a/components/icons/FirstPage.tsx b/components/icons/FirstPage.tsx new file mode 100644 index 0000000..31ab52f --- /dev/null +++ b/components/icons/FirstPage.tsx @@ -0,0 +1,26 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgFirstPage(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + , + ); +} +export default SvgFirstPage; diff --git a/components/icons/Gass.tsx b/components/icons/Gass.tsx new file mode 100644 index 0000000..f9f7b1b --- /dev/null +++ b/components/icons/Gass.tsx @@ -0,0 +1,44 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgGass(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + , + ); +} +export default SvgGass; diff --git a/components/icons/Github.tsx b/components/icons/Github.tsx new file mode 100644 index 0000000..60ab407 --- /dev/null +++ b/components/icons/Github.tsx @@ -0,0 +1,17 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgGithub(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + , + ); +} +export default SvgGithub; diff --git a/components/icons/Info.tsx b/components/icons/Info.tsx new file mode 100644 index 0000000..16df0b9 --- /dev/null +++ b/components/icons/Info.tsx @@ -0,0 +1,33 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgInfo(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + , + ); +} +export default SvgInfo; diff --git a/components/icons/LastPage.tsx b/components/icons/LastPage.tsx new file mode 100644 index 0000000..0fe5a06 --- /dev/null +++ b/components/icons/LastPage.tsx @@ -0,0 +1,26 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgLastPage(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + , + ); +} +export default SvgLastPage; diff --git a/components/icons/Link.tsx b/components/icons/Link.tsx new file mode 100644 index 0000000..3f87047 --- /dev/null +++ b/components/icons/Link.tsx @@ -0,0 +1,21 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgLink(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgLink; diff --git a/components/icons/Medium.tsx b/components/icons/Medium.tsx new file mode 100644 index 0000000..9184925 --- /dev/null +++ b/components/icons/Medium.tsx @@ -0,0 +1,17 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgMedium(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + , + ); +} +export default SvgMedium; diff --git a/components/icons/More.tsx b/components/icons/More.tsx new file mode 100644 index 0000000..0638ad1 --- /dev/null +++ b/components/icons/More.tsx @@ -0,0 +1,29 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgMore(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + , + ); +} +export default SvgMore; diff --git a/components/icons/Next.tsx b/components/icons/Next.tsx new file mode 100644 index 0000000..81e5374 --- /dev/null +++ b/components/icons/Next.tsx @@ -0,0 +1,23 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgNext(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + , + ); +} +export default SvgNext; diff --git a/components/icons/NextPage.tsx b/components/icons/NextPage.tsx new file mode 100644 index 0000000..d4eff10 --- /dev/null +++ b/components/icons/NextPage.tsx @@ -0,0 +1,21 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgNextPage(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgNextPage; diff --git a/components/icons/PrevPage.tsx b/components/icons/PrevPage.tsx new file mode 100644 index 0000000..87d5a81 --- /dev/null +++ b/components/icons/PrevPage.tsx @@ -0,0 +1,21 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgPrevPage(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgPrevPage; diff --git a/components/icons/Refresh.tsx b/components/icons/Refresh.tsx new file mode 100644 index 0000000..87316f1 --- /dev/null +++ b/components/icons/Refresh.tsx @@ -0,0 +1,19 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgRefresh(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgRefresh; diff --git a/components/icons/Running.tsx b/components/icons/Running.tsx new file mode 100644 index 0000000..4b5340d --- /dev/null +++ b/components/icons/Running.tsx @@ -0,0 +1,61 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgRunning(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + , + ); +} +export default SvgRunning; diff --git a/components/icons/Search.tsx b/components/icons/Search.tsx new file mode 100644 index 0000000..295555f --- /dev/null +++ b/components/icons/Search.tsx @@ -0,0 +1,30 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgSearch(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + , + ); +} +export default SvgSearch; diff --git a/components/icons/Steps.tsx b/components/icons/Steps.tsx new file mode 100644 index 0000000..3fc76d7 --- /dev/null +++ b/components/icons/Steps.tsx @@ -0,0 +1,21 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgSteps(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgSteps; diff --git a/components/icons/Success.tsx b/components/icons/Success.tsx new file mode 100644 index 0000000..50a817d --- /dev/null +++ b/components/icons/Success.tsx @@ -0,0 +1,20 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgSuccess(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + , + ); +} +export default SvgSuccess; diff --git a/components/icons/Telegram.tsx b/components/icons/Telegram.tsx new file mode 100644 index 0000000..57e44ff --- /dev/null +++ b/components/icons/Telegram.tsx @@ -0,0 +1,17 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgTelegram(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + , + ); +} +export default SvgTelegram; diff --git a/components/icons/Twitter.tsx b/components/icons/Twitter.tsx new file mode 100644 index 0000000..dfbddab --- /dev/null +++ b/components/icons/Twitter.tsx @@ -0,0 +1,19 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgTwitter(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + , + ); +} +export default SvgTwitter; diff --git a/components/icons/Widget.tsx b/components/icons/Widget.tsx new file mode 100644 index 0000000..e398ccb --- /dev/null +++ b/components/icons/Widget.tsx @@ -0,0 +1,21 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgWidget(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + , + ); +} +export default SvgWidget; diff --git a/components/icons/Youtube.tsx b/components/icons/Youtube.tsx new file mode 100644 index 0000000..3f2c0fe --- /dev/null +++ b/components/icons/Youtube.tsx @@ -0,0 +1,17 @@ +import React, { createElement } from 'react'; +import type { SvgIconPropsWithChildren } from '../common/SvgIcon'; +import { SvgIcon } from '../common/SvgIcon'; +function SvgYoutube(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + , + ); +} +export default SvgYoutube; diff --git a/components/icons/index.ts b/components/icons/index.ts new file mode 100644 index 0000000..df24044 --- /dev/null +++ b/components/icons/index.ts @@ -0,0 +1,31 @@ +export { default as AffiliateIcon } from './Affiliate'; +export { default as ApiManagementIcon } from './ApiManagement'; +export { default as CheckIcon } from './Check'; +export { default as ChevronDownIcon } from './ChevronDown'; +export { default as ChevronRightIcon } from './ChevronRight'; +export { default as ChevronUpIcon } from './ChevronUp'; +export { default as CloseIcon } from './Close'; +export { default as CopyIcon } from './Copy'; +export { default as DiscordIcon } from './Discord'; +export { default as DocsIcon } from './Docs'; +export { default as FailIcon } from './Fail'; +export { default as FirstPageIcon } from './FirstPage'; +export { default as GassIcon } from './Gass'; +export { default as GithubIcon } from './Github'; +export { default as InfoIcon } from './Info'; +export { default as LastPageIcon } from './LastPage'; +export { default as LinkIcon } from './Link'; +export { default as MediumIcon } from './Medium'; +export { default as MoreIcon } from './More'; +export { default as NextIcon } from './Next'; +export { default as NextPageIcon } from './NextPage'; +export { default as PrevPageIcon } from './PrevPage'; +export { default as RefreshIcon } from './Refresh'; +export { default as RunningIcon } from './Running'; +export { default as SearchIcon } from './Search'; +export { default as StepsIcon } from './Steps'; +export { default as SuccessIcon } from './Success'; +export { default as TelegramIcon } from './Telegram'; +export { default as TwitterIcon } from './Twitter'; +export { default as WidgetIcon } from './Widget'; +export { default as YoutubeIcon } from './Youtube'; diff --git a/components/search/NotFound/NotFound.type.ts b/components/search/NotFound/NotFound.type.ts new file mode 100644 index 0000000..faafe05 --- /dev/null +++ b/components/search/NotFound/NotFound.type.ts @@ -0,0 +1,3 @@ +export interface PropsType { + query: string; +} diff --git a/components/search/NotFound/index.tsx b/components/search/NotFound/index.tsx new file mode 100644 index 0000000..2fc7ed6 --- /dev/null +++ b/components/search/NotFound/index.tsx @@ -0,0 +1,32 @@ +import NotFoundImage from 'public/img/notFound.svg'; +import Image from 'next/image'; +import { PropsType } from './NotFound.type'; +import Link from 'next/link'; + +function NotFound(props: PropsType) { + const { query } = props; + return ( +
    + Not Found +
    + Oops! We couldn't find what you are looking for +
    +
    + {`The search string you entered was: ${query || ''}`} +
    +
    + This is an invalid search string. +
    + + Back To Home + +
    + ); +} +export default NotFound; diff --git a/components/search/Pagination/Pagination.type.ts b/components/search/Pagination/Pagination.type.ts new file mode 100644 index 0000000..9c15428 --- /dev/null +++ b/components/search/Pagination/Pagination.type.ts @@ -0,0 +1,5 @@ +export interface PropsType { + query: string; + total: number; + page: number; +} diff --git a/components/search/Pagination/index.tsx b/components/search/Pagination/index.tsx new file mode 100644 index 0000000..bd24a2c --- /dev/null +++ b/components/search/Pagination/index.tsx @@ -0,0 +1,71 @@ +import { SEARCH_RESULT_OFFSET as offsetPage } from 'constant'; +import { PropsType } from './Pagination.type'; +import { + FirstPageIcon, + LastPageIcon, + NextPageIcon, + PrevPageIcon, +} from 'components/icons'; +import Link from 'next/link'; + +function Pagination(props: PropsType) { + const { page, total, query } = props; + const totalPage = Math.ceil(total / offsetPage); + + return ( +
    + {page > 0 && totalPage > 1 ? ( + <> + + + + + + + + ) : ( + <> + + + + )} +
    {`Page ${ + page + 1 + } of ${totalPage}`}
    + + {page + 1 < totalPage && totalPage > 1 ? ( + <> + + + + + + + + ) : ( + <> + + + + )} +
    + ); +} + +export default Pagination; diff --git a/components/search/Result/Result.type.ts b/components/search/Result/Result.type.ts new file mode 100644 index 0000000..561529b --- /dev/null +++ b/components/search/Result/Result.type.ts @@ -0,0 +1,8 @@ +import { SwapType } from 'types'; + +export interface PropsType { + data: SwapType[]; + query: string; + total: number; + page: number; +} diff --git a/components/search/Result/index.tsx b/components/search/Result/index.tsx new file mode 100644 index 0000000..b5ca139 --- /dev/null +++ b/components/search/Result/index.tsx @@ -0,0 +1,29 @@ +import { PropsType } from './Result.type'; +import Pagination from '../Pagination'; +import Table from 'components/common/Table'; + +function Result(props: PropsType) { + const { data, query, total, page } = props; + return ( +
    +
    +
    +

    + Search Results +

    +

    + {`Found ${total} Rango swaps for this wallet address`} +

    +
    +
    + + +
    + +
    + + + ); +} + +export default Result; diff --git a/constant/index.ts b/constant/index.ts index cb7d77c..e073e3e 100644 --- a/constant/index.ts +++ b/constant/index.ts @@ -1,14 +1,17 @@ export const MATCH_TYPE = { ADDRESS: 'ADDRESS', - REQUESTID: 'REQUESTID' -} + REQUESTID: 'REQUESTID', +}; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const STATUS: any = { success: 'success', failed: 'failed', running: 'running', unknown: 'Pending', - null: 'Pending' -} + null: 'Pending', +}; -export const API_URL = process.env.NEXT_PUBLIC_BASE_URL +export const SEARCH_RESULT_OFFSET = 14; + +export const API_URL = process.env.NEXT_PUBLIC_BASE_URL; diff --git a/next.config.js b/next.config.js index ae88795..3d3bc99 100644 --- a/next.config.js +++ b/next.config.js @@ -2,6 +2,6 @@ const nextConfig = { reactStrictMode: true, swcMinify: true, -} +}; -module.exports = nextConfig +module.exports = nextConfig; diff --git a/package.json b/package.json index 710d0e6..e3b6d4a 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,16 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint", - "prepare": "husky install" + "lint": "eslint --fix --quiet .", + "prettier": "prettier --write", + "prepare": "husky install", + "build:icons": "svgr svgs/resources/ --config-file svgs/configs/.svgrrc.default.cjs && prettier -w ./components/icons" }, "dependencies": { + "@artsy/fresnel": "^7.1.3", "@react-spring/web": "^9.5.5", + "@svgr/babel-plugin-remove-jsx-attribute": "^8.0.0", + "@svgr/cli": "^8.1.0", "@visx/curve": "^2.1.0", "@visx/xychart": "^2.16.0", "dayjs": "^1.11.6", @@ -26,20 +31,28 @@ }, "devDependencies": { "@next/eslint-plugin-next": "^13.0.7", + "@tailwindcss/aspect-ratio": "^0.4.2", "@types/node": "18.11.9", "@types/react": "18.2.33", "@types/react-dom": "18.2.14", - "@typescript-eslint/eslint-plugin": "^5.43.0", + "@typescript-eslint/eslint-plugin": "^6.13.1", + "@typescript-eslint/parser": "^6.13.1", "autoprefixer": "^10.4.13", - "eslint": "^8.28.0", + "eslint": "^8.55.0", + "eslint-config-prettier": "^9.0.0", "eslint-config-standard-with-typescript": "^23.0.0", - "eslint-plugin-import": "^2.26.0", + "eslint-plugin-destructuring": "^2.2.1", + "eslint-plugin-import": "^2.29.0", "eslint-plugin-n": "^15.5.1", + "eslint-plugin-prettier": "^5.0.1", "eslint-plugin-promise": "^6.1.1", - "eslint-plugin-react": "^7.31.11", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", "husky": "^8.0.0", + "lint-staged": "^15.2.0", "postcss": "^8.4.19", + "prettier": "^3.1.0", "tailwindcss": "^3.2.4", - "typescript": "^4.9.3" + "typescript": "^5.3.2" } } diff --git a/pages/404.tsx b/pages/404.tsx index 847a2f5..b10d537 100644 --- a/pages/404.tsx +++ b/pages/404.tsx @@ -1,33 +1,38 @@ -import Layout from '../components/Layout' -import NotFoundAnything from '../components/NotFoundAnything' -import type { NextPage } from 'next' -import { useRouter } from 'next/router' -import copy from '../public/img/copy.svg' -import { CopyText } from '../utils/copyText' -import Image from 'next/image' +import Navbar from 'components/common/Navbar'; +import Image from 'next/image'; +import Link from 'next/link'; +import notFound404 from 'public/img/404.svg'; +import notFoundImage from 'public/img/notFound.png'; -const NotFound: NextPage = () => { - const router = useRouter() - const { query }: { query?: string } = router.query +function NotFoundPage() { return ( - - {query != null && ( -
    - search results: {query} - +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + Page Not Found +
    +
    + There is no page with this URL! +
    + + Back To Home +
    - )} - - - ) +
    +
    + ); } -export default NotFound +export default NotFoundPage; diff --git a/pages/_app.tsx b/pages/_app.tsx index a58e512..6804da8 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,22 +1,17 @@ -import '../styles/globals.scss' -import type { AppProps } from 'next/app' -import NextNProgress from 'nextjs-progressbar' -import { ReactNode } from 'react' -import 'react-toastify/dist/ReactToastify.css' -import { ToastContainer } from 'react-toastify' +import '../styles/globals.css'; +import type { AppProps } from 'next/app'; +import NextNProgress from 'nextjs-progressbar'; +import { ReactNode } from 'react'; +import 'react-toastify/dist/ReactToastify.css'; +import { ToastContainer } from 'react-toastify'; -export default function App ({ Component, pageProps }: AppProps): ReactNode { +export default function App({ Component, pageProps }: AppProps): ReactNode { return ( <> - + - - ) + ); } diff --git a/pages/_document.tsx b/pages/_document.tsx index 589457e..cc25984 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -1,16 +1,22 @@ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type /* eslint-disable @typescript-eslint/explicit-function-return-type */ -import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document' +import Document, { + Html, + Head, + Main, + NextScript, + DocumentContext, +} from 'next/document'; const description = - 'Multi-chain DEX aggregator, binance bridge, 1inch, Thorchain, Terra Bridge, Terra Swap, crypto API under a unified UX' + 'Multi-chain DEX aggregator, binance bridge, 1inch, Thorchain, Terra Bridge, Terra Swap, crypto API under a unified UX'; class MyDocument extends Document { - static async getInitialProps (ctx: DocumentContext) { - const initialProps = await Document.getInitialProps(ctx) - return { ...initialProps } + static async getInitialProps(ctx: DocumentContext) { + const initialProps = await Document.getInitialProps(ctx); + return { ...initialProps }; } - render () { + render() { return ( @@ -27,8 +33,8 @@ class MyDocument extends Document { - ) + ); } } -export default MyDocument +export default MyDocument; diff --git a/pages/index.tsx b/pages/index.tsx index c94b962..daeca4d 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,87 +1,98 @@ -import ChartBox from '../components/ChartBox' -import { makeColumns } from '../components/MakeColumns' -import Navbar from '../components/Navbar' -import SearchBox from '../components/SearchBox' -import Table from '../components/Table' -import { GetServerSideProps, NextPage } from 'next' -import Head from 'next/head' -import { useRouter } from 'next/router' -import { useCallback, useEffect, useState } from 'react' -import { getLastSwaps, getSummary } from '../services' -import { SummaryType, SwapType } from '../types' -import Error from 'next/error' +import { GetServerSideProps } from 'next'; +import { useEffect, useState } from 'react'; +import { getLastSwaps, getSummary } from '../services'; +import { SummaryType, SwapType } from '../types'; +import Error from 'next/error'; +import ChartBox from 'components/home/ChartBox'; +import Layout from 'components/common/Layout'; +import SearchBox from 'components/common/SearchBox'; +import Summary from 'components/home/Summary'; +import { RefreshIcon } from 'components/icons'; +import Table from 'components/common/Table'; interface PropsType { - swaps: SwapType[] - summary: SummaryType - status: number + swaps: SwapType[]; + summary: SummaryType; + status: number; } -const Home: NextPage = ({ swaps, summary, status }: PropsType) => { - const [lastSwaps, setLastSwaps] = useState([]) - const [second, setSecond] = useState(30) - - const router = useRouter() +function Home(props: PropsType) { + const { swaps, summary, status } = props; + const [lastSwaps, setLastSwaps] = useState([]); + const [second, setSecond] = useState(30); useEffect(() => { const interval = setInterval(async () => { - let sec = second - 1 + let sec = second - 1; if (sec === 0) { - const swaps = await getLastSwaps() - console.log(swaps) - if (Array.isArray(swaps)) setLastSwaps(swaps) - sec = 30 + const swaps = await getLastSwaps(); + if (Array.isArray(swaps)) setLastSwaps(swaps); + sec = 30; } - setSecond(sec) - }, 1000) - - return () => clearInterval(interval) - }, [second]) - useEffect(() => setLastSwaps(swaps), []) + setSecond(sec); + }, 1000); - const handleSwapDetails = useCallback((id: string) => { - router.push(`/swap/${id}`) - }, []) + return () => clearInterval(interval); + }, [second]); + useEffect(() => setLastSwaps(swaps), []); return status ? ( ) : ( -
    - - Rango Scanner - - -
    - -
    -
    - -
    -
    -

    Recent Swaps

    -
    - 00 : {second < 10 ? `0${second}` : second} + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +

    + Recent Swaps +

    +

    + Latest 25 swaps on Rango +

    +
    +
    + + + Refresh in {second} seconds +
    -
    +
    +
    + - - - ) + + + ); } export const getServerSideProps: GetServerSideProps = async () => { - const swaps = await getLastSwaps() - const summary = await getSummary() + const swaps = await getLastSwaps(); + const summary = await getSummary(); return { props: { swaps, summary, - status: swaps?.error || summary?.error ? swaps?.status || summary?.status : 0 - } - } -} + status: + swaps?.error || summary?.error ? swaps?.status || summary?.status : 0, + }, + }; +}; -export default Home +export default Home; diff --git a/pages/search.tsx b/pages/search.tsx index 78324a4..fd4f2bb 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -1,77 +1,73 @@ -/* eslint-disable @typescript-eslint/prefer-optional-chain */ -import { makeColumns } from '../components/MakeColumns' -import Layout from '../components/Layout' -import Table from '../components/Table' -import { GetServerSideProps, NextPage } from 'next' -import { useRouter } from 'next/router' -import { useCallback } from 'react' -import { getSearchResult, getWalletSwaps } from '../services' -import { MATCH_TYPE } from '../constant' -import NotFoundAnything from '../components/NotFoundAnything' -import Loading from '../components/Loading' -import useSWR from 'swr' -import Error from 'next/error' -import Image from 'next/image' -import copy from '../public/img/copy.svg' -import { CopyText } from '../utils/copyText' +import { GetServerSideProps } from 'next'; +import { useRouter } from 'next/router'; +import { getSearchResult, getWalletSwaps } from '../services'; +import { MATCH_TYPE } from '../constant'; +import useSWR from 'swr'; +import Error from 'next/error'; +import Layout from 'components/common/Layout'; +import Loading from 'components/common/Loading'; +import SearchBox from 'components/common/SearchBox'; +import Result from 'components/search/Result'; +import NotFound from 'components/search/NotFound'; + interface PropsType { - status?: number + status?: number; } -const Home: NextPage = ({ status }: PropsType) => { - const router = useRouter() - const { query } = router.query - const { data } = useSWR(query, getWalletSwaps) - - const handleSwapDetails = useCallback((id: string) => { - router.push(`/swap/${id}`) - }, []) +function Search(props: PropsType) { + const { status } = props; + const router = useRouter(); + const { query, page } = router.query; + const { data } = useSWR([query, page], getWalletSwaps); + const { transactions, total } = data || {}; return status || (data && data.error && data.status) ? ( ) : ( - -
    - search results: {query} - -
    - - {!data ? ( -
    - + +
    +
    + +
    +
    + {data && ( + <> + {transactions && transactions.length ? ( + + ) : ( + + )} + + )} + {!data && ( +
    + +
    + )}
    - ) : !data.transactions.length ? ( - - ) : ( -
    - )} + - ) + ); } export const getServerSideProps: GetServerSideProps = async (context) => { - const query = context.query.query - - const result = await getSearchResult(query as string) - if (result?.error) return { props: { status: result.status } } - if (!result.length) return { notFound: true } - if (result[0].matchType === MATCH_TYPE.REQUESTID) { + const { query } = context?.query || {}; + const result = await getSearchResult(query as string); + if (result?.error) return { props: { status: result.status } }; + if (result?.length && result[0].matchType === MATCH_TYPE.REQUESTID) { return { redirect: { permanent: false, - destination: `/swap/${query as string}` - } - } + destination: `/swap/${query as string}`, + }, + }; } return { - props: {} - } -} -export default Home + props: {}, + }; +}; +export default Search; diff --git a/pages/swap/[id]/index.tsx b/pages/swap/[id]/index.tsx index ea7da61..3028ffa 100644 --- a/pages/swap/[id]/index.tsx +++ b/pages/swap/[id]/index.tsx @@ -1,61 +1,65 @@ -import Layout from '../../../components/Layout' -import TxDetails from '../../../components/TxDetails' -import TxSteps from '../../../components/TxSteps' -import { GetServerSideProps, NextPage } from 'next' -import { useRouter } from 'next/router' -import { getTxDetails } from '../../../services' -import { DetailsType } from '../../../types' -import Error from 'next/error' -import Image from 'next/image' -import copy from '../../../public/img/copy.svg' -import { CopyText } from '../../../utils/copyText' +import { GetServerSideProps } from 'next'; +import { useRouter } from 'next/router'; +import Error from 'next/error'; +import Link from 'next/link'; +import { DetailsType } from 'types'; +import Layout from 'components/common/Layout'; +import SearchBox from 'components/common/SearchBox'; +import { getTxDetails } from 'services'; +import { ChevronRightIcon } from 'components/icons'; +import SwapDetailSummary from 'components/detail/SwapDetailSummary'; +import SwapSteps from 'components/detail/SwapSteps'; interface PropsType { - details: DetailsType - status: number + details: DetailsType; + status: number; } -const SwapDetails: NextPage = ({ details, status }: PropsType) => { - const router = useRouter() - const id = router.query.id as string +function SwapDetails(props: PropsType) { + const { details, status } = props; + const router = useRouter(); + const id = router.query.id as string; return status ? ( ) : ( - -

    - Swap From {details.from.symbol} (On{' '} - {details.from.blockchain}) to {details.to.symbol} (On{' '} - {details.to.blockchain}) -

    -
    - Request ID: {id}{' '} - -
    -
    - + +
    +
    + +
    +
    +
    +
    + + Home + + + + Swap Details + +
    + + + +
    +
    -
    - ) + ); } -export const getServerSideProps: GetServerSideProps = async ({ query }) => { - const { id } = query - const details = await getTxDetails(id as string) +export const getServerSideProps: GetServerSideProps = async ({ + query, +}) => { + const { id } = query; + const details = await getTxDetails(id as string); + return { props: { details, - status: details?.error ? details?.status : 0 - } - } -} -export default SwapDetails + status: details?.error ? details?.status : 0, + }, + }; +}; +export default SwapDetails; diff --git a/postcss.config.js b/postcss.config.js index 33ad091..12a703d 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -3,4 +3,4 @@ module.exports = { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/public/favicon copy.png b/public/favicon copy.png new file mode 100644 index 0000000..25cf040 Binary files /dev/null and b/public/favicon copy.png differ diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..f62b812 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/fonts/Roboto-Black.ttf b/public/fonts/Roboto-Black.ttf new file mode 100644 index 0000000..0112e7d Binary files /dev/null and b/public/fonts/Roboto-Black.ttf differ diff --git a/public/fonts/Roboto-BlackItalic.ttf b/public/fonts/Roboto-BlackItalic.ttf new file mode 100644 index 0000000..b2c6aca Binary files /dev/null and b/public/fonts/Roboto-BlackItalic.ttf differ diff --git a/public/fonts/Roboto-Bold.ttf b/public/fonts/Roboto-Bold.ttf new file mode 100644 index 0000000..43da14d Binary files /dev/null and b/public/fonts/Roboto-Bold.ttf differ diff --git a/public/fonts/Roboto-BoldItalic.ttf b/public/fonts/Roboto-BoldItalic.ttf new file mode 100644 index 0000000..bcfdab4 Binary files /dev/null and b/public/fonts/Roboto-BoldItalic.ttf differ diff --git a/public/fonts/Roboto-Italic.ttf b/public/fonts/Roboto-Italic.ttf new file mode 100644 index 0000000..1b5eaa3 Binary files /dev/null and b/public/fonts/Roboto-Italic.ttf differ diff --git a/public/fonts/Roboto-Light.ttf b/public/fonts/Roboto-Light.ttf new file mode 100644 index 0000000..e7307e7 Binary files /dev/null and b/public/fonts/Roboto-Light.ttf differ diff --git a/public/fonts/Roboto-LightItalic.ttf b/public/fonts/Roboto-LightItalic.ttf new file mode 100644 index 0000000..2d277af Binary files /dev/null and b/public/fonts/Roboto-LightItalic.ttf differ diff --git a/public/fonts/Roboto-Medium.ttf b/public/fonts/Roboto-Medium.ttf new file mode 100644 index 0000000..ac0f908 Binary files /dev/null and b/public/fonts/Roboto-Medium.ttf differ diff --git a/public/fonts/Roboto-MediumItalic.ttf b/public/fonts/Roboto-MediumItalic.ttf new file mode 100644 index 0000000..fc36a47 Binary files /dev/null and b/public/fonts/Roboto-MediumItalic.ttf differ diff --git a/public/fonts/Roboto-Regular.ttf b/public/fonts/Roboto-Regular.ttf new file mode 100644 index 0000000..ddf4bfa Binary files /dev/null and b/public/fonts/Roboto-Regular.ttf differ diff --git a/public/fonts/Roboto-Thin.ttf b/public/fonts/Roboto-Thin.ttf new file mode 100644 index 0000000..2e0dee6 Binary files /dev/null and b/public/fonts/Roboto-Thin.ttf differ diff --git a/public/fonts/Roboto-ThinItalic.ttf b/public/fonts/Roboto-ThinItalic.ttf new file mode 100644 index 0000000..084f9c0 Binary files /dev/null and b/public/fonts/Roboto-ThinItalic.ttf differ diff --git a/public/img/404.svg b/public/img/404.svg new file mode 100644 index 0000000..d97db53 --- /dev/null +++ b/public/img/404.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/img/backgrounds/footer.svg b/public/img/backgrounds/footer.svg new file mode 100644 index 0000000..8b8ad38 --- /dev/null +++ b/public/img/backgrounds/footer.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/img/backgrounds/mask.svg b/public/img/backgrounds/mask.svg new file mode 100644 index 0000000..d7f3e49 --- /dev/null +++ b/public/img/backgrounds/mask.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/img/backgrounds/mask2.png b/public/img/backgrounds/mask2.png new file mode 100644 index 0000000..a6697e1 Binary files /dev/null and b/public/img/backgrounds/mask2.png differ diff --git a/public/img/notFound.png b/public/img/notFound.png new file mode 100644 index 0000000..21622e6 Binary files /dev/null and b/public/img/notFound.png differ diff --git a/public/img/notFound.svg b/public/img/notFound.svg new file mode 100644 index 0000000..09c2fe3 --- /dev/null +++ b/public/img/notFound.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/logo-with-text.svg b/public/logo-with-text.svg new file mode 100644 index 0000000..905c9a5 --- /dev/null +++ b/public/logo-with-text.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..5d699d2 Binary files /dev/null and b/public/logo.png differ diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..e75495f --- /dev/null +++ b/public/logo.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/index.ts b/services/index.ts index 9157d04..39543a0 100644 --- a/services/index.ts +++ b/services/index.ts @@ -1,46 +1,52 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/restrict-template-expressions */ -import { API_URL } from '../constant' +import { API_URL, SEARCH_RESULT_OFFSET } from '../constant'; export const getLastSwaps = async () => - await fetch(`${API_URL}/tx/latest?count=20&apiKey=${process.env.NEXT_PUBLIC_API_KEY}`) + await fetch( + `${API_URL}/tx/latest?count=20&apiKey=${process.env.NEXT_PUBLIC_API_KEY}`, + ) .then(async (res) => await res.json()) .then((data) => data?.transactions || data) .catch((error) => { - console.error('There was an error!', error) - return error - }) + console.error('There was an error!', error); + return error; + }); export const getSummary = async () => await fetch(`${API_URL}/summary?apiKey=${process.env.NEXT_PUBLIC_API_KEY}`) .then(async (res) => await res.json()) .then((data) => data) .catch((error) => { - console.error('There was an error!', error) - return error - }) + console.error('There was an error!', error); + return error; + }); export const getSearchResult = async (query: string) => - await fetch(`${API_URL}/tx/search?query=${query}&apiKey=${process.env.NEXT_PUBLIC_API_KEY}`) + await fetch( + `${API_URL}/tx/search?query=${query}&apiKey=${process.env.NEXT_PUBLIC_API_KEY}`, + ) .then(async (res) => await res.json()) .then((data) => data?.searchResult || data) .catch((error) => { - console.error('There was an error!', error) - return [] - }) + console.error('There was an error!', error); + return []; + }); -export const getWalletSwaps = async (address: string) => +export const getWalletSwaps = async (address: string, page?: number) => await fetch( - `${API_URL}/tx/wallet?walletAddress=${address}&count=10&apiKey=${process.env.NEXT_PUBLIC_API_KEY}` - ).then(async (res) => await res.json()) + `${API_URL}/tx/wallet?walletAddress=${address}&offset=${SEARCH_RESULT_OFFSET}&page=${ + page || 0 + }&apiKey=${process.env.NEXT_PUBLIC_API_KEY}`, + ).then(async (res) => await res.json()); export const getTxDetails = async (requestId: string) => await fetch( - `${API_URL}/tx/detail?requestId=${requestId}&count=10&apiKey=${process.env.NEXT_PUBLIC_API_KEY}` + `${API_URL}/tx/detail?requestId=${requestId}&count=10&apiKey=${process.env.NEXT_PUBLIC_API_KEY}`, ) .then(async (res) => await res.json()) .then((data) => data?.detailedTransaction || data) .catch((error) => { - console.error('There was an error!', error) - return error - }) + console.error('There was an error!', error); + return error; + }); diff --git a/styles/globals.css b/styles/globals.css new file mode 100644 index 0000000..2e481db --- /dev/null +++ b/styles/globals.css @@ -0,0 +1,229 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: normal; + font-display: swap; + src: + local('Roboto Regular'), + url('/fonts/Roboto-Regular.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: normal; + font-display: swap; + src: + local('Roboto Italic'), + url('/fonts/Roboto-Italic.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 100; + font-display: swap; + src: + local('Roboto Thin'), + url('/fonts/Roboto-Thin.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 100; + font-display: swap; + src: + local('Roboto Thin Italic'), + url('/fonts/Roboto-ThinItalic.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: + local('Roboto Light'), + url('/fonts/Roboto-Light.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 300; + font-display: swap; + src: + local('Roboto Light Italic'), + url('/fonts/Roboto-LightItalic.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: + local('Roboto Light'), + url('/fonts/Roboto-Regular.ttf') format('truetype'); + } + + + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: + local('Roboto Bold'), + url('/fonts/Roboto-Medium.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 500; + font-display: swap; + src: + local('Roboto Bold Italic'), + url('/fonts/Roboto-MediumItalic.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: + local('Roboto Bold'), + url('/fonts/Roboto-Bold.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 600; + font-display: swap; + src: + local('Roboto Bold Italic'), + url('/fonts/Roboto-BoldItalic.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: bold; + font-display: swap; + src: + local('Roboto Bold'), + url('/fonts/Roboto-Bold.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: bold; + font-display: swap; + src: + local('Roboto Bold Italic'), + url('/fonts/Roboto-BoldItalic.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 1000; + font-display: swap; + src: + local('Roboto Black'), + url('/fonts/Roboto-Black.ttf') format('truetype'); + } + + @font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 1000; + font-display: swap; + src: + local('Roboto Black Italic'), + url('/fonts/Roboto-BlackItalic.ttf') format('truetype'); + } +} + +html, +body, +#__next { + height: 100%; +} + +span.ripple { + position: absolute; + border-radius: 50%; + transform: scale(0); + animation: ripple 600ms linear; + background-color: rgba(255, 255, 255, 0.7); +} +@keyframes ripple { + to { + transform: scale(4); + opacity: 0; + } +} + +.animate-modal { + transition-timing-function: cubic-bezier(10, 2, 3, 1); + transform: translateY(50rem); + transition: 0.5s; +} + +.animate-mount-modal { + transform: translateY(0rem); +} + +.animate-menu { + transition-timing-function: cubic-bezier(10, 2, 3, 1); + transform: translateX(50rem); + transition: 0.5s; +} + +.animate-mount-menu { + transform: translateX(0rem); +} + +.slick-slide > div { + margin: 0 3%; +} +.slick-list { + margin: 0 -3%; +} + +* { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.text-3d { + text-shadow: + 1px 1px 1px #dea873, + 1px 2px 1px #dea873, + 1px 3px 1px #ba7331; +} + +.bg-orange-1 { + background: #ff9600; +} + +.mask-2 { + -webkit-background-size: 100% 100%; +} + +@-moz-document url-prefix() { + .mask-2 { + background-size: 100% 100%; + } +} diff --git a/styles/globals.scss b/styles/globals.scss deleted file mode 100644 index fd42b07..0000000 --- a/styles/globals.scss +++ /dev/null @@ -1,51 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -html, -body { - padding: 0; - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, - Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; - background-color: #ecf3f4; - color: black; - -} - -a { - color: inherit; - text-decoration: none; -} - -* { - box-sizing: border-box; -} - -.visx-axis-tick{ - text{ - font-size: 12px !important; - font-weight: 600; - } -} -.text-failed { - @apply text-error; -} -.text-running, -.text-unknown { - @apply text-warning; -} -.border-failed { - @apply border-error; -} -.border-running, -.border-unknown { - @apply border-warning; -} -.bg-failed { - @apply bg-error; -} -.bg-running, -.bg-unknown { - @apply bg-warning; -} diff --git a/svgs/configs/.svgrrc.default.cjs b/svgs/configs/.svgrrc.default.cjs new file mode 100755 index 0000000..5cce45c --- /dev/null +++ b/svgs/configs/.svgrrc.default.cjs @@ -0,0 +1,33 @@ +module.exports = { + jsx: { + babelConfig: { + plugins: [ + [ + '@svgr/babel-plugin-remove-jsx-attribute', + { + elements: ['svg'], + attributes: ['id', 'width', 'height', 'class', 'title', 'fill'], + }, + ], + ], + }, + }, + icon: false, + plugins: ['@svgr/plugin-jsx', '@svgr/plugin-prettier'], + typescript: true, + outDir: 'components/icons', + expandProps: false, + prettier: true, + filenameCase: 'pascal', + jsxRuntime: 'automatic', + replaceAttrValues: { + '#373737': 'currentColor', + '#010101': 'currentColor', + '#469BF5': 'currentColor', + '#727272': 'currentColor', + '#B8B8B8': 'currentColor', + '#A2A2A2': 'currentColor', + }, + template: require('./template/react.cjs'), + indexTemplate: require('./template/index.cjs'), +}; diff --git a/svgs/configs/template/index.cjs b/svgs/configs/template/index.cjs new file mode 100644 index 0000000..4e67544 --- /dev/null +++ b/svgs/configs/template/index.cjs @@ -0,0 +1,12 @@ +const path = require('path'); + +function defaultIndexTemplate(filePaths) { + const exportEntries = filePaths.map(({ path: filePath }) => { + const basename = path.basename(filePath, path.extname(filePath)); + const exportName = /^\d/.test(basename) ? `Svg${basename}` : basename; + return `export { default as ${exportName}Icon } from './${basename}'`; + }); + return exportEntries.join('\n'); +} + +module.exports = defaultIndexTemplate; diff --git a/svgs/configs/template/react.cjs b/svgs/configs/template/react.cjs new file mode 100644 index 0000000..6a654a4 --- /dev/null +++ b/svgs/configs/template/react.cjs @@ -0,0 +1,19 @@ +const template = (variables, options) => { + return options.tpl` + import React, {createElement} from 'react'; + import type {SvgIconPropsWithChildren} from '../common/SvgIcon'; + import {SvgIcon} from '../common/SvgIcon'; + + ${variables.imports}; + + ${variables.interfaces}; + + function ${variables.componentName}(props: SvgIconPropsWithChildren){ + return createElement(SvgIcon, props, ${variables.jsx}) + } + + ${variables.exports}; + `; +}; + +module.exports = template; diff --git a/svgs/resources/affiliate.svg b/svgs/resources/affiliate.svg new file mode 100644 index 0000000..1fea91b --- /dev/null +++ b/svgs/resources/affiliate.svg @@ -0,0 +1,4 @@ + + + + diff --git a/svgs/resources/apiManagement.svg b/svgs/resources/apiManagement.svg new file mode 100644 index 0000000..eb7f6b6 --- /dev/null +++ b/svgs/resources/apiManagement.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/svgs/resources/check.svg b/svgs/resources/check.svg new file mode 100644 index 0000000..067c758 --- /dev/null +++ b/svgs/resources/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/svgs/resources/chevronDown.svg b/svgs/resources/chevronDown.svg new file mode 100644 index 0000000..53c8efe --- /dev/null +++ b/svgs/resources/chevronDown.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/chevronRight.svg b/svgs/resources/chevronRight.svg new file mode 100644 index 0000000..e2b7019 --- /dev/null +++ b/svgs/resources/chevronRight.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/chevronUp.svg b/svgs/resources/chevronUp.svg new file mode 100644 index 0000000..233c4a2 --- /dev/null +++ b/svgs/resources/chevronUp.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/close.svg b/svgs/resources/close.svg new file mode 100644 index 0000000..14bfca1 --- /dev/null +++ b/svgs/resources/close.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/svgs/resources/copy.svg b/svgs/resources/copy.svg new file mode 100644 index 0000000..153f9d2 --- /dev/null +++ b/svgs/resources/copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/svgs/resources/discord.svg b/svgs/resources/discord.svg new file mode 100644 index 0000000..fb8bed0 --- /dev/null +++ b/svgs/resources/discord.svg @@ -0,0 +1,3 @@ + + + diff --git a/svgs/resources/docs.svg b/svgs/resources/docs.svg new file mode 100644 index 0000000..1ed3eb4 --- /dev/null +++ b/svgs/resources/docs.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/svgs/resources/fail.svg b/svgs/resources/fail.svg new file mode 100644 index 0000000..45a5d67 --- /dev/null +++ b/svgs/resources/fail.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/svgs/resources/firstPage.svg b/svgs/resources/firstPage.svg new file mode 100644 index 0000000..b449d0d --- /dev/null +++ b/svgs/resources/firstPage.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/svgs/resources/gass.svg b/svgs/resources/gass.svg new file mode 100644 index 0000000..70e0745 --- /dev/null +++ b/svgs/resources/gass.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/svgs/resources/github.svg b/svgs/resources/github.svg new file mode 100644 index 0000000..694e2d6 --- /dev/null +++ b/svgs/resources/github.svg @@ -0,0 +1,3 @@ + + + diff --git a/svgs/resources/info.svg b/svgs/resources/info.svg new file mode 100644 index 0000000..0e722ba --- /dev/null +++ b/svgs/resources/info.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/svgs/resources/lastPage.svg b/svgs/resources/lastPage.svg new file mode 100644 index 0000000..7abb4da --- /dev/null +++ b/svgs/resources/lastPage.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/svgs/resources/link.svg b/svgs/resources/link.svg new file mode 100644 index 0000000..8c1b19d --- /dev/null +++ b/svgs/resources/link.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/medium.svg b/svgs/resources/medium.svg new file mode 100644 index 0000000..b874cf3 --- /dev/null +++ b/svgs/resources/medium.svg @@ -0,0 +1,3 @@ + + + diff --git a/svgs/resources/more.svg b/svgs/resources/more.svg new file mode 100644 index 0000000..dffa06e --- /dev/null +++ b/svgs/resources/more.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/svgs/resources/next.svg b/svgs/resources/next.svg new file mode 100644 index 0000000..e5bde68 --- /dev/null +++ b/svgs/resources/next.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/svgs/resources/nextPage.svg b/svgs/resources/nextPage.svg new file mode 100644 index 0000000..1788079 --- /dev/null +++ b/svgs/resources/nextPage.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/prevPage.svg b/svgs/resources/prevPage.svg new file mode 100644 index 0000000..b846e8b --- /dev/null +++ b/svgs/resources/prevPage.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/refresh.svg b/svgs/resources/refresh.svg new file mode 100644 index 0000000..17ee638 --- /dev/null +++ b/svgs/resources/refresh.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/running.svg b/svgs/resources/running.svg new file mode 100644 index 0000000..ec4045a --- /dev/null +++ b/svgs/resources/running.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/svgs/resources/search.svg b/svgs/resources/search.svg new file mode 100644 index 0000000..ddb0d6e --- /dev/null +++ b/svgs/resources/search.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/svgs/resources/steps.svg b/svgs/resources/steps.svg new file mode 100644 index 0000000..7818966 --- /dev/null +++ b/svgs/resources/steps.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/success.svg b/svgs/resources/success.svg new file mode 100644 index 0000000..c9c3f7e --- /dev/null +++ b/svgs/resources/success.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/svgs/resources/telegram.svg b/svgs/resources/telegram.svg new file mode 100644 index 0000000..f81dea8 --- /dev/null +++ b/svgs/resources/telegram.svg @@ -0,0 +1,3 @@ + + + diff --git a/svgs/resources/twitter.svg b/svgs/resources/twitter.svg new file mode 100644 index 0000000..0402642 --- /dev/null +++ b/svgs/resources/twitter.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svgs/resources/widget.svg b/svgs/resources/widget.svg new file mode 100644 index 0000000..e00dc88 --- /dev/null +++ b/svgs/resources/widget.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/svgs/resources/youtube.svg b/svgs/resources/youtube.svg new file mode 100644 index 0000000..57448c6 --- /dev/null +++ b/svgs/resources/youtube.svg @@ -0,0 +1,3 @@ + + + diff --git a/tailwind.config.js b/tailwind.config.js index e49726e..7e63942 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,33 +1,164 @@ module.exports = { + darkMode: 'false', content: [ './pages/**/*.{js,ts,jsx,tsx}', - './components/**/*.{js,ts,jsx,tsx}' + './components/**/*.{js,ts,jsx,tsx}', ], - safelist: ['text-success', 'bg-success', 'border-success'], theme: { + borderWidth: { + DEFAULT: '1px', + 0: '0', + 2: '2px', + }, fontFamily: { - sans: ['Aileron'], - heading: ['impactreg'] + sans: ['Roboto'], + heading: ['Roboto'], + }, + screens: { + 'xs': '330px', + 'sm': '640px', + 'md': '1024px', + 'lg': '1280px', + }, + container: { + screens: { + md: '1024px', + lg: '1180px', + }, + }, + borderRadius: { + none: '0', + micro: '0.312rem', + soft: '0.625rem', + normal: '0.937rem', + large: '1.5625rem', + full: '9999px', }, extend: { - visibility: ['group-hover'], - + rotate: { + 4.5: '4.5deg', + }, + gap: { + 10: '0.625rem', + 15: '0.937rem', + }, + inset: { 15: '3.75rem' }, + padding: { + 5: '0.32rem', + 8: '0.5rem', + 10: '0.625rem', + 12: '0.75rem', + 15: '0.937rem', + 16: '1rem', + 18: '1.125rem', + 20: '1.25rem', + 25: '1.56rem', + 30: '1.875rem', + 35: '2.1875rem', + 40: '2.5rem', + 50: '3.125rem', + }, + margin: { + 5: '0.32rem', + 10: '0.625rem', + 15: '0.937rem', + 20: '1.25rem', + 25: '1.56rem', + 30: '1.875rem', + 35: '2.1875rem', + 40: '2.5rem', + 50: '3.125rem', + 60: '3.75rem', + }, + lineHeight: { + 7.5: '1.875rem', + 12: '0.75rem', + 13: '3.2rem', + 14: '0.875rem', + 16: '1rem', + }, + backgroundImage: { + 'body-mask': "url('/img/backgrounds/mask.svg')", + 'body-mask-2': "url('/img/backgrounds/mask2.png')", + 'footer-mask': "url('/img/backgrounds/footer.svg')", + 'foreground-mask': "url('/img/backgrounds/mask-foreground.svg')", + 'cover-1': "url('/img/videos/video1-cover.jpg')", + 'cover-2': "url('/img/videos/video2-cover.jpg')", + }, + fontSize: { + 10: '0.625rem', + 11: '0.6875rem', + 12: '0.75rem', + 14: '0.875rem', + 16: '1rem', + 18: '1.125rem', + 20: '1.25rem', + 22: '1.375rem', + 28: '1.75rem', + 45: '2.8125rem', + 56: '3.5rem', + }, + height: { + 21: '5.25rem', + }, colors: { - primary: '#00A9BB', - secondary: '#da606c', - background: '#ECF3F4', + white: '#FFFFFF', + baseBackground: '#070917', + baseForeground: '#FDFDFD', + surfacesBackground: '#F9F9F9', + surfacesTooltip: '#F6F6F6', + hoverBackground: '#E9F3FF', + hoverBackgroundIcon: '#E6E6E6', + hoverIcon: '#2284ED', error: '#F40000', - failed: '#F40000', - warning: '#ef9b0f', - success: '#0AA65B', + success: '#06C270', + backgroundSuccess: '#BDECD7', + running: '#5BABFF', + backgroundRunning: '#C8E2FF', + failed: '#FF3B3B', + backgroundFailed: '#FFD7D7', + tooltipBackground: '#2B3462', + + primary: { + 500: '#010101', + 600: '#1c3cf1', + }, + secondary: { + 200: '#D6EAFF', + 500: '#469BF5', + 600: '#3b83d0', + 700: '#242D5B', + }, neutral: { - 100: '#FFFFFF', - 300: '#D0D0D0', - 600: '#636363', - 900: '#000000' - } - } + 100: '#E9E9E9', + 200: '#B8B8B8', + 300: '#F2F2F2', + 400: '#727272', + 500: '#161C38', + 700: '#0F142E', + 800: '#A2A2A2', + 900: '#EEEEEE', + }, + }, + keyframes: { + ['mount']: { + '0%': { + opacity: 0, + transform: 'translateY(50%)', + }, + '100%': { + opacity: 1, + transform: 'translateY(0)', + }, + }, + }, + animation: { + ['mount']: 'mount 0.4s linear', + }, + boxShadow: { + inner: 'inset 0 0 0 1000px rgba(0,0,0,.15)', + }, }, - plugins: [] - } -} + plugins: [require('@tailwindcss/aspect-ratio')], + }, +}; diff --git a/tsconfig.json b/tsconfig.json index 1e7b26a..757a370 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,8 +15,16 @@ "baseUrl": "./", "jsx": "preserve", "incremental": true, - "allowSyntheticDefaultImports": true, + "allowSyntheticDefaultImports": true }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + "components/home/Summary/SummaryItem.tss", + "next.config.js", + "tailwind.config.js", + "postcss.config.js" + ], "exclude": ["node_modules"] } diff --git a/types/index.ts b/types/index.ts index 27dbfef..c18dd0f 100644 --- a/types/index.ts +++ b/types/index.ts @@ -1,2 +1,2 @@ -export * from './transations' -export * from './summary' +export * from './transations'; +export * from './summary'; diff --git a/types/summary.ts b/types/summary.ts index 52f6257..2a89a80 100644 --- a/types/summary.ts +++ b/types/summary.ts @@ -1,16 +1,16 @@ -export type SummaryType = { - totalTxCount: number - totalTxVolumeUSD: number - connectedWallets: number - supportedDexes: number - supportedBridges: number - supportedChains: number - lastUpdateDate: string - dailyInterval: Array +export interface SummaryType { + totalTxCount: number; + totalTxVolumeUSD: number; + connectedWallets: number; + supportedDexes: number; + supportedBridges: number; + supportedChains: number; + lastUpdateDate: string; + dailyInterval: DailyIntervalType[]; } -export type DailyIntervalType = { - date: string - count: number - volumeUSD: number +export interface DailyIntervalType { + date: string; + count: number; + volumeUSD: number; } diff --git a/types/transations.ts b/types/transations.ts index c43dd84..497ed98 100644 --- a/types/transations.ts +++ b/types/transations.ts @@ -1,76 +1,97 @@ export interface RouteType { - blockchain: string - symbol: string - image: string - address: string - decimals: number - name: string - blockchainLogo: string + blockchain: string; + symbol: string; + decimals: number; + name: string; + blockchainLogo: string; + blockchainType: string; + expectedAmount: number; + logo: string; + price: number; + realAmount: number; } +export type SwapStatus = 'running' | 'failed' | 'success' | 'unknown'; + export interface StepSummary { - fromToken: RouteType - toToken: RouteType - dstAmount: Number + feeUsd: number; + status: SwapStatus; + stepNumber: number; + fromToken: RouteType; + toToken: RouteType; } export interface SwapType { - requestId: string - transactionTime: string - status: string - sourceToken: RouteType - destination: RouteType - sourceAmount: number - destinationAmount: number - stepsSummary: StepSummary[] + requestId: string; + transactionTime: string; + status: SwapStatus; + stepsSummary: StepSummary[]; +} + +export interface WalletType { + address: string; + explorer: string; } export interface AssetType { - blockchain: string - symbol: string - address: string - blockchainLogo: string + address: string; + blockchain: string; + blockchainLogo: string; + blockchainType: string; + decimals: 18; + expectedAmount: number; + logo: string; + price: number; + symbol: string; + realAmount: number; + name: string; } export interface ExplorerUrlsType { - url: string - description: string + url: string; + description: string; } export interface ApproveUrlsType { - txId: string - url: string - status: string + txId: string; + url: string; + status: string; +} + +export interface SwapperType { + swapperId: string; + swapperLogo: string; + swapperTitle: string; + swapperType: 'DEX' | 'BRIDGE' | 'AGGREGATOR'; +} + +export interface InternalPathType { + swapper: SwapperType; + from: AssetType; + to: AssetType; } export interface StepType { - swapperId: string - fromAsset: AssetType - toAsset: AssetType - toAmount: number - fromAmount: number - status: string - generatedTxId: string[] - estimatedTimeInSeconds: number - expectedToAmount: number - explorerUrls: ExplorerUrlsType[] - approveUrls: ApproveUrlsType[] - sourceWallet: string - destinationWallet: string - destinationWalletAddress: string - sourceWalletAddress: string + swapper: SwapperType; + from: AssetType; + to: AssetType; + status: SwapStatus; + generatedTxId: string[]; + internalPath: InternalPathType[]; + estimatedTimeInSeconds: number; + executionTimeInSeconds: number; + explorerUrls: ExplorerUrlsType[]; + approveUrls: ApproveUrlsType[]; + sourceWallet: WalletType; + destinationWallet: WalletType; + startTime: number; } export interface DetailsType { - requestId: string - creationDate: string - verificationState: string - sourceWallet: string - destinationWallet: string - destinationWalletAddress: string - sourceWalletAddress: string - destination: RouteType - from: AssetType - to: AssetType - srcAmount: number - dstAmount: number - steps: StepType[] - status: string - estimatedTimeInSeconds: number + requestId: string; + creationDate: string; + verificationState: string; + sourceWallet: WalletType; + destinationWallet: WalletType; + from: AssetType; + to: AssetType; + steps: StepType[]; + status: SwapStatus; + estimatedTimeInSeconds: number; } diff --git a/utils/amountConverter.ts b/utils/amountConverter.ts index 0be9335..7ee1053 100644 --- a/utils/amountConverter.ts +++ b/utils/amountConverter.ts @@ -1,12 +1,20 @@ /* eslint-disable @typescript-eslint/restrict-plus-operands */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ -const unitlist = ['', 'K', 'M', 'B'] -export function AmountConverter (number: number) { - const sign = Math.sign(number) - let unit = 0 +const unitlist = ['', 'K', 'M', 'B']; +export function AmountConverter(number: number) { + const sign = Math.sign(number); + let unit = 0; while (Math.abs(number) > 1000) { - unit = unit + 1 - number = Math.floor(Math.abs(number) / 10) / 100 + unit = unit + 1; + number = Math.floor(Math.abs(number) / 10) / 100; } - return sign * Math.abs(number) + unitlist[unit] + return sign * Math.abs(number) + unitlist[unit]; +} + +export function getPercentageChange( + input: number | null, + output: number | null, +) { + if (!input || !output) return null; + return parseFloat(Number((output / input - 1) * 100).toFixed(2)); } diff --git a/utils/capitalizeFirstLetter.ts b/utils/capitalizeFirstLetter.ts index 5931b5d..9e8fa29 100644 --- a/utils/capitalizeFirstLetter.ts +++ b/utils/capitalizeFirstLetter.ts @@ -1,2 +1,6 @@ -export const CapitalizeFirstLetter = (str: string): string => - str.charAt(0).toUpperCase() + str.slice(1) +export const CapitalizeFirstLetter = (str: string): string => { + if (str && str.length > 1) { + return str.charAt(0).toUpperCase() + str.toLowerCase().slice(1); + } + return str; +}; diff --git a/utils/copyText.ts b/utils/copyText.ts index a33140b..1fcaa02 100644 --- a/utils/copyText.ts +++ b/utils/copyText.ts @@ -1,15 +1,3 @@ -import { toast } from 'react-toastify' - export const CopyText = (text: string): void => { - navigator.clipboard.writeText(text) - toast.info('copied!', { - position: 'top-right', - autoClose: 3000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - theme: 'light' - }) -} + navigator.clipboard.writeText(text); +}; diff --git a/utils/secondsTohms.ts b/utils/secondsTohms.ts index b7f9479..9ca004d 100644 --- a/utils/secondsTohms.ts +++ b/utils/secondsTohms.ts @@ -1,6 +1,8 @@ -export function SecondsTohms (seconds: number): string { - const h = Math.floor((seconds % (3600 * 24)) / 3600) - const m = Math.floor((seconds % 3600) / 60) - const s = Math.floor(seconds % 60) - return `${h < 10 ? '0' : ''}${h}:${m < 10 ? '0' : ''}${m}:${s < 10 ? '0' : ''}${s}` +export function SecondsTohms(seconds: number): string { + const h = Math.floor((seconds % (3600 * 24)) / 3600); + const m = Math.floor((seconds % 3600) / 60); + const s = Math.floor(seconds % 60); + return `${h < 10 ? '0' : ''}${h}:${m < 10 ? '0' : ''}${m}:${ + s < 10 ? '0' : '' + }${s}`; } diff --git a/yarn.lock b/yarn.lock index 856caf7..ea91063 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,164 @@ resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@artsy/fresnel@^7.1.3": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@artsy/fresnel/-/fresnel-7.1.3.tgz#65a7c6a5bee5487813dbd0b38aa971e6d38c3a2f" + integrity sha512-IUXPNu11g1VCItpBGLgJQUQkk90hpg7Ye1iEEc9+z54dHnks/NahnjVJAj2nnbbl+lrX3Svd2JRTj+Y94FtPjg== + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/compat-data@^7.22.9": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + +"@babel/core@^7.21.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.5.tgz#6e23f2acbcb77ad283c5ed141f824fd9f70101c7" + integrity sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.5" + "@babel/parser" "^7.23.5" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.5.tgz#17d0a1ea6b62f351d281350a5f80b87a810c4755" + integrity sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA== + dependencies: + "@babel/types" "^7.23.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.22.15": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helpers@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.5.tgz#52f522840df8f1a848d06ea6a79b79eefa72401e" + integrity sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.22.15", "@babel/parser@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.5.tgz#37dee97c4752af148e1d38c34b856b2507660563" + integrity sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ== + "@babel/runtime@^7.20.7": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" @@ -19,22 +177,56 @@ dependencies: regenerator-runtime "^0.14.0" -"@eslint-community/eslint-utils@^4.2.0": +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.5.tgz#f546bf9aba9ef2b042c0e00d245990c15508e7ec" + integrity sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.5" + "@babel/types" "^7.23.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.21.3", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.5.tgz#48d730a00c95109fa4393352705954d74fb5b602" + integrity sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": version "4.10.0" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== -"@eslint/eslintrc@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" - integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -46,10 +238,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.52.0": - version "8.52.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.52.0.tgz#78fe5f117840f69dc4a353adf9b9cd926353378c" - integrity sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA== +"@eslint/js@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6" + integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA== "@humanwhocodes/config-array@^0.11.13": version "0.11.13" @@ -70,7 +262,7 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== -"@jridgewell/gen-mapping@^0.3.2": +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== @@ -94,7 +286,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": version "0.3.20" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== @@ -185,6 +377,18 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@pkgr/utils@^2.3.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" + integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== + dependencies: + cross-spawn "^7.0.3" + fast-glob "^3.3.0" + is-glob "^4.0.3" + open "^9.1.0" + picocolors "^1.0.0" + tslib "^2.6.0" + "@react-spring/animated@~9.7.3": version "9.7.3" resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.3.tgz#4211b1a6d48da0ff474a125e93c0f460ff816e0f" @@ -229,6 +433,122 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz#5f1b518ec5fa54437c0b7c4a821546c64fed6922" integrity sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA== +"@svgr/babel-plugin-add-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz#4001f5d5dd87fa13303e36ee106e3ff3a7eb8b22" + integrity sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g== + +"@svgr/babel-plugin-remove-jsx-attribute@8.0.0", "@svgr/babel-plugin-remove-jsx-attribute@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== + +"@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz#8fbb6b2e91fa26ac5d4aa25c6b6e4f20f9c0ae27" + integrity sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ== + +"@svgr/babel-plugin-svg-dynamic-title@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz#1d5ba1d281363fc0f2f29a60d6d936f9bbc657b0" + integrity sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og== + +"@svgr/babel-plugin-svg-em-dimensions@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz#35e08df300ea8b1d41cb8f62309c241b0369e501" + integrity sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g== + +"@svgr/babel-plugin-transform-react-native-svg@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz#90a8b63998b688b284f255c6a5248abd5b28d754" + integrity sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q== + +"@svgr/babel-plugin-transform-svg-component@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz#013b4bfca88779711f0ed2739f3f7efcefcf4f7e" + integrity sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw== + +"@svgr/babel-preset@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-8.1.0.tgz#0e87119aecdf1c424840b9d4565b7137cabf9ece" + integrity sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "8.0.0" + "@svgr/babel-plugin-replace-jsx-attribute-value" "8.0.0" + "@svgr/babel-plugin-svg-dynamic-title" "8.0.0" + "@svgr/babel-plugin-svg-em-dimensions" "8.0.0" + "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" + "@svgr/babel-plugin-transform-svg-component" "8.0.0" + +"@svgr/cli@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-8.1.0.tgz#dd7fcf42a144eb681bb9923c5d806bf6cafd7512" + integrity sha512-SnlaLspB610XFXvs3PmhzViHErsXp0yIy4ERyZlHDlO1ro2iYtHMWYk2mztdLD/lBjiA4ZXe4RePON3qU/Tc4A== + dependencies: + "@svgr/core" "8.1.0" + "@svgr/plugin-jsx" "8.1.0" + "@svgr/plugin-prettier" "8.1.0" + "@svgr/plugin-svgo" "8.1.0" + camelcase "^6.2.0" + chalk "^4.1.2" + commander "^9.4.1" + dashify "^2.0.0" + glob "^8.0.3" + snake-case "^3.0.4" + +"@svgr/core@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-8.1.0.tgz#41146f9b40b1a10beaf5cc4f361a16a3c1885e88" + integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + camelcase "^6.2.0" + cosmiconfig "^8.1.3" + snake-case "^3.0.4" + +"@svgr/hast-util-to-babel-ast@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz#6952fd9ce0f470e1aded293b792a2705faf4ffd4" + integrity sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q== + dependencies: + "@babel/types" "^7.21.3" + entities "^4.4.0" + +"@svgr/plugin-jsx@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz#96969f04a24b58b174ee4cd974c60475acbd6928" + integrity sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + "@svgr/hast-util-to-babel-ast" "8.0.0" + svg-parser "^2.0.4" + +"@svgr/plugin-prettier@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-prettier/-/plugin-prettier-8.1.0.tgz#71bf0d0b0ae4c2234a2deb0e5bad21c2cfe31364" + integrity sha512-o4/uFI8G64tAjBZ4E7gJfH+VP7Qi3T0+M4WnIsP91iFnGPqs5WvPDkpZALXPiyWEtzfYs1Rmwy1Zdfu8qoZuKw== + dependencies: + deepmerge "^4.3.1" + prettier "^2.8.7" + +"@svgr/plugin-svgo@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz#b115b7b967b564f89ac58feae89b88c3decd0f00" + integrity sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA== + dependencies: + cosmiconfig "^8.1.3" + deepmerge "^4.3.1" + svgo "^3.0.2" + "@swc/helpers@0.5.2": version "0.5.2" resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.2.tgz#85ea0c76450b61ad7d10a37050289eded783c27d" @@ -236,6 +556,16 @@ dependencies: tslib "^2.4.0" +"@tailwindcss/aspect-ratio@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz#9ffd52fee8e3c8b20623ff0dcb29e5c21fb0a9ba" + integrity sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ== + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + "@types/d3-color@^1": version "1.4.4" resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.4.tgz#d8a270d6fd864977ea339899a0dfb35974da93a4" @@ -277,10 +607,10 @@ resolved "https://registry.yarnpkg.com/@types/d3-voronoi/-/d3-voronoi-1.1.11.tgz#3dcc6c55459e239e362cecab4dcd870e06882005" integrity sha512-M33h1O9HUn/DkWpxYyTRD4jUSnmrssZlCsGhVr97vRyHdZjaZoKxJIYtKPSCiv00izKShwN6fZtvKvRbmmAXjA== -"@types/json-schema@^7.0.9": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" - integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== +"@types/json-schema@^7.0.12": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" @@ -328,26 +658,27 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.5.tgz#4751153abbf8d6199babb345a52e1eb4167d64af" integrity sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw== -"@types/semver@^7.3.12": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" - integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== - -"@typescript-eslint/eslint-plugin@^5.43.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" - integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/type-utils" "5.62.0" - "@typescript-eslint/utils" "5.62.0" +"@types/semver@^7.5.0": + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== + +"@typescript-eslint/eslint-plugin@^6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.1.tgz#f98bd887bf95551203c917e734d113bf8d527a0c" + integrity sha512-5bQDGkXaxD46bPvQt08BUz9YSaO4S0fB1LB5JHQuXTfkGPI3+UUeS387C/e9jRie5GqT8u5kFTrMvAjtX4O5kA== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.13.1" + "@typescript-eslint/type-utils" "6.13.1" + "@typescript-eslint/utils" "6.13.1" + "@typescript-eslint/visitor-keys" "6.13.1" debug "^4.3.4" graphemer "^1.4.0" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" "@typescript-eslint/parser@^5.0.0": version "5.62.0" @@ -370,6 +701,17 @@ "@typescript-eslint/visitor-keys" "6.9.0" debug "^4.3.4" +"@typescript-eslint/parser@^6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.13.1.tgz#29d6d4e5fab4669e58bc15f6904b67da65567487" + integrity sha512-fs2XOhWCzRhqMmQf0eicLa/CWSaYss2feXsy7xBD/pLyWke/jCIVc2s1ikEAtSW7ina1HNhv7kONoEfVNEcdDQ== + dependencies: + "@typescript-eslint/scope-manager" "6.13.1" + "@typescript-eslint/types" "6.13.1" + "@typescript-eslint/typescript-estree" "6.13.1" + "@typescript-eslint/visitor-keys" "6.13.1" + debug "^4.3.4" + "@typescript-eslint/scope-manager@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" @@ -378,6 +720,14 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" +"@typescript-eslint/scope-manager@6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.13.1.tgz#58c7c37c6a957d3d9f59bc4f64c2888e0cac1d70" + integrity sha512-BW0kJ7ceiKi56GbT2KKzZzN+nDxzQK2DS6x0PiSMPjciPgd/JRQGMibyaN2cPt2cAvuoH0oNvn2fwonHI+4QUQ== + dependencies: + "@typescript-eslint/types" "6.13.1" + "@typescript-eslint/visitor-keys" "6.13.1" + "@typescript-eslint/scope-manager@6.9.0": version "6.9.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz#2626e9a7fe0e004c3e25f3b986c75f584431134e" @@ -386,21 +736,26 @@ "@typescript-eslint/types" "6.9.0" "@typescript-eslint/visitor-keys" "6.9.0" -"@typescript-eslint/type-utils@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" - integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== +"@typescript-eslint/type-utils@6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.13.1.tgz#e6e5885e387841cae9c38fc0638fd8b7561973d6" + integrity sha512-A2qPlgpxx2v//3meMqQyB1qqTg1h1dJvzca7TugM3Yc2USDY+fsRBiojAEo92HO7f5hW5mjAUF6qobOPzlBCBQ== dependencies: - "@typescript-eslint/typescript-estree" "5.62.0" - "@typescript-eslint/utils" "5.62.0" + "@typescript-eslint/typescript-estree" "6.13.1" + "@typescript-eslint/utils" "6.13.1" debug "^4.3.4" - tsutils "^3.21.0" + ts-api-utils "^1.0.1" "@typescript-eslint/types@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== +"@typescript-eslint/types@6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.13.1.tgz#b56f26130e7eb8fa1e429c75fb969cae6ad7bb5c" + integrity sha512-gjeEskSmiEKKFIbnhDXUyiqVma1gRCQNbVZ1C8q7Zjcxh3WZMbzWVfGE9rHfWd1msQtPS0BVD9Jz9jded44eKg== + "@typescript-eslint/types@6.9.0": version "6.9.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.9.0.tgz#86a0cbe7ac46c0761429f928467ff3d92f841098" @@ -419,6 +774,19 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.1.tgz#d01dda78d2487434d1c503853fa00291c566efa4" + integrity sha512-sBLQsvOC0Q7LGcUHO5qpG1HxRgePbT6wwqOiGLpR8uOJvPJbfs0mW3jPA3ujsDvfiVwVlWUDESNXv44KtINkUQ== + dependencies: + "@typescript-eslint/types" "6.13.1" + "@typescript-eslint/visitor-keys" "6.13.1" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + "@typescript-eslint/typescript-estree@6.9.0": version "6.9.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz#d0601b245be873d8fe49f3737f93f8662c8693d4" @@ -432,19 +800,18 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" - integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - eslint-scope "^5.1.1" - semver "^7.3.7" +"@typescript-eslint/utils@6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.13.1.tgz#925b3a2453a71ada914ae329b7bb7e7d96634b2f" + integrity sha512-ouPn/zVoan92JgAegesTXDB/oUp6BP1v8WpfYcqh649ejNc9Qv+B4FF2Ff626kO1xg0wWwwG48lAJ4JuesgdOw== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.13.1" + "@typescript-eslint/types" "6.13.1" + "@typescript-eslint/typescript-estree" "6.13.1" + semver "^7.5.4" "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" @@ -454,6 +821,14 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.1.tgz#c4b692dcc23a4fc60685b718f10fde789d65a540" + integrity sha512-NDhQUy2tg6XGNBGDRm1XybOHSia8mcXmlbKWoQP+nm1BIIMxa55shyJfZkHpEBN62KNPLrocSM2PdPcaLgDKMQ== + dependencies: + "@typescript-eslint/types" "6.13.1" + eslint-visitor-keys "^3.4.1" + "@typescript-eslint/visitor-keys@6.9.0": version "6.9.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz#cc69421c10c4ac997ed34f453027245988164e80" @@ -706,11 +1081,30 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-escapes@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-6.2.0.tgz#8a13ce75286f417f1963487d86ba9f90dccf9947" + integrity sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw== + dependencies: + type-fest "^3.0.0" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -718,6 +1112,11 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^6.0.0, ansi-styles@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + any-promise@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -878,11 +1277,28 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -891,6 +1307,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -898,7 +1321,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.21.10: +browserslist@^4.21.10, browserslist@^4.21.9: version "4.22.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== @@ -915,6 +1338,13 @@ builtins@^5.0.1: dependencies: semver "^7.0.0" +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + busboy@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -941,12 +1371,31 @@ camelcase-css@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541: version "1.0.30001558" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001558.tgz#d2c6e21fdbfe83817f70feab902421a19b7983ee" integrity sha512-/Et7DwLqpjS47JPEcz6VnxU9PwcIdVi0ciLXRWBQdj1XFye68pSQYpV0QtPTfUKWuOaEig+/Vez2l74eDc1tPQ== -chalk@^4.0.0: +chalk@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -974,6 +1423,21 @@ classnames@^2.3.1: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== +cli-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" + integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg== + dependencies: + restore-cursor "^4.0.0" + +cli-truncate@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-4.0.0.tgz#6cc28a2924fee9e25ce91e973db56c7066e6172a" + integrity sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA== + dependencies: + slice-ansi "^5.0.0" + string-width "^7.0.0" + client-only@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" @@ -984,6 +1448,13 @@ clsx@^1.1.1: resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -991,22 +1462,62 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colorette@^2.0.20: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" + integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== + commander@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^9.4.1: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -cross-spawn@^7.0.2: +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cosmiconfig@^8.1.3: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -1015,11 +1526,50 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-tree@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + +css-tree@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== + dependencies: + mdn-data "2.0.28" + source-map-js "^1.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +csso@5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== + dependencies: + css-tree "~2.2.0" + csstype@^3.0.2: version "3.1.2" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" @@ -1125,6 +1675,11 @@ damerau-levenshtein@^1.0.8: resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +dashify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dashify/-/dashify-2.0.0.tgz#fff270ca2868ca427fee571de35691d6e437a648" + integrity sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A== + dayjs@^1.11.6: version "1.11.10" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" @@ -1135,6 +1690,13 @@ debounce@^1.2.1: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== +debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -1142,18 +1704,34 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + define-data-property@^1.0.1, define-data-property@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" @@ -1163,6 +1741,11 @@ define-data-property@^1.0.1, define-data-property@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" @@ -1208,11 +1791,54 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + electron-to-chromium@^1.4.535: version "1.4.569" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz#1298b67727187ffbaac005a7425490d157f3ad03" integrity sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg== +emoji-regex@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.3.0.tgz#76998b9268409eb3dae3de989254d456e70cfe23" + integrity sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw== + emoji-regex@^9.2.2: version "9.2.2" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" @@ -1226,6 +1852,18 @@ enhanced-resolve@^5.12.0: graceful-fs "^4.2.4" tapable "^2.2.0" +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + es-abstract@^1.22.1: version "1.22.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" @@ -1321,6 +1959,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -1341,6 +1984,11 @@ eslint-config-next@^13.0.4: eslint-plugin-react "^7.33.2" eslint-plugin-react-hooks "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" +eslint-config-prettier@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f" + integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== + eslint-config-standard-with-typescript@^23.0.0: version "23.0.0" resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-23.0.0.tgz#aa4b656740bbb2592d4cadec735d41e36245a44b" @@ -1383,6 +2031,13 @@ eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" +eslint-plugin-destructuring@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-destructuring/-/eslint-plugin-destructuring-2.2.1.tgz#7c0681174699af03fd9fab4c9619fcad45156fbe" + integrity sha512-I/jbm7E3xamiFqn8NLwyhZkDjCb0lTFIykNxIWwDwHsTlU+8hR4gDQmrXTWdyDHG9k1i2uFeHMhoMAtERNWp4w== + dependencies: + lodash.zipobject "^4.1.3" + eslint-plugin-es@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz#f0822f0c18a535a97c3e714e89f88586a7641ec9" @@ -1391,7 +2046,7 @@ eslint-plugin-es@^4.1.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@^2.26.0, eslint-plugin-import@^2.28.1: +eslint-plugin-import@^2.28.1, eslint-plugin-import@^2.29.0: version "2.29.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== @@ -1450,17 +2105,25 @@ eslint-plugin-n@^15.5.1: resolve "^1.22.1" semver "^7.3.8" +eslint-plugin-prettier@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz#a3b399f04378f79f066379f544e42d6b73f11515" + integrity sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.8.5" + eslint-plugin-promise@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816" integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== -"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": +"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705", eslint-plugin-react-hooks@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== -eslint-plugin-react@^7.31.11, eslint-plugin-react@^7.33.2: +eslint-plugin-react@^7.33.2: version "7.33.2" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== @@ -1482,14 +2145,6 @@ eslint-plugin-react@^7.31.11, eslint-plugin-react@^7.33.2: semver "^6.3.1" string.prototype.matchall "^4.0.8" -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" @@ -1527,15 +2182,15 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@^8.28.0: - version "8.52.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.52.0.tgz#d0cd4a1fac06427a61ef9242b9353f36ea7062fc" - integrity sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg== +eslint@^8.55.0: + version "8.55.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.55.0.tgz#078cb7b847d66f2c254ea1794fa395bf8e7e03f8" + integrity sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.52.0" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.55.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -1594,11 +2249,6 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" @@ -1609,11 +2259,66 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + +execa@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +execa@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" + integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" @@ -1720,6 +2425,16 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-east-asian-width@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz#5e6ebd9baee6fb8b7b6bd505221065f0cd91f64e" + integrity sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" @@ -1730,6 +2445,16 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -1800,6 +2525,22 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^13.19.0: version "13.23.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" @@ -1848,6 +2589,11 @@ has-bigints@^1.0.1, has-bigints@^1.0.2: resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -1889,6 +2635,21 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== + husky@^8.0.0: version "8.0.3" resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" @@ -1899,12 +2660,17 @@ ignore@^5.1.1, ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +ignore@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + immutable@^4.0.0: version "4.3.4" resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== -import-fresh@^3.2.1: +import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -1953,6 +2719,11 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: get-intrinsic "^1.2.0" is-typed-array "^1.1.10" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-async-function@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" @@ -2001,6 +2772,16 @@ is-date-object@^1.0.1, is-date-object@^1.0.5: dependencies: has-tostringtag "^1.0.0" +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2013,6 +2794,18 @@ is-finalizationregistry@^1.0.2: dependencies: call-bind "^1.0.2" +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + +is-fullwidth-code-point@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz#9609efced7c2f97da7b60145ef481c787c7ba704" + integrity sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA== + dependencies: + get-east-asian-width "^1.0.0" + is-generator-function@^1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" @@ -2027,6 +2820,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-map@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -2079,6 +2879,16 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -2120,6 +2930,13 @@ is-weakset@^2.0.1: call-bind "^1.0.2" get-intrinsic "^1.1.1" +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -2146,7 +2963,7 @@ jiti@^1.19.1: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.20.0.tgz#2d823b5852ee8963585c8dd8b7992ffc1ae83b42" integrity sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA== -"js-tokens@^3.0.0 || ^4.0.0": +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -2158,11 +2975,21 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -2180,6 +3007,11 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -2217,6 +3049,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lilconfig@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc" + integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g== + lilconfig@^2.0.5, lilconfig@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" @@ -2227,6 +3064,34 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +lint-staged@^15.2.0: + version "15.2.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.2.0.tgz#3111534ca58096a3c8f70b044b6e7fe21b36f859" + integrity sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ== + dependencies: + chalk "5.3.0" + commander "11.1.0" + debug "4.3.4" + execa "8.0.1" + lilconfig "3.0.0" + listr2 "8.0.0" + micromatch "4.0.5" + pidtree "0.6.0" + string-argv "0.3.2" + yaml "2.3.4" + +listr2@8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-8.0.0.tgz#aa7c230995f8ce378585f7c96c0c6d1cefa4700d" + integrity sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg== + dependencies: + cli-truncate "^4.0.0" + colorette "^2.0.20" + eventemitter3 "^5.0.1" + log-update "^6.0.0" + rfdc "^1.3.0" + wrap-ansi "^9.0.0" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -2239,11 +3104,27 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.zipobject@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lodash.zipobject/-/lodash.zipobject-4.1.3.tgz#b399f5aba8ff62a746f6979bf20b214f964dbef8" + integrity sha512-A9SzX4hMKWS25MyalwcOnNoplyHbkNVsjidhTp8ru0Sj23wY9GWBKS8gAIGDSAqeWjIjvE4KBEl24XXAs+v4wQ== + lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +log-update@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-6.0.0.tgz#0ddeb7ac6ad658c944c1de902993fce7c33f5e59" + integrity sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw== + dependencies: + ansi-escapes "^6.2.0" + cli-cursor "^4.0.0" + slice-ansi "^7.0.0" + strip-ansi "^7.1.0" + wrap-ansi "^9.0.0" + loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -2251,6 +3132,20 @@ loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -2263,12 +3158,27 @@ math-expression-evaluator@^1.2.14: resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz#3d66031117fbb7b9715ea6c9c68c2cd2eebd37e2" integrity sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw== +mdn-data@2.0.28: + version "2.0.28" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== + +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micromatch@^4.0.4, micromatch@^4.0.5: +micromatch@4.0.5, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -2276,6 +3186,16 @@ micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -2283,6 +3203,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -2317,11 +3244,6 @@ nanoid@^3.3.6: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -2359,6 +3281,14 @@ nextjs-progressbar@^0.0.16: nprogress "^0.2.0" prop-types "^15.8.1" +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + node-releases@^2.0.13: version "2.0.13" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" @@ -2374,11 +3304,32 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + nprogress@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" integrity sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA== +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2461,6 +3412,30 @@ once@^1.3.0: dependencies: wrappy "1" +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + optionator@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" @@ -2494,6 +3469,16 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -2504,11 +3489,16 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -2529,6 +3519,11 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pidtree@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== + pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -2597,6 +3592,23 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.8.7: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +prettier@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.0.tgz#c6d16474a5f764ea1a4a373c593b779697744d5e" + integrity sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw== + prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" @@ -2739,11 +3751,24 @@ resolve@^2.0.0-next.4: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +restore-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" + integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -2751,6 +3776,13 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -2845,12 +3877,46 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + +slice-ansi@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-7.1.0.tgz#cd6b4655e298a8d1bdeb04250a433094b347b9a9" + integrity sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg== + dependencies: + ansi-styles "^6.2.1" + is-fullwidth-code-point "^5.0.0" + +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -2860,6 +3926,20 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +string-argv@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" + integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== + +string-width@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.0.0.tgz#14aa1b7aaa126d5b64fa79d3c894da8a9650ba06" + integrity sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw== + dependencies: + emoji-regex "^10.3.0" + get-east-asian-width "^1.0.0" + strip-ansi "^7.1.0" + string.prototype.matchall@^4.0.8: version "4.0.10" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" @@ -2909,11 +3989,28 @@ strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -2939,6 +4036,13 @@ sucrase@^3.32.0: pirates "^4.0.1" ts-interface-checker "^0.1.9" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -2951,11 +4055,37 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svg-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^3.0.2: + version "3.0.5" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.0.5.tgz#0595cf3c762c4e5180713d7b92dc67deaf46c6a0" + integrity sha512-HQKHEo73pMNOlDlBcLgZRcHW2+1wo7bFYayAXkGN0l/2+h68KjlfZyMRhdhaGvoHV2eApOovl12zoFz42sT6rQ== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^5.1.0" + css-tree "^2.2.1" + css-what "^6.1.0" + csso "5.0.5" + picocolors "^1.0.0" + swr@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8" integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw== +synckit@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" + integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== + dependencies: + "@pkgr/utils" "^2.3.1" + tslib "^2.5.0" + tailwindcss@^3.2.4: version "3.3.5" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.5.tgz#22a59e2fbe0ecb6660809d9cc5f3976b077be3b8" @@ -3008,6 +4138,16 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -3040,7 +4180,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.4.0: +tslib@^2.0.3, tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -3064,6 +4204,11 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^3.0.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" + integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== + typed-array-buffer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" @@ -3103,10 +4248,10 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typescript@^4.9.3: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43" + integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ== unbox-primitive@^1.0.2: version "1.0.2" @@ -3118,6 +4263,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" @@ -3203,16 +4353,35 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +wrap-ansi@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz#1a3dc8b70d85eeb8398ddfb1e4a02cd186e58b3e" + integrity sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q== + dependencies: + ansi-styles "^6.2.1" + string-width "^7.0.0" + strip-ansi "^7.1.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== + yaml@^2.1.1: version "2.3.3" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.3.tgz#01f6d18ef036446340007db8e016810e5d64aad9"