= ({
element={`Define the price you are willing to ${type} ${base.symbol} at. Make sure the price is in ${quote.symbol} tokens.`}
>
-
- Set {capitalize(type)} Price
+
+ Set {type} Price
({quote.symbol} per 1 {base.symbol})
diff --git a/src/components/simulator/input/SimInputStrategyType.tsx b/src/components/simulator/input/SimInputStrategyType.tsx
index 6a23de373..74f0398ee 100644
--- a/src/components/simulator/input/SimInputStrategyType.tsx
+++ b/src/components/simulator/input/SimInputStrategyType.tsx
@@ -1,4 +1,4 @@
-import { FC } from 'react';
+import { FC, ReactNode } from 'react';
import { Tooltip } from 'components/common/tooltip/Tooltip';
import { ReactComponent as IconTwoRanges } from 'assets/icons/recurring.svg';
import { ReactComponent as IconOverlappingStrategy } from 'assets/icons/overlapping.svg';
@@ -9,7 +9,7 @@ import { Link } from 'libs/routing';
interface ItemProps {
title: string;
label: SimulatorType;
- svg: JSX.Element;
+ svg: ReactNode;
tooltipText: string;
}
diff --git a/src/components/simulator/input/overlapping/CreateOverlappingStrategy.tsx b/src/components/simulator/input/overlapping/CreateOverlappingStrategy.tsx
index 30511e2ab..c23bedb49 100644
--- a/src/components/simulator/input/overlapping/CreateOverlappingStrategy.tsx
+++ b/src/components/simulator/input/overlapping/CreateOverlappingStrategy.tsx
@@ -47,6 +47,13 @@ export const CreateOverlappingStrategy: FC = (props) => {
const [touched, setTouched] = useState(false);
const [anchor, setAnchor] = useState<'buy' | 'sell' | undefined>();
+ useEffect(() => {
+ // Hack: on focus from input while scrolling as it prevents reactive state to behave correctly
+ if (document.activeElement instanceof HTMLInputElement) {
+ document.activeElement.blur();
+ }
+ }, [state.start]);
+
const { buyMarginal, sellMarginal } = useMemo(() => {
const min = state.buy.min;
const max = state.sell.max;
diff --git a/src/components/simulator/result/SimulatorProvider.tsx b/src/components/simulator/result/SimulatorProvider.tsx
index d897aa999..b5332bcee 100644
--- a/src/components/simulator/result/SimulatorProvider.tsx
+++ b/src/components/simulator/result/SimulatorProvider.tsx
@@ -5,7 +5,6 @@ import {
import { useTokens } from 'hooks/useTokens';
import { SimulatorData, SimulatorReturn, useGetSimulator } from 'libs/queries';
import { SimulatorResultSearch, useSearch } from 'libs/routing';
-import { isNil } from 'lodash';
import {
createContext,
FC,
@@ -45,7 +44,7 @@ const SimulatorCTX = createContext(undefined);
export const useSimulator = () => {
const ctx = useContext(SimulatorCTX);
- if (isNil(ctx)) {
+ if (ctx === null || ctx === undefined) {
throw new Error('No context found for simulator provider.');
}
return ctx;
@@ -81,7 +80,7 @@ export const SimulatorProvider: FC = ({ children }) => {
const status = useRef('idle');
const animationFrame = useRef(0);
const playbackSpeed = useRef('1x');
- const actionAfterBrushEnd = useRef<'run' | 'pause' | undefined>();
+ const actionAfterBrushEnd = useRef<'run' | 'pause' | null>(null);
const setPlaybackSpeed = (speed: PlaybackSpeed) => {
playbackSpeed.current = speed;
@@ -187,7 +186,7 @@ export const SimulatorProvider: FC = ({ children }) => {
status.current = 'running';
handleAnimationStep();
}
- actionAfterBrushEnd.current = undefined;
+ actionAfterBrushEnd.current = null;
};
useEffect(() => {
diff --git a/src/components/strategies/StrategyPageTabs.tsx b/src/components/strategies/StrategyPageTabs.tsx
index 5289c1650..4211f6566 100644
--- a/src/components/strategies/StrategyPageTabs.tsx
+++ b/src/components/strategies/StrategyPageTabs.tsx
@@ -1,11 +1,12 @@
import { Link, Pathnames, PathParams, useMatchRoute } from 'libs/routing';
+import { ReactNode } from 'react';
import { cn } from 'utils/helpers';
export interface StrategyTab {
label: string;
href: Pathnames;
params?: PathParams;
- icon: JSX.Element;
+ icon: ReactNode;
badge?: number;
}
@@ -45,7 +46,7 @@ export const StrategyPageTabs = ({ currentPathname, tabs }: Props) => {
>
{icon}
{label}
- {!!badge && (
+ {typeof badge === 'number' && (
{badge}
diff --git a/src/components/strategies/StrategySelectLayout.tsx b/src/components/strategies/StrategySelectLayout.tsx
new file mode 100644
index 000000000..f9331c668
--- /dev/null
+++ b/src/components/strategies/StrategySelectLayout.tsx
@@ -0,0 +1,48 @@
+import { useNavigate, useSearch } from '@tanstack/react-router';
+import { Radio, RadioGroup } from 'components/common/radio/RadioGroup';
+import { ReactComponent as IconGrid } from 'assets/icons/grid.svg';
+import { ReactComponent as IconTable } from 'assets/icons/table.svg';
+import { FC } from 'react';
+import { lsService } from 'services/localeStorage';
+
+export type StrategyLayout = 'grid' | 'table';
+
+const urls = {
+ explorer: '/explore/$type/$slug/' as const,
+ myStrategy: '/my-strategy-layout/' as const,
+};
+interface Props {
+ from: keyof typeof urls;
+}
+export const StrategySelectLayout: FC = ({ from }) => {
+ const config = { from: urls[from] };
+ const { layout = lsService.getItem('strategyLayout') } = useSearch(config);
+ const nav = useNavigate(config);
+ const set = (layout: StrategyLayout) => {
+ lsService.setItem('strategyLayout', layout);
+ nav({ search: (s) => ({ ...s, layout }) });
+ };
+ return (
+
+ set('grid')}
+ aria-label="List"
+ >
+
+
+ set('table')}
+ aria-label="Table"
+ >
+
+
+
+ );
+};
diff --git a/src/components/strategies/common/StrategyChartHistory.tsx b/src/components/strategies/common/StrategyChartHistory.tsx
index 581afcbcc..e63e54054 100644
--- a/src/components/strategies/common/StrategyChartHistory.tsx
+++ b/src/components/strategies/common/StrategyChartHistory.tsx
@@ -63,7 +63,7 @@ interface Props {
}
export const StrategyChartHistory: FC = (props) => {
- const timeout = useRef();
+ const timeout = useRef(null);
const { base, quote, type, order0, order1, activities } = props;
const { priceStart, priceEnd } = useSearch({ strict: false }) as TradeSearch;
const { marketPrice: externalPrice } = useMarketPrice({ base, quote });
diff --git a/src/components/strategies/common/StrategyChartOverlapping.tsx b/src/components/strategies/common/StrategyChartOverlapping.tsx
index bf37ebf1d..096aaf98f 100644
--- a/src/components/strategies/common/StrategyChartOverlapping.tsx
+++ b/src/components/strategies/common/StrategyChartOverlapping.tsx
@@ -67,7 +67,7 @@ export const StrategyChartOverlapping: FC = (props) => {
};
const OverlappingChartContent: FC = (props) => {
- const timeout = useRef();
+ const timeout = useRef(null);
const { base, quote, marketPrice, order0, order1, readonly, set } = props;
const search = useSearch({ strict: false }) as OverlappingSearch;
diff --git a/src/components/strategies/common/d3Chart/D3PriceHistory.tsx b/src/components/strategies/common/d3Chart/D3PriceHistory.tsx
index f48a7dc7e..46309028f 100644
--- a/src/components/strategies/common/d3Chart/D3PriceHistory.tsx
+++ b/src/components/strategies/common/d3Chart/D3PriceHistory.tsx
@@ -79,7 +79,7 @@ const useZoom = (
data: CandlestickData[],
behavior: TransformBehavior
) => {
- const zoomHandler = useRef>();
+ const zoomHandler = useRef>(null);
const [transform, setTransform] = useState();
const selection = select('#interactive-chart');
diff --git a/src/components/strategies/overview/StrategyContent.module.css b/src/components/strategies/overview/StrategyContent.module.css
index 5242341f2..1012a1146 100644
--- a/src/components/strategies/overview/StrategyContent.module.css
+++ b/src/components/strategies/overview/StrategyContent.module.css
@@ -1,8 +1,71 @@
.strategy-list {
contain: content;
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+ grid-template-columns: repeat(auto-fill, 375px);
+ justify-content: center;
}
-.strategy-list > li {
- /* content-visibility: auto; */ /* to prevent no tooltips when scrolling down */
- contain-intrinsic-size: auto 410px;
+.strategy-item {
+ height: 400px;
+ max-width: 375px;
+ content-visibility: auto; /* to prevent no tooltips when scrolling down */
+ contain-intrinsic-size: 375px 400px;
}
+@media (prefers-reduced-motion: no-preference) {
+ .animate-item {
+ animation: open-item 200ms var(--delay, 0ms) backwards;
+ }
+}
+.strategy-table {
+ @apply bg-background-900 text-14;
+ border-radius: 8px;
+ animation: open 300ms ease-out;
+}
+.strategy-table th {
+ @apply border-b border-background-800;
+ font-weight: 400;
+ color: rgba(255 255 255 / .6);
+ padding: 16px;
+ text-align: start;
+ text-wrap: nowrap;
+}
+.strategy-table td {
+ padding: 8px 16px;
+}
+.strategy-table td:first-child {
+ padding-left: 24px;
+}
+.strategy-table td:last-child {
+ padding-right: 24px;
+}
+.strategy-table th:first-child {
+ border-top-left-radius: 8px;
+}
+.strategy-table th:last-child {
+ border-top-right-radius: 8px;
+}
+.strategy-table tr:not(:last-child) td {
+ @apply border-b border-background-800;
+}
+.strategy-table tr:last-child td:first-child {
+ border-bottom-left-radius: 8px;
+}
+.strategy-table tr:last-child td:last-child {
+ border-bottom-right-radius: 8px;
+}
+
+@keyframes open {
+ from {
+ opacity: 0;
+ transform: translateY(10px);
+ }
+}
+
+@keyframes open-item {
+ from {
+ opacity: 0;
+ transform: scale(0.9);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
\ No newline at end of file
diff --git a/src/components/strategies/overview/StrategyContent.tsx b/src/components/strategies/overview/StrategyContent.tsx
index c986974f7..3239f7d70 100644
--- a/src/components/strategies/overview/StrategyContent.tsx
+++ b/src/components/strategies/overview/StrategyContent.tsx
@@ -1,17 +1,21 @@
import { FC, memo, ReactElement } from 'react';
import { StrategyWithFiat } from 'libs/queries';
-import { m } from 'libs/motion';
import { StrategyBlock } from 'components/strategies/overview/strategyBlock';
import { StrategyBlockCreate } from 'components/strategies/overview/strategyBlock';
import { CarbonLogoLoading } from 'components/common/CarbonLogoLoading';
import { cn } from 'utils/helpers';
+import { StrategyTable } from './StrategyTable';
+import { StrategyLayout } from '../StrategySelectLayout';
+import { lsService } from 'services/localeStorage';
import styles from './StrategyContent.module.css';
+import { useBreakpoints } from 'hooks/useBreakpoints';
type Props = {
strategies: StrategyWithFiat[];
isPending: boolean;
emptyElement: ReactElement;
isExplorer?: boolean;
+ layout?: StrategyLayout;
};
export const _StrategyContent: FC = ({
@@ -19,41 +23,54 @@ export const _StrategyContent: FC = ({
isExplorer,
isPending,
emptyElement,
+ layout = lsService.getItem('strategyLayout') || 'grid',
}) => {
+ const { belowBreakpoint } = useBreakpoints();
+
if (isPending) {
return (
-
+
);
}
if (!strategies?.length) return emptyElement;
+ if (layout === 'table' && !belowBreakpoint('xl')) {
+ return ;
+ }
+
return (
- {strategies.map((s) => (
-
- ))}
+ {strategies.map((s, i) => {
+ const animate = i < 12;
+ const style = { ['--delay' as any]: `${i * 50}ms` };
+ return (
+
+ );
+ })}
{!isExplorer && }
);
};
-export const StrategyContent = memo(
- _StrategyContent,
- (prev, next) =>
- prev.isPending === next.isPending &&
- JSON.stringify(prev.strategies) === JSON.stringify(next.strategies)
-);
+export const StrategyContent = memo(_StrategyContent, (prev, next) => {
+ if (prev.isPending !== next.isPending) return false;
+ if (prev.layout !== next.layout) return false;
+ return JSON.stringify(prev.strategies) === JSON.stringify(next.strategies);
+});
diff --git a/src/components/strategies/overview/StrategyFilterSort.tsx b/src/components/strategies/overview/StrategyFilterSort.tsx
index a451e7139..ad1a885e5 100644
--- a/src/components/strategies/overview/StrategyFilterSort.tsx
+++ b/src/components/strategies/overview/StrategyFilterSort.tsx
@@ -29,7 +29,7 @@ export const strategySort = {
pairAsc: 'Pair (A->Z)',
pairDesc: 'Pair (Z->A)',
totalBudgetDesc: 'Total Budget',
- trades: 'Trade Count',
+ trades: 'Trades',
};
export type StrategySort = keyof typeof strategySort;
diff --git a/src/components/strategies/overview/StrategyTable.tsx b/src/components/strategies/overview/StrategyTable.tsx
new file mode 100644
index 000000000..d179b4b4b
--- /dev/null
+++ b/src/components/strategies/overview/StrategyTable.tsx
@@ -0,0 +1,149 @@
+import { Link, useMatch } from '@tanstack/react-router';
+import { PairLogoName } from 'components/common/PairLogoName';
+import { StrategyWithFiat } from 'libs/queries';
+import { FC, useEffect, useId, useState } from 'react';
+import { StrategyStatusTag } from './strategyBlock/StrategyBlockHeader';
+import { useFiatCurrency } from 'hooks/useFiatCurrency';
+import { prettifyNumber, tokenAmount } from 'utils/helpers';
+import { StrategyGraph } from './strategyBlock/StrategyGraph';
+import { ReactComponent as DashboardIcon } from 'assets/icons/dashboard.svg';
+import {
+ ManageButtonIcon,
+ StrategyBlockManage,
+} from './strategyBlock/StrategyBlockManage';
+import styles from './StrategyContent.module.css';
+import { FiatPrice } from 'components/common/FiatPrice';
+import { Tooltip } from 'components/common/tooltip/Tooltip';
+
+interface Props {
+ strategies: StrategyWithFiat[];
+}
+export const StrategyTable: FC = ({ strategies }) => {
+ return (
+
+
+
+ ID |
+ Token Pair |
+ Status |
+ Trades |
+ Total Budget |
+ Buy Budget |
+ Sell Budget |
+ Price |
+ |
+
+
+
+ {strategies.map((strategy, index) => (
+
+ ))}
+
+
+ );
+};
+
+interface RowProps {
+ strategy: StrategyWithFiat;
+ initVisible: boolean;
+}
+const StrategyRow: FC = ({ strategy, initVisible }) => {
+ const id = useId();
+ const { base, quote, status, order0, order1 } = strategy;
+ const isExplorer = !!useMatch({ from: '/explore', shouldThrow: false });
+ const { selectedFiatCurrency: currentCurrency } = useFiatCurrency();
+ const totalBalance = strategy.fiatBudget.total;
+
+ const [visible, setVisible] = useState(initVisible);
+
+ useEffect(() => {
+ if (visible) return;
+ const el = document.getElementById(id);
+ if (!el) return;
+ const observer = new IntersectionObserver((entries) => {
+ for (const entry of entries) {
+ setVisible(entry.intersectionRatio > 0);
+ }
+ });
+ observer.observe(el);
+ return () => observer.disconnect();
+ }, [id, visible]);
+
+ if (!visible) return
;
+
+ return (
+
+ {strategy.idDisplay} |
+
+
+
+
+ |
+
+
+ |
+ {strategy.tradeCount} |
+
+
+
+ {prettifyNumber(totalBalance, {
+ currentCurrency,
+ abbreviate: true,
+ })}
+
+
+ |
+
+
+
+
+ {tokenAmount(order0.balance, quote, { abbreviate: true })}
+
+
+
+
+ |
+
+
+
+
+ {tokenAmount(order1.balance, base, { abbreviate: true })}
+
+
+
+
+ |
+
+
+ |
+
+
+
+
+
+ }
+ />
+
+ |
+
+ );
+};
diff --git a/src/components/strategies/overview/index.ts b/src/components/strategies/overview/index.ts
deleted file mode 100644
index 5a65bfc80..000000000
--- a/src/components/strategies/overview/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { StrategyContent } from './StrategyContent';
diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlock.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlock.tsx
index 30d1a6cb3..0e5b3c697 100644
--- a/src/components/strategies/overview/strategyBlock/StrategyBlock.tsx
+++ b/src/components/strategies/overview/strategyBlock/StrategyBlock.tsx
@@ -1,6 +1,5 @@
-import { FC } from 'react';
+import { CSSProperties, FC, useEffect, useId, useState } from 'react';
import { StrategyWithFiat } from 'libs/queries';
-import { m, mItemVariant } from 'libs/motion';
import { StrategyBlockBuySell } from 'components/strategies/overview/strategyBlock/StrategyBlockBuySell';
import { cn } from 'utils/helpers';
@@ -12,40 +11,62 @@ interface Props {
strategy: StrategyWithFiat;
className?: string;
isExplorer?: boolean;
+ style?: CSSProperties;
}
export const StrategyBlock: FC = ({
strategy,
className,
+ style,
isExplorer,
}) => {
+ const id = useId();
+ const [visible, setVisible] = useState(false);
+ useEffect(() => {
+ if (visible) return;
+ const el = document.getElementById(id);
+ if (!el) return;
+ const observer = new IntersectionObserver((entries) => {
+ for (const entry of entries) {
+ setVisible(entry.intersectionRatio > 0);
+ }
+ });
+ observer.observe(el);
+ return () => observer.disconnect();
+ }, [id, visible]);
+
return (
-
-
-
-
-
+ {visible && (
+ <>
+
+
+
+ >
+ )}
+
);
};
diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockCreate.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockCreate.tsx
index 193f562e6..7b9af6e79 100644
--- a/src/components/strategies/overview/strategyBlock/StrategyBlockCreate.tsx
+++ b/src/components/strategies/overview/strategyBlock/StrategyBlockCreate.tsx
@@ -13,7 +13,6 @@ export const StrategyBlockCreate: FC = ({
title = 'Create Strategy',
className = '',
}) => {
- console.log(`DEBUG: ${buttonStyles({ variant: 'success' })}`);
return (
carbonEvents.strategy.newStrategyCreateClick(undefined)}
diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockHeader.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockHeader.tsx
index 93104ba33..c30427b37 100644
--- a/src/components/strategies/overview/strategyBlock/StrategyBlockHeader.tsx
+++ b/src/components/strategies/overview/strategyBlock/StrategyBlockHeader.tsx
@@ -27,13 +27,15 @@ export const StrategyBlockHeader: FC = ({ strategy, isExplorer }) => {
size={40}
tokens={[base, quote]}
/>
-
-
- {base.symbol}
- /
- {quote.symbol}
-
-
+
+
+
+ {base.symbol}
+ /
+ {quote.symbol}
+
+
+
= (props) => {
- {status === 'active' && (
-
- {statusText.active}
-
- )}
- {status !== 'active' && (
-
-
- {statusText.inactive}
-
-
-
- )}
+
);
};
+
+export const StrategyStatusTag: FC<{
+ status: StrategyStatus;
+ isExplorer?: boolean;
+}> = (props) => {
+ const { status, isExplorer } = props;
+ if (status === 'active') {
+ return (
+
+ {statusText.active}
+
+ );
+ } else {
+ return (
+
+
+ {statusText.inactive}
+
+
+
+ );
+ }
+};
diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockManage.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockManage.tsx
index 2aa0236f6..554ca8b2c 100644
--- a/src/components/strategies/overview/strategyBlock/StrategyBlockManage.tsx
+++ b/src/components/strategies/overview/strategyBlock/StrategyBlockManage.tsx
@@ -2,7 +2,7 @@ import {
isOverlappingStrategy,
isPaused,
} from 'components/strategies/common/utils';
-import { FC, forwardRef, useState } from 'react';
+import { FC, forwardRef, ReactNode, useState } from 'react';
import { useModal } from 'hooks/useModal';
import { Strategy } from 'libs/queries';
import { useNavigate, useParams } from 'libs/routing';
@@ -45,7 +45,7 @@ type separatorCounterType = number;
interface Props {
strategy: Strategy;
- button: (props: ManageButtonProps) => JSX.Element;
+ button: (props: ManageButtonProps) => ReactNode;
}
export const StrategyBlockManage: FC
= (props) => {
diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockTradeCount.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockTradeCount.tsx
index 0eb61ebfd..4ce7fd55a 100644
--- a/src/components/strategies/overview/strategyBlock/StrategyBlockTradeCount.tsx
+++ b/src/components/strategies/overview/strategyBlock/StrategyBlockTradeCount.tsx
@@ -18,9 +18,7 @@ export const StrategyBlockTradeCount: FC = ({ strategy }) => {
strategy.status === 'active' ? '' : 'opacity-50'
)}
>
-
- Trade Count
-
+ Trades
{count}
);
diff --git a/src/components/strategies/overview/strategyBlock/StrategyGraph.tsx b/src/components/strategies/overview/strategyBlock/StrategyGraph.tsx
index 3f4dbc9a6..f5b731d58 100644
--- a/src/components/strategies/overview/strategyBlock/StrategyGraph.tsx
+++ b/src/components/strategies/overview/strategyBlock/StrategyGraph.tsx
@@ -1,4 +1,4 @@
-import { FC } from 'react';
+import { FC, useId } from 'react';
import { Strategy } from 'libs/queries';
import { cn, prettifyNumber, sanitizeNumber } from 'utils/helpers';
import {
@@ -17,6 +17,7 @@ import style from './StrategyGraph.module.css';
interface Props {
strategy: Strategy;
+ className?: string;
}
const isSmallRange = ({ order0, order1 }: Strategy) => {
@@ -49,7 +50,8 @@ const highest = width - 10;
const fontSize = 16;
const fontWidth = fontSize / 2;
-export const StrategyGraph: FC = ({ strategy }) => {
+export const StrategyGraph: FC = ({ strategy, className }) => {
+ const clipPathId = useId();
const { base, quote, order0: buyOrder, order1: sellOrder } = strategy;
const { marketPrice: currentPrice } = useMarketPrice({ base, quote });
const buy = {
@@ -161,7 +163,7 @@ export const StrategyGraph: FC = ({ strategy }) => {
return (
)}
- {!isPending && !hideChart && (
-
- )}
+ {!isPending && !hideChart &&
}
);
};
+
+interface ChartProps {
+ options?: Options;
+}
+const Chart: FC = ({ options }) => {
+ const [loading, setLoading] = useState(true);
+ const highchart = useRef(null);
+ useEffect(() => {
+ loadHighchart().then((chart) => {
+ highchart.current = chart;
+ setLoading(false);
+ });
+ }, []);
+ if (loading) return;
+ return ;
+};
diff --git a/src/components/trade/TradeExplorerTabs.tsx b/src/components/trade/TradeExplorerTabs.tsx
index 3b11f407b..5e337dc01 100644
--- a/src/components/trade/TradeExplorerTabs.tsx
+++ b/src/components/trade/TradeExplorerTabs.tsx
@@ -55,7 +55,7 @@ export const TradeExplorerTab: FC = ({ current }) => {
>
{icon}
{label}
- {!!badge && (
+ {typeof badge === 'number' && (
{badge}
diff --git a/src/fonts.css b/src/fonts.css
index bf96528e5..e7288918f 100644
--- a/src/fonts.css
+++ b/src/fonts.css
@@ -24,7 +24,7 @@
@font-face {
font-family: 'Carbon-Title';
font-weight: 500;
- font-display: swap;
+ font-display: block; /* Prevent layout shifting for 100ms. This font is the first to be seen (header) */
src: url('assets/font/title/medium.woff2') format('woff');
}
@@ -74,7 +74,7 @@
@font-face {
font-family: 'Carbon-Text';
font-weight: 400, normal;
- font-display: swap;
+ font-display: block;
src: url('assets/font/text/regular.ttf')
format('truetype');
}
diff --git a/src/hooks/useContract.ts b/src/hooks/useContract.ts
index b904b3cf0..dbf5a6fbd 100644
--- a/src/hooks/useContract.ts
+++ b/src/hooks/useContract.ts
@@ -1,8 +1,22 @@
import { useWagmi } from 'libs/wagmi';
import { Token__factory, Voucher__factory } from 'abis/types';
-import { useCallback, useMemo } from 'react';
+import { useCallback } from 'react';
+import { useQuery } from '@tanstack/react-query';
import config from 'config';
+export const useVoucher = () => {
+ const { provider, signer } = useWagmi();
+ return useQuery({
+ queryKey: ['contract', 'voucher'],
+ queryFn: () => ({
+ read: Voucher__factory.connect(
+ config.addresses.carbon.voucher,
+ provider!
+ ),
+ write: Voucher__factory.connect(config.addresses.carbon.voucher, signer!),
+ }),
+ });
+};
export const useContract = () => {
const { provider, signer } = useWagmi();
@@ -14,16 +28,5 @@ export const useContract = () => {
[provider, signer]
);
- const Voucher = useMemo(
- () => ({
- read: Voucher__factory.connect(
- config.addresses.carbon.voucher,
- provider!
- ),
- write: Voucher__factory.connect(config.addresses.carbon.voucher, signer!),
- }),
- [provider, signer]
- );
-
- return { Token, Voucher };
+ return { Token };
};
diff --git a/src/hooks/useDebounce.ts b/src/hooks/useDebounce.ts
deleted file mode 100644
index 677a5bd54..000000000
--- a/src/hooks/useDebounce.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { useMemo, useState } from 'react';
-import { debounce } from 'lodash';
-
-export const useDebounce = (
- initialState: any = null,
- interval: number = 500
-) => {
- const [state, setState] = useState(initialState);
-
- const setDebouncedState = (_val: string) => {
- debouncer(_val);
- };
-
- const debouncer = useMemo(
- () =>
- debounce((_prop: string) => {
- setState(_prop);
- }, interval),
- [interval]
- );
-
- return [state, setDebouncedState];
-};
diff --git a/src/hooks/useDimensions.ts b/src/hooks/useDimensions.ts
deleted file mode 100644
index 635a5976b..000000000
--- a/src/hooks/useDimensions.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { useRef, useEffect, useCallback } from 'react';
-import { useDebounce } from './useDebounce';
-
-const observerErr =
- "💡 react-cool-dimensions: the browser doesn't support Resize Observer, please use polyfill: https://github.com/wellyshen/react-cool-dimensions#resizeobserver-polyfill";
-const borderBoxWarn =
- "💡 react-cool-dimensions: the browser doesn't support border-box size, fallback to content-box size. Please see: https://github.com/wellyshen/react-cool-dimensions#border-box-size-measurement";
-
-interface State {
- readonly width: number;
- readonly height: number;
- readonly entry?: ResizeObserverEntry;
-}
-interface Observe {
- (element?: T | null): void;
-}
-interface Event extends State {
- readonly entry: ResizeObserverEntry;
- observe: Observe;
- unobserve: () => void;
-}
-interface Options {
- debouncedMs?: number;
- useBorderBoxSize?: boolean;
-}
-interface Return extends Omit, 'entry'> {
- entry?: ResizeObserverEntry;
-}
-
-const initialState: State = {
- width: 0,
- height: 0,
-};
-
-const useDimensions = ({
- debouncedMs,
- useBorderBoxSize,
-}: Options = {}): Return => {
- const [stateDebounced, setStateDebounced] = useDebounce(
- initialState,
- debouncedMs
- );
-
- const prevSizeRef = useRef<{ width?: number; height?: number }>({});
- const observerRef = useRef();
- const warnedRef = useRef(false);
- const ref = useRef();
-
- const unobserve = useCallback(() => {
- if (observerRef.current) observerRef.current.disconnect();
- }, []);
-
- const observe = useCallback>(
- (element) => {
- if (element && element !== ref.current) {
- unobserve();
- ref.current = element;
- }
- if (observerRef.current && ref.current)
- observerRef.current.observe(ref.current as HTMLElement);
- },
- [unobserve]
- );
-
- useEffect(() => {
- if (!('ResizeObserver' in window) || !('ResizeObserverEntry' in window)) {
- console.error(observerErr);
- return () => null;
- }
-
- let raf: number | null = null;
-
- observerRef.current = new ResizeObserver(([entry]) => {
- raf = requestAnimationFrame(() => {
- const { contentBoxSize, borderBoxSize, contentRect } = entry;
-
- let boxSize = contentBoxSize;
- if (useBorderBoxSize)
- if (borderBoxSize) {
- boxSize = borderBoxSize;
- } else if (!warnedRef.current) {
- console.warn(borderBoxWarn);
- warnedRef.current = true;
- }
-
- const width =
- boxSize && boxSize[0] ? boxSize[0].inlineSize : contentRect.width;
- const height =
- boxSize && boxSize[0] ? boxSize[0].blockSize : contentRect.height;
-
- const isUnchanged =
- width === prevSizeRef.current.width &&
- height === prevSizeRef.current.height;
-
- if (isUnchanged) {
- return;
- }
-
- prevSizeRef.current = { width, height };
-
- setStateDebounced({ width, height, entry });
- });
- });
-
- observe();
-
- return () => {
- unobserve();
- if (raf) cancelAnimationFrame(raf);
- };
- }, [observe, setStateDebounced, unobserve, useBorderBoxSize]);
-
- return { ...stateDebounced, observe, unobserve };
-};
-
-export default useDimensions;
diff --git a/src/hooks/useInterval.ts b/src/hooks/useInterval.ts
index 1bd7a31e2..484f1abe0 100644
--- a/src/hooks/useInterval.ts
+++ b/src/hooks/useInterval.ts
@@ -5,7 +5,7 @@ export const useInterval = (
delay: null | number,
leading = true
) => {
- const savedCallback = useRef<() => void>();
+ const savedCallback = useRef<() => void>(null);
useEffect(() => {
savedCallback.current = callback;
diff --git a/src/hooks/useKeyPress/index.ts b/src/hooks/useKeyPress/index.ts
deleted file mode 100644
index 767d4e833..000000000
--- a/src/hooks/useKeyPress/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { useCallback, useEffect, useState } from 'react';
-
-export const useKeyPress = () => {
- const [keyPressed, setKeyPressed] = useState('');
-
- const handleKeyDown = useCallback((event: KeyboardEvent) => {
- setKeyPressed(event.key);
- }, []);
-
- useEffect(() => {
- document.addEventListener('keydown', handleKeyDown);
-
- return () => {
- document.removeEventListener('keydown', handleKeyDown);
- };
- }, [handleKeyDown]);
-
- return {
- keyPressed,
- };
-};
diff --git a/src/hooks/useKeyPress/useKeyPress.test.ts b/src/hooks/useKeyPress/useKeyPress.test.ts
deleted file mode 100644
index 0c51dc112..000000000
--- a/src/hooks/useKeyPress/useKeyPress.test.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { useKeyPress } from '.';
-import { test, expect, vi, describe } from 'vitest';
-import { renderHook, act } from 'libs/testing-library';
-
-describe('useKeyPress', () => {
- test('Should update the keyPressed state when esc key is pressed', () => {
- const { result } = renderHook(() => useKeyPress());
- expect(result.current.keyPressed).toBe('');
-
- act(() => {
- const keyboardEvent = new KeyboardEvent('keydown', { key: 'esc' });
- document.dispatchEvent(keyboardEvent);
- });
- expect(result.current.keyPressed).toBe('esc');
- });
-
- test('Should remove the event listener when the component unmounts', () => {
- const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
- const { unmount } = renderHook(() => useKeyPress());
- expect(removeEventListenerSpy).not.toHaveBeenCalled();
- unmount();
- expect(removeEventListenerSpy).toHaveBeenCalled();
- });
-});
diff --git a/src/hooks/useModal.ts b/src/hooks/useModal.ts
index 3f579e5a0..0b4756678 100644
--- a/src/hooks/useModal.ts
+++ b/src/hooks/useModal.ts
@@ -1,9 +1,8 @@
-import { useCallback, useEffect } from 'react';
+import { useCallback } from 'react';
import { ModalKey } from 'libs/modals/modals.types';
import { uuid } from 'utils/helpers';
import { useStore } from 'store';
import { ModalSchema } from 'libs/modals/modals';
-import { useKeyPress } from './useKeyPress';
export const useModal = () => {
const {
@@ -12,8 +11,6 @@ export const useModal = () => {
} = useStore();
const { open: modalsOpen, minimized: modalsMinimized } = modals;
- const { keyPressed } = useKeyPress();
-
const openModal = useCallback(
(key: T, data: ModalSchema[T]) => {
if (key === 'wallet') {
@@ -42,11 +39,6 @@ export const useModal = () => {
[modalsOpen, setModalsOpen]
);
- useEffect(() => {
- keyPressed === 'Escape' && closeModal(activeModalId);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [keyPressed]);
-
const minimizeModal = (id: string) => {
const index = modalsOpen.findIndex((modal) => modal.id === id);
if (index > -1) {
diff --git a/src/hooks/useStrategies.tsx b/src/hooks/useStrategies.tsx
index a3ee61a9c..108924874 100644
--- a/src/hooks/useStrategies.tsx
+++ b/src/hooks/useStrategies.tsx
@@ -116,7 +116,7 @@ export const useStrategiesWithFiat = (
for (const item of tradeCountQuery.data ?? []) {
tradeCount[item.strategyId] = item.tradeCount;
}
- return strategies.map((strategy) => {
+ const result = strategies.map((strategy) => {
const basePrice = new SafeDecimal(prices[strategy.base.address] ?? 0);
const quotePrice = new SafeDecimal(prices[strategy.quote.address] ?? 0);
const base = basePrice.times(strategy.order1.balance);
@@ -128,6 +128,13 @@ export const useStrategiesWithFiat = (
tradeCount: tradeCount[strategy.id] ?? 0,
};
});
+ return {
+ strategies: result,
+ isPending:
+ query.isPending ||
+ priceQueries.some((q) => q.isPending) ||
+ tradeCountQuery.isPending,
+ };
};
type StrategyCtx = ReturnType;
@@ -148,8 +155,8 @@ interface StrategyProviderProps {
children: ReactNode;
}
export const StrategyProvider: FC = (props) => {
- const strategies = useStrategiesWithFiat(props.query);
- const ctx = useStrategyFilter(strategies, props.query.isPending);
+ const { strategies, isPending } = useStrategiesWithFiat(props.query);
+ const ctx = useStrategyFilter(strategies, isPending);
return (
{props.children}
diff --git a/src/hooks/useTokens.ts b/src/hooks/useTokens.ts
index c716a2ffd..63e9510ca 100644
--- a/src/hooks/useTokens.ts
+++ b/src/hooks/useTokens.ts
@@ -8,7 +8,7 @@ import { useWagmi } from 'libs/wagmi';
export const useTokens = () => {
const { user } = useWagmi();
const {
- tokens: { tokensMap, importedTokens, setImportedTokens, ...props },
+ tokens: { tokensMap, setImportedTokens, ...props },
} = useStore();
const getTokenById = useCallback(
@@ -16,23 +16,21 @@ export const useTokens = () => {
[tokensMap]
);
- const importToken = useCallback(
- (token: Token) => {
- const normalizedAddress = utils.getAddress(token.address);
- const exists =
- tokensMap.has(normalizedAddress) ||
- !!importedTokens.find((tkn) => tkn.address === normalizedAddress);
- if (exists) return;
+ const importTokens = useCallback(
+ (tokens: Token[]) => {
+ const missing: Token[] = [];
+ for (const token of tokens) {
+ if (getTokenById(token.address)) continue;
+ const normalizedAddress = utils.getAddress(token.address);
+ missing.push({ ...token, address: normalizedAddress });
+ }
const lsImportedTokens = lsService.getItem('importedTokens') ?? [];
- const newTokens = [
- ...lsImportedTokens,
- { ...token, address: normalizedAddress },
- ];
+ const newTokens = [...lsImportedTokens, ...missing];
setImportedTokens(newTokens);
lsService.setItem('importedTokens', newTokens);
},
- [tokensMap, importedTokens, setImportedTokens]
+ [getTokenById, setImportedTokens]
);
const [favoriteTokens, _setFavoriteTokens] = useState(
@@ -66,7 +64,7 @@ export const useTokens = () => {
return {
...props,
getTokenById,
- importToken,
+ importTokens,
addFavoriteToken,
removeFavoriteToken,
favoriteTokens,
diff --git a/src/index.css b/src/index.css
index c3f26d773..b82817b81 100644
--- a/src/index.css
+++ b/src/index.css
@@ -16,6 +16,12 @@
--main-menu-height: 80px;
--mobile-menu-height: 80px;
+
+ --ease-in: cubic-bezier(.55, 0, 1, .45);
+ --ease-out: cubic-bezier(0, .55, .45, 1);
+ --ease-in-out: cubic-bezier(.85, 0, .15, 1);
+ --ease-back-in-out: cubic-bezier(.68, -.6, .32, 1.6);
+ --ease-back-out: cubic-bezier(.34, 1.56, .64, 1);
}
@@ -23,7 +29,11 @@
html,
body,
#root {
- @apply text-white bg-black font-text w-full min-h-screen;
+ @apply text-white bg-black font-text min-h-screen;
+ }
+
+ html {
+ scrollbar-gutter: stable both-edges; /* Prevent layout shifting */
}
h1, h2, th {
@@ -264,3 +274,37 @@
input[type='search']::-webkit-search-cancel-button {
display: none;
}
+
+dialog.modal, dialog.modal::backdrop {
+ transition-behavior: allow-discrete;
+ transition-property: display, overlay, opacity, transform;
+ transition-duration: 0.5s;
+ transition-timing-function: var(--ease-back-in-out);
+}
+@starting-style {
+ dialog.modal[open] {
+ opacity: 0;
+ transform: translateY(100px);
+ }
+ dialog.modal[open]::backdrop {
+ opacity: 0;
+ }
+}
+dialog.modal:not([open]) {
+ opacity: 0;
+ transform: scale(0.8);
+}
+dialog.modal:not([open])::backdrop {
+ opacity: 0;
+}
+dialog.modal form {
+ @apply bg-background-900;
+ border-radius: 8px;
+ padding: 16px;
+ max-width: 390px;
+ transition: transform 0.3s var(--ease-out);
+}
+dialog.modal::backdrop {
+ @apply bg-black/40;
+ backdrop-filter: blur(8px);
+}
\ No newline at end of file
diff --git a/src/index.tsx b/src/index.tsx
index ce7f7112d..1f6a90641 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -8,7 +8,6 @@ import { LazyMotion } from 'libs/motion';
import { QueryProvider } from 'libs/queries';
import { RouterProvider, router } from 'libs/routing';
import 'init-sentry';
-import 'utils/buffer';
import 'fonts.css';
import 'index.css';
import 'init-config';
diff --git a/src/init-sentry.ts b/src/init-sentry.ts
index dd8d2770a..63877c6eb 100644
--- a/src/init-sentry.ts
+++ b/src/init-sentry.ts
@@ -7,14 +7,10 @@ if (config.sentryDSN) {
dsn: config.sentryDSN,
integrations: [
Sentry.tanstackRouterBrowserTracingIntegration(router),
- Sentry.replayIntegration(),
Sentry.captureConsoleIntegration({ levels: ['error'] }),
],
// Performance Monitoring
tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production!
- // Session Replay
- replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
- replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
});
}
diff --git a/src/libs/charts/index.ts b/src/libs/charts/index.ts
index 152a3b0d0..aba977286 100644
--- a/src/libs/charts/index.ts
+++ b/src/libs/charts/index.ts
@@ -1,9 +1,16 @@
-import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
-import highchartsAccessibility from 'highcharts/modules/accessibility';
+import type Highcharts from 'highcharts';
-highchartsAccessibility(Highcharts);
+export const loadHighchart = async () => {
+ const [{ default: Highcharts }, { default: highchartsAccessibility }] =
+ await Promise.all([
+ import('highcharts'),
+ import('highcharts/modules/accessibility'),
+ ]);
+ highchartsAccessibility(Highcharts);
+ return Highcharts;
+};
//@ts-ignore
-export { Highcharts, HighchartsReact };
+export { HighchartsReact, Highcharts };
export type { Options } from 'highcharts/highcharts';
diff --git a/src/libs/d3/useChartDimensions.ts b/src/libs/d3/useChartDimensions.ts
index cc45326bf..20965747e 100644
--- a/src/libs/d3/useChartDimensions.ts
+++ b/src/libs/d3/useChartDimensions.ts
@@ -3,7 +3,7 @@ import { RefObject, useEffect, useRef, useState } from 'react';
export const useChartDimensions = (
settings: D3ChartSettingsProps
-): [RefObject, D3ChartSettings] => {
+): [RefObject, D3ChartSettings] => {
const ref = useRef(null);
const dimensions = combineChartDimensions(settings);
const [width, setWidth] = useState(dimensions.width);
diff --git a/src/libs/modals/Modal.tsx b/src/libs/modals/Modal.tsx
index ff25d86cd..6bba9c639 100644
--- a/src/libs/modals/Modal.tsx
+++ b/src/libs/modals/Modal.tsx
@@ -37,7 +37,7 @@ export const Modal: FC = ({
return (
onCloseHandler(id)}
+ close={() => onCloseHandler(id)}
className="px-content items-center justify-center"
>
= ({
};
return (
- onCloseHandler(id)} className="items-end">
+ onCloseHandler(id)} className="items-end">
e.stopPropagation()}
diff --git a/src/libs/modals/ModalSlideOver.tsx b/src/libs/modals/ModalSlideOver.tsx
index 104319452..e66ecca8b 100644
--- a/src/libs/modals/ModalSlideOver.tsx
+++ b/src/libs/modals/ModalSlideOver.tsx
@@ -4,6 +4,8 @@ import { useModal } from 'hooks/useModal';
import { ReactComponent as IconX } from 'assets/icons/X.svg';
import { Overlay } from 'libs/modals/Overlay';
import { ModalProps } from 'libs/modals/modals.types';
+import { cn } from 'utils/helpers';
+import styles from './modal.module.css';
const getSize = (size: 'sm' | 'md' | 'lg') => {
switch (size) {
@@ -27,7 +29,10 @@ export const ModalSlideOver: FC = ({
const sizeClass = getSize(size);
return (
- closeModal(id)} className="justify-end">
+ closeModal(id)}
+ className={cn('justify-end', styles.modalSlider)}
+ >
e.stopPropagation()}
className={`relative w-full ${sizeClass}`}
diff --git a/src/libs/modals/Overlay.tsx b/src/libs/modals/Overlay.tsx
index 1d72e8085..966db3766 100644
--- a/src/libs/modals/Overlay.tsx
+++ b/src/libs/modals/Overlay.tsx
@@ -1,17 +1,20 @@
import { m, Variants } from 'libs/motion';
-import { FC, MouseEventHandler, ReactNode } from 'react';
+import { FC, ReactNode } from 'react';
import { cn } from 'utils/helpers';
type Props = {
className?: string;
- onClick?: MouseEventHandler | undefined;
+ close?: () => void | undefined;
children: ReactNode;
};
-export const Overlay: FC = ({ children, onClick, className }) => {
+export const Overlay: FC = ({ children, close, className }) => {
return (
{
+ if (e.key === 'Escape' && close) close();
+ }}
+ onClick={close}
variants={fadeIn}
initial="hidden"
animate="visible"
diff --git a/src/libs/modals/modal.module.css b/src/libs/modals/modal.module.css
new file mode 100644
index 000000000..ba74240c3
--- /dev/null
+++ b/src/libs/modals/modal.module.css
@@ -0,0 +1,3 @@
+.modal-slider {
+ scrollbar-gutter: stable;
+}
\ No newline at end of file
diff --git a/src/libs/modals/modals/ModalImportToken.tsx b/src/libs/modals/modals/ModalImportToken.tsx
index 428ba76a1..fc47baf6b 100644
--- a/src/libs/modals/modals/ModalImportToken.tsx
+++ b/src/libs/modals/modals/ModalImportToken.tsx
@@ -21,13 +21,13 @@ export const ModalImportToken: ModalFC = ({
}) => {
const { closeModal } = useModal();
const { data, isPending, isError } = useGetTokenData(address);
- const { importToken } = useTokens();
+ const { importTokens } = useTokens();
const onClick = () => {
if (!data) {
return;
}
- importToken(data);
+ importTokens([data]);
closeModal(id);
};
diff --git a/src/libs/modals/modals/ModalTokenList/useModalTokenList.ts b/src/libs/modals/modals/ModalTokenList/useModalTokenList.ts
index df94cfbf2..0a62c7aff 100644
--- a/src/libs/modals/modals/ModalTokenList/useModalTokenList.ts
+++ b/src/libs/modals/modals/ModalTokenList/useModalTokenList.ts
@@ -5,7 +5,6 @@ import { useModal } from 'hooks/useModal';
import Fuse from 'fuse.js';
import { utils } from 'ethers';
import { ModalTokenListData } from 'libs/modals/modals/ModalTokenList/ModalTokenList';
-import { orderBy } from 'lodash';
import config from 'config';
import {
NATIVE_TOKEN_ADDRESS,
@@ -114,7 +113,7 @@ export const useModalTokenList = ({ id, data }: Props) => {
const filteredTokens = useMemo(() => {
if (search.length === 0) {
- return orderBy(sanitizedTokens, 'symbol', 'asc');
+ return sanitizedTokens.sort((a, b) => a.symbol.localeCompare(b.symbol));
}
const isAddress = utils.isAddress(search.toLowerCase());
diff --git a/src/libs/queries/chain/voucher.ts b/src/libs/queries/chain/voucher.ts
index 158e7aabe..6818c9ef7 100644
--- a/src/libs/queries/chain/voucher.ts
+++ b/src/libs/queries/chain/voucher.ts
@@ -1,15 +1,15 @@
import { useQuery } from '@tanstack/react-query';
-import { useContract } from 'hooks/useContract';
+import { useVoucher } from 'hooks/useContract';
import { QueryKey } from 'libs/queries/queryKey';
import { ONE_DAY_IN_MS } from 'utils/time';
export const useGetVoucherOwner = (id?: string) => {
- const { Voucher } = useContract();
+ const { data: contract, isPending } = useVoucher();
return useQuery({
queryKey: QueryKey.voucherOwner(id),
- queryFn: () => Voucher.read.ownerOf(id ?? ''),
- enabled: !!id,
+ queryFn: () => contract?.read.ownerOf(id ?? ''),
+ enabled: !!id && !isPending,
retry: 1,
staleTime: ONE_DAY_IN_MS,
});
diff --git a/src/libs/queries/extApi/tokenPrice.ts b/src/libs/queries/extApi/tokenPrice.ts
index af89d9830..1a5d976d6 100644
--- a/src/libs/queries/extApi/tokenPrice.ts
+++ b/src/libs/queries/extApi/tokenPrice.ts
@@ -42,6 +42,7 @@ export const useGetMultipleTokenPrices = (addresses: string[] = []) => {
refetchInterval: FIVE_MIN_IN_MS,
staleTime: FIVE_MIN_IN_MS,
refetchOnWindowFocus: false,
+ retry: 0, // Critical for initial load
};
}),
});
diff --git a/src/libs/queries/extApi/tokens.ts b/src/libs/queries/extApi/tokens.ts
index dcb1b3da2..447a2cffc 100644
--- a/src/libs/queries/extApi/tokens.ts
+++ b/src/libs/queries/extApi/tokens.ts
@@ -8,13 +8,16 @@ export const useTokensQuery = () => {
return useQuery({
queryKey: QueryKey.tokens(),
queryFn: async () => {
+ const local = lsService.getItem('tokenListCache');
+ if (local && local.timestamp > Date.now() - ONE_HOUR_IN_MS) {
+ return local.tokens;
+ }
const tokens = buildTokenList(await fetchTokenLists());
lsService.setItem('tokenListCache', { tokens, timestamp: Date.now() });
return tokens;
},
staleTime: ONE_HOUR_IN_MS,
- initialData: lsService.getItem('tokenListCache')?.tokens,
- initialDataUpdatedAt: lsService.getItem('tokenListCache')?.timestamp,
+ placeholderData: (previous) => previous,
meta: {
errorMessage: 'useTokensQuery failed with error:',
},
diff --git a/src/libs/queries/queryKey.ts b/src/libs/queries/queryKey.ts
index f6502e975..20fdcc647 100644
--- a/src/libs/queries/queryKey.ts
+++ b/src/libs/queries/queryKey.ts
@@ -55,6 +55,12 @@ export namespace QueryKey {
token0,
token1,
];
+ export const strategiesByToken = (token?: string) => [
+ ...sdk,
+ 'strategies',
+ 'token',
+ token,
+ ];
export const approval = (user: string, token: string, spender: string) => [
...chain,
diff --git a/src/libs/queries/sdk/pairs.ts b/src/libs/queries/sdk/pairs.ts
index 343628911..cdf83a66c 100644
--- a/src/libs/queries/sdk/pairs.ts
+++ b/src/libs/queries/sdk/pairs.ts
@@ -3,39 +3,48 @@ import { QueryKey } from 'libs/queries/queryKey';
import { fetchTokenData } from 'libs/tokens/tokenHelperFn';
import { useContract } from 'hooks/useContract';
import { useTokens } from 'hooks/useTokens';
-import { ONE_DAY_IN_MS } from 'utils/time';
-import { useCarbonInit } from 'hooks/useCarbonInit';
+import { ONE_HOUR_IN_MS } from 'utils/time';
import { carbonSDK } from 'libs/sdk';
import { lsService } from 'services/localeStorage';
-
-const getCachedData = () => {
- const cachedPairs = lsService.getItem('tokenPairsCache');
- if (cachedPairs && cachedPairs.timestamp > Date.now() - 1000 * 60 * 60) {
- return cachedPairs.pairs;
- }
- return undefined;
-};
+import { useState } from 'react';
+import { Token } from 'libs/tokens';
export const useGetTradePairsData = () => {
- const { isInitialized } = useCarbonInit();
const { Token } = useContract();
- const { tokens, getTokenById, importToken } = useTokens();
-
- const _getTknData = async (address: string) => {
- const data = await fetchTokenData(Token, address);
- importToken(data);
- return data;
- };
+ const { tokens, getTokenById, importTokens } = useTokens();
+ const [cache] = useState(lsService.getItem('tokenPairsCache'));
return useQuery({
queryKey: QueryKey.pairs(),
queryFn: async () => {
const pairs = await carbonSDK.getAllPairs();
- const promises = pairs.map(async (pair) => ({
- baseToken: getTokenById(pair[0]) ?? (await _getTknData(pair[0])),
- quoteToken: getTokenById(pair[1]) ?? (await _getTknData(pair[1])),
+ const tokens = new Map();
+ const missing = new Set();
+
+ const markForMissing = (address: string) => {
+ if (tokens.has(address)) return;
+ const existing = getTokenById(address);
+ if (existing) tokens.set(address, existing);
+ else missing.add(address);
+ };
+
+ for (const pair of pairs) {
+ markForMissing(pair[0]);
+ markForMissing(pair[1]);
+ }
+
+ const getMissing = Array.from(missing).map(async (address) => {
+ const token = await fetchTokenData(Token, address);
+ tokens.set(address, token);
+ return token;
+ });
+ const missingTokens = await Promise.all(getMissing);
+ importTokens(missingTokens);
+
+ const result = pairs.map((pair) => ({
+ baseToken: tokens.get(pair[0])!,
+ quoteToken: tokens.get(pair[1])!,
}));
- const result = await Promise.all(promises);
const pairsWithInverse = [
...result,
@@ -52,9 +61,10 @@ export const useGetTradePairsData = () => {
return pairsWithInverse;
},
- placeholderData: getCachedData(),
- enabled: !!tokens.length && isInitialized,
+ initialData: cache?.pairs,
+ initialDataUpdatedAt: cache?.timestamp,
+ enabled: !!tokens.length,
retry: 1,
- staleTime: ONE_DAY_IN_MS,
+ staleTime: ONE_HOUR_IN_MS,
});
};
diff --git a/src/libs/queries/sdk/strategy.ts b/src/libs/queries/sdk/strategy.ts
index 4d9b46191..4fbab5726 100644
--- a/src/libs/queries/sdk/strategy.ts
+++ b/src/libs/queries/sdk/strategy.ts
@@ -10,7 +10,6 @@ import { useContract } from 'hooks/useContract';
import config from 'config';
import { ONE_DAY_IN_MS } from 'utils/time';
import { useTokens } from 'hooks/useTokens';
-import { useCarbonInit } from 'hooks/useCarbonInit';
import {
EncodedStrategyBNStr,
StrategyUpdate,
@@ -20,6 +19,8 @@ import { MarginalPriceOptions } from '@bancor/carbon-sdk/strategy-management';
import { carbonSDK } from 'libs/sdk';
import { getLowestBits } from 'utils/helpers';
import { useGetAddressFromEns } from 'libs/queries/chain/ens';
+import { getAddress } from 'ethers/lib/utils';
+import { usePairs } from 'hooks/usePairs';
export type StrategyStatus = 'active' | 'noBudget' | 'paused' | 'inactive';
@@ -53,27 +54,42 @@ export interface StrategyWithFiat extends Strategy {
interface StrategiesHelperProps {
strategies: SDKStrategy[];
getTokenById: (id: string) => Token | undefined;
- importToken: (token: Token) => void;
+ importTokens: (tokens: Token[]) => void;
Token: (address: string) => { read: TokenContract };
}
const buildStrategiesHelper = async ({
strategies,
getTokenById,
- importToken,
+ importTokens,
Token,
}: StrategiesHelperProps) => {
- const _getTknData = async (address: string) => {
- const data = await fetchTokenData(Token, address);
- importToken(data);
- return data;
+ const tokens = new Map();
+ const missing = new Set();
+
+ const markForMissing = (address: string) => {
+ if (tokens.has(address)) return;
+ const existing = getTokenById(address);
+ if (existing) tokens.set(address, existing);
+ else missing.add(address);
};
- const promises = strategies.map(async (s) => {
- const base = getTokenById(s.baseToken) || (await _getTknData(s.baseToken));
- const quote =
- getTokenById(s.quoteToken) || (await _getTknData(s.quoteToken));
+ for (const strategy of strategies) {
+ markForMissing(strategy.baseToken);
+ markForMissing(strategy.quoteToken);
+ }
+ const getMissing = Array.from(missing).map(async (address) => {
+ const token = await fetchTokenData(Token, address);
+ tokens.set(address, token);
+ return token;
+ });
+ const missingTokens = await Promise.all(getMissing);
+ importTokens(missingTokens);
+
+ return strategies.map((s) => {
+ const base = tokens.get(s.baseToken)!;
+ const quote = tokens.get(s.quoteToken)!;
const sellLow = new SafeDecimal(s.sellPriceLow);
const sellHigh = new SafeDecimal(s.sellPriceHigh);
const sellBudget = new SafeDecimal(s.sellBudget);
@@ -119,7 +135,7 @@ const buildStrategiesHelper = async ({
marginalRate: s.sellPriceMarginal,
};
- const strategy: Strategy = {
+ return {
id: s.id,
idDisplay: getLowestBits(s.id),
base,
@@ -128,12 +144,8 @@ const buildStrategiesHelper = async ({
order1,
status,
encoded: s.encoded,
- };
-
- return strategy;
+ } as Strategy;
});
-
- return await Promise.all(promises);
};
interface Props {
@@ -141,8 +153,7 @@ interface Props {
}
export const useGetUserStrategies = ({ user }: Props) => {
- const { isInitialized } = useCarbonInit();
- const { tokens, getTokenById, importToken } = useTokens();
+ const { tokens, getTokenById, importTokens } = useTokens();
const { Token } = useContract();
const ensAddress = useGetAddressFromEns(user || '');
@@ -155,24 +166,22 @@ export const useGetUserStrategies = ({ user }: Props) => {
queryKey: QueryKey.strategies(address),
queryFn: async () => {
if (!address || !isValidAddress || isZeroAddress) return [];
-
const strategies = await carbonSDK.getUserStrategies(address);
return buildStrategiesHelper({
strategies,
getTokenById,
- importToken,
+ importTokens,
Token,
});
},
- enabled: tokens.length > 0 && isInitialized && ensAddress.isFetched,
+ enabled: tokens.length > 0 && ensAddress.isFetched,
staleTime: ONE_DAY_IN_MS,
retry: false,
});
};
export const useGetStrategy = (id: string) => {
- const { isInitialized } = useCarbonInit();
- const { tokens, getTokenById, importToken } = useTokens();
+ const { tokens, getTokenById, importTokens } = useTokens();
const { Token } = useContract();
return useQuery({
@@ -182,12 +191,12 @@ export const useGetStrategy = (id: string) => {
const strategies = await buildStrategiesHelper({
strategies: [strategy],
getTokenById,
- importToken,
+ importTokens,
Token,
});
return strategies[0];
},
- enabled: tokens.length > 0 && isInitialized,
+ enabled: tokens.length > 0,
staleTime: ONE_DAY_IN_MS,
retry: false,
});
@@ -199,8 +208,7 @@ interface PropsPair {
}
export const useGetPairStrategies = ({ token0, token1 }: PropsPair) => {
- const { isInitialized } = useCarbonInit();
- const { tokens, getTokenById, importToken } = useTokens();
+ const { tokens, getTokenById, importTokens } = useTokens();
const { Token } = useContract();
return useQuery({
@@ -211,11 +219,55 @@ export const useGetPairStrategies = ({ token0, token1 }: PropsPair) => {
return buildStrategiesHelper({
strategies,
getTokenById,
- importToken,
+ importTokens,
+ Token,
+ });
+ },
+ enabled: !token0 || !token1 || tokens.length > 0,
+ staleTime: ONE_DAY_IN_MS,
+ retry: false,
+ });
+};
+
+interface PropsPair {
+ token0?: string;
+ token1?: string;
+}
+
+export const useTokenStrategies = (token?: string) => {
+ const { getTokenById, importTokens } = useTokens();
+ const { Token } = useContract();
+ const { map: pairMap } = usePairs();
+ return useQuery({
+ queryKey: QueryKey.strategiesByToken(token),
+ queryFn: async () => {
+ const allQuotes = new Set();
+ const base = getAddress(token!);
+ for (const { baseToken, quoteToken } of pairMap.values()) {
+ if (baseToken.address === base) allQuotes.add(quoteToken.address);
+ if (quoteToken.address === base) allQuotes.add(baseToken.address);
+ }
+ const getStrategies: Promise[] = [];
+ for (const quote of allQuotes) {
+ getStrategies.push(carbonSDK.getStrategiesByPair(base, quote));
+ }
+
+ const allResponses = await Promise.allSettled(getStrategies);
+ for (const res of allResponses) {
+ if (res.status === 'rejected') console.error(res.reason);
+ }
+ const allStrategies = allResponses
+ .filter((v) => v.status === 'fulfilled')
+ .map((v) => (v as PromiseFulfilledResult).value);
+ const result = await buildStrategiesHelper({
+ strategies: allStrategies.flat(),
+ getTokenById,
+ importTokens,
Token,
});
+ return result;
},
- enabled: tokens.length > 0 && isInitialized,
+ enabled: !!token && !!pairMap.size,
staleTime: ONE_DAY_IN_MS,
retry: false,
});
diff --git a/src/libs/routing/routes/explorer.ts b/src/libs/routing/routes/explorer.ts
index 62716c35d..dc2995c05 100644
--- a/src/libs/routing/routes/explorer.ts
+++ b/src/libs/routing/routes/explorer.ts
@@ -8,8 +8,9 @@ import { ExplorerTypeOverviewPage } from 'pages/explorer/type/overview';
import { ExplorerTypePortfolioPage } from 'pages/explorer/type/portfolio';
import { ExplorerTypePortfolioTokenPage } from 'pages/explorer/type/portfolio/token';
import { validateActivityParams } from 'components/activity/utils';
-import { getLastVisitedPair } from '../utils';
+import { getLastVisitedPair, searchValidator } from '../utils';
import { toPairSlug } from 'utils/pairSearch';
+import * as v from 'valibot';
// Used for redirecting old explorer route to new explorer route
// TODO: remove this on May 2024
@@ -82,6 +83,9 @@ export const explorerOverviewPage = createRoute({
getParentRoute: () => explorerResultLayout,
path: '/',
component: ExplorerTypeOverviewPage,
+ validateSearch: searchValidator({
+ layout: v.optional(v.picklist(['grid', 'table'])),
+ }),
});
export const explorerPortfolioLayout = createRoute({
diff --git a/src/libs/routing/routes/myStrategies.ts b/src/libs/routing/routes/myStrategies.ts
index 82a715081..aa1692d57 100644
--- a/src/libs/routing/routes/myStrategies.ts
+++ b/src/libs/routing/routes/myStrategies.ts
@@ -22,6 +22,7 @@ export const strategyOverviewPage = createRoute({
component: StrategiesOverviewPage,
validateSearch: searchValidator({
search: v.optional(validString),
+ layout: v.optional(v.picklist(['grid', 'table'])),
}),
postSearchFilters: [
(search: MyStrategiesSearch) => {
diff --git a/src/libs/testing-library/utils/types.ts b/src/libs/testing-library/utils/types.ts
index 9be7c017a..d6669c8be 100644
--- a/src/libs/testing-library/utils/types.ts
+++ b/src/libs/testing-library/utils/types.ts
@@ -1,5 +1,7 @@
+import { ReactNode } from 'react';
+
export type RouterRenderParams = {
- component: () => JSX.Element;
+ component: () => ReactNode;
basePath?: string;
search?: Record;
params?: Record;
diff --git a/src/libs/tokens/tokenHelperFn.ts b/src/libs/tokens/tokenHelperFn.ts
index d57c500eb..40f8362b6 100644
--- a/src/libs/tokens/tokenHelperFn.ts
+++ b/src/libs/tokens/tokenHelperFn.ts
@@ -1,10 +1,9 @@
-import { uniqBy } from 'lodash';
import { utils } from 'ethers';
import { Token, TokenList } from 'libs/tokens/token.types';
import { Token as TokenContract } from 'abis/types';
import { lsService } from 'services/localeStorage';
-import config from 'config';
import { tokenParserMap } from 'config/utils';
+import config from 'config';
const getLogoByURI = (uri: string | undefined) =>
uri && uri.startsWith('ipfs') ? buildIpfsUri(uri.split('//')[1]) : uri;
@@ -67,9 +66,10 @@ export const buildTokenList = (tokenList: TokenList[]): Token[] => {
tokens.push(...merged);
const lsImportedTokens = lsService.getItem('importedTokens') ?? [];
- tokens.push(...lsImportedTokens);
-
- return uniqBy(tokens, (token: Token) => token.address);
+ const result = new Map();
+ for (const token of lsImportedTokens) result.set(token.address, token);
+ for (const token of tokens) result.set(token.address, token);
+ return Array.from(result.values());
};
export const fetchTokenData = async (
diff --git a/src/libs/twmerge/index.ts b/src/libs/twmerge/index.ts
index 5566eb839..154613f0e 100644
--- a/src/libs/twmerge/index.ts
+++ b/src/libs/twmerge/index.ts
@@ -92,6 +92,7 @@ export const customTwMerge = extendTailwindMerge({
'ping',
'pulse',
'bounce',
+ 'fade',
'slideUp',
'scaleUp',
],
diff --git a/src/pages/explorer/index.tsx b/src/pages/explorer/index.tsx
index 69230173a..80cd9c631 100644
--- a/src/pages/explorer/index.tsx
+++ b/src/pages/explorer/index.tsx
@@ -20,8 +20,7 @@ export const ExplorerPage = () => {
if (slug && type === 'token-pair') {
// Set last visited pair
const [base, quote] = slug.split('_');
- lsService.setItem('tradePair', [base, quote]);
- return;
+ if (base && quote) lsService.setItem('tradePair', [base, quote]);
}
}, [slug, navigate, type]);
@@ -34,7 +33,7 @@ export const ExplorerPage = () => {
-
+
{slug &&
}
diff --git a/src/pages/explorer/type/overview/index.tsx b/src/pages/explorer/type/overview/index.tsx
index 86eea8ae5..ca88af190 100644
--- a/src/pages/explorer/type/overview/index.tsx
+++ b/src/pages/explorer/type/overview/index.tsx
@@ -1,9 +1,11 @@
-import { StrategyContent } from 'components/strategies/overview';
+import { StrategyContent } from 'components/strategies/overview/StrategyContent';
import { useStrategyCtx } from 'hooks/useStrategies';
import { NotFound } from 'components/common/NotFound';
+import { useSearch } from '@tanstack/react-router';
export const ExplorerTypeOverviewPage = () => {
const { strategies, filteredStrategies, isPending } = useStrategyCtx();
+ const search = useSearch({ from: '/explore/$type/$slug/' });
const isFilterTooNarrow =
strategies.length > 0 && filteredStrategies.length === 0;
@@ -20,13 +22,12 @@ export const ExplorerTypeOverviewPage = () => {
const empty =
;
return (
- <>
-
- >
+
);
};
diff --git a/src/pages/simulator/overlapping/index.tsx b/src/pages/simulator/overlapping/index.tsx
index 1dfb0f2d9..e2fac2106 100644
--- a/src/pages/simulator/overlapping/index.tsx
+++ b/src/pages/simulator/overlapping/index.tsx
@@ -1,4 +1,8 @@
-import { calculateOverlappingPrices } from '@bancor/carbon-sdk/strategy-management';
+import {
+ calculateOverlappingBuyBudget,
+ calculateOverlappingPrices,
+ calculateOverlappingSellBudget,
+} from '@bancor/carbon-sdk/strategy-management';
import { useNavigate } from '@tanstack/react-router';
import { Button } from 'components/common/button';
import { CreateOverlappingStrategy } from 'components/simulator/input/overlapping/CreateOverlappingStrategy';
@@ -7,7 +11,7 @@ import { useSimulatorOverlappingInput } from 'hooks/useSimulatorOverlappingInput
import { useGetTokenPriceHistory } from 'libs/queries/extApi/tokenPrice';
import { simulatorInputOverlappingRoute } from 'libs/routing/routes/sim';
import { defaultEnd, defaultStart } from 'components/strategies/common/utils';
-import { FormEvent, useEffect } from 'react';
+import { FormEvent, useEffect, useMemo } from 'react';
import { formatNumber, roundSearchParam } from 'utils/helpers';
export const SimulatorInputOverlappingPage = () => {
@@ -24,6 +28,11 @@ export const SimulatorInputOverlappingPage = () => {
end: defaultEnd().toString(),
});
+ const marketPrice = useMemo(() => {
+ if (!state.start) return data?.[0].open;
+ return data?.find((d) => d.date.toString() === state.start)?.open;
+ }, [data, state.start]);
+
useEffect(() => {
if (searchState.sellMax || searchState.buyMin) return;
dispatch('baseToken', searchState.baseToken);
@@ -59,37 +68,60 @@ export const SimulatorInputOverlappingPage = () => {
const submit = (e: FormEvent
) => {
e.preventDefault();
if (isPending || isError || noBudget) return;
+ if (!state.baseToken || !state.quoteToken) return;
const start = state.start ?? defaultStart();
const end = state.end ?? defaultEnd();
+ const search = {
+ baseToken: state.baseToken.address,
+ quoteToken: state.quoteToken.address,
+ buyMin: roundSearchParam(state.buy.min),
+ buyMax: roundSearchParam(state.buy.max),
+ buyBudget: roundSearchParam(state.buy.budget),
+ buyMarginal: '',
+ buyIsRange: true,
+ sellMin: roundSearchParam(state.sell.min),
+ sellMax: roundSearchParam(state.sell.max),
+ sellBudget: roundSearchParam(state.sell.budget),
+ sellMarginal: '',
+ sellIsRange: true,
+ start: start.toString(),
+ end: end.toString(),
+ type: 'overlapping' as const,
+ spread: state.spread,
+ };
+
+ if (search.buyBudget) {
+ search.sellBudget = calculateOverlappingSellBudget(
+ state.baseToken.decimals,
+ state.quoteToken.decimals,
+ state.buy.min,
+ state.sell.max,
+ marketPrice!.toString(),
+ state.spread,
+ search.buyBudget
+ );
+ } else {
+ search.buyBudget = calculateOverlappingBuyBudget(
+ state.baseToken.decimals,
+ state.quoteToken.decimals,
+ state.buy.min,
+ state.sell.max,
+ marketPrice!.toString(),
+ state.spread,
+ search.sellBudget
+ );
+ }
+
const { buyPriceMarginal, sellPriceMarginal } = calculateOverlappingPrices(
formatNumber(state.buy.min),
formatNumber(state.sell.max),
- data[0].open.toString(),
+ marketPrice!.toString(),
state.spread
);
-
- navigate({
- to: '/simulate/result',
- search: {
- baseToken: state.baseToken?.address || '',
- quoteToken: state.quoteToken?.address || '',
- buyMin: roundSearchParam(state.buy.min),
- buyMax: roundSearchParam(state.buy.max),
- buyBudget: roundSearchParam(state.buy.budget),
- buyMarginal: roundSearchParam(buyPriceMarginal),
- buyIsRange: true,
- sellMin: roundSearchParam(state.sell.min),
- sellMax: roundSearchParam(state.sell.max),
- sellBudget: roundSearchParam(state.sell.budget),
- sellMarginal: roundSearchParam(sellPriceMarginal),
- sellIsRange: true,
- start: start.toString(),
- end: end.toString(),
- type: 'overlapping',
- spread: state.spread,
- },
- });
+ search.buyMarginal = buyPriceMarginal;
+ search.sellMarginal = sellPriceMarginal;
+ navigate({ to: '/simulate/result', search });
};
return (
@@ -102,7 +134,7 @@ export const SimulatorInputOverlappingPage = () => {
dispatch('spread', v)}
/>
diff --git a/src/pages/strategies/index.tsx b/src/pages/strategies/index.tsx
index d3a237ef6..c85c6aeaf 100644
--- a/src/pages/strategies/index.tsx
+++ b/src/pages/strategies/index.tsx
@@ -18,6 +18,7 @@ import { cn } from 'utils/helpers';
import { carbonEvents } from 'services/events';
import { buttonStyles } from 'components/common/button/buttonStyles';
import { StrategyFilterSort } from 'components/strategies/overview/StrategyFilterSort';
+import { StrategySelectLayout } from 'components/strategies/StrategySelectLayout';
export const StrategiesPage = () => {
const { pathname } = useRouterState().location;
@@ -30,7 +31,7 @@ export const StrategiesPage = () => {
const showFilter = useMemo(() => {
if (!isStrategiesPage) return false;
- if (belowBreakpoint('md')) return false;
+ if (belowBreakpoint('lg')) return false;
return !!(query.data && query.data.length > 2);
}, [belowBreakpoint, isStrategiesPage, query.data]);
@@ -63,6 +64,7 @@ export const StrategiesPage = () => {
<>
+
>
)}
{
const { strategies, filteredStrategies, isPending } = useStrategyCtx();
+ const search = useSearch({ from: '/my-strategy-layout/' });
const isFilterTooNarrow =
strategies.length > 0 && filteredStrategies.length === 0;
@@ -24,6 +26,7 @@ export const StrategiesOverviewPage = () => {
strategies={filteredStrategies}
isPending={isPending}
emptyElement={emptyElement}
+ layout={search.layout}
/>
);
};
diff --git a/src/pages/strategy/index.tsx b/src/pages/strategy/index.tsx
index 5085937d4..3ee9d1561 100644
--- a/src/pages/strategy/index.tsx
+++ b/src/pages/strategy/index.tsx
@@ -43,7 +43,8 @@ export const StrategyPage = () => {
});
const params = { strategyIds: id };
const query = useGetStrategy(id);
- const [strategy] = useStrategiesWithFiat(query);
+ const { strategies, isPending } = useStrategiesWithFiat(query);
+ const [strategy] = strategies;
const setSearch = (search: Partial) => {
navigate({
@@ -64,7 +65,7 @@ export const StrategyPage = () => {
end: priceEnd?.toString() ?? toUnixUTC(defaultEndDate()),
});
- if (query.isPending) {
+ if (isPending) {
return (
diff --git a/src/pages/trade/disposable.test.tsx b/src/pages/trade/disposable.test.tsx
index 9331a3f23..fa2afc588 100644
--- a/src/pages/trade/disposable.test.tsx
+++ b/src/pages/trade/disposable.test.tsx
@@ -8,6 +8,7 @@ import {
tokenList,
mockMarketRate,
priceHistoryHandler,
+ waitFor,
} from 'libs/testing-library';
import { TradeProvider } from 'components/trade/TradeContext';
import { Token } from 'libs/tokens';
@@ -69,9 +70,12 @@ describe('Create disposable page', () => {
expect(form.budget()).toHaveValue(search.budget);
// Check price range input and market price indication
- const marketPriceIndications = form.marketPriceIndicators();
- expect(marketPriceIndications[0]).toHaveTextContent('25.00% below market');
-
+ await waitFor(() => {
+ const marketPriceIndications = form.marketPriceIndicators();
+ expect(marketPriceIndications[0]).toHaveTextContent(
+ '25.00% below market'
+ );
+ });
// Check warning to approve deposit exists
expect(form.approveWarnings()).toBeInTheDocument();
});
diff --git a/src/pages/trade/recurring.test.tsx b/src/pages/trade/recurring.test.tsx
index b5c5538f5..a86758bfe 100644
--- a/src/pages/trade/recurring.test.tsx
+++ b/src/pages/trade/recurring.test.tsx
@@ -8,6 +8,7 @@ import {
tokenList,
mockMarketRate,
priceHistoryHandler,
+ waitFor,
} from 'libs/testing-library';
import { TradeProvider } from 'components/trade/TradeContext';
import { Token } from 'libs/tokens';
@@ -71,10 +72,12 @@ describe('Create recurring page', () => {
expect(form.sell.budget()).toHaveValue(search.sellBudget);
// Check price range input and market price indication
- const buyMarketPriceIndications = form.buy.marketPriceIndicators();
- expect(buyMarketPriceIndications[0]).toHaveTextContent(
- '20.00% below market'
- );
+ await waitFor(() => {
+ const buyMarketPriceIndications = form.buy.marketPriceIndicators();
+ expect(buyMarketPriceIndications[0]).toHaveTextContent(
+ '20.00% below market'
+ );
+ });
const sellMarketPriceIndications = form.sell.marketPriceIndicators();
expect(sellMarketPriceIndications[0]).toHaveTextContent(
'10.00% below market'
diff --git a/src/pages/trade/root.tsx b/src/pages/trade/root.tsx
index 209ca8763..bc7d984a4 100644
--- a/src/pages/trade/root.tsx
+++ b/src/pages/trade/root.tsx
@@ -47,7 +47,7 @@ export const TradeRoot = () => {
}
return (
-
+
diff --git a/src/services/localeStorage/index.ts b/src/services/localeStorage/index.ts
index 44d2f200d..09d2a8958 100644
--- a/src/services/localeStorage/index.ts
+++ b/src/services/localeStorage/index.ts
@@ -17,6 +17,7 @@ import {
} from 'utils/migrateLocalStorage';
import { NotificationPreference } from 'libs/notifications/NotificationPreferences';
import { AppConfig } from 'config/types';
+import { StrategyLayout } from 'components/strategies/StrategySelectLayout';
// ************************** /
// BEWARE!! Keys are not to be removed or changed without setting a proper clean-up and migration logic in place!! Same for changing the app version!
@@ -52,6 +53,7 @@ interface LocalStorageSchema {
notificationPreferences: NotificationPreference;
configOverride: Partial
;
featureFlags: string[];
+ strategyLayout: StrategyLayout;
}
enum EnumStrategySort {
diff --git a/src/store/useTokensStore.ts b/src/store/useTokensStore.ts
index bd1cee5bc..d7afc30e0 100644
--- a/src/store/useTokensStore.ts
+++ b/src/store/useTokensStore.ts
@@ -1,7 +1,7 @@
-import { uniqBy } from 'lodash';
import { Dispatch, SetStateAction, useMemo, useState } from 'react';
import { Token } from 'libs/tokens';
import { useTokensQuery } from 'libs/queries';
+import { lsService } from 'services/localeStorage';
export interface TokensStore {
tokens: Token[];
@@ -15,16 +15,16 @@ export interface TokensStore {
export const useTokensStore = (): TokensStore => {
const tokensQuery = useTokensQuery();
- const [importedTokens, setImportedTokens] = useState([]);
+ const [importedTokens, setImportedTokens] = useState(
+ lsService.getItem('importedTokens') ?? []
+ );
const tokens = useMemo(() => {
- if (tokensQuery.data && tokensQuery.data.length) {
- return uniqBy(
- [...tokensQuery.data, ...importedTokens],
- (token) => token.address
- );
- }
- return [];
+ if (!tokensQuery.data?.length) return [];
+ const result = new Map();
+ for (const token of importedTokens) result.set(token.address, token);
+ for (const token of tokensQuery.data) result.set(token.address, token);
+ return Array.from(result.values());
}, [tokensQuery.data, importedTokens]);
const tokensMap = useMemo(
diff --git a/src/utils/buffer.ts b/src/utils/buffer.ts
deleted file mode 100644
index 5cd8c6051..000000000
--- a/src/utils/buffer.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { Buffer } from 'buffer';
-
-window.Buffer = window?.Buffer || Buffer;
diff --git a/src/utils/helpers/index.ts b/src/utils/helpers/index.ts
index 2a26c4f4a..2b91f8462 100644
--- a/src/utils/helpers/index.ts
+++ b/src/utils/helpers/index.ts
@@ -2,7 +2,6 @@ import { TokenPair } from '@bancor/carbon-sdk';
import { ClassValue, clsx } from 'clsx';
import { Pathnames } from 'libs/routing';
import { customTwMerge } from 'libs/twmerge';
-import Graphemer from 'graphemer';
import { TradePair } from 'libs/modals/modals/ModalTradeTokenList';
export * from './number';
export * from './schema';
@@ -19,13 +18,20 @@ export const uuid = () => {
});
};
+const segmentText = (string: string) => {
+ if ('Segmenter' in Intl) {
+ const segmenter = new Intl.Segmenter();
+ return Array.from(segmenter.segment(string)).map((v) => v.segment);
+ } else {
+ return string.split('');
+ }
+};
export const shortenString = (
string: string,
separator = '...',
toLength = 13
): string => {
- const splitter = new Graphemer();
- const stringArray = splitter.splitGraphemes(string);
+ const stringArray = segmentText(string);
if (stringArray.length <= toLength) {
return string;
diff --git a/src/utils/helpers/number.test.ts b/src/utils/helpers/number.test.ts
index 59c4114d8..dfab5d691 100644
--- a/src/utils/helpers/number.test.ts
+++ b/src/utils/helpers/number.test.ts
@@ -323,6 +323,11 @@ describe('Test helpers', () => {
'0.00000012345'
);
});
+
+ // Very large numbers
+ test('should return "100.00e+18" for input 1e20', () => {
+ expect(prettifyNumber(1e20)).toEqual('100.00e+18');
+ });
});
});
diff --git a/src/utils/helpers/number.ts b/src/utils/helpers/number.ts
index 56a7265ed..41434892c 100644
--- a/src/utils/helpers/number.ts
+++ b/src/utils/helpers/number.ts
@@ -101,6 +101,10 @@ const subscript = (num: number, formatter: Intl.NumberFormat) => {
return formatter.formatToParts(num).map(transform).join('');
};
+export const largeNumbers = (num: number, formatter: Intl.NumberFormat) => {
+ return formatter.format(num).replace('E', 'e+');
+};
+
interface PrettifyNumberOptions {
abbreviate?: boolean;
currentCurrency?: FiatSymbol;
@@ -134,6 +138,10 @@ const getIntlOptions = (value: SafeDecimal, options: PrettifyNumberOptions) => {
if (options.abbreviate && value.gte(1_000_000)) {
intlOptions.notation = 'compact';
}
+ // When ludicrous numbers, use 1E16 notation
+ if (value.gt(1e16)) {
+ intlOptions.notation = 'engineering';
+ }
return intlOptions;
};
@@ -186,6 +194,9 @@ export function prettifyNumber(
if (!options.noSubscript && num.lt(0.001)) {
return subscript(num.toNumber(), formatter);
}
+ if (num.gte(1e16)) {
+ return largeNumbers(num.toNumber(), formatter);
+ }
return formatter.format(num.toNumber());
}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 26ddfaf17..4fa7f4fdf 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -79,10 +79,11 @@ export default {
ping: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite',
pulse: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
bounce: 'bounce 1s infinite',
+ fade: 'fade var(--duration, 0) var(--delay, 0s)',
slideUp:
- 'fade 0.4s cubic-bezier(0.16, 1, 0.3, 1) both, translateY 0.4s cubic-bezier(0.16, 1, 0.3, 1) both',
+ 'fade var(--duration, 400ms) var(--delay, 0s) var(--easing, cubic-bezier(0.16, 1, 0.3, 1)) both, translateY var(--duration, 400ms) var(--delay, 0s) var(--easing, cubic-bezier(0.16, 1, 0.3, 1)) both',
scaleUp:
- 'fade 0.4s cubic-bezier(0.16, 1, 0.3, 1) both, scale 0.4s cubic-bezier(0.16, 1, 0.3, 1) both',
+ 'fade var(--duration, 400ms) var(--delay, 0s) var(--easing, cubic-bezier(0.16, 1, 0.3, 1)) both, scale var(--duration, 400ms) var(--delay, 0s) var(--easing, cubic-bezier(0.16, 1, 0.3, 1)) both',
},
borderColor: ({ theme }) => ({
...theme('colors'),
@@ -94,8 +95,8 @@ export default {
full: '9999px',
},
fontFamily: {
- text: ['Carbon-Text', 'sans-serif'],
- title: ['Carbon-Title', 'sans-serif'],
+ text: ['Carbon-Text', 'system-ui', 'sans-serif'],
+ title: ['Carbon-Title', 'system-ui', 'sans-serif'],
},
fontSize: {
10: ['0.625rem', { lineHeight: '0.875rem' }],
@@ -158,7 +159,7 @@ export default {
},
scale: {
from: {
- transform: 'scale(0.8)',
+ transform: 'scale(var(--from-scale, 0.8))',
},
},
},
diff --git a/vite.config.ts b/vite.config.ts
index 17aaf9198..e37b20cf1 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -10,7 +10,16 @@ export default defineConfig(({ mode }) => {
// Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
const env = loadEnv(mode, process.cwd(), '');
- const plugins: PluginOption[] = [react(), viteTsconfigPaths(), svgrPlugin()];
+ const plugins: PluginOption[] = [
+ react({
+ babel: {
+ // Uncomment to enable compiler
+ // plugins: [['babel-plugin-react-compiler', {}]],
+ },
+ }),
+ viteTsconfigPaths(),
+ svgrPlugin(),
+ ];
// Put the Sentry vite plugin after all other plugins
if (env.SENTRY_ORG && env.SENTRY_PROJECT && env.SENTRY_AUTH_TOKEN) {
diff --git a/yarn.lock b/yarn.lock
index 517e91011..741db7fbd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -61,21 +61,30 @@
"@babel/highlight" "^7.24.7"
picocolors "^1.0.0"
+"@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0", "@babel/code-frame@^7.26.2":
+ version "7.26.2"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
+ integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.25.9"
+ js-tokens "^4.0.0"
+ picocolors "^1.0.0"
+
"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9":
version "7.22.9"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730"
integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==
-"@babel/compat-data@^7.24.7":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.7.tgz#d23bbea508c3883ba8251fb4164982c36ea577ed"
- integrity sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==
-
"@babel/compat-data@^7.24.8":
version "7.24.9"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.9.tgz#53eee4e68f1c1d0282aa0eb05ddb02d033fc43a0"
integrity sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==
+"@babel/compat-data@^7.25.9":
+ version "7.26.3"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.3.tgz#99488264a56b2aded63983abd6a417f03b92ed02"
+ integrity sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==
+
"@babel/core@^7.0.0-0", "@babel/core@^7.16.0", "@babel/core@^7.19.6":
version "7.22.9"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f"
@@ -118,21 +127,21 @@
json5 "^2.2.3"
semver "^6.3.1"
-"@babel/core@^7.24.5":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.7.tgz#b676450141e0b52a3d43bc91da86aa608f950ac4"
- integrity sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==
+"@babel/core@^7.26.0":
+ version "7.26.0"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40"
+ integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==
dependencies:
"@ampproject/remapping" "^2.2.0"
- "@babel/code-frame" "^7.24.7"
- "@babel/generator" "^7.24.7"
- "@babel/helper-compilation-targets" "^7.24.7"
- "@babel/helper-module-transforms" "^7.24.7"
- "@babel/helpers" "^7.24.7"
- "@babel/parser" "^7.24.7"
- "@babel/template" "^7.24.7"
- "@babel/traverse" "^7.24.7"
- "@babel/types" "^7.24.7"
+ "@babel/code-frame" "^7.26.0"
+ "@babel/generator" "^7.26.0"
+ "@babel/helper-compilation-targets" "^7.25.9"
+ "@babel/helper-module-transforms" "^7.26.0"
+ "@babel/helpers" "^7.26.0"
+ "@babel/parser" "^7.26.0"
+ "@babel/template" "^7.25.9"
+ "@babel/traverse" "^7.25.9"
+ "@babel/types" "^7.26.0"
convert-source-map "^2.0.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
@@ -188,6 +197,17 @@
"@jridgewell/trace-mapping" "^0.3.25"
jsesc "^2.5.1"
+"@babel/generator@^7.26.0", "@babel/generator@^7.26.3":
+ version "7.26.3"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.3.tgz#ab8d4360544a425c90c248df7059881f4b2ce019"
+ integrity sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==
+ dependencies:
+ "@babel/parser" "^7.26.3"
+ "@babel/types" "^7.26.3"
+ "@jridgewell/gen-mapping" "^0.3.5"
+ "@jridgewell/trace-mapping" "^0.3.25"
+ jsesc "^3.0.2"
+
"@babel/helper-annotate-as-pure@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882"
@@ -213,17 +233,6 @@
lru-cache "^5.1.1"
semver "^6.3.1"
-"@babel/helper-compilation-targets@^7.24.7":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz#4eb6c4a80d6ffeac25ab8cd9a21b5dfa48d503a9"
- integrity sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==
- dependencies:
- "@babel/compat-data" "^7.24.7"
- "@babel/helper-validator-option" "^7.24.7"
- browserslist "^4.22.2"
- lru-cache "^5.1.1"
- semver "^6.3.1"
-
"@babel/helper-compilation-targets@^7.24.8":
version "7.24.8"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz#b607c3161cd9d1744977d4f97139572fe778c271"
@@ -235,6 +244,17 @@
lru-cache "^5.1.1"
semver "^6.3.1"
+"@babel/helper-compilation-targets@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875"
+ integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==
+ dependencies:
+ "@babel/compat-data" "^7.25.9"
+ "@babel/helper-validator-option" "^7.25.9"
+ browserslist "^4.24.0"
+ lru-cache "^5.1.1"
+ semver "^6.3.1"
+
"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.5", "@babel/helper-create-class-features-plugin@^7.22.6", "@babel/helper-create-class-features-plugin@^7.22.9":
version "7.22.9"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz#c36ea240bb3348f942f08b0fbe28d6d979fab236"
@@ -347,6 +367,14 @@
"@babel/traverse" "^7.24.7"
"@babel/types" "^7.24.7"
+"@babel/helper-module-imports@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715"
+ integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==
+ dependencies:
+ "@babel/traverse" "^7.25.9"
+ "@babel/types" "^7.25.9"
+
"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9":
version "7.22.9"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129"
@@ -358,17 +386,6 @@
"@babel/helper-split-export-declaration" "^7.22.6"
"@babel/helper-validator-identifier" "^7.22.5"
-"@babel/helper-module-transforms@^7.24.7":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz#31b6c9a2930679498db65b685b1698bfd6c7daf8"
- integrity sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==
- dependencies:
- "@babel/helper-environment-visitor" "^7.24.7"
- "@babel/helper-module-imports" "^7.24.7"
- "@babel/helper-simple-access" "^7.24.7"
- "@babel/helper-split-export-declaration" "^7.24.7"
- "@babel/helper-validator-identifier" "^7.24.7"
-
"@babel/helper-module-transforms@^7.24.9":
version "7.24.9"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz#e13d26306b89eea569180868e652e7f514de9d29"
@@ -380,6 +397,15 @@
"@babel/helper-split-export-declaration" "^7.24.7"
"@babel/helper-validator-identifier" "^7.24.7"
+"@babel/helper-module-transforms@^7.26.0":
+ version "7.26.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae"
+ integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==
+ dependencies:
+ "@babel/helper-module-imports" "^7.25.9"
+ "@babel/helper-validator-identifier" "^7.25.9"
+ "@babel/traverse" "^7.25.9"
+
"@babel/helper-optimise-call-expression@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e"
@@ -392,10 +418,10 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295"
integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==
-"@babel/helper-plugin-utils@^7.24.7":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz#98c84fe6fe3d0d3ae7bfc3a5e166a46844feb2a0"
- integrity sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==
+"@babel/helper-plugin-utils@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46"
+ integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==
"@babel/helper-remap-async-to-generator@^7.22.5":
version "7.22.9"
@@ -466,6 +492,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d"
integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==
+"@babel/helper-string-parser@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
+ integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
+
"@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"
@@ -481,21 +512,26 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db"
integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==
+"@babel/helper-validator-identifier@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
+ integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
+
"@babel/helper-validator-option@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac"
integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==
-"@babel/helper-validator-option@^7.24.7":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz#24c3bb77c7a425d1742eec8fb433b5a1b38e62f6"
- integrity sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==
-
"@babel/helper-validator-option@^7.24.8":
version "7.24.8"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d"
integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==
+"@babel/helper-validator-option@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72"
+ integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==
+
"@babel/helper-wrap-function@^7.22.9":
version "7.22.9"
resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz#189937248c45b0182c1dcf32f3444ca153944cb9"
@@ -514,14 +550,6 @@
"@babel/traverse" "^7.22.6"
"@babel/types" "^7.22.5"
-"@babel/helpers@^7.24.7":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.7.tgz#aa2ccda29f62185acb5d42fb4a3a1b1082107416"
- integrity sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==
- dependencies:
- "@babel/template" "^7.24.7"
- "@babel/types" "^7.24.7"
-
"@babel/helpers@^7.24.8":
version "7.24.8"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.8.tgz#2820d64d5d6686cca8789dd15b074cd862795873"
@@ -530,6 +558,14 @@
"@babel/template" "^7.24.7"
"@babel/types" "^7.24.8"
+"@babel/helpers@^7.26.0":
+ version "7.26.0"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4"
+ integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==
+ dependencies:
+ "@babel/template" "^7.25.9"
+ "@babel/types" "^7.26.0"
+
"@babel/highlight@^7.22.13":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54"
@@ -578,6 +614,13 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.8.tgz#58a4dbbcad7eb1d48930524a3fd93d93e9084c6f"
integrity sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==
+"@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.3":
+ version "7.26.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.3.tgz#8c51c5db6ddf08134af1ddbacf16aaab48bac234"
+ integrity sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==
+ dependencies:
+ "@babel/types" "^7.26.3"
+
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e"
@@ -1142,19 +1185,19 @@
dependencies:
"@babel/plugin-transform-react-jsx" "^7.22.5"
-"@babel/plugin-transform-react-jsx-self@^7.24.5":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz#66bff0248ea0b549972e733516ffad577477bdab"
- integrity sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==
+"@babel/plugin-transform-react-jsx-self@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz#c0b6cae9c1b73967f7f9eb2fca9536ba2fad2858"
+ integrity sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==
dependencies:
- "@babel/helper-plugin-utils" "^7.24.7"
+ "@babel/helper-plugin-utils" "^7.25.9"
-"@babel/plugin-transform-react-jsx-source@^7.24.1":
- version "7.24.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz#1198aab2548ad19582013815c938d3ebd8291ee3"
- integrity sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==
+"@babel/plugin-transform-react-jsx-source@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz#4c6b8daa520b5f155b5fb55547d7c9fa91417503"
+ integrity sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==
dependencies:
- "@babel/helper-plugin-utils" "^7.24.7"
+ "@babel/helper-plugin-utils" "^7.25.9"
"@babel/plugin-transform-react-jsx@^7.22.5":
version "7.22.5"
@@ -1466,6 +1509,15 @@
"@babel/parser" "^7.24.7"
"@babel/types" "^7.24.7"
+"@babel/template@^7.25.9":
+ version "7.25.9"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016"
+ integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==
+ dependencies:
+ "@babel/code-frame" "^7.25.9"
+ "@babel/parser" "^7.25.9"
+ "@babel/types" "^7.25.9"
+
"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8":
version "7.23.2"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8"
@@ -1514,6 +1566,19 @@
debug "^4.3.1"
globals "^11.1.0"
+"@babel/traverse@^7.25.9":
+ version "7.26.4"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd"
+ integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==
+ dependencies:
+ "@babel/code-frame" "^7.26.2"
+ "@babel/generator" "^7.26.3"
+ "@babel/parser" "^7.26.3"
+ "@babel/template" "^7.25.9"
+ "@babel/types" "^7.26.3"
+ debug "^4.3.1"
+ globals "^11.1.0"
+
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.7.tgz#6027fe12bc1aa724cd32ab113fb7f1988f1f66f2"
@@ -1550,10 +1615,18 @@
"@babel/helper-validator-identifier" "^7.24.7"
to-fast-properties "^2.0.0"
-"@bancor/carbon-sdk@0.0.99-DEV":
- version "0.0.99-DEV"
- resolved "https://registry.yarnpkg.com/@bancor/carbon-sdk/-/carbon-sdk-0.0.99-DEV.tgz#ebbc1f5969a0eca9363b0217f25d140290299156"
- integrity sha512-DrevN/ahoDqyLc8IwUC6CiGOZn7BQXz42uBc7rU0aWc3mVhp8TR9WMJi3oVDS8DaYvRIcMv5U0sa6gK5IbbgGQ==
+"@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.26.3":
+ version "7.26.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.3.tgz#37e79830f04c2b5687acc77db97fbc75fb81f3c0"
+ integrity sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==
+ dependencies:
+ "@babel/helper-string-parser" "^7.25.9"
+ "@babel/helper-validator-identifier" "^7.25.9"
+
+"@bancor/carbon-sdk@0.0.103-DEV":
+ version "0.0.103-DEV"
+ resolved "https://registry.yarnpkg.com/@bancor/carbon-sdk/-/carbon-sdk-0.0.103-DEV.tgz#47e79ead02c6d3e50b47b552c5c7126e12935b74"
+ integrity sha512-uICGOxCcOE/J3qoq0EUUMseKlXNfcghw/eOymP6kP3bRjftwVKEY2yE6VmSNywL6LUShKVexnRwK43cESodNHg==
dependencies:
"@ethersproject/abi" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
@@ -1689,23 +1762,16 @@
eventemitter3 "^5.0.1"
preact "^10.24.2"
+"@date-fns/tz@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@date-fns/tz/-/tz-1.2.0.tgz#81cb3211693830babaf3b96aff51607e143030a6"
+ integrity sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==
+
"@ecies/ciphers@^0.2.1":
version "0.2.1"
resolved "https://registry.yarnpkg.com/@ecies/ciphers/-/ciphers-0.2.1.tgz#a3119516fb55d27ed2d21c497b1c4988f0b4ca02"
integrity sha512-ezMihhjW24VNK/2qQR7lH8xCQY24nk0XHF/kwJ1OuiiY5iEwQXOcKVSy47fSoHPRG8gVGXcK5SgtONDk5xMwtQ==
-"@emotion/is-prop-valid@^0.8.2":
- version "0.8.8"
- resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
- integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
- dependencies:
- "@emotion/memoize" "0.7.4"
-
-"@emotion/memoize@0.7.4":
- version "0.7.4"
- resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
- integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
-
"@esbuild/aix-ppc64@0.21.5":
version "0.21.5"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f"
@@ -2609,7 +2675,7 @@
superstruct "^1.0.3"
uuid "^9.0.1"
-"@motionone/animation@^10.13.1", "@motionone/animation@^10.15.1":
+"@motionone/animation@^10.15.1":
version "10.15.1"
resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.15.1.tgz#4a85596c31cbc5100ae8eb8b34c459fb0ccf6807"
integrity sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==
@@ -2619,18 +2685,6 @@
"@motionone/utils" "^10.15.1"
tslib "^2.3.1"
-"@motionone/dom@10.13.1":
- version "10.13.1"
- resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.13.1.tgz#fc29ea5d12538f21b211b3168e502cfc07a24882"
- integrity sha512-zjfX+AGMIt/fIqd/SL1Lj93S6AiJsEA3oc5M9VkUr+Gz+juRmYN1vfvZd6MvEkSqEjwPQgcjN7rGZHrDB9APfQ==
- dependencies:
- "@motionone/animation" "^10.13.1"
- "@motionone/generators" "^10.13.1"
- "@motionone/types" "^10.13.0"
- "@motionone/utils" "^10.13.1"
- hey-listen "^1.0.8"
- tslib "^2.3.1"
-
"@motionone/dom@^10.16.2":
version "10.16.2"
resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.16.2.tgz#0c44df8ee3d1cfc50ee11d27050b27824355a61a"
@@ -2651,7 +2705,7 @@
"@motionone/utils" "^10.15.1"
tslib "^2.3.1"
-"@motionone/generators@^10.13.1", "@motionone/generators@^10.15.1":
+"@motionone/generators@^10.15.1":
version "10.15.1"
resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.15.1.tgz#dc6abb11139d1bafe758a41c134d4c753a9b871c"
integrity sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==
@@ -2668,12 +2722,12 @@
"@motionone/dom" "^10.16.2"
tslib "^2.3.1"
-"@motionone/types@^10.13.0", "@motionone/types@^10.15.1":
+"@motionone/types@^10.15.1":
version "10.15.1"
resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.15.1.tgz#89441b54285012795cbba8612cbaa0fa420db3eb"
integrity sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==
-"@motionone/utils@^10.13.1", "@motionone/utils@^10.15.1":
+"@motionone/utils@^10.15.1":
version "10.15.1"
resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.15.1.tgz#6b5f51bde75be88b5411e084310299050368a438"
integrity sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==
@@ -4021,32 +4075,18 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f"
integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==
-"@types/prop-types@*":
- version "15.7.5"
- resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
- integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
+"@types/react-dom@19.0.2":
+ version "19.0.2"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.0.2.tgz#ad21f9a1ee881817995fd3f7fd33659c87e7b1b7"
+ integrity sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==
-"@types/react-dom@^18.0.0":
- version "18.2.7"
- resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63"
- integrity sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==
+"@types/react@19.0.1":
+ version "19.0.1"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.1.tgz#a000d5b78f473732a08cecbead0f3751e550b3df"
+ integrity sha512-YW6614BDhqbpR5KtUYzTA+zlA7nayzJRA9ljz9CQoxthR0sDisYZLuvSMsil36t4EH/uAt8T52Xb4sVw17G+SQ==
dependencies:
- "@types/react" "*"
-
-"@types/react@*", "@types/react@^18.0.0":
- version "18.2.18"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.18.tgz#c8b233919eef1bdc294f6f34b37f9727ad677516"
- integrity sha512-da4NTSeBv/P34xoZPhtcLkmZuJ+oYaCxHmyHzwaDQo9RQPBeXV+06gEk2FpqEcsX9XrnNLvRpVh6bdavDSjtiQ==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
csstype "^3.0.2"
-"@types/scheduler@*":
- version "0.16.3"
- resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5"
- integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==
-
"@types/semver@^7.3.12":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a"
@@ -4158,14 +4198,14 @@
"@typescript-eslint/types" "5.62.0"
eslint-visitor-keys "^3.3.0"
-"@vitejs/plugin-react@^4.3.1":
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz#d0be6594051ded8957df555ff07a991fb618b48e"
- integrity sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==
+"@vitejs/plugin-react@^4.3.4":
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz#c64be10b54c4640135a5b28a2432330e88ad7c20"
+ integrity sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==
dependencies:
- "@babel/core" "^7.24.5"
- "@babel/plugin-transform-react-jsx-self" "^7.24.5"
- "@babel/plugin-transform-react-jsx-source" "^7.24.1"
+ "@babel/core" "^7.26.0"
+ "@babel/plugin-transform-react-jsx-self" "^7.25.9"
+ "@babel/plugin-transform-react-jsx-source" "^7.25.9"
"@types/babel__core" "^7.20.5"
react-refresh "^0.14.2"
@@ -4816,11 +4856,6 @@ async-mutex@^0.2.6:
dependencies:
tslib "^2.0.0"
-async@^3.2.3:
- version "3.2.4"
- resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
- integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
-
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -5068,16 +5103,6 @@ browserslist@^4.21.5, browserslist@^4.21.9:
node-releases "^2.0.13"
update-browserslist-db "^1.0.11"
-browserslist@^4.22.2:
- version "4.23.1"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.1.tgz#ce4af0534b3d37db5c1a4ca98b9080f985041e96"
- integrity sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==
- dependencies:
- caniuse-lite "^1.0.30001629"
- electron-to-chromium "^1.4.796"
- node-releases "^2.0.14"
- update-browserslist-db "^1.0.16"
-
browserslist@^4.23.1:
version "4.23.2"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.2.tgz#244fe803641f1c19c28c48c4b6ec9736eb3d32ed"
@@ -5088,10 +5113,15 @@ browserslist@^4.23.1:
node-releases "^2.0.14"
update-browserslist-db "^1.1.0"
-btoa@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
- integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
+browserslist@^4.24.0:
+ version "4.24.2"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580"
+ integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==
+ dependencies:
+ caniuse-lite "^1.0.30001669"
+ electron-to-chromium "^1.5.41"
+ node-releases "^2.0.18"
+ update-browserslist-db "^1.1.1"
buffer-xor@^1.0.3:
version "1.0.3"
@@ -5146,11 +5176,16 @@ camelcase@^6.2.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
-caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001629, caniuse-lite@^1.0.30001639, caniuse-lite@^1.0.30001640:
+caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001639, caniuse-lite@^1.0.30001640:
version "1.0.30001684"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz"
integrity sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==
+caniuse-lite@^1.0.30001669:
+ version "1.0.30001687"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz#d0ac634d043648498eedf7a3932836beba90ebae"
+ integrity sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==
+
"cbw-sdk@npm:@coinbase/wallet-sdk@3.9.3":
version "3.9.3"
resolved "https://registry.yarnpkg.com/@coinbase/wallet-sdk/-/wallet-sdk-3.9.3.tgz#daf10cb0c85d0363315b7270cb3f02bedc408aab"
@@ -5201,7 +5236,7 @@ chalk@^3.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
-chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
+chalk@^4.0.0, chalk@^4.1.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==
@@ -5309,15 +5344,6 @@ cliui@^6.0.0:
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"
-cliui@^7.0.2:
- version "7.0.4"
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
- integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
- dependencies:
- string-width "^4.2.0"
- strip-ansi "^6.0.0"
- wrap-ansi "^7.0.0"
-
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
@@ -5856,6 +5882,11 @@ date-fns@^3.3.1:
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.3.1.tgz#7581daca0892d139736697717a168afbb908cfed"
integrity sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==
+date-fns@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14"
+ integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==
+
dayjs@^1.11.7:
version "1.11.9"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a"
@@ -6039,11 +6070,6 @@ dotenv@^16.3.1:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e"
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
-duplexer@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
- integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
-
duplexify@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0"
@@ -6069,35 +6095,21 @@ eciesjs@^0.4.8:
"@noble/curves" "^1.6.0"
"@noble/hashes" "^1.5.0"
-eip1193-provider@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/eip1193-provider/-/eip1193-provider-1.0.1.tgz#420d29cf4f6c443e3f32e718fb16fafb250637c3"
- integrity sha512-kSuqwQ26d7CzuS/t3yRXo2Su2cVH0QfvyKbr2H7Be7O5YDyIq4hQGCNTo5wRdP07bt+E2R/8nPCzey4ojBHf7g==
- dependencies:
- "@json-rpc-tools/provider" "^1.5.5"
-
-ejs@^3.1.5:
- version "3.1.10"
- resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b"
- integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==
- dependencies:
- jake "^10.8.5"
-
electron-to-chromium@^1.4.477:
version "1.4.485"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.485.tgz#fde3ee9ee8112a3414c0dfa545385ad08ec43408"
integrity sha512-1ndQ5IBNEnFirPwvyud69GHL+31FkE09gH/CJ6m3KCbkx3i0EVOrjwz4UNxRmN9H8OVHbC6vMRZGN1yCvjSs9w==
-electron-to-chromium@^1.4.796:
- version "1.4.816"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz#3624649d1e7fde5cdbadf59d31a524245d8ee85f"
- integrity sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==
-
electron-to-chromium@^1.4.820:
version "1.4.827"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.827.tgz#76068ed1c71dd3963e1befc8ae815004b2da6a02"
integrity sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==
+electron-to-chromium@^1.5.41:
+ version "1.5.72"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.72.tgz#a732805986d3a5b5fedd438ddf4616c7d78ac2df"
+ integrity sha512-ZpSAUOZ2Izby7qnZluSrAlGgGQzucmFbN0n64dYzocYxnxV5ufurpj3VgEe4cUp7ir9LmeLxNYo8bVnlM8bQHw==
+
elliptic@6.5.4, elliptic@^6.5.3:
version "6.5.4"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
@@ -6296,10 +6308,10 @@ escalade@^3.1.2:
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
-escape-html@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
- integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
+escalade@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
+ integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
escape-string-regexp@2.0.0:
version "2.0.0"
@@ -6842,13 +6854,6 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"
-filelist@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
- integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==
- dependencies:
- minimatch "^5.0.1"
-
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
@@ -6931,26 +6936,14 @@ fraction.js@^4.2.0:
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950"
integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==
-framer-motion@7.6.7:
- version "7.6.7"
- resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-7.6.7.tgz#4ab0f33d0b77b4fe2289ce8b7c5cf6448d84f23d"
- integrity sha512-vEGsjXygf4qSmgXXsCT1FC56DjiZau9tSQTCchwAP2mOHnYHUy5gbthc4RXFWJh4Z/gFtqE8bzEmjahwOrfT7w==
+framer-motion@11.13.5:
+ version "11.13.5"
+ resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.13.5.tgz#2cec307d2395ba6924a683abd79a517ec1f318f5"
+ integrity sha512-rArI0zPU9VkpS3Wt0J7dmRxAFUWtzPWoSofNQAP0UO276CmJ+Xlf5xN19GMw3w2QsdrS2sU+0+Q2vtuz4IEZaw==
dependencies:
- "@motionone/dom" "10.13.1"
- framesync "6.1.2"
- hey-listen "^1.0.8"
- popmotion "11.0.5"
- style-value-types "5.1.2"
- tslib "2.4.0"
- optionalDependencies:
- "@emotion/is-prop-valid" "^0.8.2"
-
-framesync@6.1.2:
- version "6.1.2"
- resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.1.2.tgz#755eff2fb5b8f3b4d2b266dd18121b300aefea27"
- integrity sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==
- dependencies:
- tslib "2.4.0"
+ motion-dom "^11.13.0"
+ motion-utils "^11.13.0"
+ tslib "^2.4.0"
fs-extra@^7.0.0:
version "7.0.1"
@@ -7086,7 +7079,7 @@ glob@^10.3.10:
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-scurry "^1.10.1"
-glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
+glob@^7.1.3, glob@^7.1.4:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@@ -7171,13 +7164,6 @@ graphql@^16.8.1:
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f"
integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==
-gzip-size@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462"
- integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==
- dependencies:
- duplexer "^0.1.2"
-
h3@^1.10.2, h3@^1.11.1:
version "1.11.1"
resolved "https://registry.yarnpkg.com/h3/-/h3-1.11.1.tgz#e9414ae6f2a076a345ea07256b320edb29bab9f7"
@@ -7506,11 +7492,6 @@ is-date-object@^1.0.1:
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"
@@ -7637,13 +7618,6 @@ is-weakref@^1.0.2:
dependencies:
call-bind "^1.0.2"
-is-wsl@^2.1.1:
- 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"
-
is-wsl@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2"
@@ -7718,16 +7692,6 @@ jackspeak@^2.3.5:
optionalDependencies:
"@pkgjs/parseargs" "^0.11.0"
-jake@^10.8.5:
- version "10.8.7"
- resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f"
- integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==
- dependencies:
- async "^3.2.3"
- chalk "^4.0.2"
- filelist "^1.0.4"
- minimatch "^3.1.2"
-
jiti@^1.21.0:
version "1.21.0"
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
@@ -7802,6 +7766,11 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
+jsesc@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
+ integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
+
jsesc@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
@@ -8047,7 +8016,7 @@ 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@^4.17.15, lodash@^4.17.20, lodash@^4.17.21:
+lodash@^4.17.15, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -8063,7 +8032,7 @@ log-update@^5.0.1:
strip-ansi "^7.0.1"
wrap-ansi "^8.0.1"
-loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
+loose-envify@^1.0.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -8240,13 +8209,6 @@ 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"
-
minimatch@^8.0.2:
version "8.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229"
@@ -8281,13 +8243,6 @@ mipd@0.0.7:
resolved "https://registry.yarnpkg.com/mipd/-/mipd-0.0.7.tgz#bb5559e21fa18dc3d9fe1c08902ef14b7ce32fd9"
integrity sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==
-mkdirp@^0.5.1:
- version "0.5.6"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
- integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
- dependencies:
- minimist "^1.2.6"
-
mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
@@ -8323,6 +8278,16 @@ mlly@^1.6.1, mlly@^1.7.0:
pkg-types "^1.1.0"
ufo "^1.5.3"
+motion-dom@^11.13.0:
+ version "11.13.0"
+ resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-11.13.0.tgz#a8f86b3aedb55598a8e3dd4114f1c3347153baf2"
+ integrity sha512-Oc1MLGJQ6nrvXccXA89lXtOqFyBmvHtaDcTRGT66o8Czl7nuA8BeHAd9MQV1pQKX0d2RHFBFaw5g3k23hQJt0w==
+
+motion-utils@^11.13.0:
+ version "11.13.0"
+ resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-11.13.0.tgz#e65fab5e26a1da3b18b4b4d1f3d0067977ccfd4a"
+ integrity sha512-lq6TzXkH5c/ysJQBxgLXgM01qwBH1b4goTPh57VvZWJbVJZF/0SB31UWEn4EIqbVPf3au88n2rvK17SpDTja1A==
+
motion@10.16.2:
version "10.16.2"
resolved "https://registry.yarnpkg.com/motion/-/motion-10.16.2.tgz#7dc173c6ad62210a7e9916caeeaf22c51e598d21"
@@ -8454,6 +8419,11 @@ node-releases@^2.0.14:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==
+node-releases@^2.0.18:
+ version "2.0.19"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
+ integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
+
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
@@ -8600,14 +8570,6 @@ onetime@^6.0.0:
dependencies:
mimic-fn "^4.0.0"
-open@^7.3.1:
- version "7.4.2"
- resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
- integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
- dependencies:
- is-docker "^2.0.0"
- is-wsl "^2.1.1"
-
optionator@^0.9.3:
version "0.9.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64"
@@ -8912,16 +8874,6 @@ pony-cause@^2.1.10:
resolved "https://registry.yarnpkg.com/pony-cause/-/pony-cause-2.1.11.tgz#d69a20aaccdb3bdb8f74dd59e5c68d8e6772e4bd"
integrity sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==
-popmotion@11.0.5:
- version "11.0.5"
- resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.5.tgz#8e3e014421a0ffa30ecd722564fd2558954e1f7d"
- integrity sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==
- dependencies:
- framesync "6.1.2"
- hey-listen "^1.0.8"
- style-value-types "5.1.2"
- tslib "2.4.0"
-
postcss-import@^15.1.0:
version "15.1.0"
resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70"
@@ -9204,18 +9156,20 @@ randomfill@^1.0.3:
randombytes "^2.0.5"
safe-buffer "^5.1.0"
-react-day-picker@^8.10.0:
- version "8.10.0"
- resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-8.10.0.tgz#729c5b9564967a924213978fb9c0751884a60595"
- integrity sha512-mz+qeyrOM7++1NCb1ARXmkjMkzWVh2GL9YiPbRjKe0zHccvekk4HE+0MPOZOrosn8r8zTHIIeOUXTmXRqmkRmg==
+react-day-picker@9.4.2:
+ version "9.4.2"
+ resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-9.4.2.tgz#235f2ce45c0ad0662393879ca00baea6fb93bc5c"
+ integrity sha512-qKunVfJ+QWJqdHylZ9TsXSSJzzK9vDLsZ+c80/r+ZwOWqGW8mADwPy1iOBrNcZiAokQ4xrSsPLnWzTRHS4mSsQ==
+ dependencies:
+ "@date-fns/tz" "^1.2.0"
+ date-fns "^4.1.0"
-react-dom@18.2.0, react-dom@^18.2.0:
- version "18.2.0"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
- integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
+react-dom@19.0.0:
+ version "19.0.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.0.0.tgz#43446f1f01c65a4cd7f7588083e686a6726cfb57"
+ integrity sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==
dependencies:
- loose-envify "^1.1.0"
- scheduler "^0.23.0"
+ scheduler "^0.25.0"
react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
@@ -9245,12 +9199,10 @@ react-refresh@^0.14.2:
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9"
integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==
-react@18.2.0, react@^18.2.0:
- version "18.2.0"
- resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
- integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
- dependencies:
- loose-envify "^1.1.0"
+react@19.0.0:
+ version "19.0.0"
+ resolved "https://registry.yarnpkg.com/react/-/react-19.0.0.tgz#6e1969251b9f108870aa4bff37a0ce9ddfaaabdd"
+ integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==
read-cache@^1.0.0:
version "1.0.0"
@@ -9451,13 +9403,6 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
-rimraf@~2.6.2:
- version "2.6.3"
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
- integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
- dependencies:
- glob "^7.1.3"
-
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
@@ -9564,12 +9509,10 @@ saxes@^6.0.0:
dependencies:
xmlchars "^2.2.0"
-scheduler@^0.23.0:
- version "0.23.0"
- resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
- integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
- dependencies:
- loose-envify "^1.1.0"
+scheduler@^0.25.0:
+ version "0.25.0"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.25.0.tgz#336cd9768e8cceebf52d3c80e3dcf5de23e7e015"
+ integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==
scrypt-js@3.0.1:
version "3.0.1"
@@ -9685,24 +9628,6 @@ sonic-boom@^2.2.1:
dependencies:
atomic-sleep "^1.0.0"
-source-map-explorer@^2.5.3:
- version "2.5.3"
- resolved "https://registry.yarnpkg.com/source-map-explorer/-/source-map-explorer-2.5.3.tgz#33551b51e33b70f56d15e79083cdd4c43e583b69"
- integrity sha512-qfUGs7UHsOBE5p/lGfQdaAj/5U/GWYBw2imEpD6UQNkqElYonkow8t+HBL1qqIl3CuGZx7n8/CQo4x1HwSHhsg==
- dependencies:
- btoa "^1.2.1"
- chalk "^4.1.0"
- convert-source-map "^1.7.0"
- ejs "^3.1.5"
- escape-html "^1.0.3"
- glob "^7.1.6"
- gzip-size "^6.0.0"
- lodash "^4.17.20"
- open "^7.3.1"
- source-map "^0.7.4"
- temp "^0.9.4"
- yargs "^16.2.0"
-
source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
@@ -9713,11 +9638,6 @@ source-map-js@^1.2.1:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
-source-map@^0.7.4:
- version "0.7.4"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
- integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
-
source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
@@ -9910,15 +9830,7 @@ strip-literal@^2.0.0:
dependencies:
js-tokens "^9.0.0"
-style-value-types@5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.1.2.tgz#6be66b237bd546048a764883528072ed95713b62"
- integrity sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==
- dependencies:
- hey-listen "^1.0.8"
- tslib "2.4.0"
-
-sucrase@^3.32.0, sucrase@^3.35.0:
+sucrase@^3.32.0:
version "3.35.0"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263"
integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==
@@ -10020,42 +9932,6 @@ tailwindcss@3.4.3:
resolve "^1.22.2"
sucrase "^3.32.0"
-tailwindcss@^3.3.1:
- version "3.4.16"
- resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.16.tgz#35a7c3030844d6000fc271878db4096b6a8d2ec9"
- integrity sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==
- dependencies:
- "@alloc/quick-lru" "^5.2.0"
- arg "^5.0.2"
- chokidar "^3.6.0"
- didyoumean "^1.2.2"
- dlv "^1.1.3"
- fast-glob "^3.3.2"
- glob-parent "^6.0.2"
- is-glob "^4.0.3"
- jiti "^1.21.6"
- lilconfig "^3.1.3"
- micromatch "^4.0.8"
- normalize-path "^3.0.0"
- object-hash "^3.0.0"
- picocolors "^1.1.1"
- postcss "^8.4.47"
- postcss-import "^15.1.0"
- postcss-js "^4.0.1"
- postcss-load-config "^4.0.2"
- postcss-nested "^6.2.0"
- postcss-selector-parser "^6.1.2"
- resolve "^1.22.8"
- sucrase "^3.35.0"
-
-temp@^0.9.4:
- version "0.9.4"
- resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.4.tgz#cd20a8580cb63635d0e4e9d4bd989d44286e7620"
- integrity sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==
- dependencies:
- mkdirp "^0.5.1"
- rimraf "~2.6.2"
-
test-exclude@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
@@ -10202,16 +10078,16 @@ tslib@1.14.1, 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:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
- integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
-
tslib@^2.0.0, tslib@^2.3.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410"
integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==
+tslib@^2.4.0:
+ version "2.8.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
+ integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
+
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
@@ -10452,14 +10328,6 @@ update-browserslist-db@^1.0.11:
escalade "^3.1.1"
picocolors "^1.0.0"
-update-browserslist-db@^1.0.16:
- version "1.0.16"
- resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz#f6d489ed90fb2f07d67784eb3f53d7891f736356"
- integrity sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==
- dependencies:
- escalade "^3.1.2"
- picocolors "^1.0.1"
-
update-browserslist-db@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e"
@@ -10468,6 +10336,14 @@ update-browserslist-db@^1.1.0:
escalade "^3.1.2"
picocolors "^1.0.1"
+update-browserslist-db@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5"
+ integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==
+ dependencies:
+ escalade "^3.2.0"
+ picocolors "^1.1.0"
+
uqr@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/uqr/-/uqr-0.1.2.tgz#5c6cd5dcff9581f9bb35b982cb89e2c483a41d7d"
@@ -10573,6 +10449,11 @@ viem@^2.1.1:
webauthn-p256 "0.0.5"
ws "8.17.1"
+vite-bundle-analyzer@^0.15.2:
+ version "0.15.2"
+ resolved "https://registry.yarnpkg.com/vite-bundle-analyzer/-/vite-bundle-analyzer-0.15.2.tgz#176cbe1dd04f3d5aef42de5338a0b447354e191e"
+ integrity sha512-AwFOewhvf7EkTACa9c/inbxMrJOWwyVF4nUMITwN26lM5TAYkcnJC4KFgZXym3sYRAWe1Qgvk8X4OFTw4HPaJw==
+
vite-node@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.6.0.tgz#2c7e61129bfecc759478fa592754fd9704aaba7f"
@@ -10909,11 +10790,6 @@ yargs-parser@^18.1.2:
camelcase "^5.0.0"
decamelize "^1.2.0"
-yargs-parser@^20.2.2:
- version "20.2.9"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
- integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
-
yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
@@ -10936,19 +10812,6 @@ yargs@^15.3.1:
y18n "^4.0.0"
yargs-parser "^18.1.2"
-yargs@^16.2.0:
- version "16.2.0"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
- integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
- dependencies:
- cliui "^7.0.2"
- escalade "^3.1.1"
- get-caller-file "^2.0.5"
- require-directory "^2.1.1"
- string-width "^4.2.0"
- y18n "^5.0.5"
- yargs-parser "^20.2.2"
-
yargs@^17.7.2:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"