Merge pull request #32 from mars-protocol/v1.5.0

v1.5.0
This commit is contained in:
Linkie Link 2023-06-19 16:27:34 +02:00 committed by GitHub
commit 5a19e840bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
109 changed files with 5079 additions and 3387 deletions

2
.env
View File

@ -1,2 +0,0 @@
NEXT_PUBLIC_NETWORK=mainnet
NEXT_PUBLIC_STAGE=production

View File

@ -1,4 +1,14 @@
NEXT_PUBLIC_NETWORK=mainnet
NEXT_PUBLIC_RPC=https://rpc-osmosis.blockapsis.com
NEXT_PUBLIC_GQL=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql
NEXT_PUBLIC_REST=https://lcd-osmosis.blockapsis.com
# OSMOSIS-1 #
NEXT_PUBLIC_OSMOSIS_RPC=https://rpc-osmosis.blockapsis.com
NEXT_PUBLIC_OSMOSIS_REST=https://lcd-osmosis.blockapsis.com
NEXT_PUBLIC_OSMOSIS_GQL=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql
# OSMO-TEST-5 #
NEXT_PUBLIC_OSMOSIS_TEST_RPC=https://rpc.osmotest5.osmosis.zone
NEXT_PUBLIC_OSMOSIS_TEST_REST=https://lcd.osmotest5.osmosis.zone
NEXT_PUBLIC_OSMOSIS_TEST_GQL=https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql
# PION-1 #
NEXT_PUBLIC_NEUTRON_TEST_RPC=https://rpc-palvus.pion-1.ntrn.tech/
NEXT_PUBLIC_NEUTRON_TEST_REST=https://rest-palvus.pion-1.ntrn.tech/
NEXT_PUBLIC_NEUTRON_TEST_GQL=https://testnet-neutron-gql.marsprotocol.io/graphql

View File

@ -1,7 +1,17 @@
# DO NOT EDIT THIS FILE WHEN USING DOCKER
# These values are used to replace the values in the built app,
# you should pass environment variables as defined in README.md
NEXT_PUBLIC_NETWORK=APP_NEXT_NETWORK
NEXT_PUBLIC_RPC=APP_NEXT_RPC
NEXT_PUBLIC_GQL=APP_NEXT_GQL
NEXT_PUBLIC_REST=APP_NEXT_REST
# OSMOSIS-1 #
NEXT_PUBLIC_OSMOSIS_RPC=APP_NEXT_OSMOSIS_RPC
NEXT_PUBLIC_OSMOSIS_REST=APP_NEXT_OSMOSIS_REST
NEXT_PUBLIC_OSMOSIS_GQL=APP_NEXT_OSMOSIS_GQL
# OSMO-TEST-5 #
NEXT_PUBLIC_OSMOSIS_TEST_RPC=APP_NEXT_OSMOSIS_TEST_RPC
NEXT_PUBLIC_OSMOSIS_TEST_REST=APP_NEXT_OSMOSIS_TEST_REST
NEXT_PUBLIC_OSMOSIS_TEST_GQL=APP_NEXT_OSMOSIS_TEST_GQL
# PION-1 #
NEXT_PUBLIC_NEUTRON_TEST_RPC=APP_NEXT_NEUTRON_TEST_RPC
NEXT_PUBLIC_NEUTRON_TEST_REST=APP_NEXT_NEUTRON_TEST_REST
NEXT_PUBLIC_NEUTRON_TEST_GQL=APP_NEXT_NEUTRON_TEST_GQL

View File

@ -31,10 +31,15 @@ We allow the use of environment variables to be passed to the Docker container t
|Variable|Description|Default|
|--------|-----------|-------|
|NETWORK|Flag for mainnet or testnet|mainnet|
|URL_GQL|The Hive GraphQL endpoint to use|https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql|
|URL_REST|The node REST endpoint to use|https://lcd-osmosis.blockapsis.com|
|URL_RPC|The node RPC endpoint to use|https://rpc-osmosis.blockapsis.com|
|URL_OSMOSIS_GQL|The Osmosis Hive GraphQL endpoint to use|https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql|
|URL_OSMOSIS_REST|The Osmosis node REST endpoint to use|https://lcd-osmosis.blockapsis.com|
|URL_OSMOSIS_RPC|The Osmosis node RPC endpoint to use|https://rpc-osmosis.blockapsis.com|
|URL_OSMOSIS_TEST_GQL|The Osmosis Testnet Hive GraphQL endpoint to use|https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql|
|URL_OSMOSIS_TEST_REST|The Osmosis Testnet node REST endpoint to use|https://lcd.osmotest5.osmosis.zone|
|URL_OSMOSIS_TEST_RPC|The Osmosis Testnet node RPC endpoint to use|https://rpc.osmotest5.osmosis.zone|
|URL_NEUTRON_TEST_GQL|The Neutron Testnet Hive GraphQL endpoint to use|https://testnet-neutron-gql.marsprotocol.io/graphql|
|URL_NEUTRON_TEST_REST|The Neutron Testnet node REST endpoint to use|https://rest-palvus.pion-1.ntrn.tech|
|URL_NEUTRON_TEST_RPC|The Neutron Testnet node RPC endpoint to use|https://rpc-palvus.pion-1.ntrn.tech|
**Sample Docker run command**
@ -43,9 +48,15 @@ This command will start the container in interactive mode with port 3000 bound t
```sh
docker run -it -p 3000:3000 \
-e NETWORK=mainnet \
-e URL_GQL=https://your-hive-endpoint.com \
-e URL_REST=https://your-rest-endpoint.com \
-e URL_RPC=https://your-rpc-endpoint.com marsprotocol/interface:latest
-e URL_OSMOSIS_GQL=https://your-osmosis-hive-endpoint.com \
-e URL_OSMOSIS_REST=https://your-osmosis-rest-endpoint.com \
-e URL_OSMOSIS_RPC=https://your-osmosis-rpc-endpoint.com \
-e URL_OSMOSIS_TEST_GQL=https://your-osmosis-testnet-hive-endpoint.com \
-e URL_OSMOSIS_TEST_REST=https://your-osmosis-testnet-rest-endpoint.com \
-e URL_OSMOSIS_TEST_RPC=https://your-osmosis-testnet-rpc-endpoint.com \
-e URL_NEUTRON_TEST_GQL=https://your-neutron-testnet-hive-endpoint.com \
-e URL_NEUTRON_TEST_REST=https://your-neutron-testnet-rest-endpoint.com \
-e URL_NEUTRON_TEST_RPC=https://your-neutron-testnet-rpc-endpoint.com marsprotocol/interface:latest
```
## 3. Text and translations

View File

@ -4,10 +4,15 @@ set +x
nextFolder='/app/.next'
# create the config file from environment variables
envFilename='override.conf'
echo "APP_NEXT_NETWORK=$NETWORK" >> $envFilename
echo "APP_NEXT_GQL=$URL_GQL" >> $envFilename
echo "APP_NEXT_REST=$URL_REST" >> $envFilename
echo "APP_NEXT_RPC=$URL_RPC" >> $envFilename
echo "APP_NEXT_OSMOSIS_RPC=$URL_OSMOSIS_RPC" >> $envFilename
echo "APP_NEXT_OSMOSIS_REST=$URL_OSMOSIS_REST" >> $envFilename
echo "APP_NEXT_OSMOSIS_GQL=$URL_OSMOSIS_GQL" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_RPC=$URL_OSMOSIS_TEST_RPC" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_REST=$URL_OSMOSIS_TEST_REST" >> $envFilename
echo "APP_NEXT_OSMOSIS_TEST_GQL=$URL_OSMOSIS_TEST_GQL" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_RPC=$URL_NEUTRON_TEST_RPC" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_REST=$URL_NEUTRON_TEST_REST" >> $envFilename
echo "APP_NEXT_NEUTRON_TEST_GQL=$URL_NEUTRON_TEST_GQL" >> $envFilename
function apply_path {
# read all config file
while read line; do

View File

@ -4,7 +4,6 @@ const path = require('path')
const moduleExports = {
reactStrictMode: true,
experimental: { images: { unoptimized: true } },
sassOptions: {
includePaths: [path.join(__dirname, 'src/styles')],
},

View File

@ -1,7 +1,7 @@
{
"name": "mars",
"homepage": "./",
"version": "1.4.9",
"version": "1.5.0",
"license": "SEE LICENSE IN LICENSE FILE",
"private": false,
"scripts": {
@ -22,7 +22,7 @@
"@cosmjs/launchpad": "^0.27.1",
"@cosmjs/proto-signing": "^0.30.1",
"@cosmjs/stargate": "^0.30.1",
"@marsprotocol/wallet-connector": "^1.5.8",
"@marsprotocol/wallet-connector": "^1.8.6",
"@material-ui/core": "^4.12.4",
"@material-ui/icons": "^4.11.3",
"@ramonak/react-progress-bar": "^5.0.3",

View File

@ -7,15 +7,21 @@ interface Props {
color?: string
size?: number
className?: string
forceAnimation?: boolean
}
export const CircularProgress = ({ color = '#FFFFFF', size = 20, className }: Props) => {
export const CircularProgress = ({
color = '#FFFFFF',
size = 20,
className,
forceAnimation = false,
}: Props) => {
const enableAnimations = useStore((s) => s.enableAnimations)
const borderWidth = `${size / 10}px`
const borderColor = `${color} transparent transparent transparent`
const loaderClasses = classNames(styles.loader, className)
if (!enableAnimations) return <div className={styles.staticLoader}>...</div>
if (!enableAnimations && !forceAnimation) return <div className={styles.staticLoader}>...</div>
return (
<div className={loaderClasses} style={{ width: `${size}px`, height: `${size}px` }}>

View File

@ -1,6 +1,5 @@
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
import {
ChainInfoID,
getChainInfo,
getClient,
useWallet,
@ -9,7 +8,6 @@ import {
} from '@marsprotocol/wallet-connector'
import { useQueryClient } from '@tanstack/react-query'
import { MARS_SYMBOL } from 'constants/appConstants'
import { NETWORK } from 'constants/env'
import {
useBlockHeight,
useDepositAndDebt,
@ -20,12 +18,14 @@ import {
useUserDebt,
useUserIcns,
} from 'hooks/queries'
import { usePythVaa } from 'hooks/queries/usePythVaa'
import { useSpotPrice } from 'hooks/queries/useSpotPrice'
import { useUserCollaterals } from 'hooks/queries/useUserCollaterals'
import { ReactNode, useEffect, useState } from 'react'
import useStore from 'store'
import { State } from 'types/enums'
import { Network } from 'types/enums/network'
import { MigrationInProgress } from '../MigrationInProgress/MigrationInProgress'
interface CommonContainerProps {
children: ReactNode
@ -35,70 +35,76 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
// ------------------
// EXTERNAL HOOKS
// ---------------
const { recentWallet, simulate, sign, broadcast } = useWallet()
const { status } = useWalletManager()
const { simulate, sign, broadcast } = useWallet()
const { status, connectedWallet } = useWalletManager()
const queryClient = useQueryClient()
const chainInfo = recentWallet?.network
? getChainInfo(recentWallet?.network.chainId as ChainInfoID)
: undefined
const address = status !== WalletConnectionStatus.Connected ? '' : recentWallet?.account.address
const [cosmWasmClient, setCosmWasmClient] = useState<CosmWasmClient | undefined>()
// ------------------
// STORE STATE
// ------------------
const chainID = useStore((s) => s.chainInfo?.chainId)
const assetPricesUSDState = useStore((s) => s.assetPricesUSDState)
const assetPricesUSD = useStore((s) => s.assetPricesUSD)
const chainId = useStore((s) => s.currentNetwork)
const exchangeRates = useStore((s) => s.exchangeRates)
const exchangeRatesState = useStore((s) => s.exchangeRatesState)
const isNetworkLoaded = useStore((s) => s.isNetworkLoaded)
const rpc = useStore((s) => s.chainInfo?.rpc)
const networkConfig = useStore((s) => s.networkConfig)
const marketDeposits = useStore((s) => s.marketDeposits)
const marketInfo = useStore((s) => s.marketInfo)
const marketIncentiveInfo = useStore((s) => s.marketIncentiveInfo)
const migrationInProgress = useStore((s) => s.migrationInProgress)
const redBankState = useStore((s) => s.redBankState)
const rpc = useStore((s) => s.networkConfig.rpcUrl)
const userBalances = useStore((s) => s.userBalances)
const userBalancesState = useStore((s) => s.userBalancesState)
const userDebts = useStore((s) => s.userDebts)
const userDeposits = useStore((s) => s.userDeposits)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const loadNetworkConfig = useStore((s) => s.loadNetworkConfig)
const setRedBankAssets = useStore((s) => s.setRedBankAssets)
const setChainInfo = useStore((s) => s.setChainInfo)
const setCurrentNetwork = useStore((s) => s.setCurrentNetwork)
const setLcdClient = useStore((s) => s.setLcdClient)
const setClient = useStore((s) => s.setClient)
const setChainInfo = useStore((s) => s.setChainInfo)
const setUserBalancesState = useStore((s) => s.setUserBalancesState)
const setUserWalletAddress = useStore((s) => s.setUserWalletAddress)
const pythVaa = useStore((s) => s.pythVaa)
// ------------------
// SETTERS
// ------------------
useEffect(() => {
if (NETWORK === 'mainnet') {
setCurrentNetwork(Network.MAINNET)
if (status !== WalletConnectionStatus.Connected && cosmWasmClient) {
setCosmWasmClient(undefined)
useStore.setState({
client: undefined,
creditManagerClient: undefined,
accountNftClient: undefined,
userWalletAddress: '',
})
}
loadNetworkConfig()
}, [loadNetworkConfig, setCurrentNetwork])
}, [status, cosmWasmClient])
useEffect(() => {
if (!chainInfo) return
const chainInfo = getChainInfo(chainId, {
rpc: networkConfig.rpcUrl,
rest: networkConfig.restUrl,
})
setChainInfo(chainInfo)
}, [chainInfo, setChainInfo])
}, [chainId, networkConfig, setChainInfo])
useEffect(() => {
setUserWalletAddress(address || '')
}, [setUserWalletAddress, address])
if (!connectedWallet || connectedWallet.network.chainId !== chainId) return
setUserWalletAddress(connectedWallet.account.address)
}, [setUserWalletAddress, connectedWallet, chainId])
useEffect(() => {
if (!rpc || !chainID) return
setLcdClient(rpc, chainID)
}, [rpc, chainID, setLcdClient])
if (!rpc || !chainId) return
setLcdClient(rpc, chainId)
}, [rpc, chainId, setLcdClient])
useEffect(() => {
if (userDebts && userDeposits && userBalances) {
if (userBalances) {
setUserBalancesState(State.READY)
} else {
setUserBalancesState(State.ERROR)
@ -106,10 +112,10 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
}, [userDebts, userDeposits, userBalances, setUserBalancesState])
useEffect(() => {
if (!recentWallet) return
if (!connectedWallet || connectedWallet.network.chainId !== chainId) return
if (!cosmWasmClient) {
const getCosmWasmClient = async () => {
const cosmClient = await getClient(recentWallet.network.rpc)
const cosmClient = await getClient(networkConfig.rpcUrl)
setCosmWasmClient(cosmClient)
}
@ -117,19 +123,22 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
return
}
const client = {
broadcast,
cosmWasmClient,
recentWallet,
sign,
simulate,
}
setClient(client)
}, [simulate, sign, recentWallet, cosmWasmClient, broadcast, setClient])
useStore.setState({
client: {
broadcast,
cosmWasmClient,
connectedWallet,
sign,
simulate,
},
})
}, [simulate, sign, connectedWallet, cosmWasmClient, broadcast, networkConfig, chainId])
useEffect(() => {
setRedBankAssets()
}, [
assetPricesUSD,
assetPricesUSDState,
exchangeRatesState,
redBankState,
userBalancesState,
@ -151,17 +160,19 @@ export const CommonContainer = ({ children }: CommonContainerProps) => {
// ------------------
// QUERY RELATED
// ------------------
useUsdPrice()
useBlockHeight()
useRedBank()
useUserBalance()
useUserIcns()
useUserDebt()
useUserCollaterals()
useMarsOracle()
useSpotPrice(MARS_SYMBOL)
useUsdPrice()
useDepositAndDebt()
useRedBank()
usePythVaa()
return <>{isNetworkLoaded && children}</>
if (migrationInProgress) return <MigrationInProgress />
return <>{children}</>
}

View File

@ -1,4 +1,4 @@
import React, { ReactNode, useEffect } from 'react'
import { ReactNode, useEffect } from 'react'
import useStore from 'store'
import { AccountNftClient, CreditManagerClient } from 'types/classes'
@ -8,24 +8,39 @@ interface FieldsContainerProps {
export const FieldsContainer = ({ children }: FieldsContainerProps) => {
const client = useStore((s) => s.client)
const currentNetwork = useStore((s) => s.currentNetwork)
const networkConfig = useStore((s) => s.networkConfig)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const getVaults = useStore((s) => s.getVaults)
const setCreditManagerMsgComposer = useStore((s) => s.setCreditManagerMsgComposer)
useEffect(() => {
if (!client || !networkConfig) return
useStore.setState({
creditManagerClient: new CreditManagerClient(networkConfig?.contracts.creditManager, client),
})
useStore.setState({
accountNftClient: new AccountNftClient(networkConfig?.contracts.accountNft, client),
})
}, [client, networkConfig])
const creditManagerAddress = networkConfig.contracts.creditManager
const accountNftContractAddress = networkConfig.contracts.accountNft
useEffect(() => {
if (!userWalletAddress || !networkConfig?.contracts.creditManager) return
if (!networkConfig.isFieldsEnabled || !creditManagerAddress || !accountNftContractAddress)
return
if (!client || client.connectedWallet.network.chainId !== currentNetwork) return
useStore.setState({
creditManagerClient: new CreditManagerClient(creditManagerAddress, client),
accountNftClient: new AccountNftClient(accountNftContractAddress, client),
apys: null,
})
getVaults({ refetch: true })
}, [
client,
networkConfig,
accountNftContractAddress,
creditManagerAddress,
currentNetwork,
getVaults,
])
useEffect(() => {
if (!userWalletAddress || !networkConfig.contracts.creditManager) return
setCreditManagerMsgComposer(userWalletAddress, networkConfig.contracts.creditManager)
}, [userWalletAddress, networkConfig, setCreditManagerMsgComposer])
}, [userWalletAddress, networkConfig.contracts.creditManager, setCreditManagerMsgComposer])
return <>{children}</>
}

View File

@ -1,7 +1,9 @@
import { ChainInfoID, WalletID, WalletManagerProvider } from '@marsprotocol/wallet-connector'
import { WalletID, WalletManagerProvider } from '@marsprotocol/wallet-connector'
import { CircularProgress, SVG } from 'components/common'
import { NETWORK } from 'constants/env'
import { useEffect, useState } from 'react'
import { SUPPORTED_CHAINS } from 'constants/appConstants'
import { getCurrentChainId } from 'libs/chainId'
import { useEffect } from 'react'
import useStore from 'store'
import styles from './CosmosWalletConnectProvider.module.scss'
@ -10,42 +12,36 @@ type Props = {
}
export const CosmosWalletConnectProvider = ({ children }: Props) => {
const [chainInfoOverrides, setChainInfoOverrides] = useState<{
rpc: string
rest: string
chainID: ChainInfoID
}>()
const [enabledWallets, setEnabledWallets] = useState<WalletID[]>([])
const currentNetwork = useStore((s) => s.currentNetwork)
const setCurrentNetwork = useStore((s) => s.setCurrentNetwork)
const loadNetworkConfig = useStore((s) => s.loadNetworkConfig)
const networkConfig = useStore((s) => s.networkConfig)
useEffect(() => {
if (chainInfoOverrides) return
setCurrentNetwork(getCurrentChainId())
loadNetworkConfig()
}, [loadNetworkConfig, setCurrentNetwork])
const fetchConfig = async () => {
const file = await import(
`../../../configs/${NETWORK !== 'mainnet' ? 'osmo-test-5' : 'osmosis-1'}.ts`
)
const networkConfig: NetworkConfig = file.NETWORK_CONFIG
setChainInfoOverrides({
rpc: networkConfig.rpcUrl,
rest: networkConfig.restUrl,
chainID: networkConfig.name,
})
setEnabledWallets(networkConfig.wallets)
}
fetchConfig()
})
if (!chainInfoOverrides || !enabledWallets?.length) return null
const supportedChains = SUPPORTED_CHAINS.map((chain) => chain.chainId)
return (
<WalletManagerProvider
chainInfoOverrides={chainInfoOverrides}
chainInfoOverrides={{
rpc: networkConfig.rpcUrl,
rest: networkConfig.restUrl,
}}
chainIds={supportedChains}
closeIcon={<SVG.Close />}
defaultChainId={chainInfoOverrides.chainID}
enabledWallets={enabledWallets}
defaultChainId={currentNetwork}
enabledWallets={[
WalletID.Keplr,
WalletID.Xdefi,
WalletID.StationWallet,
WalletID.Leap,
WalletID.Cosmostation,
WalletID.KeplrMobile,
WalletID.CosmostationMobile,
]}
persistent
renderLoader={() => (
<div className={styles.loader}>

View File

@ -1,6 +1,5 @@
import { Coin } from '@cosmjs/stargate'
import { AnimatedNumber } from 'components/common'
import { useEffect, useState } from 'react'
import useStore from 'store'
interface Props {
@ -21,15 +20,7 @@ export const DisplayCurrency = ({
const networkConfig = useStore((s) => s.networkConfig)
const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency)
const amount = convertToDisplayCurrency(coin)
const [displayCurrency, setDisplayCurrency] = useState<DisplayCurrency>(
networkConfig?.displayCurrency,
)
useEffect(() => {
if (!networkConfig) return
if (displayCurrency.denom !== networkConfig?.displayCurrency.denom)
setDisplayCurrency(networkConfig?.displayCurrency)
}, [networkConfig?.displayCurrency, displayCurrency.denom, networkConfig])
const displayCurrency = networkConfig.displayCurrency
if (!displayCurrency) return null

View File

@ -1,6 +1,5 @@
import { WalletID } from '@marsprotocol/wallet-connector'
import { SVG } from 'components/common'
import { FIELDS_FEATURE } from 'constants/appConstants'
import { getCouncilLink } from 'libs/council'
import { useTranslation } from 'react-i18next'
import useStore from 'store'
@ -13,6 +12,8 @@ export const Footer = () => {
const { t } = useTranslation()
const client = useStore((s) => s.client)
const currentNetwork = useStore((s) => s.currentNetwork)
const networkConfig = useStore((s) => s.networkConfig)
return (
<footer className={styles.footer}>
@ -22,17 +23,17 @@ export const Footer = () => {
<div className={styles.header}>{t('global.mars')}</div>
<a
className={styles.item}
href='https://osmosis.marsprotocol.io/#/redbank'
href='https://app.marsprotocol.io/#/redbank'
rel='noopener noreferrer'
target='_blank'
title={t('global.redBank')}
>
{t('global.redBank')}
</a>
{FIELDS_FEATURE && (
{networkConfig.isFieldsEnabled && (
<a
className={styles.item}
href='https://osmosis.marsprotocol.io/#/farm'
href='https://app.marsprotocol.io/#/farm'
rel='noopener noreferrer'
target='_blank'
title={t('global.fields')}
@ -42,7 +43,7 @@ export const Footer = () => {
)}
<a
className={styles.item}
href={getCouncilLink(client?.recentWallet.providerId as WalletID)}
href={getCouncilLink(currentNetwork, client?.connectedWallet.providerId as WalletID)}
rel='noopener noreferrer'
target='_blank'
title={t('global.council')}

View File

@ -0,0 +1,109 @@
@import 'src/styles/master';
.container {
position: relative;
display: inline;
.menu {
display: flex;
position: absolute;
flex-direction: column;
justify-content: flex-start;
max-width: calc(100vw - 2 * #{$spacingBase}px);
top: rem-calc(40);
width: rem-calc(240);
right: left(1);
z-index: 100;
@include layoutPopover;
}
.header {
display: flex;
flex: 0 0 100%;
flex-wrap: nowrap;
width: 100%;
@include padding(4, 0, 2);
@include margin(0);
position: relative;
border-bottom: 1px solid $alphaBlack20;
text-align: center;
.text {
@include margin(0);
@include typoScaps;
color: $colorSecondaryDark;
width: 100%;
}
}
.subheader {
text-align: center;
flex: 0 0 100%;
@include typoScaps;
opacity: 0.6;
}
.chains {
@include padding(2, 2, 4);
display: flex;
flex-wrap: wrap;
}
.chain {
display: flex;
flex: 0 0 100%;
align-items: center;
@include padding(1, 2);
@include margin(0.5, 0);
opacity: 0.6;
transition: background-color 0.2s ease-in-out;
&.active {
color: $colorSecondaryDark;
pointer-events: none;
opacity: 1;
&:hover {
background-color: transparent;
}
}
&:hover {
cursor: pointer;
opacity: 1;
border-radius: $borderRadiusXS;
background-color: $alphaBlack10;
}
.image {
@include margin(0, 2, 0, 0);
display: flex;
align-items: center;
justify-content: center;
}
.chainId {
@include margin(0);
@include typoXS;
opacity: 0.6;
}
}
}
.button {
font-size: rem-calc(16);
@include margin(0, 2, 0, 0);
}
.clickAway {
display: block;
position: fixed;
z-index: 99;
height: 100vh;
width: 100vw;
left: 0;
top: 0;
&:hover {
cursor: pointer;
}
}

View File

@ -0,0 +1,124 @@
import { ChainInfoID } from '@marsprotocol/wallet-connector'
import { useQueryClient } from '@tanstack/react-query'
import classNames from 'classnames'
import { Button } from 'components/common'
import { CHAIN_ID_KEY, SUPPORTED_CHAINS } from 'constants/appConstants'
import { getNetworkConfig } from 'libs/networkConfig'
import Image from 'next/image'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import useStore from 'store'
import { State } from 'types/enums'
import styles from './ChainSelect.module.scss'
interface Chain {
chainId: ChainInfoID
type: 'testnet' | 'mainnet'
}
interface ChainList {
chains: Chain[]
currentNetwork: ChainInfoID
handleChainSelect: (chainId: ChainInfoID) => void
}
function ChainList({ chains, currentNetwork, handleChainSelect }: ChainList) {
return (
<div className={styles.chains}>
{chains.map((chain) => {
const { chainId } = chain
const nc = getNetworkConfig(chainId)
return (
<div
key={chainId}
className={classNames(styles.chain, chainId === currentNetwork && styles.active)}
onClick={() => handleChainSelect(chainId)}
role='button'
>
<div className={styles.image}>
<Image src={nc.chainIcon} height={24} width={24} alt={nc.name} />
</div>
<div className={styles.description}>
<p className='sCaps'>{nc.displayName}</p>
<p className={styles.chainId}>{chainId}</p>
</div>
</div>
)
})}
</div>
)
}
export const ChainSelect = () => {
const networkConfig = useStore((s) => s.networkConfig)
const currentNetwork = useStore((s) => s.currentNetwork)
const loadNetworkConfig = useStore((s) => s.loadNetworkConfig)
const queryClient = useQueryClient()
const { t } = useTranslation()
const [showMenu, setShowMenu] = useState(false)
function handleChainSelect(chainId: ChainInfoID) {
useStore.setState({
currentNetwork: chainId,
exchangeRates: [],
assetPricesUSD: [],
marketAssetLiquidity: [],
marketIncentiveInfo: [],
marketInfo: [],
userIcns: undefined,
redBankAssets: [],
networkConfig: getNetworkConfig(chainId),
redBankState: State.INITIALISING,
userBalancesState: State.INITIALISING,
migrationInProgress: false,
pythVaa: {
priceFeeds: [],
data: [],
},
})
loadNetworkConfig()
localStorage.setItem(CHAIN_ID_KEY, chainId)
queryClient.removeQueries()
setShowMenu(false)
}
const mainnets: Chain[] = SUPPORTED_CHAINS.filter((chain) => chain.type === 'mainnet')
const testnets: Chain[] = SUPPORTED_CHAINS.filter((chain) => chain.type === 'testnet')
return (
<div className={styles.container}>
<Button
className={styles.button}
variant='round'
color='tertiary'
suffix={
<Image src={networkConfig.chainIcon} height={20} width={20} alt={networkConfig.name} />
}
onClick={() => setShowMenu(true)}
/>
{showMenu && (
<>
<div className={styles.menu}>
<div className={styles.header}>
<p className={styles.text}>{t('common.selectChain')}</p>
</div>
<ChainList
chains={mainnets}
currentNetwork={currentNetwork}
handleChainSelect={handleChainSelect}
/>
<div className={styles.subheader}>{t('common.testnet')}</div>{' '}
<ChainList
chains={testnets}
currentNetwork={currentNetwork}
handleChainSelect={handleChainSelect}
/>
</div>
<div className={styles.clickAway} onClick={() => setShowMenu(false)} role='button' />
</>
)}
</div>
)
}

View File

@ -2,9 +2,9 @@ import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-c
import { ConnectButton, ConnectedButton } from 'components/common'
export const Connect = () => {
const { status } = useWalletManager()
const { status, connectedWallet } = useWalletManager()
if (status === WalletConnectionStatus.Connected) return <ConnectedButton />
if (status === WalletConnectionStatus.Connected && connectedWallet) return <ConnectedButton />
return <ConnectButton />
}

View File

@ -1,14 +1,16 @@
import { ChainInfoID, useWallet, useWalletManager } from '@marsprotocol/wallet-connector'
import { useWalletManager } from '@marsprotocol/wallet-connector'
import { AnimatedNumber, Button, CircularProgress, DisplayCurrency, SVG } from 'components/common'
import { SUPPORTED_CHAINS } from 'constants/appConstants'
import { findByDenom } from 'functions'
import { useUserBalance } from 'hooks/queries'
import { formatValue, lookup } from 'libs/parse'
import { truncate } from 'libs/text'
import { useCallback, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import useClipboard from 'react-use-clipboard'
import useStore from 'store'
import colors from 'styles/_assets.module.scss'
import { State } from 'types/enums'
import styles from './ConnectedButton.module.scss'
@ -16,8 +18,7 @@ export const ConnectedButton = () => {
// ---------------
// EXTERNAL HOOKS
// ---------------
const { disconnect } = useWallet()
const { disconnect: terminate } = useWalletManager()
const { disconnect, connectedWallet } = useWalletManager()
const { t } = useTranslation()
// ---------------
@ -27,6 +28,7 @@ export const ConnectedButton = () => {
const chainInfo = useStore((s) => s.chainInfo)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const userIcns = useStore((s) => s.userIcns)
const [isTestnet, setIsTestnet] = useState(false)
// ---------------
// LOCAL STATE
@ -59,23 +61,37 @@ export const ConnectedButton = () => {
baseCurrency.decimals,
)
const handleDisconnect = () => {
disconnect()
terminate()
}
useEffect(() => {
if (!chainInfo) return
setIsTestnet(
!!SUPPORTED_CHAINS.find(
(chain) => chain.type === 'testnet' && chain.chainId === chainInfo?.chainId,
),
)
}, [chainInfo])
useEffect(() => {
if (userWalletAddress === connectedWallet?.account.address) return
useStore.setState({
userWalletAddress: connectedWallet?.account.address,
marketAssetLiquidity: [],
marketInfo: [],
userIcns: undefined,
redBankAssets: [],
redBankState: State.INITIALISING,
userBalancesState: State.INITIALISING,
})
}, [connectedWallet?.account.address, userWalletAddress])
return (
<div className={styles.wrapper}>
{chainInfo?.chainId !== ChainInfoID.Osmosis1 && (
<span className={styles.network}>{chainInfo?.chainId}</span>
)}
{isTestnet && <span className={styles.network}>{chainInfo?.chainId}</span>}
<Button
className={styles.button}
onClick={() => {
setShowDetails(!showDetails)
}}
color='tertiary'
prefix={<SVG.Osmo className={styles.svg} />}
text={
<>
<span className={styles.address}>
@ -98,7 +114,7 @@ export const ConnectedButton = () => {
<div className={styles.detailsBalance}>
<div className={styles.detailsDenom}>{baseCurrency.symbol}</div>
<div className={`${styles.detailsBalanceAmount}`}>
<AnimatedNumber amount={currentBalanceAmount} abbreviated={false} />
<AnimatedNumber amount={currentBalanceAmount} />
<DisplayCurrency
className='s faded'
coin={{
@ -109,11 +125,7 @@ export const ConnectedButton = () => {
</div>
</div>
<div className={styles.detailsButton}>
<Button
color='secondary'
onClick={handleDisconnect}
text={t('common.disconnect')}
/>
<Button color='secondary' onClick={disconnect} text={t('common.disconnect')} />
</div>
</div>
<div className={styles.detailsBody}>

View File

@ -1,13 +1,13 @@
import { WalletID } from '@marsprotocol/wallet-connector'
import classNames from 'classnames'
import { IncentivesButton, Settings, SVG } from 'components/common'
import { FIELDS_FEATURE } from 'constants/appConstants'
import { getCouncilLink } from 'libs/council'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useTranslation } from 'react-i18next'
import useStore from 'store'
import { ChainSelect } from './ChainSelect'
import { Connect } from './Connect'
import styles from './Header.module.scss'
@ -15,6 +15,8 @@ export const Header = () => {
const { t } = useTranslation()
const router = useRouter()
const client = useStore((s) => s.client)
const networkConfig = useStore((s) => s.networkConfig)
const currentNetwork = useStore((s) => s.currentNetwork)
return (
<header className={styles.header}>
@ -33,7 +35,7 @@ export const Header = () => {
>
{t('global.redBank')}
</Link>
{FIELDS_FEATURE && (
{networkConfig.isFieldsEnabled && (
<Link
passHref
href='/farm'
@ -48,7 +50,7 @@ export const Header = () => {
)}
<a
className={styles.nav}
href={getCouncilLink(client?.recentWallet.providerId as WalletID)}
href={getCouncilLink(currentNetwork, client?.connectedWallet.providerId as WalletID)}
target='_blank'
rel='noreferrer'
>
@ -57,6 +59,7 @@ export const Header = () => {
</div>
<div className={styles.connector}>
<IncentivesButton />
<ChainSelect />
<Connect />
<Settings />
</div>

View File

@ -35,7 +35,7 @@ export const IncentivesButton = () => {
const otherAssets = useStore((s) => s.otherAssets)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const unclaimedRewards = useStore((s) => s.userUnclaimedRewards)
const incentivesContractAddress = useStore((s) => s.networkConfig?.contracts.incentives)
const incentivesContractAddress = useStore((s) => s.networkConfig.contracts.incentives)
const chainInfo = useStore((s) => s.chainInfo)
const executeMsg = useStore((s) => s.executeMsg)

View File

@ -3,10 +3,11 @@ import { useQueryClient } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import classNames from 'classnames'
import { Button, NumberInput, SVG, Toggle, Tooltip } from 'components/common'
import { DISPLAY_CURRENCY_KEY, ENABLE_ANIMATIONS_KEY, FIELDS_FEATURE } from 'constants/appConstants'
import React, { useState } from 'react'
import { DISPLAY_CURRENCY_KEY, ENABLE_ANIMATIONS_KEY } from 'constants/appConstants'
import React, { useEffect, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import useStore from 'store'
import { State } from 'types/enums'
import styles from './Settings.module.scss'
@ -18,6 +19,7 @@ export const Settings = () => {
const slippage = useStore((s) => s.slippage)
const networkConfig = useStore((s) => s.networkConfig)
const currencyAssets = useStore((s) => s.currencyAssets)
const calculateExchangeRates = useStore((s) => s.calculateExchangeRates)
const [customSlippage, setCustomSlippage] = useState<number>(0)
const [inputRef, setInputRef] = useState<React.RefObject<HTMLInputElement>>()
const [isCustom, setIsCustom] = useState(false)
@ -26,7 +28,7 @@ export const Settings = () => {
const exchangeRates = useStore((s) => s.exchangeRates)
const [displayCurrency, setDisplayCurrency] = useState<DisplayCurrency>(
networkConfig?.displayCurrency,
networkConfig.displayCurrency,
)
const onInputChange = (value: number) => {
@ -67,7 +69,7 @@ export const Settings = () => {
const changeDisplayCurrency = (denom: string) => {
const selectedAsset = currencyAssets.find((asset) => asset.denom === denom)
if (!selectedAsset || !networkConfig || !exchangeRates?.length) return
if (!selectedAsset || !exchangeRates?.length) return
const newDisplayCurrency = {
denom: selectedAsset.denom,
prefix: selectedAsset.prefix ?? '',
@ -76,14 +78,23 @@ export const Settings = () => {
}
const exchangeRate = exchangeRates.find((rate) => rate.denom === newDisplayCurrency.denom)
if (!exchangeRate) return
if (!exchangeRate && newDisplayCurrency.denom !== 'usd') return
setDisplayCurrency(newDisplayCurrency)
useStore.setState({ networkConfig: { ...networkConfig, displayCurrency: newDisplayCurrency } })
useStore.setState({ baseToDisplayCurrencyRatio: 1 / Number(exchangeRate.amount) })
useStore.setState({
networkConfig: { ...networkConfig, displayCurrency: newDisplayCurrency },
exchangeRates: [],
exchangeRatesState: State.INITIALISING,
})
localStorage.setItem(DISPLAY_CURRENCY_KEY, JSON.stringify(newDisplayCurrency))
queryClient.invalidateQueries()
calculateExchangeRates()
}
useEffect(() => {
if (networkConfig.displayCurrency && networkConfig.displayCurrency !== displayCurrency)
setDisplayCurrency(networkConfig.displayCurrency)
}, [networkConfig.displayCurrency, displayCurrency])
if (status !== WalletConnectionStatus.Connected) return null
return (
@ -139,7 +150,7 @@ export const Settings = () => {
</div>
</div>
</div>
{FIELDS_FEATURE && (
{networkConfig.isFieldsEnabled && (
<>
<div className={styles.header}>
<p className={styles.text}>{t('fields.settings')}</p>

View File

@ -4,7 +4,6 @@ import BigNumber from 'bignumber.js'
import { getLeverageRatio } from 'functions/fields'
import { formatValue, roundToDecimals } from 'libs/parse'
import throttle from 'lodash.throttle'
import React from 'react'
import { useTranslation } from 'react-i18next'
import colors from 'styles/_assets.module.scss'
@ -67,6 +66,7 @@ export const InputSlider = ({
// -------------------------
// Presentation
// -------------------------
const leverageRatio = getLeverageRatio(leverageMax, maxValue)
const marksArray =
minValue === 0 && maxValue === 100

View File

@ -1,12 +1,12 @@
import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
import { useWallet, useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
import classNames from 'classnames'
import { Footer, Header, MobileNav, TermsOfService } from 'components/common'
import { FieldsNotConnected } from 'components/fields'
import { RedbankNotConnected } from 'components/redbank'
import { SESSION_WALLET_KEY, TERMS_OF_SERVICE } from 'constants/appConstants'
import { TERMS_OF_SERVICE } from 'constants/appConstants'
import { useAnimations } from 'hooks/data'
import { useRouter } from 'next/router'
import React, { useEffect } from 'react'
import React, { useEffect, useState } from 'react'
import useStore from 'store'
type Props = {
@ -19,16 +19,20 @@ export const Layout = ({ children }: Props) => {
const router = useRouter()
const { status } = useWalletManager()
const currentNetwork = useStore((s) => s.currentNetwork)
const { wallets } = useWallet()
const [isConnected, setIsConnected] = useState(false)
const [wasConnectedBefore, setWasConnectedBefore] = useState(false)
useAnimations()
const enableAnimations = useStore((s) => s.enableAnimations)
const isConnected = status === WalletConnectionStatus.Connected
const backgroundClasses = classNames('background', !isConnected && 'night')
const vaultConfigs = useStore((s) => s.vaultConfigs)
const wasConnectedBefore =
localStorage.getItem(SESSION_WALLET_KEY) &&
localStorage.getItem(SESSION_WALLET_KEY) !== '[]' &&
status !== WalletConnectionStatus.Errored
useEffect(() => {
setIsConnected(status === WalletConnectionStatus.Connected)
setWasConnectedBefore(!!wallets.find((w) => w.network.chainId === currentNetwork))
}, [status, wallets, currentNetwork])
useEffect(() => {
if (!isConnected) {

View File

@ -0,0 +1,34 @@
@import 'src/styles/master';
.container {
position: fixed;
left: 0;
top: 0;
z-index: 1;
right: 0;
bottom: 0;
display: grid;
place-items: center;
.card {
max-width: min(rem-calc(500), 95vw);
@include padding(2, 0, 4, 0);
justify-content: center;
display: flex;
flex-wrap: wrap;
.headline {
@include margin(4, 0);
@include typoLcaps;
text-align: center;
width: 100%;
}
.text {
@include typoM;
@include margin(0, 0, 4);
text-align: center;
width: 100%;
}
}
}

View File

@ -0,0 +1,21 @@
import { Card, CircularProgress } from 'components/common'
import { useTranslation } from 'react-i18next'
import styles from './MigrationInProgress.module.scss'
export const MigrationInProgress = () => {
const { t } = useTranslation()
return (
<>
<div className={styles.container}>
<Card title={t('common.migration.title')} className={styles.card}>
<p className={styles.headline}>{t('common.migration.headline')}</p>
<p className={styles.text}>{t('common.migration.info')}</p>
<CircularProgress size={40} forceAnimation={true} />
</Card>
</div>
<div className='background night' />
</>
)
}

View File

@ -1,7 +1,6 @@
import { WalletID } from '@marsprotocol/wallet-connector'
import classNames from 'classnames'
import { SVG } from 'components/common'
import { FIELDS_FEATURE } from 'constants/appConstants'
import { getCouncilLink } from 'libs/council'
import Link from 'next/link'
import { useRouter } from 'next/router'
@ -14,6 +13,8 @@ export const MobileNav = () => {
const { t } = useTranslation()
const router = useRouter()
const client = useStore((s) => s.client)
const networkConfig = useStore((s) => s.networkConfig)
const currentNetwork = useStore((s) => s.currentNetwork)
return (
<nav className={styles.mobileNav}>
@ -29,7 +30,7 @@ export const MobileNav = () => {
<a
className={styles.nav}
target='_blank'
href={getCouncilLink(client?.recentWallet.providerId as WalletID)}
href={getCouncilLink(currentNetwork, client?.connectedWallet.providerId as WalletID)}
rel='noreferrer'
>
<div className={styles.icon}>
@ -37,7 +38,7 @@ export const MobileNav = () => {
</div>
<span>{t('global.council')}</span>
</a>
{FIELDS_FEATURE && (
{networkConfig.isFieldsEnabled && (
<Link
href='/farm'
passHref

View File

@ -2,7 +2,8 @@ import classNames from 'classnames/bind'
import { SVG } from 'components/common'
import { ReactNode, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { NotificationType } from 'types/enums'
import useStore from 'store'
import { NotificationType, State } from 'types/enums'
import styles from './Notification.module.scss'
@ -17,6 +18,7 @@ export const Notification = ({ showNotification, content, type, hideCloseBtn = f
const { t } = useTranslation()
const [closeNotification, setCloseNotification] = useState(false)
const classes = classNames.bind(styles)
const redBankState = useStore((s) => s.redBankState)
const notificationClasses = classes({
notification: true,
@ -25,7 +27,7 @@ export const Notification = ({ showNotification, content, type, hideCloseBtn = f
warning: type === NotificationType.Warning,
})
if (!showNotification || closeNotification) return <></>
if (!showNotification || closeNotification || redBankState !== State.READY) return null
return (
<div className={notificationClasses}>

View File

@ -22,7 +22,7 @@ export const TermsOfService = () => {
return (
<div className={styles.container}>
<Card title='Disclaimer' className={styles.card}>
<Card title={t('common.disclaimers')} className={styles.card}>
<div className={classNames('xs', styles.subtitle)}>
<Trans i18nKey='common.termsOfService.intro'>
<span className={classNames('faded xs')}>

View File

@ -24,7 +24,7 @@
position: relative;
width: space(10);
height: space(5);
border-radius: space(4);
border-radius: $borderRadiusXL;
box-shadow: inset 0 0 rem-calc(4) $alphaBlack40;
background: $colorGreyLight;

View File

@ -2,7 +2,6 @@ import { Coin } from '@cosmjs/proto-signing'
import { AnimatedNumber } from 'components/common'
import { useAsset } from 'hooks/data'
import { lookup } from 'libs/parse'
import React from 'react'
interface Props {
coin: Coin

View File

@ -85,6 +85,7 @@ export const Action = ({
const convertToBaseCurrency = useStore((s) => s.convertToBaseCurrency)
const findUserDebt = useStore((s) => s.findUserDebt)
const enableAnimations = useStore((s) => s.enableAnimations)
const baseCurrencyDecimals = useStore((s) => s.baseCurrency.decimals)
// ------------------
// LOCAL STATE
@ -134,6 +135,7 @@ export const Action = ({
amount * currentAssetPrice, // amount in display currency
activeView,
relevantBalanceKey,
baseCurrencyDecimals,
),
[
activeView,
@ -143,6 +145,7 @@ export const Action = ({
denom,
redBankAssets,
relevantBalanceKey,
baseCurrencyDecimals,
],
)
@ -154,6 +157,7 @@ export const Action = ({
0.0,
activeView,
relevantBalanceKey,
baseCurrencyDecimals,
),
relevantBalanceKey,
)
@ -220,7 +224,13 @@ export const Action = ({
const calculateMaxBorrowableAmount = useMemo((): number => {
const assetLiquidity = Number(findByDenom(marketAssetLiquidity, denom)?.amount || 0)
return maxBorrowableAmount(assetLiquidity, availableBalanceBaseCurrency, currentAssetPrice)
return maxBorrowableAmount(
assetLiquidity,
availableBalanceBaseCurrency,
new BigNumber(currentAssetPrice)
.shiftedBy(baseCurrency.decimals - (currentAsset?.decimals || 0))
.toNumber(),
)
}, [
denom,
availableBalanceBaseCurrency,
@ -230,9 +240,7 @@ export const Action = ({
currentAsset?.decimals,
])
const repayMax = useMemo((): number => {
return Math.min(assetBorrowBalance, walletBalance)
}, [assetBorrowBalance, walletBalance])
const repayMax = Math.min(assetBorrowBalance, walletBalance)
const maxWithdrawableAmount = useMemo((): number => {
const assetLtvRatio = findByDenom(marketInfo, denom)?.max_loan_to_value || 0
@ -248,9 +256,10 @@ export const Action = ({
if (!asset || !asset.depositBalance || !asset.denom) return 0
// When withdrawing, we have to remove the slippage, otherwise we can't actually hit the borrow limit.
const withdrawableAmountOfAsset = new BigNumber(availableBalanceBaseCurrency)
.div(1 - DEFAULT_SLIPPAGE)
.div(currentAssetPrice * assetLtvRatio)
const withdrawableAmountOfAsset = new BigNumber(
availableBalanceBaseCurrency / (1 - DEFAULT_SLIPPAGE) / (currentAssetPrice * assetLtvRatio),
)
.shiftedBy(asset.decimals - baseCurrency.decimals)
.toNumber()
return withdrawableAmountOfAsset < assetBalanceOrAvailableLiquidity

View File

@ -30,14 +30,14 @@ export const TxResponse = ({
const [txFee, setTxFee] = useState<Coin>()
const [txStatus, setTxStatus] = useState<TxStatus>(TxStatus.LOADING)
const rpc = useStore((s) => s.chainInfo?.rpc)
const chainID = useStore((s) => s.chainInfo?.chainId)
const chainId = useStore((s) => s.chainInfo?.chainId)
const client = useStore((s) => s.client)
const baseCurrency = useStore((s) => s.baseCurrency)
useEffect(() => {
const getTxInfo = async (hash?: string) => {
if (txStatus !== TxStatus.LOADING) return
if (!rpc || !chainID || !hash || !response) return
if (!rpc || !chainId || !hash || !response) return
try {
const coin = getFeeFromResponse(response)
@ -56,7 +56,7 @@ export const TxResponse = ({
}
getTxInfo(response?.hash || undefined)
}, [client, response, rpc, chainID, checkTxStatus, onSuccess, txStatus, baseCurrency.denom])
}, [client, response, rpc, chainId, checkTxStatus, onSuccess, txStatus, baseCurrency.denom])
// reset scroll
useEffect(() => {

View File

@ -15,6 +15,7 @@ export { CosmosWalletConnectProvider } from './CosmosWalletConnectProvider/Cosmo
export { DisplayCurrency } from './DisplayCurrency/DisplayCurrency'
export { ErrorMessage } from './ErrorMessage/ErrorMessage'
export { Footer } from './Footer/Footer'
export { ChainSelect } from './Header/ChainSelect'
export { Connect } from './Header/Connect'
export { ConnectButton } from './Header/ConnectButton'
export { ConnectedButton } from './Header/ConnectedButton'
@ -26,6 +27,7 @@ export { InputSection } from './InputSection/InputSection'
export { InputSlider } from './InputSlider/InputSlider'
export { Layout } from './Layout/Layout'
export { Loading } from './Loading/Loading'
export { MigrationInProgress } from './MigrationInProgress/MigrationInProgress'
export { MobileNav } from './MobileNav/MobileNav'
export { Notification } from './Notification/Notification'
export { NumberInput } from './NumberInput/NumberInput'

View File

@ -100,13 +100,9 @@ export const useAvailableVaultsColumns = () => {
if (secondaryBorrowAsset?.borrowEnabled) borrowRates.push(secondaryBorrowAsset.borrowRate)
const borrowRate = Math.min(...borrowRates)
const maxBorrowRate = borrowRate * (ltvToLeverage(row.original.ltv.contract) - 1)
const minAPY = row.original.apy.total ?? 0
const maxAPY = new BigNumber(minAPY).times(maxLeverage).toNumber() - maxBorrowRate
const minDailyAPY = new BigNumber(convertApyToDailyApy(minAPY))
.decimalPlaces(2)
.toNumber()

View File

@ -131,17 +131,19 @@ export const BreakdownTable = (props: Props) => {
const getValueText = (
type: 'primary' | 'secondary' | 'net' | 'borrowedPrimary' | 'borrowedSecondary' | 'total',
) => (
<DisplayCurrency
prefixClass='s faded'
valueClass='m faded'
isApproximation
coin={{
amount: props.newPosition.values[type].toString(),
denom: baseCurrency.denom,
}}
/>
)
) => {
return (
<DisplayCurrency
prefixClass='s faded'
valueClass='m faded'
isApproximation
coin={{
amount: props.newPosition.values[type].toString(),
denom: baseCurrency.denom,
}}
/>
)
}
const maxBorrowValue = useMemo(
() => getMaxBorrowValue(props.vault, props.newPosition),

View File

@ -43,6 +43,9 @@ export const PositionInput = (props: Props) => {
denom: props.vault.denoms.secondary,
amount: position.amounts.borrowedSecondary.toString(),
})
position.values.primary = primaryValue
position.values.secondary = secondaryValue
position.values.borrowedPrimary = borrowedPrimaryValue
position.values.borrowedSecondary = borrowedSecondaryValue
position.values.total =
@ -71,6 +74,7 @@ export const PositionInput = (props: Props) => {
const onBorrowChange = (amount: number, type: 'primary' | 'secondary') => {
props.position.borrowDenom =
type === 'primary' ? props.vault.denoms.primary : props.vault.denoms.secondary
const borrowValue = convertToBaseCurrency({
denom: props.position.borrowDenom,
amount: amount.toString(),

View File

@ -60,6 +60,7 @@ export const RepayInput = (props: Props) => {
denom: props.vault.denoms.secondary,
amount: position.amounts.borrowedSecondary.toString(),
})
position.values.primary = primaryValue
position.values.secondary = secondaryValue
position.values.borrowedPrimary = borrowedPrimaryValue

View File

@ -19,11 +19,12 @@ export const ActionsRow = ({ row, type }: Props) => {
const router = useRouter()
const chainInfo = useStore((s) => s.chainInfo)
const redBankAssets = useStore((s) => s.redBankAssets)
const assetPricesUSD = useStore((s) => s.assetPricesUSD)
const hasBalance = Number(row.original.walletBalance ?? 0) > 0
const hasDeposits = Number(row.original.depositBalance ?? 0) > 0
const hasNeverDeposited = Number(balanceSum(redBankAssets, 'depositBalanceBaseCurrency')) === 0
const appUrl = useStore((s) => s.networkConfig?.appUrl) || ''
const appUrl = useStore((s) => s.networkConfig.appUrl) || ''
const classes = classNames.bind(styles)
const trClasses = classes({
tr: true,
@ -31,6 +32,8 @@ export const ActionsRow = ({ row, type }: Props) => {
})
const assetID = row.original.id
const assetPrice = assetPricesUSD?.find((asset) => asset.denom === row.original.denom)?.amount
return (
<tr key={row.id} className={trClasses} onClick={() => row.toggleExpanded()}>
<td key={row.id} className={styles.td} colSpan={7}>
@ -56,7 +59,7 @@ export const ActionsRow = ({ row, type }: Props) => {
text={
<Button
color='tertiary'
disabled={!hasBalance}
disabled={!hasBalance || !assetPrice}
prefix={<SVG.Deposit />}
size='small'
text={t('redbank.deposit')}
@ -64,12 +67,14 @@ export const ActionsRow = ({ row, type }: Props) => {
/>
}
tooltip={
hasBalance
? null
: t('redbank.toDepositAssetOnChain', {
!assetPrice
? t('redbank.noPriceAvailable', { symbol: row.original.symbol })
: !hasBalance
? t('redbank.toDepositAssetOnChain', {
asset: assetID,
chain: chainInfo?.name,
})
: null
}
/>
{hasDeposits && (
@ -131,16 +136,20 @@ export const ActionsRow = ({ row, type }: Props) => {
<Button
color='tertiary'
prefix={<SVG.Withdraw />}
disabled={row.original.marketLiquidity === '0' || hasNeverDeposited}
disabled={
row.original.marketLiquidity === '0' || hasNeverDeposited || !assetPrice
}
size='small'
text={t('common.borrow')}
onClick={() => router.push(`/redbank/borrow/${assetID}`)}
/>
}
tooltip={
row.original.marketLiquidity === '0' || hasNeverDeposited
row.original.marketLiquidity === '0' || hasNeverDeposited || !assetPrice
? hasNeverDeposited
? t('redbank.warning.borrow')
: !assetPrice
? t('redbank.noPriceAvailable', { symbol: row.original.symbol })
: t('redbank.notEnoughMarketLiquidity')
: null
}

View File

@ -1,44 +0,0 @@
@import 'src/styles/master';
.color {
position: absolute;
top: 0;
width: rem-calc(7);
height: space(16);
margin-left: rem-calc(-7);
&.OSMO {
background-image: $colorGradientOSMO;
}
&.ATOM {
background-image: $colorGradientATOM;
}
&.AXL {
background-image: $colorGradientAXL;
}
&.JUNO {
background-image: $colorGradientJUNO;
}
&.axlUSDC,
&.nUSDC {
background-image: $colorGradientAxlUSDC;
}
&.axlWBTC {
background-image: $colorGradientAxlWBTC;
}
&.axlWETH {
background-image: $colorGradientAxlWETH;
}
}
.logo {
display: grid;
margin: auto;
width: rem-calc(32);
}

View File

@ -5,7 +5,7 @@ import { useMemo } from 'react'
import { isMobile, isTablet } from 'react-device-detect'
import { useTranslation } from 'react-i18next'
import styles from './useBorrowColumns.module.scss'
import styles from '../RedbankColumns.module.scss'
export const useBorrowColumns = () => {
const { t } = useTranslation()
@ -19,7 +19,7 @@ export const useBorrowColumns = () => {
header: '',
cell: (info) => (
<div
className={`${styles.color} ${styles[info.row.original.id]} ${
className={`${styles.color} ${styles[info.row.original.id.toLowerCase()]} ${
info.row.getIsExpanded() ? styles.expanded : ''
}`}
/>

View File

@ -8,7 +8,7 @@ import { useMemo } from 'react'
import { isMobile, isTablet } from 'react-device-detect'
import { useTranslation } from 'react-i18next'
import styles from './useDepositColumns.module.scss'
import styles from '../RedbankColumns.module.scss'
export const useDepositColumns = () => {
const { t } = useTranslation()
@ -23,7 +23,7 @@ export const useDepositColumns = () => {
header: '',
cell: (info) => (
<div
className={`${styles.color} ${styles[info.row.original.id]} ${
className={`${styles.color} ${styles[info.row.original.id.toLowerCase()]} ${
info.row.getIsExpanded() ? styles.expanded : ''
}`}
/>

View File

@ -69,7 +69,7 @@ export const RedbankAction = React.memo(
// Read only states
const borrowAssetName = redBankAssets.find((asset) => asset.denom === denom)
const redBankContractAddress = networkConfig?.contracts.redBank
const redBankContractAddress = networkConfig.contracts.redBank
const totalScaledDepositbaseCurrencyBalance = useMemo(() => {
if (!userCollateral) return 0
return ltvWeightedDepositValue(

View File

@ -7,38 +7,42 @@
height: space(16);
@include margin(0, 0, 0, -2);
&.OSMO {
&.osmo {
background-image: $colorGradientOSMO;
}
&.ATOM {
&.atom {
background-image: $colorGradientATOM;
}
&.AXL {
&.axl {
background-image: $colorGradientAXL;
}
&.JUNO {
&.juno {
background-image: $colorGradientJUNO;
}
&.axlUSDC,
&.nUSDC {
&.axlusdc,
&.nusdc {
background-image: $colorGradientAxlUSDC;
}
&.stATOM {
&.statom {
background-image: $colorGradientStATOM;
}
&.axlWBTC {
&.axlwbtc {
background-image: $colorGradientAxlWBTC;
}
&.axlWETH {
&.axlweth {
background-image: $colorGradientAxlWETH;
}
&.ntrn {
background-image: $colorGradientNTRN;
}
}
.logo {

View File

@ -1,5 +1,4 @@
import { ChainInfoID, WalletID } from '@marsprotocol/wallet-connector'
import { URL_GQL, URL_REST, URL_RPC } from 'constants/env'
import { ChainInfoID } from '@marsprotocol/wallet-connector'
import atom from 'images/atom.svg'
import axl from 'images/axl.svg'
import axlusdc from 'images/axlusdc.svg'
@ -8,7 +7,7 @@ import nusdc from 'images/nusdc.svg'
import osmo from 'images/osmo.svg'
import colors from 'styles/_assets.module.scss'
export const ASSETS: { [denom: string]: Asset } = {
const ASSETS: NetworkAssets = {
osmo: {
symbol: 'OSMO',
name: 'Osmosis',
@ -17,6 +16,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.osmo,
logo: osmo,
decimals: 6,
priceFeedId: '5867f5683c757393a0670ef0f701490950fe93fdb006d181c8265a831ac0c5c6',
},
atom: {
symbol: 'ATOM',
@ -26,6 +26,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.atom,
logo: atom,
decimals: 6,
priceFeedId: 'b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e612819',
},
axl: {
symbol: 'AXL',
@ -44,6 +45,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.usdc,
decimals: 6,
logo: axlusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
nusdc: {
symbol: 'USDC.n',
@ -53,6 +55,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.usdc,
decimals: 6,
logo: nusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
}
@ -60,10 +63,12 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
mars: {
symbol: 'MARS',
name: 'Mars',
denom: 'ibc/DB9D326CF53EA07610C394D714D78F8BB4DC7E312D4213193791A9046BF45E20',
id: 'MARS',
denom: 'ibc/2E7368A14AC9AB7870F32CFEA687551C5064FA861868EDF7437BC877358A81F9',
color: colors.mars,
logo: mars,
decimals: 6,
poolId: 9,
},
usd: {
symbol: '',
@ -77,20 +82,23 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
}
export const NETWORK_CONFIG: NetworkConfig = {
name: ChainInfoID.OsmosisTestnet5,
name: ChainInfoID.OsmosisTestnet,
displayName: 'Osmosis Testnet',
hiveUrl:
URL_GQL ??
process.env.NEXT_PUBLIC_OSMOSIS_TEST_GQL ??
'https://testnet-osmosis-node.marsprotocol.io/XF32UOOU55CX/osmosis-hive-front/graphql',
rpcUrl: URL_RPC ?? 'https://rpc.osmotest5.osmosis.zone/',
restUrl: URL_REST ?? 'https://lcd.osmotest5.osmosis.zone/',
rpcUrl: process.env.NEXT_PUBLIC_OSMOSIS_TEST_RPC ?? 'https://rpc.osmotest5.osmosis.zone/',
restUrl: process.env.NEXT_PUBLIC_OSMOSIS_TEST_REST ?? 'https://lcd.osmotest5.osmosis.zone/',
apolloAprUrl: 'https://api.apollo.farm/api/vault_infos/v2/osmo-test-5',
osmoUsdPriceUrl: 'https://api-osmosis.imperator.co/tokens/v2/OSMO',
usdPriceUrl: 'https://xc-mainnet.pyth.network/api/',
chainIcon: osmo,
contracts: {
redBank: 'osmo1dl4rylasnd7mtfzlkdqn2gr0ss4gvyykpvr6d7t5ylzf6z535n9s5jjt8u',
incentives: 'osmo1zyz57xf82963mcsgqu3hq5y0h9mrltm4ttq2qe5mjth9ezp3375qe0sm7d',
oracle: 'osmo1khe29uw3t85nmmp3mtr8dls7v2qwsfk3tndu5h4w5g2r5tzlz5qqarq2e2',
oracle: 'osmo1tx9987hjkx3kc9jvxmdzaf9uz8ukzscl88c476r7854205rkhecsc20tnk',
creditManager: 'osmo15ywk53ck3wp6tnqgedfd8cnfx7fuhz9dr583hw8scp0xjgw46m0sf3kyyp',
accountNft: 'osmo1ye2rntzz9qmxgv7eg09supww6k6xs0y0sekcr3x5clp087fymn4q3y33s4',
pyth: 'osmo12u2vqdecdte84kg6c3d40nwzjsya59hsj048n687m9q3t6wdmqgsq6zrlx',
},
assets: {
base: ASSETS.osmo,
@ -108,7 +116,7 @@ export const NETWORK_CONFIG: NetworkConfig = {
},
displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://testnet.osmosis.zone',
wallets: [WalletID.Keplr, WalletID.Leap, WalletID.Cosmostation],
isFieldsEnabled: true,
}
export const VAULT_CONFIGS: Vault[] = [

View File

@ -1,5 +1,4 @@
import { ChainInfoID, WalletID } from '@marsprotocol/wallet-connector'
import { URL_GQL, URL_REST, URL_RPC } from 'constants/env'
import { ChainInfoID } from '@marsprotocol/wallet-connector'
import atom from 'images/atom.svg'
import axl from 'images/axl.svg'
import axlusdc from 'images/axlusdc.svg'
@ -10,7 +9,7 @@ import osmo from 'images/osmo.svg'
import statom from 'images/statom.svg'
import colors from 'styles/_assets.module.scss'
export const ASSETS: { [denom: string]: Asset } = {
const ASSETS: NetworkAssets = {
osmo: {
symbol: 'OSMO',
name: 'Osmosis',
@ -19,6 +18,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.osmo,
logo: osmo,
decimals: 6,
priceFeedId: '5867f5683c757393a0670ef0f701490950fe93fdb006d181c8265a831ac0c5c6',
},
axlusdc: {
symbol: 'USDC.axl',
@ -28,6 +28,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.usdc,
decimals: 6,
logo: axlusdc,
priceFeedId: 'eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a',
},
axlwbtc: {
symbol: 'WBTC.axl',
@ -37,6 +38,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.wbtc,
logo: axlwbtc,
decimals: 8,
priceFeedId: 'e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43',
},
axlweth: {
symbol: 'WETH.axl',
@ -46,6 +48,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.weth,
logo: axlweth,
decimals: 18,
priceFeedId: 'ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace',
},
atom: {
symbol: 'ATOM',
@ -55,6 +58,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.atom,
logo: atom,
decimals: 6,
priceFeedId: 'b00b60f88b03a6a625a8d1c048c3f66653edf217439983d037e7222c4e612819',
},
axl: {
symbol: 'AXL',
@ -64,6 +68,7 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.axl,
logo: axl,
decimals: 6,
priceFeedId: '60144b1d5c9e9851732ad1d9760e3485ef80be39b984f6bf60f82b28a2b7f126',
},
statom: {
symbol: 'stATOM',
@ -73,7 +78,6 @@ export const ASSETS: { [denom: string]: Asset } = {
color: colors.statom,
logo: statom,
decimals: 6,
poolBase: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
},
}
@ -81,6 +85,7 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
mars: {
symbol: 'MARS',
name: 'Mars',
id: 'MARS',
denom: 'ibc/573FCD90FACEE750F55A8864EF7D38265F07E5A9273FA0E8DAFD39951332B580',
color: colors.mars,
logo: mars,
@ -100,18 +105,22 @@ const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
export const NETWORK_CONFIG: NetworkConfig = {
name: ChainInfoID.Osmosis1,
displayName: 'Osmosis',
hiveUrl:
URL_GQL ?? 'https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql',
rpcUrl: URL_RPC ?? 'https://rpc-osmosis.blockapsis.com/',
restUrl: URL_REST ?? 'https://lcd-osmosis.blockapsis.com/',
process.env.NEXT_PUBLIC_OSMOSIS_GQL ??
'https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-hive-front/graphql',
rpcUrl: process.env.NEXT_PUBLIC_OSMOSIS_RPC ?? 'https://rpc-osmosis.blockapsis.com/',
restUrl: process.env.NEXT_PUBLIC_OSMOSIS_REST ?? 'https://lcd-osmosis.blockapsis.com/',
apolloAprUrl: 'https://api.apollo.farm/api/vault_infos/v2/osmosis-1',
osmoUsdPriceUrl: 'https://api-osmosis.imperator.co/tokens/v2/OSMO',
usdPriceUrl: 'https://xc-mainnet.pyth.network/api/',
chainIcon: osmo,
contracts: {
redBank: 'osmo1c3ljch9dfw5kf52nfwpxd2zmj2ese7agnx0p9tenkrryasrle5sqf3ftpg',
incentives: 'osmo1nkahswfr8shg8rlxqwup0vgahp0dk4x8w6tkv3rra8rratnut36sk22vrm',
oracle: 'osmo1mhznfr60vjdp2gejhyv2gax9nvyyzhd3z0qcwseyetkfustjauzqycsy2g',
creditManager: 'osmo1f2m24wktq0sw3c0lexlg7fv4kngwyttvzws3a3r3al9ld2s2pvds87jqvf',
accountNft: 'osmo1450hrg6dv2l58c0rvdwx8ec2a0r6dd50hn4frk370tpvqjhy8khqw7sw09',
pyth: 'osmo13ge29x4e2s63a8ytz2px8gurtyznmue4a69n5275692v3qn3ks8q7cwck7',
},
assets: {
base: ASSETS.osmo,
@ -138,15 +147,7 @@ export const NETWORK_CONFIG: NetworkConfig = {
},
displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://app.osmosis.zone',
wallets: [
WalletID.Keplr,
WalletID.Xdefi,
WalletID.StationWallet,
WalletID.Leap,
WalletID.Cosmostation,
WalletID.KeplrMobile,
WalletID.CosmostationMobile,
],
isFieldsEnabled: true,
}
export const VAULT_CONFIGS: Vault[] = [
@ -234,4 +235,60 @@ export const VAULT_CONFIGS: Vault[] = [
vaultAddress: '',
},
},
{
address: 'osmo185gqewrlde8vrqw7j8lpad67v8jfrx9u7770k9q87tqqecctp5tq50wt2c',
name: { name: 'OSMO-WBTC.axl', unlockDuration: 14, unlockTimeframe: 'days' },
denoms: {
primary: 'uosmo',
secondary: 'ibc/D1542AA8762DB13087D8364F3EA6509FD6F009A34F00426AF9E4F9FA85CBBF1F',
lpToken: 'gamm/pool/712',
},
symbols: {
primary: 'OSMO',
secondary: 'WBTC.axl',
},
color: colors.wbtc,
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 2.44, lpName: 'OSMO-WBTC.axl' },
ltv: {
max: 0.58,
contract: 0.59,
liq: 0.62,
},
apy: {
apys: null,
fees: null,
total: null,
vaultAddress: '',
},
},
{
address: 'osmo1r235f4tdkwrsnj3mdm9hf647l754y6g6xsmz0nas5r4vr5tda3qsgtftef',
name: { name: 'OSMO-WETH.axl', unlockDuration: 14, unlockTimeframe: 'days' },
denoms: {
primary: 'uosmo',
secondary: 'ibc/EA1D43981D5C9A1C4AAEA9C23BB1D4FA126BA9BC7020A25E0AE4AA841EA25DC5',
lpToken: 'gamm/pool/704',
},
symbols: {
primary: 'OSMO',
secondary: 'WETH.axl',
},
color: colors.weth,
lockup: 86400 * 14,
provider: 'Apollo vault',
description: { maxLeverage: 2.86, lpName: 'OSMO-WETH.axl' },
ltv: {
max: 0.645,
contract: 0.65,
liq: 0.67,
},
apy: {
apys: null,
fees: null,
total: null,
vaultAddress: '',
},
},
]

84
src/configs/pion-1.ts Normal file
View File

@ -0,0 +1,84 @@
import { ChainInfoID } from '@marsprotocol/wallet-connector'
import atom from 'images/atom.svg'
import axlusdc from 'images/axlusdc.svg'
import mars from 'images/mars.svg'
import ntrn from 'images/ntrn.svg'
import colors from 'styles/_assets.module.scss'
export const ASSETS: NetworkAssets = {
ntrn: {
symbol: 'NTRN',
name: 'Neutron',
id: 'NTRN',
denom: 'untrn',
color: colors.ntrn,
logo: ntrn,
decimals: 6,
},
atom: {
symbol: 'ATOM',
name: 'Atom',
id: 'ATOM',
denom: 'ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9',
color: colors.atom,
logo: atom,
decimals: 6,
},
axlusdc: {
symbol: 'USDC.axl',
name: 'Axelar USDC',
id: 'axlUSDC',
denom: 'ibc/EFB00E728F98F0C4BBE8CA362123ACAB466EDA2826DC6837E49F4C1902F21BBA',
color: colors.usdc,
decimals: 6,
logo: axlusdc,
},
}
const OTHER_ASSETS: { [denom: string]: OtherAsset } = {
mars: {
symbol: 'MARS',
id: 'MARS',
name: 'Mars',
denom: 'ibc/FAD9EE91F499D275D9135F95F52D59D90C621B8438A9CFF1757BB886EEE90E3E',
color: colors.mars,
logo: mars,
decimals: 6,
},
usd: {
symbol: '',
prefix: '$',
name: 'US Dollar',
denom: 'usd',
color: '',
logo: '',
decimals: 2,
},
}
export const NETWORK_CONFIG: NetworkConfig = {
name: ChainInfoID.NeutronTestnet,
displayName: 'Neutron Testnet',
hiveUrl:
process.env.NEXT_PUBLIC_NEUTRON_TEST_GQL ??
'https://testnet-neutron-gql.marsprotocol.io/graphql',
rpcUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_RPC ?? 'https://rpc-palvus.pion-1.ntrn.tech/',
restUrl: process.env.NEXT_PUBLIC_NEUTRON_TEST_REST ?? 'https://rest-palvus.pion-1.ntrn.tech/',
chainIcon: ntrn,
contracts: {
redBank: 'neutron15dld0kmz0zl89zt4yeks4gy8mhmawy3gp4x5rwkcgkj5krqvu9qs4q7wve',
incentives: 'neutron1t8fectc2ntxhuee2f9ty2mxh8l0ykzm6yxfsp9k35vdktksm2vfsd2d6rl',
oracle: 'neutron1nx9txtmpmkt58gxka20z72wdkguw4n0606zkeqvelv7q7uc06zmsym3qgx',
},
assets: {
base: ASSETS.ntrn,
whitelist: [ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc],
other: [OTHER_ASSETS.usd, OTHER_ASSETS.mars],
currencies: [OTHER_ASSETS.usd, ASSETS.ntrn, ASSETS.atom, ASSETS.axlusdc, OTHER_ASSETS.mars],
},
displayCurrency: OTHER_ASSETS.usd,
appUrl: 'https://app.astroport.fi/swap',
isFieldsEnabled: false,
}
export const VAULT_CONFIGS: Vault[] = []

View File

@ -1,3 +1,5 @@
import { ChainInfoID } from '@marsprotocol/wallet-connector'
/* cosmos:network */
export const FORUM_URL = 'https://forum.marsprotocol.io/'
@ -14,11 +16,6 @@ export const SESSION_WALLET_KEY = 'shuttle'
export const SWAP_THRESHOLD = 10
export const VAULT_DEPOSIT_BUFFER = 0.99
export const GAS_ADJUSTMENT = 1.3
export const GAS_PRICE = '0.025uosmo'
/* feature flags */
export const FIELDS_FEATURE = true
export const PROPOSAL_ACTION_BUTTONS_FEATURE = false
/* fields query keys */
export const CONFIG = 'config'
@ -37,4 +34,12 @@ export const FIELDS_TUTORIAL_KEY = 'fieldsHideTutorial'
export const RED_BANK_TUTORIAL_KEY = 'redbankHideTutorial'
export const DISPLAY_CURRENCY_KEY = 'displayCurrency'
export const ENABLE_ANIMATIONS_KEY = 'enableAnimations'
export const CHAIN_ID_KEY = 'currentChainId'
export const TERMS_OF_SERVICE = 'termsOfService'
/* chains */
export const SUPPORTED_CHAINS: { chainId: ChainInfoID; type: 'testnet' | 'mainnet' }[] = [
{ chainId: ChainInfoID.Osmosis1, type: 'mainnet' },
{ chainId: ChainInfoID.OsmosisTestnet, type: 'testnet' },
{ chainId: ChainInfoID.NeutronTestnet, type: 'testnet' },
]

View File

@ -9,13 +9,6 @@ export const getTokenValueFromCoins = (assets: Asset[], coins: Coin[] = []) => {
const convertedValue = lookup(Number(token.amount), asset.symbol, asset.decimals)
return formatValue(
convertedValue,
2,
asset.decimals,
true,
convertedValue >= 0.01 ? false : '>',
` ${asset.symbol}`,
)
return formatValue(convertedValue, 2, asset.decimals, true, false, ` ${asset.symbol}`)
})
}

View File

@ -4,5 +4,6 @@ export { findByDenom } from './findByDenom'
export { formatToValueSymbol } from './formatToValueSymbol'
export { getFeeFromResponse } from './getFeeFromResponse'
export { getSwapUrl } from './getSwapUrl'
export { updateAssetPrices } from './updateAssetPrices'
export { updateExchangeRate } from './updateExchangeRate'
// @endindex

View File

@ -12,6 +12,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Deposit,
'borrowBalanceBaseCurrency',
6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@ -27,6 +28,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Deposit,
'borrowBalanceBaseCurrency',
6,
)
expect(assets.length).toBe(2)
expect(assets[1]).toEqual({
@ -42,6 +44,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Deposit,
'borrowBalanceBaseCurrency',
6,
)
expect(assets.length).toBe(2)
expect(assets[1]).toEqual({
@ -59,6 +62,7 @@ describe('produceUpdatedAssetData', () => {
50,
ViewType.Deposit,
'depositBalanceBaseCurrency',
6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@ -74,6 +78,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Deposit,
'depositBalanceBaseCurrency',
6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@ -92,6 +97,7 @@ describe('produceUpdatedAssetData', () => {
50,
ViewType.Borrow,
'borrowBalanceBaseCurrency',
6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@ -107,6 +113,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Borrow,
'borrowBalanceBaseCurrency',
6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({
@ -125,6 +132,7 @@ describe('produceUpdatedAssetData', () => {
100,
ViewType.Repay,
'borrowBalanceBaseCurrency',
6,
)
expect(assets.length).toBe(1)
expect(assets[0]).toEqual({

View File

@ -1,3 +1,4 @@
import { demagnify } from 'libs/parse'
import { ViewType } from 'types/enums'
export const produceUpdatedAssetData = (
@ -7,6 +8,7 @@ export const produceUpdatedAssetData = (
updateAmount: number,
activeView: ViewType,
key: 'depositBalanceBaseCurrency' | 'borrowBalanceBaseCurrency',
baseCurrencyDecimals: number,
) => {
const alreadyPresent = assetData.some((asset: RedBankAsset) => asset.denom === denom)
// For first use, when the user has no borrow balance yet and this list will be empty
@ -14,15 +16,19 @@ export const produceUpdatedAssetData = (
const asset = redBankAssets.find((redBankAsset) => redBankAsset.denom === denom)
if (!asset) return assetData
const additionalDecimals = asset.decimals - baseCurrencyDecimals
const amountAdjustedForDecimals = demagnify(updateAmount, additionalDecimals)
// We are only interested in display currency balance. The asset will update post tx.
assetData.push({
...asset,
[key]: updateAmount,
[key]: amountAdjustedForDecimals,
})
return assetData
}
return assetData.map((asset) => {
const additionalDecimals = asset.decimals - baseCurrencyDecimals
const amountAdjustedForDecimals = demagnify(updateAmount, additionalDecimals)
const newAsset = { ...asset }
const assetbaseCurrencyBalance = asset[key] || 0
let updatedAssetbaseCurrencyBalance = asset[key]
@ -31,8 +37,8 @@ export const produceUpdatedAssetData = (
// if we are repaaying or redeeming, we decrease the amount
updatedAssetbaseCurrencyBalance =
activeView === ViewType.Borrow || activeView === ViewType.Deposit
? assetbaseCurrencyBalance + updateAmount
: assetbaseCurrencyBalance - updateAmount
? assetbaseCurrencyBalance + amountAdjustedForDecimals
: assetbaseCurrencyBalance - amountAdjustedForDecimals
}
newAsset[key] = updatedAssetbaseCurrencyBalance
return newAsset

View File

@ -0,0 +1,12 @@
import { Coin } from '@cosmjs/proto-signing'
export const updateAssetPrices = (coin: Coin, assetPricesUSD: Coin[], override?: boolean) => {
const assetIndex = assetPricesUSD.findIndex((asset) => asset.denom === coin.denom)
if (assetIndex > -1) {
if (Number(coin.amount) > 0 && override) assetPricesUSD[assetIndex] = coin
} else {
if (Number(coin.amount) > 0) assetPricesUSD.push(coin)
}
return assetPricesUSD
}

View File

@ -9,12 +9,13 @@ export const useCreateCreditAccount = () => {
return useMutation(async (fee: StdFee) => {
const message = { create_credit_account: {} }
const creditManagerAddress = networkConfig.contracts?.creditManager
if (!networkConfig) return null
if (!creditManagerAddress) return null
return executeMsg({
msg: message,
fee,
contract: networkConfig.contracts.creditManager,
contract: creditManagerAddress,
}).then((broadcastResult) => {
if (broadcastResult) {
try {

View File

@ -16,6 +16,7 @@ export const useUpdateAccount = () => {
const executeMsg = useStore((s) => s.executeMsg)
const networkConfig = useStore((s) => s.networkConfig)
const getVaults = useStore((s) => s.getVaults)
const creditManagerAddress = networkConfig.contracts?.creditManager
return useMutation(async (props: Props) => {
queryClient.removeQueries([QUERY_KEYS.ESTIMATE_FARM_FEE])
@ -26,12 +27,12 @@ export const useUpdateAccount = () => {
},
}
if (!networkConfig) return
if (!creditManagerAddress) return
return executeMsg({
msg: message,
fee: props.fee,
contract: networkConfig.contracts.creditManager,
contract: creditManagerAddress,
funds: props.funds,
}).then((broadcastResult) => {
if (broadcastResult?.response.code === 0) {

View File

@ -7,6 +7,7 @@ export { useEstimateFarmFee } from './useEstimateFarmFee'
export { useEstimateFee } from './useEstimateFee'
export { useMarsOracle } from './useMarsOracle'
export { useProvideLiquidity } from './useProvideLiquidity'
export { usePythVaa } from './usePythVaa'
export { useRedBank } from './useRedBank'
export { useRepayPosition } from './useRepayPosition'
export { useRequestUnlockPosition } from './useRequestUnlockPosition'

View File

@ -24,7 +24,7 @@ export interface BlockHeightData {
}
export const useBlockHeight = () => {
const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const processBlockHeightQuery = useStore((s) => s.processBlockHeightQuery)
useQuery<BlockHeightData>(
[QUERY_KEYS.BLOCK_HEIGHT],

View File

@ -25,13 +25,15 @@ export interface DepositAndDebtData {
axlWETHDebt: string
stATOMDeposits: string
stATOMDebt: string
NTRNDeposits: string
NTRNDebt: string
}
}
export const useDepositAndDebt = () => {
const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const redBankAddress = useStore((s) => s.networkConfig?.contracts.redBank) || ''
const redBankAddress = useStore((s) => s.networkConfig.contracts.redBank) || ''
const marketInfo = useStore((s) => s.marketInfo)
const processDepositAndDebtQuery = useStore((s) => s.processDepositAndDebtQuery)

View File

@ -148,18 +148,19 @@ export const useEditPosition = (props: Props) => {
const primaryBaseAmount = convertToBaseCurrency({
denom: props.vault.denoms.primary,
amount: String(editPosition.amounts.primary + editPosition.amounts.borrowedPrimary),
amount: (editPosition.amounts.primary + editPosition.amounts.borrowedPrimary).toString(),
})
const secondaryBaseAmount = convertToBaseCurrency({
denom: props.vault.denoms.secondary,
amount: String(editPosition.amounts.secondary + editPosition.amounts.borrowedSecondary),
amount: (editPosition.amounts.secondary + editPosition.amounts.borrowedSecondary).toString(),
})
const swapMessage: Action[] = []
// If difference is larger than 10 ubase, initiate a swap
const difference = primaryBaseAmount - secondaryBaseAmount
if (Math.abs(difference) > SWAP_THRESHOLD) {
const inputDenom = difference > 0 ? props.vault.denoms.primary : props.vault.denoms.secondary
const outputDenom = difference < 0 ? props.vault.denoms.primary : props.vault.denoms.secondary

View File

@ -2,6 +2,7 @@ import { MsgExecuteContract } from '@marsprotocol/wallet-connector'
import { useQuery } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import { GAS_ADJUSTMENT } from 'constants/appConstants'
import { getPythVaaMessage } from 'libs/pyth'
import useStore from 'store'
import { QUERY_KEYS } from 'types/enums/queryKeys'
import { Action, Coin } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
@ -18,34 +19,45 @@ export const useEstimateFarmFee = (props: Props) => {
const userWalletAddress = useStore((s) => s.userWalletAddress)
const client = useStore((s) => s.client)
const networkConfig = useStore((s) => s.networkConfig)
const pythVaa = useStore((s) => s.pythVaa)
const pythContractAddress = useStore((s) => s.networkConfig.contracts?.pyth)
const pythVaaMessage = getPythVaaMessage(
pythVaa,
networkConfig.assets.base.denom,
pythContractAddress,
userWalletAddress,
)
const creditManagerAddress = networkConfig.contracts?.creditManager
return useQuery(
[QUERY_KEYS.ESTIMATE_FARM_FEE, props.actions],
async () => {
const gasAdjustment = GAS_ADJUSTMENT
if (!client) return null
if (!client || !creditManagerAddress || !networkConfig) return null
const messages = [
new MsgExecuteContract({
sender: userWalletAddress,
contract: creditManagerAddress,
msg: props.isCreate
? { create_credit_account: {} }
: {
update_credit_account: {
account_id: props.accountId,
actions: props.actions,
},
},
funds: props.funds,
}),
]
if (!networkConfig) return null
if (pythVaaMessage) messages.unshift(pythVaaMessage)
try {
const simulateOptions = {
messages: [
new MsgExecuteContract({
sender: userWalletAddress,
contract: networkConfig.contracts.creditManager,
msg: props.isCreate
? { create_credit_account: {} }
: {
update_credit_account: {
account_id: props.accountId,
actions: props.actions,
},
},
funds: props.funds,
}),
],
wallet: client.recentWallet,
messages,
wallet: client.connectedWallet,
}
const result = await client.simulate(simulateOptions)
@ -60,6 +72,7 @@ export const useEstimateFarmFee = (props: Props) => {
}
throw result.error
} catch (e) {
console.error(e)
throw e
}
},

View File

@ -4,6 +4,7 @@ import { MsgExecuteContract } from '@marsprotocol/wallet-connector'
import { useQuery } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import { GAS_ADJUSTMENT } from 'constants/appConstants'
import { getPythVaaMessage } from 'libs/pyth'
import useStore from 'store'
import { QUERY_KEYS } from 'types/enums/queryKeys'
import { ContractMsg } from 'types/types'
@ -19,6 +20,16 @@ interface Props {
export const useEstimateFee = (props: Props) => {
const userWalletAddress = useStore((s) => s.userWalletAddress)
const client = useStore((s) => s.client)
const pythVaa = useStore((s) => s.pythVaa)
const networkConfig = useStore((s) => s.networkConfig)
const baseCurrencyDenom = networkConfig.assets.base.denom
const pythContractAddress = networkConfig.contracts?.pyth
const pythVaaMessage = getPythVaaMessage(
pythVaa,
baseCurrencyDenom,
pythContractAddress,
userWalletAddress,
)
return useQuery(
[QUERY_KEYS.ESTIMATE_FEE, props.msg],
@ -28,17 +39,20 @@ export const useEstimateFee = (props: Props) => {
if (!client || !props.contract || !props.msg) return
const messages = [
new MsgExecuteContract({
sender: sender,
contract: props.contract,
msg: props.msg,
funds: props.funds,
}),
]
if (pythVaaMessage) messages.unshift(pythVaaMessage)
try {
const simulateOptions = {
messages: [
new MsgExecuteContract({
sender: sender,
contract: props.contract,
msg: props.msg,
funds: props.funds,
}),
],
wallet: client.recentWallet,
messages,
wallet: client.connectedWallet,
}
const result = await client.simulate(simulateOptions)
@ -53,6 +67,7 @@ export const useEstimateFee = (props: Props) => {
}
throw result.error
} catch (e) {
console.error(e)
throw e
}
},

View File

@ -1,26 +1,25 @@
import { useQuery } from '@tanstack/react-query'
import { getContractQuery } from 'functions/queries'
import { gql, request } from 'graphql-request'
import useStore from 'store'
import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
export interface MarsOracleData {
prices: {
[key: string]: {
denom: string
price: string
}
}
}
export const useMarsOracle = () => {
const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
const oracleAddress = useStore((s) => s.networkConfig?.contracts.oracle)
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const oracleAddress = useStore((s) => s.networkConfig.contracts.oracle)
const whitelistedAssets = useStore((s) => s.whitelistedAssets) || []
const basePriceState = useStore((s) => s.basePriceState)
const processMarsOracleQuery = useStore((s) => s.processMarsOracleQuery)
const setExchangeRatesState = useStore((s) => s.setExchangeRatesState)
let queries = ``
let priceQueries = ``
const configQuery = getContractQuery('config', oracleAddress || '', '{ config: {} }')
const priceSourcesQuery = getContractQuery(
'price_sources',
oracleAddress || '',
'{ price_sources: {} }',
)
whitelistedAssets
.filter((asset: Asset) => !!asset.denom)
@ -28,33 +27,39 @@ export const useMarsOracle = () => {
const denom = whitelistAsset.denom
const asset = `{
denom: "${denom}"
}`
denom: "${denom}"
}`
const querySegment = `
${whitelistAsset.id}: contractQuery(contractAddress: "${oracleAddress}", query: {
price: ${asset}
})
`
queries = queries + querySegment
${whitelistAsset.id}: contractQuery(contractAddress: "${oracleAddress}", query: {
price: ${asset}
})
`
priceQueries = priceQueries + querySegment
})
useQuery<MarsOracleData>(
useQuery<OracleData>(
[QUERY_KEYS.MARS_ORACLE],
async () => {
return await request(
hiveUrl!,
gql`
query MarsOracle {
prices: wasm {
${queries}
}
}
`,
query MarsOracle {
oracle: wasm {
${configQuery}
},
sources: wasm {
${priceSourcesQuery}
},
prices: wasm {
${priceQueries}
}
}
`,
)
},
{
enabled: !!hiveUrl && !!oracleAddress,
enabled: !!hiveUrl && !!oracleAddress && basePriceState === State.READY,
staleTime: 30000,
refetchInterval: 30000,
onError: () => setExchangeRatesState(State.ERROR),

View File

@ -0,0 +1,39 @@
import { useQuery } from '@tanstack/react-query'
import useStore from 'store'
import { QUERY_KEYS } from 'types/enums/queryKeys'
export const usePythVaa = () => {
let pythVaaUrl = useStore((s) => s.networkConfig.usdPriceUrl)
const pythVaa = useStore((s) => s.pythVaa)
const hasPriceFeeds = pythVaa.priceFeeds.length > 0
if (pythVaaUrl && hasPriceFeeds) {
const pythApiUrl = new URL(pythVaaUrl + 'latest_vaas')
pythVaa.priceFeeds.forEach((priceFeedId) => {
pythApiUrl.searchParams.append('ids[]', priceFeedId)
})
pythVaaUrl = pythApiUrl.href
}
useQuery<string[]>(
[QUERY_KEYS.PYTH_VAA],
async () => {
if (!pythVaaUrl || !hasPriceFeeds) return
const res = await fetch(pythVaaUrl)
return res.json()
},
{
enabled: hasPriceFeeds && !!pythVaaUrl,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: (data) => {
useStore.setState({
pythVaa: {
priceFeeds: pythVaa.priceFeeds,
data,
},
})
},
},
)
}

View File

@ -6,11 +6,11 @@ import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
export const useRedBank = () => {
const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const redbankContractAddress = useStore((s) => s.networkConfig?.contracts.redBank)
const incentivesContractAddress = useStore((s) => s.networkConfig?.contracts.incentives)
const redbankAddress = useStore((s) => s.networkConfig.contracts.redBank)
const incentivesAddress = useStore((s) => s.networkConfig.contracts.incentives)
const processRedBankQuery = useStore((s) => s.processRedBankQuery)
const setRedBankState = useStore((s) => s.setRedBankState)
@ -21,20 +21,15 @@ export const useRedBank = () => {
hiveUrl!,
gql`
${getRedbankQuery(
userWalletAddress!,
redbankContractAddress!,
incentivesContractAddress!,
userWalletAddress,
redbankAddress,
incentivesAddress,
whitelistedAssets,
)}
`,
),
{
enabled:
!!hiveUrl &&
!!userWalletAddress &&
!!redbankContractAddress &&
!!incentivesContractAddress &&
!!whitelistedAssets?.length,
enabled: !!userWalletAddress && !!whitelistedAssets?.length,
staleTime: 30000,
refetchInterval: 30000,
onError: () => setRedBankState(State.ERROR),

View File

@ -1,18 +1,25 @@
import { useQuery } from '@tanstack/react-query'
import BigNumber from 'bignumber.js'
import { updateAssetPrices } from 'functions/updateAssetPrices'
import { updateExchangeRate } from 'functions/updateExchangeRate'
import { useAsset } from 'hooks/data'
import useStore from 'store'
import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
const poolsEndpoint = 'osmosis/gamm/v1beta1/pools/'
export const useSpotPrice = (symbol: string) => {
const networkConfig = useStore((s) => s.networkConfig)
const displayCurrency = networkConfig?.displayCurrency
const lcd = useStore((s) => s.chainInfo?.rest)
const baseCurrency = networkConfig.assets.base
const displayCurrency = networkConfig.displayCurrency
const exchangeRates = useStore((s) => s.exchangeRates)
const assetPricesUSD = useStore((s) => s.assetPricesUSD)
const exchangeRatesState = useStore((s) => s.assetPricesUSDState)
const basePriceState = useStore((s) => s.assetPricesUSDState)
const asset = useAsset({ symbol })
const lcd = networkConfig.restUrl ?? ''
const poolBase = asset?.poolBase
? exchangeRates?.find((ratesAsset) => ratesAsset.denom === asset.poolBase)
: true
@ -26,41 +33,70 @@ export const useSpotPrice = (symbol: string) => {
})
},
{
enabled: !!lcd && !!asset && !!asset.poolId && !!poolBase,
enabled:
!!asset &&
!!asset.poolId &&
!!poolBase &&
basePriceState === State.READY &&
exchangeRatesState === State.READY,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: (data) => {
if (!asset || !displayCurrency) return
if (!asset || !assetPricesUSD) return
const poolDataAssets = data.pool.pool_assets
const assetFirst = poolDataAssets[0].token.denom === asset.denom
const targetAsset = poolDataAssets[assetFirst ? 0 : 1]
const otherAsset = poolDataAssets[assetFirst ? 1 : 0]
const primaryAsset = poolDataAssets[assetFirst ? 0 : 1]
const secondaryAsset = poolDataAssets[assetFirst ? 1 : 0]
const targetAssetAmount = new BigNumber(targetAsset.token.amount)
const targetAssetWeight = new BigNumber(targetAsset.weight)
const otherAssetAmount = new BigNumber(otherAsset.token.amount)
const otherAssetWeight = new BigNumber(otherAsset.weight)
const primaryAssetAmount = new BigNumber(primaryAsset.token.amount)
const primaryAssetWeight = new BigNumber(primaryAsset.weight)
const secondaryAssetAmount = new BigNumber(secondaryAsset.token.amount)
const secondaryAssetWeight = new BigNumber(secondaryAsset.weight)
const rate = otherAssetAmount
.div(targetAssetAmount)
.multipliedBy(otherAssetWeight.div(targetAssetWeight))
const rate = secondaryAssetAmount
.div(primaryAssetAmount)
.multipliedBy(secondaryAssetWeight.div(primaryAssetWeight))
const hasDisplayCurrency = exchangeRates?.find(
(ratesAsset) => ratesAsset.denom === displayCurrency.denom,
)
if (displayCurrency.denom === asset.denom && !hasDisplayCurrency) {
useStore.setState({ baseToDisplayCurrencyRatio: 1 / rate.toNumber() })
const coinExchangeRate = { denom: asset.denom, amount: '1' }
useStore.setState({
exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
})
} else {
const coin = { denom: asset.denom, amount: rate.toString() }
const secondaryRate =
exchangeRates?.find((rate) => rate.denom === secondaryAsset.token.denom)?.amount ?? 1
const coinExchangeRate = {
denom: asset.denom,
amount: rate.times(secondaryRate).toString(),
}
if (typeof poolBase === 'object') {
const baseRate = Number(rate.toString()) * Number(poolBase.amount)
coin.amount = baseRate.toString()
useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates || []) })
coinExchangeRate.amount = baseRate.toString()
useStore.setState({
exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
})
} else {
useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates || []) })
useStore.setState({
exchangeRates: updateExchangeRate(coinExchangeRate, exchangeRates || []),
})
}
const baseCurrencyPrice = assetPricesUSD.find(
(asset) => asset.denom === baseCurrency.denom,
)?.amount
if (!baseCurrencyPrice) return
const assetPriceCoin = {
denom: coinExchangeRate.denom,
amount: new BigNumber(coinExchangeRate.amount).times(baseCurrencyPrice).toString(),
}
useStore.setState({
assetPricesUSD: updateAssetPrices(assetPriceCoin, assetPricesUSD || []),
})
}
},
},

View File

@ -1,45 +1,68 @@
import { Coin } from '@cosmjs/proto-signing'
import { useQuery } from '@tanstack/react-query'
import { updateExchangeRate } from 'functions'
import BigNumber from 'bignumber.js'
import { updateAssetPrices } from 'functions/updateAssetPrices'
import useStore from 'store'
import { State } from 'types/enums'
import { QUERY_KEYS } from 'types/enums/queryKeys'
interface CoinPriceData {
price: number
denom: string
symbol: string
liquidity: number
liquidity_24h_change: number
volume_24h: number
volume_24h_change: number
name: string
price_24h_change: number
exponent: number
display: string
}
export const useUsdPrice = () => {
const osmoUsdPriceUrl = useStore((s) => s.networkConfig?.osmoUsdPriceUrl ?? '')
const exchangeRates = useStore((s) => s.exchangeRates ?? [])
const networkConfig = useStore((s) => s.networkConfig)
const displayCurrency = networkConfig?.displayCurrency
let usdPriceUrl = useStore((s) => s.networkConfig.usdPriceUrl)
let hasPriceFeeds = false
const whitelistedAssets = useStore((s) => s.whitelistedAssets)
const assetPricesUSD = useStore((s) => s.assetPricesUSD ?? [])
const basePriceState = useStore((s) => s.basePriceState)
const baseAsset = useStore((s) => s.networkConfig.assets.base)
if (!usdPriceUrl && basePriceState !== State.READY) {
useStore.setState({ basePriceState: State.READY })
}
if (usdPriceUrl && whitelistedAssets) {
const pythApiUrl = new URL(usdPriceUrl + 'latest_price_feeds')
whitelistedAssets.forEach((asset) => {
if (asset.priceFeedId) {
hasPriceFeeds = true
pythApiUrl.searchParams.append('ids[]', asset.priceFeedId)
}
})
usdPriceUrl = pythApiUrl.href
}
useQuery<CoinPriceData[]>(
[QUERY_KEYS.USD_PRICE],
async () => {
const res = await fetch(osmoUsdPriceUrl)
if (!usdPriceUrl || !whitelistedAssets || !hasPriceFeeds) return
const res = await fetch(usdPriceUrl)
return res.json()
},
{
enabled: !!osmoUsdPriceUrl && !!exchangeRates.length && !!displayCurrency,
enabled: !!usdPriceUrl || !!whitelistedAssets,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: (data) => {
const coin = { denom: 'usd', amount: (1 / data[0].price).toString() }
if (displayCurrency.denom === coin.denom) {
useStore.setState({ baseToDisplayCurrencyRatio: data[0].price })
}
let updatedAssetPricesUSD: Coin[] = []
data.map((priceData) => {
const denom = whitelistedAssets.find(
(asset) => asset?.priceFeedId === priceData.id,
)?.denom
useStore.setState({ exchangeRates: updateExchangeRate(coin, exchangeRates) })
if (denom) {
const amount = new BigNumber(priceData.price.price)
.times(new BigNumber(10).pow(priceData.price.expo))
.toString()
const coin = { denom, amount }
updatedAssetPricesUSD = updateAssetPrices(coin, assetPricesUSD, true)
if (denom === baseAsset?.denom) {
useStore.setState({
basePriceState: State.READY,
})
}
}
})
useStore.setState({ assetPricesUSD: updatedAssetPricesUSD })
},
},
)

View File

@ -12,7 +12,7 @@ export interface UserBalanceData {
}
export const useUserBalance = () => {
const hiveUrl = useStore((s) => s.networkConfig?.hiveUrl)
const hiveUrl = useStore((s) => s.networkConfig.hiveUrl)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const processUserBalanceQuery = useStore((s) => s.processUserBalanceQuery)
@ -36,7 +36,7 @@ export const useUserBalance = () => {
)
},
{
enabled: (!!hiveUrl && !!userWalletAddress) || false,
enabled: !!userWalletAddress,
staleTime: 30000,
refetchInterval: 30000,
onSuccess: processUserBalanceQuery,

View File

@ -7,7 +7,7 @@ const QUERY_LIMIT = 10
export const useUserCollaterals = () => {
const userWalletAddress = useStore((s) => s.userWalletAddress)
const redbankContractAddress = useStore((s) => s.networkConfig?.contracts.redBank)
const redbankContractAddress = useStore((s) => s.networkConfig.contracts.redBank)
const client = useStore((s) => s.client)
const resolveUserDeposits = (collaterals: UserCollateral[]): Coin[] => {

View File

@ -14,7 +14,7 @@ export interface UserDebtData {
export const useUserDebt = () => {
const userWalletAddress = useStore((s) => s.userWalletAddress)
const redbankContractAddress = useStore((s) => s.networkConfig?.contracts.redBank)
const redbankContractAddress = useStore((s) => s.networkConfig.contracts.redBank)
const client = useStore((s) => s.client)
const resolveDebtResponse = (debts: UserDebtData[]): Coin[] => {

View File

@ -1,5 +1,4 @@
import { useQuery } from '@tanstack/react-query'
import { NETWORK_CONFIG } from 'configs/osmosis-1'
import { gql, request } from 'graphql-request'
import { useMemo } from 'react'
import useStore from 'store'
@ -16,17 +15,16 @@ export interface UserIcnsData {
export const useUserIcns = () => {
/* only possible to query on mainnet */
const hiveUrl = NETWORK_CONFIG.hiveUrl
const resolverContract = 'osmo1xk0s8xgktn9x5vwcgtjdxqzadg88fgn33p8u9cnpdxwemvxscvast52cdd'
const networkConfig = useStore((s) => s.networkConfig)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const setUserIcns = useStore((s) => s.setUserIcns)
const hiveUrl = networkConfig.hiveUrl
const result = useQuery<UserIcnsData>(
[QUERY_KEYS.USER_ICNS],
async () => {
return await request(
hiveUrl!,
hiveUrl,
gql`
query UserIcnsQuery {
wasm {
@ -40,10 +38,10 @@ export const useUserIcns = () => {
)
},
{
enabled: !!userWalletAddress || false,
enabled: !!userWalletAddress,
onSuccess: (data) => {
const icns = data.wasm.contractQuery.primary_name
if (icns !== '') setUserIcns(icns)
const userIcns = data.wasm.contractQuery.primary_name
if (userIcns !== '') useStore.setState({ userIcns })
},
},
)

View File

@ -1,44 +1,20 @@
<svg
id='Layer_1'
data-name='Layer 1'
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 2500 2500'
>
<title>cosmos-atom-logo</title>
<circle cx='1250' cy='1250' r='1250' style='fill:#2e3148' />
<circle cx='1250' cy='1250' r='725.31' style='fill:#1b1e36' />
<path
d='M1252.57,159.47c-134.93,0-244.34,489.4-244.34,1093.11s109.41,1093.11,244.34,1093.11,244.34-489.4,244.34-1093.11S1387.5,159.47,1252.57,159.47ZM1269.44,2284c-15.43,20.58-30.86,5.14-30.86,5.14-62.14-72-93.21-205.76-93.21-205.76-108.69-349.79-82.82-1100.82-82.82-1100.82,51.08-596.24,144-737.09,175.62-768.36a19.29,19.29,0,0,1,24.74-2c45.88,32.51,84.36,168.47,84.36,168.47,113.63,421.81,103.34,817.9,103.34,817.9,10.29,344.65-56.94,730.45-56.94,730.45C1341.92,2222.22,1269.44,2284,1269.44,2284Z'
style='fill:#6f7390'
/>
<path
d='M2200.72,708.59c-67.18-117.08-546.09,31.58-1070,332s-893.47,638.89-826.34,755.92,546.09-31.58,1070-332,893.47-638.89,826.34-755.92h0ZM366.36,1780.45c-25.72-3.24-19.91-24.38-19.91-24.38C378,1666.36,478.4,1572.84,478.4,1572.84c249.43-268.36,913.79-619.65,913.79-619.65,542.54-252.42,711.06-241.77,753.81-230a19.29,19.29,0,0,1,14,20.58c-5.14,56-104.17,157-104.17,157C1746.71,1209.36,1398,1397.58,1398,1397.58c-293.83,180.5-661.93,314.09-661.93,314.09-280.09,100.93-369.7,68.78-369.7,68.78h0Z'
style='fill:#6f7390'
/>
<path
d='M2198.35,1800.41c67.7-116.77-300.93-456.79-823-759.47S374.43,587.76,306.79,704.73s300.93,456.79,823.3,759.47S2130.71,1917.39,2198.35,1800.41ZM351.65,749.85c-10-23.71,11.11-29.42,11.11-29.42C456.22,702.78,587.5,743,587.5,743c357.15,81.33,994,480.25,994,480.25,490.33,343.11,565.53,494.24,576.8,537.14a19.29,19.29,0,0,1-10.7,22.43c-51.13,23.41-188.07-11.47-188.07-11.47-422.07-113.17-759.62-320.52-759.62-320.52-303.29-163.58-603.19-415.28-603.19-415.28-227.88-191.87-245-285.44-245-285.44Z'
style='fill:#6f7390'
/>
<circle cx='1250' cy='1250' r='128.6' style='fill:#b7b9c8' />
<ellipse
cx='1777.26'
cy='756.17'
rx='74.59'
ry='77.16'
style='fill:#b7b9c8'
/>
<ellipse
cx='552.98'
cy='1018.52'
rx='74.59'
ry='77.16'
style='fill:#b7b9c8'
/>
<ellipse
cx='1098.25'
cy='1965.02'
rx='74.59'
ry='77.16'
style='fill:#b7b9c8'
/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2500 2500">
<circle cx="1250" cy="1250" r="1250" fill="#2e3148" />
<circle cx="1250" cy="1250" r="725.31" fill="#1b1e36" />
<path
d="M1252.57,159.47c-134.93,0-244.34,489.4-244.34,1093.11s109.41,1093.11,244.34,1093.11,244.34-489.4,244.34-1093.11S1387.5,159.47,1252.57,159.47ZM1269.44,2284c-15.43,20.58-30.86,5.14-30.86,5.14-62.14-72-93.21-205.76-93.21-205.76-108.69-349.79-82.82-1100.82-82.82-1100.82,51.08-596.24,144-737.09,175.62-768.36a19.29,19.29,0,0,1,24.74-2c45.88,32.51,84.36,168.47,84.36,168.47,113.63,421.81,103.34,817.9,103.34,817.9,10.29,344.65-56.94,730.45-56.94,730.45C1341.92,2222.22,1269.44,2284,1269.44,2284Z"
fill="#6f7390"
/>
<path
d="M2200.72,708.59c-67.18-117.08-546.09,31.58-1070,332s-893.47,638.89-826.34,755.92,546.09-31.58,1070-332,893.47-638.89,826.34-755.92h0ZM366.36,1780.45c-25.72-3.24-19.91-24.38-19.91-24.38C378,1666.36,478.4,1572.84,478.4,1572.84c249.43-268.36,913.79-619.65,913.79-619.65,542.54-252.42,711.06-241.77,753.81-230a19.29,19.29,0,0,1,14,20.58c-5.14,56-104.17,157-104.17,157C1746.71,1209.36,1398,1397.58,1398,1397.58c-293.83,180.5-661.93,314.09-661.93,314.09-280.09,100.93-369.7,68.78-369.7,68.78h0Z"
fill="#6f7390"
/>
<path
d="M2198.35,1800.41c67.7-116.77-300.93-456.79-823-759.47S374.43,587.76,306.79,704.73s300.93,456.79,823.3,759.47S2130.71,1917.39,2198.35,1800.41ZM351.65,749.85c-10-23.71,11.11-29.42,11.11-29.42C456.22,702.78,587.5,743,587.5,743c357.15,81.33,994,480.25,994,480.25,490.33,343.11,565.53,494.24,576.8,537.14a19.29,19.29,0,0,1-10.7,22.43c-51.13,23.41-188.07-11.47-188.07-11.47-422.07-113.17-759.62-320.52-759.62-320.52-303.29-163.58-603.19-415.28-603.19-415.28-227.88-191.87-245-285.44-245-285.44Z"
fill="#6f7390"
/>
<circle cx="1250" cy="1250" r="128.6" fill="#b7b9c8" />
<ellipse cx="1777.26" cy="756.17" rx="74.59" ry="77.16" fill="#b7b9c8" />
<ellipse cx="552.98" cy="1018.52" rx="74.59" ry="77.16" fill="#b7b9c8" />
<ellipse cx="1098.25" cy="1965.02" rx="74.59" ry="77.16" fill="#b7b9c8" />
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,9 +1,15 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 24 24">
<path fill="#FFFFFF" d="M12,24c6.6,0,12-5.4,12-12S18.6,0,12,0S0,5.4,0,12S5.4,24,12,24z"/>
<path fillRule="evenodd" clipRule="evenodd" d="M12,22.5c5.8,0,10.5-4.7,10.5-10.5S17.8,1.5,12,1.5S1.5,6.2,1.5,12S6.2,22.5,12,22.5z M24,12
c0,6.6-5.4,12-12,12S0,18.6,0,12S5.4,0,12,0S24,5.4,24,12z"/>
<path d="M12.8,10.9L17,6.8l-1.6-1.6L12,8.5L8.6,5.2L7,6.8l4.2,4.2c0.2,0.2,0.5,0.3,0.8,0.3S12.6,11.1,12.8,10.9L12.8,10.9z"/>
<path d="M18.9,15.4L15.5,12l3.4-3.4L17.3,7l-4.2,4.2c-0.4,0.4-0.4,1.1,0,1.6l4.2,4.2L18.9,15.4z"/>
<path d="M12,15.5l3.4,3.4l1.6-1.6l-4.2-4.2c-0.4-0.4-1.2-0.4-1.6,0L7,17.2l1.6,1.6L12,15.5L12,15.5z"/>
<path d="M10.9,12.8c0.2-0.2,0.3-0.5,0.3-0.8c0-0.3-0.1-0.6-0.3-0.8L6.7,7L5.1,8.6L8.5,12l-3.4,3.4L6.7,17L10.9,12.8z"/>
<path fill="#FFFFFF" d="M12,24c6.6,0,12-5.4,12-12S18.6,0,12,0S0,5.4,0,12S5.4,24,12,24z" />
<path
d="M12.9,10.8l4.5-4.4l-1.7-1.7L12,8.2L8.4,4.7L6.6,6.4l4.5,4.5c0.2,0.2,0.5,0.3,0.9,0.3S12.6,11,12.9,10.8L12.9,10.8z"
/>
<path
d="M19.4,15.6L15.8,12l3.6-3.6l-1.7-1.7l-4.5,4.5c-0.4,0.4-0.4,1.2,0,1.7l4.5,4.5L19.4,15.6z"
/>
<path
d="M12,15.7l3.6,3.6l1.7-1.7l-4.5-4.5c-0.4-0.4-1.3-0.4-1.7,0l-4.5,4.4l1.7,1.7L12,15.7L12,15.7z"
/>
<path
d="M10.8,12.9c0.2-0.2,0.3-0.5,0.3-0.9s-0.1-0.6-0.3-0.9L6.3,6.6L4.6,8.4L8.2,12l-3.6,3.6l1.7,1.7L10.8,12.9z"
/>
</svg>

Before

Width:  |  Height:  |  Size: 831 B

After

Width:  |  Height:  |  Size: 668 B

View File

@ -1,11 +1,40 @@
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 24C18.6499 24 24 18.6499 24 12C24 5.3501 18.6499 0 12 0C5.3501 0 0 5.3501 0 12C0 18.6499 5.3501 24 12 24Z" fill="#2775CA"/>
<path d="M15.2997 13.8998C15.2997 12.1497 14.2494 11.5497 12.1501 11.2996C10.6501 11.0994 10.3501 10.6996 10.3501 9.99977C10.3501 9.29998 10.8503 8.84967 11.8501 8.84967C12.7501 8.84967 13.2503 9.14967 13.4997 9.89998C13.5496 10.0503 13.7 10.1501 13.8496 10.1501H14.6498C14.8501 10.1501 14.9997 9.99977 14.9997 9.80019V9.7503C14.7995 8.65009 13.8995 7.80061 12.7501 7.70019V6.50019C12.7501 6.29998 12.5997 6.1503 12.3503 6.1004H11.6C11.3997 6.1004 11.2501 6.25009 11.2002 6.50019V7.6503C9.70016 7.85051 8.75027 8.8503 8.75027 10.1002C8.75027 11.7499 9.75006 12.4004 11.8501 12.6499C13.2503 12.9 13.7 13.2 13.7 13.9996C13.7 14.7991 13.0002 15.3492 12.0503 15.3492C10.7505 15.3492 10.3002 14.7991 10.1505 14.0495C10.1006 13.8492 9.95027 13.7495 9.80059 13.7495H8.95048C8.75027 13.7495 8.60059 13.8998 8.60059 14.0993V14.1492C8.8008 15.3991 9.60037 16.2991 11.2507 16.5492V17.7492C11.2507 17.9495 11.401 18.0991 11.6505 18.149H12.4008C12.601 18.149 12.7507 17.9987 12.8006 17.7492V16.5492C14.3006 16.2991 15.3004 15.2495 15.3004 13.8991L15.2997 13.8998Z" fill="white"/>
<path d="M9.45047 19.1501C5.55047 17.7499 3.55026 13.4002 5.00036 9.55014C5.75068 7.45014 7.40036 5.85035 9.45047 5.10003C9.65068 5.00024 9.75047 4.84993 9.75047 4.59982V3.90003C9.75047 3.69982 9.65068 3.55014 9.45047 3.50024C9.40057 3.50024 9.30015 3.50024 9.25026 3.55014C4.50015 5.05014 1.89994 10.1002 3.39994 14.8503C4.29994 17.6501 6.44984 19.8 9.24963 20.7C9.44984 20.7998 9.64941 20.7 9.69994 20.4998C9.74984 20.4499 9.74984 20.4 9.74984 20.2996V19.5998C9.74984 19.4495 9.60015 19.2499 9.44984 19.1501H9.45047ZM14.75 3.55014C14.5498 3.45035 14.3503 3.55014 14.2997 3.75035C14.2498 3.80024 14.2498 3.85014 14.2498 3.95056V4.65035C14.2498 4.85056 14.4002 5.05014 14.5498 5.15056C18.4498 6.55077 20.45 10.9005 18.9999 14.7506C18.2496 16.8506 16.5999 18.4503 14.5498 19.2007C14.3496 19.3005 14.2498 19.4508 14.2498 19.7009V20.4007C14.2498 20.6009 14.3496 20.7506 14.5498 20.8005C14.5997 20.8005 14.7002 20.8005 14.75 20.7506C19.5002 19.2506 22.0997 14.2005 20.5997 9.45035C19.6997 6.60067 17.4999 4.45014 14.75 3.55014V3.55014Z" fill="white"/>
<path d="M20 24C22.2091 24 24 22.2091 24 20C24 17.7909 22.2091 16 20 16C17.7909 16 16 17.7909 16 20C16 22.2091 17.7909 24 20 24Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 23.5C21.933 23.5 23.5 21.933 23.5 20C23.5 18.067 21.933 16.5 20 16.5C18.067 16.5 16.5 18.067 16.5 20C16.5 21.933 18.067 23.5 20 23.5ZM24 20C24 22.2091 22.2091 24 20 24C17.7909 24 16 22.2091 16 20C16 17.7909 17.7909 16 20 16C22.2091 16 24 17.7909 24 20Z" fill="black"/>
<path d="M20.266 19.6405L21.6634 18.2507L21.1332 17.7236L20.0006 18.8499L18.8681 17.7236L18.3379 18.2507L19.7352 19.6405C19.8086 19.7133 19.9046 19.7497 20 19.7497C20.0954 19.7497 20.192 19.7133 20.2648 19.6405H20.266Z" fill="black"/>
<path d="M22.2886 21.1251L21.1561 19.9988L22.2886 18.8725L21.7584 18.3455L20.3611 19.7353C20.2149 19.8808 20.2149 20.1168 20.3611 20.2623L21.7584 21.6521L22.2886 21.1251Z" fill="black"/>
<path d="M19.9985 21.1501L21.1311 22.2764L21.6613 21.7493L20.264 20.3595C20.1178 20.214 19.88 20.214 19.7338 20.3595L18.3364 21.7493L18.8666 22.2764L19.9992 21.1501H19.9985Z" fill="black"/>
<path d="M19.6385 20.2642C19.7087 20.1945 19.7483 20.0991 19.7483 20.0006C19.7483 19.9021 19.7087 19.8067 19.6385 19.7371L18.2411 18.3473L17.7109 18.8743L18.8435 20.0006L17.7109 21.1269L18.2411 21.654L19.6385 20.2642Z" fill="black"/>
<path
d="M12 24C18.6499 24 24 18.6499 24 12C24 5.3501 18.6499 0 12 0C5.3501 0 0 5.3501 0 12C0 18.6499 5.3501 24 12 24Z"
fill="#2775CA"
/>
<path
d="M15.2997 13.8998C15.2997 12.1497 14.2494 11.5497 12.1501 11.2996C10.6501 11.0994 10.3501 10.6996 10.3501 9.99977C10.3501 9.29998 10.8503 8.84967 11.8501 8.84967C12.7501 8.84967 13.2503 9.14967 13.4997 9.89998C13.5496 10.0503 13.7 10.1501 13.8496 10.1501H14.6498C14.8501 10.1501 14.9997 9.99977 14.9997 9.80019V9.7503C14.7995 8.65009 13.8995 7.80061 12.7501 7.70019V6.50019C12.7501 6.29998 12.5997 6.1503 12.3503 6.1004H11.6C11.3997 6.1004 11.2501 6.25009 11.2002 6.50019V7.6503C9.70016 7.85051 8.75027 8.8503 8.75027 10.1002C8.75027 11.7499 9.75006 12.4004 11.8501 12.6499C13.2503 12.9 13.7 13.2 13.7 13.9996C13.7 14.7991 13.0002 15.3492 12.0503 15.3492C10.7505 15.3492 10.3002 14.7991 10.1505 14.0495C10.1006 13.8492 9.95027 13.7495 9.80059 13.7495H8.95048C8.75027 13.7495 8.60059 13.8998 8.60059 14.0993V14.1492C8.8008 15.3991 9.60037 16.2991 11.2507 16.5492V17.7492C11.2507 17.9495 11.401 18.0991 11.6505 18.149H12.4008C12.601 18.149 12.7507 17.9987 12.8006 17.7492V16.5492C14.3006 16.2991 15.3004 15.2495 15.3004 13.8991L15.2997 13.8998Z"
fill="white"
/>
<path
d="M9.45047 19.1501C5.55047 17.7499 3.55026 13.4002 5.00036 9.55014C5.75068 7.45014 7.40036 5.85035 9.45047 5.10003C9.65068 5.00024 9.75047 4.84993 9.75047 4.59982V3.90003C9.75047 3.69982 9.65068 3.55014 9.45047 3.50024C9.40057 3.50024 9.30015 3.50024 9.25026 3.55014C4.50015 5.05014 1.89994 10.1002 3.39994 14.8503C4.29994 17.6501 6.44984 19.8 9.24963 20.7C9.44984 20.7998 9.64941 20.7 9.69994 20.4998C9.74984 20.4499 9.74984 20.4 9.74984 20.2996V19.5998C9.74984 19.4495 9.60015 19.2499 9.44984 19.1501H9.45047ZM14.75 3.55014C14.5498 3.45035 14.3503 3.55014 14.2997 3.75035C14.2498 3.80024 14.2498 3.85014 14.2498 3.95056V4.65035C14.2498 4.85056 14.4002 5.05014 14.5498 5.15056C18.4498 6.55077 20.45 10.9005 18.9999 14.7506C18.2496 16.8506 16.5999 18.4503 14.5498 19.2007C14.3496 19.3005 14.2498 19.4508 14.2498 19.7009V20.4007C14.2498 20.6009 14.3496 20.7506 14.5498 20.8005C14.5997 20.8005 14.7002 20.8005 14.75 20.7506C19.5002 19.2506 22.0997 14.2005 20.5997 9.45035C19.6997 6.60067 17.4999 4.45014 14.75 3.55014V3.55014Z"
fill="white"
/>
<path
d="M20 24C22.2091 24 24 22.2091 24 20C24 17.7909 22.2091 16 20 16C17.7909 16 16 17.7909 16 20C16 22.2091 17.7909 24 20 24Z"
fill="white"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M20 23.5C21.933 23.5 23.5 21.933 23.5 20C23.5 18.067 21.933 16.5 20 16.5C18.067 16.5 16.5 18.067 16.5 20C16.5 21.933 18.067 23.5 20 23.5ZM24 20C24 22.2091 22.2091 24 20 24C17.7909 24 16 22.2091 16 20C16 17.7909 17.7909 16 20 16C22.2091 16 24 17.7909 24 20Z"
fill="black"
/>
<path
d="M20.266 19.6405L21.6634 18.2507L21.1332 17.7236L20.0006 18.8499L18.8681 17.7236L18.3379 18.2507L19.7352 19.6405C19.8086 19.7133 19.9046 19.7497 20 19.7497C20.0954 19.7497 20.192 19.7133 20.2648 19.6405H20.266Z"
fill="black"
/>
<path
d="M22.2886 21.1251L21.1561 19.9988L22.2886 18.8725L21.7584 18.3455L20.3611 19.7353C20.2149 19.8808 20.2149 20.1168 20.3611 20.2623L21.7584 21.6521L22.2886 21.1251Z"
fill="black"
/>
<path
d="M19.9985 21.1501L21.1311 22.2764L21.6613 21.7493L20.264 20.3595C20.1178 20.214 19.88 20.214 19.7338 20.3595L18.3364 21.7493L18.8666 22.2764L19.9992 21.1501H19.9985Z"
fill="black"
/>
<path
d="M19.6385 20.2642C19.7087 20.1945 19.7483 20.0991 19.7483 20.0006C19.7483 19.9021 19.7087 19.8067 19.6385 19.7371L18.2411 18.3473L17.7109 18.8743L18.8435 20.0006L17.7109 21.1269L18.2411 21.654L19.6385 20.2642Z"
fill="black"
/>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -1,23 +1,49 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="#FFFFFF" d="M23.6,14.9C22,21.3,15.5,25.2,9,23.6C2.6,22-1.3,15.5,0.3,9.1C1.9,2.7,8.4-1.2,14.8,0.4
C21.3,2,25.2,8.5,23.6,14.9L23.6,14.9L23.6,14.9z"/>
<path id="Shape" fill="#5A5564" d="M19.6,5l-0.7,0.7c3.3,3.6,3.3,9,0,12.6l0.7,0.7C23.2,15,23.2,9,19.6,5L19.6,5z"/>
<path id="Shape-2" fill="#5A5564" d="M5.7,5.1c3.6-3.3,9-3.3,12.6,0L19,4.4C15,0.8,9,0.8,5,4.4L5.7,5.1z"/>
<path id="Shape-3" fill="#5A5564" d="M5.1,18.3c-3.3-3.6-3.3-9,0-12.6L4.4,5C0.8,9,0.8,15,4.4,19L5.1,18.3z"/>
<path id="Shape-4" fill="#5A5564" d="M18.3,18.9c-3.6,3.3-9,3.3-12.6,0L5,19.6c3.9,3.6,10,3.6,13.9,0L18.3,18.9z"/>
<path id="Shape-5" fill="#F09242" d="M16.2,9.8c-0.1-1.4-1.3-1.8-2.8-2V5.9h-1.2v1.9c-0.3,0-0.6,0-0.9,0V5.9h-1.2v1.9H7.8v1.2
<path
fill="#FFFFFF"
d="M23.6,14.9C22,21.3,15.5,25.2,9,23.6C2.6,22-1.3,15.5,0.3,9.1C1.9,2.7,8.4-1.2,14.8,0.4
C21.3,2,25.2,8.5,23.6,14.9L23.6,14.9L23.6,14.9z"
/>
<path
fill="#5A5564"
d="M19.6,5l-0.7,0.7c3.3,3.6,3.3,9,0,12.6l0.7,0.7C23.2,15,23.2,9,19.6,5L19.6,5z"
/>
<path fill="#5A5564" d="M5.7,5.1c3.6-3.3,9-3.3,12.6,0L19,4.4C15,0.8,9,0.8,5,4.4L5.7,5.1z" />
<path fill="#5A5564" d="M5.1,18.3c-3.3-3.6-3.3-9,0-12.6L4.4,5C0.8,9,0.8,15,4.4,19L5.1,18.3z" />
<path
fill="#5A5564"
d="M18.3,18.9c-3.6,3.3-9,3.3-12.6,0L5,19.6c3.9,3.6,10,3.6,13.9,0L18.3,18.9z"
/>
<path
fill="#F09242"
d="M16.2,9.8c-0.1-1.4-1.3-1.8-2.8-2V5.9h-1.2v1.9c-0.3,0-0.6,0-0.9,0V5.9h-1.2v1.9H7.8v1.2
c0,0,0.9,0,0.8,0c0.3,0,0.6,0.2,0.7,0.5v5.2c0,0.1-0.1,0.2-0.1,0.3c-0.1,0.1-0.2,0.1-0.3,0.1c0,0-0.8,0-0.8,0l-0.2,1.4h2.3v1.9
h1.2v-1.9h0.9v1.9h1.2v-1.9c2-0.1,3.3-0.6,3.5-2.4c0.1-1.5-0.6-2.1-1.7-2.4C15.8,11.4,16.3,10.8,16.2,9.8z M14.5,13.9
c0,1.4-2.5,1.3-3.3,1.3v-2.6C12.1,12.6,14.5,12.4,14.5,13.9z M14,10.3c0,1.3-2.1,1.2-2.7,1.2V9.2C11.9,9.2,14,9,14,10.3z"/>
<path id="Shape-6" fill="#282138" d="M12,24C5.4,24,0,18.6,0,12S5.4,0,12,0c6.6,0,12,5.4,12,12C24,18.6,18.6,24,12,24
c0,1.4-2.5,1.3-3.3,1.3v-2.6C12.1,12.6,14.5,12.4,14.5,13.9z M14,10.3c0,1.3-2.1,1.2-2.7,1.2V9.2C11.9,9.2,14,9,14,10.3z"
/>
<path
fill="#282138"
d="M12,24C5.4,24,0,18.6,0,12S5.4,0,12,0c6.6,0,12,5.4,12,12C24,18.6,18.6,24,12,24
C12,24,12,24,12,24z M12,0.9c-6.1,0-11.1,5-11,11.1c0,6.1,5,11.1,11.1,11c6.1,0,11-5,11-11.1C23.1,5.9,18.1,0.9,12,0.9
C12,0.9,12,0.9,12,0.9z"/>
<path fill="#FFFFFF" d="M20,24c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S17.8,24,20,24z"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20,23.5c1.9,0,3.5-1.6,3.5-3.5s-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5
S18.1,23.5,20,23.5z M24,20c0,2.2-1.8,4-4,4s-4-1.8-4-4s1.8-4,4-4S24,17.8,24,20z"/>
<path d="M20.3,19.6l1.4-1.4l-0.5-0.5L20,18.8l-1.1-1.1l-0.5,0.5l1.4,1.4c0.1,0.1,0.2,0.1,0.3,0.1S20.2,19.7,20.3,19.6L20.3,19.6z"
/>
<path d="M22.3,21.1L21.2,20l1.1-1.1l-0.5-0.5l-1.4,1.4c-0.1,0.1-0.1,0.4,0,0.5l1.4,1.4L22.3,21.1z"/>
<path d="M20,21.2l1.1,1.1l0.5-0.5l-1.4-1.4c-0.1-0.1-0.4-0.1-0.5,0l-1.4,1.4l0.5,0.5L20,21.2L20,21.2z"/>
<path d="M19.6,20.3c0.1-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.2-0.1-0.3l-1.4-1.4l-0.5,0.5l1.1,1.1l-1.1,1.1l0.5,0.5L19.6,20.3z"/>
C12,0.9,12,0.9,12,0.9z"
/>
<path fill="#FFFFFF" d="M20,24c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S17.8,24,20,24z" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M20,23.5c1.9,0,3.5-1.6,3.5-3.5s-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5
S18.1,23.5,20,23.5z M24,20c0,2.2-1.8,4-4,4s-4-1.8-4-4s1.8-4,4-4S24,17.8,24,20z"
/>
<path
d="M20.3,19.6l1.4-1.4l-0.5-0.5L20,18.8l-1.1-1.1l-0.5,0.5l1.4,1.4c0.1,0.1,0.2,0.1,0.3,0.1S20.2,19.7,20.3,19.6L20.3,19.6z"
/>
<path
d="M22.3,21.1L21.2,20l1.1-1.1l-0.5-0.5l-1.4,1.4c-0.1,0.1-0.1,0.4,0,0.5l1.4,1.4L22.3,21.1z"
/>
<path
d="M20,21.2l1.1,1.1l0.5-0.5l-1.4-1.4c-0.1-0.1-0.4-0.1-0.5,0l-1.4,1.4l0.5,0.5L20,21.2L20,21.2z"
/>
<path
d="M19.6,20.3c0.1-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.2-0.1-0.3l-1.4-1.4l-0.5,0.5l1.1,1.1l-1.1,1.1l0.5,0.5L19.6,20.3z"
/>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,18 +1,32 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="#FFFFFF" d="M23.6,14.9C22,21.3,15.5,25.2,9,23.6C2.6,22-1.3,15.5,0.3,9.1C1.9,2.7,8.4-1.2,14.8,0.4
C21.3,2,25.2,8.5,23.6,14.9L23.6,14.9L23.6,14.9z"/>
<polygon fill="#343434" points="11.9,1.2 11.8,1.7 11.8,15.9 11.9,16.1 18.5,12.2"/>
<polygon fill="#8C8C8C" points="11.9,1.2 5.3,12.2 11.9,16.1 11.9,9.2"/>
<polygon fill="#3C3C3B" points="11.9,17.3 11.8,17.4 11.8,22.5 11.9,22.7 18.5,13.4"/>
<polygon fill="#8C8C8C" points="11.9,22.7 11.9,17.3 5.3,13.4"/>
<polygon fill="#141414" points="11.9,16.1 18.5,12.2 11.9,9.2"/>
<polygon fill="#393939" points="5.3,12.2 11.9,16.1 11.9,9.2"/>
<path fill="#FFFFFF" d="M20,24c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S17.8,24,20,24z"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20,23.5c1.9,0,3.5-1.6,3.5-3.5s-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5
S18.1,23.5,20,23.5z M24,20c0,2.2-1.8,4-4,4s-4-1.8-4-4s1.8-4,4-4S24,17.8,24,20z"/>
<path d="M20.3,19.6l1.4-1.4l-0.5-0.5L20,18.8l-1.1-1.1l-0.5,0.5l1.4,1.4c0.1,0.1,0.2,0.1,0.3,0.1S20.2,19.7,20.3,19.6L20.3,19.6z"
/>
<path d="M22.3,21.1L21.2,20l1.1-1.1l-0.5-0.5l-1.4,1.4c-0.1,0.1-0.1,0.4,0,0.5l1.4,1.4L22.3,21.1z"/>
<path d="M20,21.2l1.1,1.1l0.5-0.5l-1.4-1.4c-0.1-0.1-0.4-0.1-0.5,0l-1.4,1.4l0.5,0.5L20,21.2L20,21.2z"/>
<path d="M19.6,20.3c0.1-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.2-0.1-0.3l-1.4-1.4l-0.5,0.5l1.1,1.1l-1.1,1.1l0.5,0.5L19.6,20.3z"/>
<path
fill="#FFFFFF"
d="M23.6,14.9C22,21.3,15.5,25.2,9,23.6C2.6,22-1.3,15.5,0.3,9.1C1.9,2.7,8.4-1.2,14.8,0.4
C21.3,2,25.2,8.5,23.6,14.9L23.6,14.9L23.6,14.9z"
/>
<polygon fill="#343434" points="11.9,1.2 11.8,1.7 11.8,15.9 11.9,16.1 18.5,12.2" />
<polygon fill="#8C8C8C" points="11.9,1.2 5.3,12.2 11.9,16.1 11.9,9.2" />
<polygon fill="#3C3C3B" points="11.9,17.3 11.8,17.4 11.8,22.5 11.9,22.7 18.5,13.4" />
<polygon fill="#8C8C8C" points="11.9,22.7 11.9,17.3 5.3,13.4" />
<polygon fill="#141414" points="11.9,16.1 18.5,12.2 11.9,9.2" />
<polygon fill="#393939" points="5.3,12.2 11.9,16.1 11.9,9.2" />
<path fill="#FFFFFF" d="M20,24c2.2,0,4-1.8,4-4s-1.8-4-4-4s-4,1.8-4,4S17.8,24,20,24z" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M20,23.5c1.9,0,3.5-1.6,3.5-3.5s-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5
S18.1,23.5,20,23.5z M24,20c0,2.2-1.8,4-4,4s-4-1.8-4-4s1.8-4,4-4S24,17.8,24,20z"
/>
<path
d="M20.3,19.6l1.4-1.4l-0.5-0.5L20,18.8l-1.1-1.1l-0.5,0.5l1.4,1.4c0.1,0.1,0.2,0.1,0.3,0.1S20.2,19.7,20.3,19.6L20.3,19.6z"
/>
<path
d="M22.3,21.1L21.2,20l1.1-1.1l-0.5-0.5l-1.4,1.4c-0.1,0.1-0.1,0.4,0,0.5l1.4,1.4L22.3,21.1z"
/>
<path
d="M20,21.2l1.1,1.1l0.5-0.5l-1.4-1.4c-0.1-0.1-0.4-0.1-0.5,0l-1.4,1.4l0.5,0.5L20,21.2L20,21.2z"
/>
<path
d="M19.6,20.3c0.1-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.2-0.1-0.3l-1.4-1.4l-0.5,0.5l1.1,1.1l-1.1,1.1l0.5,0.5L19.6,20.3z"
/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,88 +1,207 @@
<svg width="1440" height="4655" viewBox="0 0 1440 4655" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<rect width="1440" height="4655" fill="white"/>
<rect x="-95" width="1630" height="4655" fill="white"/>
<rect x="-95" width="1630" height="4655" fill="url(#paint0_linear)" fillOpacity="0.9"/>
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter0_f)">
<path d="M-95 81H-41.5427C-21.4963 98.2997 20.9354 132.416 30.2904 130.485C39.6454 128.554 57.9471 143.762 65.9286 151.607C85.2326 168.303 124.843 201.454 128.852 200.488C130.084 200.192 133.976 200.223 139.641 200.269C157.018 200.41 191.081 200.687 216.277 192.04C249.688 180.574 266.95 185.402 278.087 192.04C289.224 198.678 349.92 229.455 360.5 227.041C364.049 226.232 374.49 226.916 387.221 227.75C412.442 229.403 446.649 231.644 454.05 224.024C465.187 212.558 658.97 204.713 677.346 214.368C692.047 222.093 711.462 222.214 720 222.214C728.538 222.214 747.953 222.093 762.654 214.368C781.03 204.713 974.812 212.558 985.949 224.024C993.351 231.644 1027.56 229.403 1052.78 227.75C1065.51 226.916 1075.95 226.232 1079.5 227.041C1090.08 229.455 1150.78 198.678 1161.91 192.04C1173.05 185.402 1190.31 180.574 1223.72 192.04C1248.92 200.687 1282.98 200.41 1300.36 200.269C1306.02 200.223 1309.92 200.192 1311.15 200.488C1315.16 201.454 1354.77 168.303 1374.07 151.607C1382.05 143.762 1400.35 128.554 1409.71 130.485C1419.06 132.416 1461.5 98.2997 1481.54 81H1535V5699H-95V81Z" fill="url(#paint1_linear)"/>
</g>
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter1_b)">
<path d="M-94.4432 513.757L-95 340.635C-79.1818 340.214 -58.0175 340.376 -39.8412 340.516C-31.7833 340.577 -24.3126 340.635 -18.1552 340.635C0.777557 340.635 41.9842 351.569 77.0655 371.007C80.0141 371.713 82.7676 372.389 85.3812 373.03C103.005 377.355 114.269 380.119 136.091 380.119L288.11 383.156C290.709 382.751 297.02 380.604 301.475 375.259C305.929 369.913 317.066 360.882 322.078 357.035C325.605 354.808 335.665 350.353 347.693 350.353C357.225 350.353 369.218 351.086 377.998 351.622C383.067 351.932 387.065 352.176 388.899 352.176C393.911 352.176 406.162 349.138 410.616 344.279C414.18 340.391 449.967 297.303 467.415 276.245C473.54 269.36 489.8 256.928 505.837 262.274C525.884 268.955 581.011 268.955 589.921 262.274C598.831 255.592 619.434 244.051 639.48 247.696C641.661 248.092 644.286 248.57 647.239 249.108C671.427 253.515 717.519 261.913 720 261.913C722.481 261.913 768.573 253.515 792.761 249.108C795.714 248.57 798.339 248.092 800.52 247.696C820.566 244.051 841.169 255.592 850.079 262.274C858.989 268.955 914.116 268.955 934.163 262.274C950.2 256.928 966.46 269.36 972.585 276.245C990.033 297.303 1025.82 340.391 1029.38 344.279C1033.84 349.138 1046.09 352.176 1051.1 352.176C1052.93 352.176 1056.93 351.932 1062 351.622C1070.78 351.086 1082.78 350.353 1092.31 350.353C1104.34 350.353 1114.4 354.808 1117.92 357.035C1122.93 360.882 1134.07 369.913 1138.53 375.259C1142.98 380.604 1149.29 382.751 1151.89 383.156L1303.91 380.119C1325.73 380.119 1336.99 377.355 1354.62 373.03C1357.23 372.389 1359.99 371.713 1362.93 371.007C1398.02 351.569 1439.22 340.635 1458.16 340.635C1464.31 340.635 1471.78 340.577 1479.84 340.516C1498.02 340.376 1519.18 340.214 1535 340.635L1534.44 513.757L1535 5735H-95L-94.4432 513.757Z" fill="url(#paint2_linear)"/>
</g>
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter2_b)">
<path d="M-94.4432 564.916L-95 459.824C-83.4012 458.344 -70.3203 456.725 -56.3558 454.996C23.3155 445.133 131.749 431.709 157.808 420.338C174.83 417.587 251.452 426.321 319.591 434.089C371.82 440.042 419.065 445.428 430.663 444.637C438.9 444.075 458.907 436.012 485.925 425.125C546.58 400.681 642.565 362 720 362C797.435 362 893.42 400.681 954.075 425.125C981.093 436.012 1001.1 444.075 1009.34 444.637C1020.94 445.428 1068.18 440.042 1120.41 434.089C1188.55 426.321 1265.17 417.587 1282.19 420.338C1308.25 431.709 1416.68 445.133 1496.36 454.996C1510.32 456.725 1523.4 458.344 1535 459.824L1534.44 564.916L1535 5694H-95L-94.4432 564.916Z" fill="url(#paint3_linear)"/>
</g>
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter3_f)">
<path d="M-95 474.713C-74.9535 467.22 -31.8536 452.843 -22.0531 455.273C-9.80252 458.311 30.2904 476.535 41.9842 492.33C53.678 508.124 75.3046 507.008 77.0655 505.087C78.736 503.265 93.7709 492.127 101.567 486.862C106.207 484.432 118.384 481.03 129.966 486.862C141.548 492.694 209.409 526.552 241.892 542.751C246.161 545.181 255.034 550.041 256.37 550.041C256.615 550.041 257.181 550.093 257.983 550.167C262.657 550.596 275.317 551.76 278.644 547.611C281.762 543.723 299.247 530.197 307.6 523.919C313.725 519.869 328.537 511.769 338.783 511.769C349.029 511.769 421.382 515.819 456.278 517.844C476.51 517.439 518.088 516.508 522.542 516.022C525.854 515.66 557.031 517.663 583.224 519.345C601.072 520.491 616.606 521.489 619.434 521.489C622.857 521.489 633.093 514.341 646.164 505.215C669.243 489.1 701.158 466.815 720 466.815C738.842 466.815 770.757 489.1 793.836 505.215C806.907 514.341 817.143 521.489 820.566 521.489C823.394 521.489 838.928 520.491 856.776 519.345C882.969 517.663 914.146 515.66 917.458 516.022C921.912 516.508 963.49 517.439 983.722 517.844C1018.62 515.819 1090.97 511.769 1101.22 511.769C1111.46 511.769 1126.27 519.869 1132.4 523.919C1140.75 530.197 1158.24 543.723 1161.36 547.611C1164.68 551.76 1177.34 550.596 1182.02 550.167C1182.82 550.093 1183.39 550.041 1183.63 550.041C1184.97 550.041 1193.84 545.181 1198.11 542.751C1230.59 526.552 1298.45 492.694 1310.03 486.862C1321.62 481.03 1333.79 484.432 1338.43 486.862C1346.23 492.127 1361.26 503.265 1362.93 505.087C1364.7 507.008 1386.32 508.124 1398.02 492.33C1409.71 476.535 1449.8 458.311 1462.05 455.273C1471.85 452.843 1514.95 467.22 1535 474.713V5633H-95V474.713Z" fill="url(#paint4_linear)"/>
</g>
<g style="mix-blend-mode:hard-light" opacity="0.2" filter="url(#filter4_f)">
<path d="M-48.7082 749.921C-44.5423 750.554 -40.9302 751.102 -38.2017 751.102C-34.8768 751.102 -32.6091 748.668 -30.2117 746.094C-27.3895 743.063 -24.3874 739.84 -19.2689 740.168C-11.6958 740.654 56.2766 740.371 89.3161 740.168L101.01 742.597L154.467 778.437L160.592 789.371L195.117 792.408L230.755 805.165C243.748 808.607 270.959 815.248 275.86 814.276C278.968 813.66 288.245 806.784 297.502 799.923C306.484 793.266 315.446 786.624 318.737 785.726C325.419 783.904 346.022 774.185 349.363 771.148C349.667 770.872 350.104 770.455 350.656 769.929C356.186 764.659 373.307 748.342 384.445 751.102C389.517 752.36 394.495 755.18 399.337 757.923C406.189 761.805 412.77 765.533 418.969 764.466C426.043 763.247 448.304 744.104 463.112 731.37C470.451 725.06 475.959 720.323 476.881 720.122C479.109 719.636 515.304 681.043 533.123 661.807C539.062 655.53 556.733 646.986 575.443 655.733C594.153 664.48 621.476 664.844 633.355 664.844L701.29 670.918L720 670.86L738.71 670.918L806.645 664.844C818.524 664.844 845.847 664.48 864.557 655.733C883.267 646.986 900.938 655.53 906.877 661.807C924.696 681.043 960.891 719.636 963.119 720.122C964.041 720.323 969.549 725.06 976.888 731.37C991.696 744.104 1013.96 763.247 1021.03 764.466C1027.23 765.533 1033.81 761.805 1040.66 757.923C1045.51 755.18 1050.48 752.36 1055.56 751.102C1066.69 748.342 1083.81 764.659 1089.34 769.929C1089.9 770.455 1090.33 770.872 1090.64 771.148C1093.98 774.185 1114.58 783.904 1121.26 785.726C1124.55 786.624 1133.52 793.266 1142.5 799.923C1151.75 806.784 1161.03 813.66 1164.14 814.276C1169.04 815.248 1196.25 808.607 1209.24 805.165L1244.88 792.408L1279.41 789.371L1285.53 778.437L1338.99 742.597L1350.68 740.168C1383.72 740.371 1451.7 740.654 1459.27 740.168C1464.39 739.84 1467.39 743.063 1470.21 746.094C1472.61 748.668 1474.88 751.102 1478.2 751.102C1480.93 751.102 1484.54 750.554 1488.71 749.921C1502.07 747.89 1521.13 744.994 1535 756.571V5699H-95V756.571C-81.1327 744.994 -62.0716 747.89 -48.7082 749.921Z" fill="url(#paint5_linear)" fillOpacity="0.55"/>
</g>
<ellipse opacity="0.2" cx="720.5" cy="532.5" rx="1003.5" ry="1123.5" transform="rotate(-90 720.5 532.5)" fill="url(#paint6_radial)"/>
</g>
<defs>
<filter id="filter0_f" x="-102" y="74" width="1644" height="5632" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="3.5" result="effect1_foregroundBlur"/>
</filter>
<filter id="filter1_b" x="-103" y="239" width="1646" height="5504" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feGaussianBlur in="BackgroundImage" stdDeviation="4"/>
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur" result="shape"/>
</filter>
<filter id="filter2_b" x="-98" y="359" width="1636" height="5338" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feGaussianBlur in="BackgroundImage" stdDeviation="1.5"/>
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur" result="shape"/>
</filter>
<filter id="filter3_f" x="-98.5" y="451.5" width="1637" height="5185" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="1.75" result="effect1_foregroundBlur"/>
</filter>
<filter id="filter4_f" x="-97" y="650" width="1634" height="5051" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="1" result="effect1_foregroundBlur"/>
</filter>
<linearGradient id="paint0_linear" x1="709.247" y1="-90.5139" x2="709.247" y2="4655" gradientUnits="userSpaceOnUse">
<stop stop-color="#EB9E49"/>
<stop offset="0.078125" stop-color="#CD4E59"/>
<stop offset="0.151042" stop-color="#6E3D6E"/>
<stop offset="0.437386" stop-color="#582B3F"/>
<stop offset="0.750045" stop-color="#46172C"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="718.886" y1="234.273" x2="719.05" y2="554.095" gradientUnits="userSpaceOnUse">
<stop stop-color="#202020"/>
<stop offset="1" stop-color="#807575"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="720" y1="331.517" x2="720.166" y2="784.035" gradientUnits="userSpaceOnUse">
<stop stop-color="#610409" stop-opacity="0.35"/>
<stop offset="0.40625" stop-color="#524C4C"/>
</linearGradient>
<linearGradient id="paint3_linear" x1="720.557" y1="362" x2="720.557" y2="816.963" gradientUnits="userSpaceOnUse">
<stop stop-color="#5A0013" stop-opacity="0.54"/>
<stop offset="1" stop-color="#AEAEAE"/>
</linearGradient>
<linearGradient id="paint4_linear" x1="720.556" y1="455" x2="720.556" y2="5633" gradientUnits="userSpaceOnUse">
<stop stop-color="#2B0109" stop-opacity="0.37"/>
<stop offset="0.25" stop-color="#610D32"/>
<stop offset="1" stop-color="#610D32"/>
</linearGradient>
<linearGradient id="paint5_linear" x1="720" y1="621.113" x2="720" y2="5830.2" gradientUnits="userSpaceOnUse">
<stop stop-color="#545454" stop-opacity="0.08"/>
<stop offset="0.0001" stop-color="#390013"/>
<stop offset="1" stop-color="#582B3F"/>
</linearGradient>
<radialGradient id="paint6_radial" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(720.5 636.394) rotate(90) scale(1019.61 910.703)">
<stop stop-color="#C85658"/>
<stop offset="1" stop-color="#FF0707" stop-opacity="0"/>
</radialGradient>
<clipPath id="clip0">
<rect width="1440" height="4655" fill="white"/>
</clipPath>
</defs>
<svg
width="1440"
height="4655"
viewBox="0 0 1440 4655"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0)">
<rect width="1440" height="4655" fill="white" />
<rect x="-95" width="1630" height="4655" fill="white" />
<rect x="-95" width="1630" height="4655" fill="url(#paint0_linear)" fillOpacity="0.9" />
<g style="mix-blend-mode: hard-light" opacity="0.2" filter="url(#filter0_f)">
<path
d="M-95 81H-41.5427C-21.4963 98.2997 20.9354 132.416 30.2904 130.485C39.6454 128.554 57.9471 143.762 65.9286 151.607C85.2326 168.303 124.843 201.454 128.852 200.488C130.084 200.192 133.976 200.223 139.641 200.269C157.018 200.41 191.081 200.687 216.277 192.04C249.688 180.574 266.95 185.402 278.087 192.04C289.224 198.678 349.92 229.455 360.5 227.041C364.049 226.232 374.49 226.916 387.221 227.75C412.442 229.403 446.649 231.644 454.05 224.024C465.187 212.558 658.97 204.713 677.346 214.368C692.047 222.093 711.462 222.214 720 222.214C728.538 222.214 747.953 222.093 762.654 214.368C781.03 204.713 974.812 212.558 985.949 224.024C993.351 231.644 1027.56 229.403 1052.78 227.75C1065.51 226.916 1075.95 226.232 1079.5 227.041C1090.08 229.455 1150.78 198.678 1161.91 192.04C1173.05 185.402 1190.31 180.574 1223.72 192.04C1248.92 200.687 1282.98 200.41 1300.36 200.269C1306.02 200.223 1309.92 200.192 1311.15 200.488C1315.16 201.454 1354.77 168.303 1374.07 151.607C1382.05 143.762 1400.35 128.554 1409.71 130.485C1419.06 132.416 1461.5 98.2997 1481.54 81H1535V5699H-95V81Z"
fill="url(#paint1_linear)"
/>
</g>
<g style="mix-blend-mode: hard-light" opacity="0.2" filter="url(#filter1_b)">
<path
d="M-94.4432 513.757L-95 340.635C-79.1818 340.214 -58.0175 340.376 -39.8412 340.516C-31.7833 340.577 -24.3126 340.635 -18.1552 340.635C0.777557 340.635 41.9842 351.569 77.0655 371.007C80.0141 371.713 82.7676 372.389 85.3812 373.03C103.005 377.355 114.269 380.119 136.091 380.119L288.11 383.156C290.709 382.751 297.02 380.604 301.475 375.259C305.929 369.913 317.066 360.882 322.078 357.035C325.605 354.808 335.665 350.353 347.693 350.353C357.225 350.353 369.218 351.086 377.998 351.622C383.067 351.932 387.065 352.176 388.899 352.176C393.911 352.176 406.162 349.138 410.616 344.279C414.18 340.391 449.967 297.303 467.415 276.245C473.54 269.36 489.8 256.928 505.837 262.274C525.884 268.955 581.011 268.955 589.921 262.274C598.831 255.592 619.434 244.051 639.48 247.696C641.661 248.092 644.286 248.57 647.239 249.108C671.427 253.515 717.519 261.913 720 261.913C722.481 261.913 768.573 253.515 792.761 249.108C795.714 248.57 798.339 248.092 800.52 247.696C820.566 244.051 841.169 255.592 850.079 262.274C858.989 268.955 914.116 268.955 934.163 262.274C950.2 256.928 966.46 269.36 972.585 276.245C990.033 297.303 1025.82 340.391 1029.38 344.279C1033.84 349.138 1046.09 352.176 1051.1 352.176C1052.93 352.176 1056.93 351.932 1062 351.622C1070.78 351.086 1082.78 350.353 1092.31 350.353C1104.34 350.353 1114.4 354.808 1117.92 357.035C1122.93 360.882 1134.07 369.913 1138.53 375.259C1142.98 380.604 1149.29 382.751 1151.89 383.156L1303.91 380.119C1325.73 380.119 1336.99 377.355 1354.62 373.03C1357.23 372.389 1359.99 371.713 1362.93 371.007C1398.02 351.569 1439.22 340.635 1458.16 340.635C1464.31 340.635 1471.78 340.577 1479.84 340.516C1498.02 340.376 1519.18 340.214 1535 340.635L1534.44 513.757L1535 5735H-95L-94.4432 513.757Z"
fill="url(#paint2_linear)"
/>
</g>
<g style="mix-blend-mode: hard-light" opacity="0.2" filter="url(#filter2_b)">
<path
d="M-94.4432 564.916L-95 459.824C-83.4012 458.344 -70.3203 456.725 -56.3558 454.996C23.3155 445.133 131.749 431.709 157.808 420.338C174.83 417.587 251.452 426.321 319.591 434.089C371.82 440.042 419.065 445.428 430.663 444.637C438.9 444.075 458.907 436.012 485.925 425.125C546.58 400.681 642.565 362 720 362C797.435 362 893.42 400.681 954.075 425.125C981.093 436.012 1001.1 444.075 1009.34 444.637C1020.94 445.428 1068.18 440.042 1120.41 434.089C1188.55 426.321 1265.17 417.587 1282.19 420.338C1308.25 431.709 1416.68 445.133 1496.36 454.996C1510.32 456.725 1523.4 458.344 1535 459.824L1534.44 564.916L1535 5694H-95L-94.4432 564.916Z"
fill="url(#paint3_linear)"
/>
</g>
<g style="mix-blend-mode: hard-light" opacity="0.2" filter="url(#filter3_f)">
<path
d="M-95 474.713C-74.9535 467.22 -31.8536 452.843 -22.0531 455.273C-9.80252 458.311 30.2904 476.535 41.9842 492.33C53.678 508.124 75.3046 507.008 77.0655 505.087C78.736 503.265 93.7709 492.127 101.567 486.862C106.207 484.432 118.384 481.03 129.966 486.862C141.548 492.694 209.409 526.552 241.892 542.751C246.161 545.181 255.034 550.041 256.37 550.041C256.615 550.041 257.181 550.093 257.983 550.167C262.657 550.596 275.317 551.76 278.644 547.611C281.762 543.723 299.247 530.197 307.6 523.919C313.725 519.869 328.537 511.769 338.783 511.769C349.029 511.769 421.382 515.819 456.278 517.844C476.51 517.439 518.088 516.508 522.542 516.022C525.854 515.66 557.031 517.663 583.224 519.345C601.072 520.491 616.606 521.489 619.434 521.489C622.857 521.489 633.093 514.341 646.164 505.215C669.243 489.1 701.158 466.815 720 466.815C738.842 466.815 770.757 489.1 793.836 505.215C806.907 514.341 817.143 521.489 820.566 521.489C823.394 521.489 838.928 520.491 856.776 519.345C882.969 517.663 914.146 515.66 917.458 516.022C921.912 516.508 963.49 517.439 983.722 517.844C1018.62 515.819 1090.97 511.769 1101.22 511.769C1111.46 511.769 1126.27 519.869 1132.4 523.919C1140.75 530.197 1158.24 543.723 1161.36 547.611C1164.68 551.76 1177.34 550.596 1182.02 550.167C1182.82 550.093 1183.39 550.041 1183.63 550.041C1184.97 550.041 1193.84 545.181 1198.11 542.751C1230.59 526.552 1298.45 492.694 1310.03 486.862C1321.62 481.03 1333.79 484.432 1338.43 486.862C1346.23 492.127 1361.26 503.265 1362.93 505.087C1364.7 507.008 1386.32 508.124 1398.02 492.33C1409.71 476.535 1449.8 458.311 1462.05 455.273C1471.85 452.843 1514.95 467.22 1535 474.713V5633H-95V474.713Z"
fill="url(#paint4_linear)"
/>
</g>
<g style="mix-blend-mode: hard-light" opacity="0.2" filter="url(#filter4_f)">
<path
d="M-48.7082 749.921C-44.5423 750.554 -40.9302 751.102 -38.2017 751.102C-34.8768 751.102 -32.6091 748.668 -30.2117 746.094C-27.3895 743.063 -24.3874 739.84 -19.2689 740.168C-11.6958 740.654 56.2766 740.371 89.3161 740.168L101.01 742.597L154.467 778.437L160.592 789.371L195.117 792.408L230.755 805.165C243.748 808.607 270.959 815.248 275.86 814.276C278.968 813.66 288.245 806.784 297.502 799.923C306.484 793.266 315.446 786.624 318.737 785.726C325.419 783.904 346.022 774.185 349.363 771.148C349.667 770.872 350.104 770.455 350.656 769.929C356.186 764.659 373.307 748.342 384.445 751.102C389.517 752.36 394.495 755.18 399.337 757.923C406.189 761.805 412.77 765.533 418.969 764.466C426.043 763.247 448.304 744.104 463.112 731.37C470.451 725.06 475.959 720.323 476.881 720.122C479.109 719.636 515.304 681.043 533.123 661.807C539.062 655.53 556.733 646.986 575.443 655.733C594.153 664.48 621.476 664.844 633.355 664.844L701.29 670.918L720 670.86L738.71 670.918L806.645 664.844C818.524 664.844 845.847 664.48 864.557 655.733C883.267 646.986 900.938 655.53 906.877 661.807C924.696 681.043 960.891 719.636 963.119 720.122C964.041 720.323 969.549 725.06 976.888 731.37C991.696 744.104 1013.96 763.247 1021.03 764.466C1027.23 765.533 1033.81 761.805 1040.66 757.923C1045.51 755.18 1050.48 752.36 1055.56 751.102C1066.69 748.342 1083.81 764.659 1089.34 769.929C1089.9 770.455 1090.33 770.872 1090.64 771.148C1093.98 774.185 1114.58 783.904 1121.26 785.726C1124.55 786.624 1133.52 793.266 1142.5 799.923C1151.75 806.784 1161.03 813.66 1164.14 814.276C1169.04 815.248 1196.25 808.607 1209.24 805.165L1244.88 792.408L1279.41 789.371L1285.53 778.437L1338.99 742.597L1350.68 740.168C1383.72 740.371 1451.7 740.654 1459.27 740.168C1464.39 739.84 1467.39 743.063 1470.21 746.094C1472.61 748.668 1474.88 751.102 1478.2 751.102C1480.93 751.102 1484.54 750.554 1488.71 749.921C1502.07 747.89 1521.13 744.994 1535 756.571V5699H-95V756.571C-81.1327 744.994 -62.0716 747.89 -48.7082 749.921Z"
fill="url(#paint5_linear)"
fillOpacity="0.55"
/>
</g>
<ellipse
opacity="0.2"
cx="720.5"
cy="532.5"
rx="1003.5"
ry="1123.5"
transform="rotate(-90 720.5 532.5)"
fill="url(#paint6_radial)"
/>
</g>
<defs>
<filter
id="filter0_f"
x="-102"
y="74"
width="1644"
height="5632"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="3.5" result="effect1_foregroundBlur" />
</filter>
<filter
id="filter1_b"
x="-103"
y="239"
width="1646"
height="5504"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feGaussianBlur in="BackgroundImage" stdDeviation="4" />
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur" />
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur" result="shape" />
</filter>
<filter
id="filter2_b"
x="-98"
y="359"
width="1636"
height="5338"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feGaussianBlur in="BackgroundImage" stdDeviation="1.5" />
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur" />
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur" result="shape" />
</filter>
<filter
id="filter3_f"
x="-98.5"
y="451.5"
width="1637"
height="5185"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="1.75" result="effect1_foregroundBlur" />
</filter>
<filter
id="filter4_f"
x="-97"
y="650"
width="1634"
height="5051"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="1" result="effect1_foregroundBlur" />
</filter>
<linearGradient
id="paint0_linear"
x1="709.247"
y1="-90.5139"
x2="709.247"
y2="4655"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#EB9E49" />
<stop offset="0.078125" stop-color="#CD4E59" />
<stop offset="0.151042" stop-color="#6E3D6E" />
<stop offset="0.437386" stop-color="#582B3F" />
<stop offset="0.750045" stop-color="#46172C" />
</linearGradient>
<linearGradient
id="paint1_linear"
x1="718.886"
y1="234.273"
x2="719.05"
y2="554.095"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#202020" />
<stop offset="1" stop-color="#807575" />
</linearGradient>
<linearGradient
id="paint2_linear"
x1="720"
y1="331.517"
x2="720.166"
y2="784.035"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#610409" stop-opacity="0.35" />
<stop offset="0.40625" stop-color="#524C4C" />
</linearGradient>
<linearGradient
id="paint3_linear"
x1="720.557"
y1="362"
x2="720.557"
y2="816.963"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#5A0013" stop-opacity="0.54" />
<stop offset="1" stop-color="#AEAEAE" />
</linearGradient>
<linearGradient
id="paint4_linear"
x1="720.556"
y1="455"
x2="720.556"
y2="5633"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#2B0109" stop-opacity="0.37" />
<stop offset="0.25" stop-color="#610D32" />
<stop offset="1" stop-color="#610D32" />
</linearGradient>
<linearGradient
id="paint5_linear"
x1="720"
y1="621.113"
x2="720"
y2="5830.2"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#545454" stop-opacity="0.08" />
<stop offset="0.0001" stop-color="#390013" />
<stop offset="1" stop-color="#582B3F" />
</linearGradient>
<radialGradient
id="paint6_radial"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(720.5 636.394) rotate(90) scale(1019.61 910.703)"
>
<stop stop-color="#C85658" />
<stop offset="1" stop-color="#FF0707" stop-opacity="0" />
</radialGradient>
<clipPath id="clip0">
<rect width="1440" height="4655" fill="white" />
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,92 +0,0 @@
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" id="svg8" version="1.1" viewBox="0 0 192.6982 188.16626" height="711.17957" width="728.30817" sodipodi:docname="juno.svg" inkscape:version="1.1.1 (c3084ef, 2021-09-22)"><script xmlns=""/><script xmlns="" id="argent-x-extension" data-extension-id="dlcobpjiigpikoobohmabehhmhfoodbb"/>
<sodipodi:namedview id="namedview175" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" showgrid="false" inkscape:zoom="0.774" inkscape:cx="370.80103" inkscape:cy="344.96124" inkscape:window-width="1323" inkscape:window-height="958" inkscape:window-x="0" inkscape:window-y="25" inkscape:window-maximized="0" inkscape:current-layer="svg8"/>
<defs id="defs2">
<linearGradient id="linearGradient982" inkscape:swatch="gradient">
<stop id="stop978" offset="0" style="stop-color:#f0827d;stop-opacity:1;"/>
<stop id="stop980" offset="1" style="stop-color:#f0827d;stop-opacity:0;"/>
</linearGradient>
<linearGradient id="linearGradient923">
<stop id="stop919" offset="0" style="stop-color:#000000;stop-opacity:1;"/>
<stop id="stop921" offset="1" style="stop-color:#000000;stop-opacity:0;"/>
</linearGradient>
<linearGradient id="linearGradient915">
<stop id="stop911" offset="0" style="stop-color:#ff6255;stop-opacity:1;"/>
<stop id="stop913" offset="1" style="stop-color:#ff6255;stop-opacity:0;"/>
</linearGradient>
<linearGradient id="linearGradient868" inkscape:swatch="solid">
<stop id="stop866" offset="0" style="stop-color:#000000;stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linearGradient1607" inkscape:swatch="gradient">
<stop id="stop1603" offset="0" style="stop-color:#ff6255;stop-opacity:1"/>
<stop id="stop1605" offset="1" style="stop-color:#da5b51;stop-opacity:0;"/>
</linearGradient>
<linearGradient id="linearGradient6891-7">
<stop style="stop-color:#ff8c8c;stop-opacity:1;" offset="0" id="stop6887"/>
<stop style="stop-color:#ff8c8c;stop-opacity:0;" offset="1" id="stop6889"/>
</linearGradient>
<linearGradient xlink:href="#linearGradient6891-7" id="linearGradient6893" x1="116.28441" y1="131.06845" x2="330.48346" y2="131.06845" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0176293,0,0,1.043284,-52.786314,-431.941)"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672" xlink:href="#linearGradient923"/>
<linearGradient gradientUnits="userSpaceOnUse" y2="-360.58929" x2="294.47836" y1="-366.6369" x1="-5.883111" id="linearGradient917" xlink:href="#linearGradient915"/>
<linearGradient gradientTransform="translate(-161.77381,-52.916668)" gradientUnits="userSpaceOnUse" y2="137.55695" x2="1492.8649" y1="137.55695" x1="956.32697" id="linearGradient925" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-0" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-6" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-8" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-4" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-62" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-3" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-8" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-37" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-5" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-0-4" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-6-1" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-8-7" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-4-6" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-62-8" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-3-6" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-8-6" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-2" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-0" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-0-9" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-6-4" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-8-0" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-4-9" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-62-5" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-3-1" xlink:href="#linearGradient923"/>
<radialGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.4006544,0,-10.327923)" r="11.343032" fy="25.777636" fx="25.051212" cy="25.777636" cx="25.051212" id="radialGradient1672-5-8-8" xlink:href="#linearGradient923"/>
</defs>
<metadata id="metadata5">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(-34.189243,-73.416721)" id="layer1">
<ellipse ry="90.662651" rx="92.928627" style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:13.7355;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" id="circle1199" cx="130.53835" cy="169.52222"/>
<ellipse ry="90.662651" rx="92.928627" cy="167.49985" cx="130.53835" id="path1185" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:6.84095;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"/>
<g transform="matrix(2.4170273,0,0,2.5557268,70.439041,106.28282)" id="g1265" style="clip-rule:evenodd;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2">
<g style="fill:#ffffff;fill-opacity:1" transform="matrix(0.721351,0,0,0.811444,6.54562,5.10326)" id="g1229">
<path style="fill:#ffffff;fill-opacity:1" d="m 27.411,7.92 c 0,-0.84 -0.766,-1.521 -1.711,-1.521 0,0 -10e-4,0 -0.002,0 -0.944,0 -1.71,0.681 -1.71,1.521 0,6.129 0,28.987 0,35.117 0,0.84 0.766,1.521 1.71,1.521 0.001,0 0.002,0 0.002,0 0.945,0 1.711,-0.681 1.711,-1.521 0,-6.13 0,-28.988 0,-35.117 z" id="path1227"/>
</g>
<g style="fill:#ffffff;fill-opacity:1" transform="matrix(5.99295e-4,-0.721351,0.258566,2.14816e-4,18.4279,54.7844)" id="g1233">
<path style="fill:#ffffff;fill-opacity:1" d="m 27.411,11.171 c 0,-2.635 -0.766,-4.772 -1.711,-4.772 0,0 -10e-4,0 -0.002,0 -0.944,0 -1.71,2.137 -1.71,4.772 0,7.331 0,21.283 0,28.614 0,2.636 0.766,4.773 1.71,4.773 0.001,0 0.002,0 0.002,0 0.945,0 1.711,-2.137 1.711,-4.773 0,-7.331 0,-21.283 0,-28.614 z" id="path1231"/>
</g>
<g style="fill:#ffffff;fill-opacity:1" transform="matrix(5.99295e-4,-0.721351,0.579332,4.81307e-4,10.2753,38.6396)" id="g1237">
<path style="fill:#ffffff;fill-opacity:1" d="m 27.411,8.529 c 0,-1.177 -0.766,-2.13 -1.711,-2.13 0,0 -10e-4,0 -0.002,0 -0.944,0 -1.71,0.953 -1.71,2.13 0,6.687 0,27.212 0,33.899 0,1.176 0.766,2.13 1.71,2.13 0.001,0 0.002,0 0.002,0 0.945,0 1.711,-0.954 1.711,-2.13 0,-6.687 0,-27.212 0,-33.899 z" id="path1235"/>
</g>
<g style="fill:#ffffff;fill-opacity:1" transform="matrix(0.509521,-0.510622,0.393855,0.393005,1.94156,23.2426)" id="g1241">
<path style="fill:#ffffff;fill-opacity:1" d="m 27.411,8.617 c 0,-1.225 -0.766,-2.218 -1.711,-2.218 0,0 -10e-4,0 -0.002,0 -0.944,0 -1.71,0.993 -1.71,2.218 0,6.747 0,26.976 0,33.723 0,1.225 0.766,2.218 1.71,2.218 0.001,0 0.002,0 0.002,0 0.945,0 1.711,-0.993 1.711,-2.218 0,-6.747 0,-26.976 0,-33.723 z" id="path1239"/>
</g>
<g style="fill:#ffffff;fill-opacity:1" transform="matrix(-0.51096,-0.509182,0.392744,-0.394115,28.1955,43.2602)" id="g1245">
<path style="fill:#ffffff;fill-opacity:1" d="m 27.411,8.617 c 0,-1.225 -0.766,-2.218 -1.711,-2.218 0,0 -10e-4,0 -0.002,0 -0.944,0 -1.71,0.993 -1.71,2.218 0,6.747 0,26.976 0,33.723 0,1.225 0.766,2.218 1.71,2.218 0.001,0 0.002,0 0.002,0 0.945,0 1.711,-0.993 1.711,-2.218 0,-6.747 0,-26.976 0,-33.723 z" id="path1243"/>
</g>
</g>
<ellipse ry="79.882423" rx="81.878975" cy="168.1187" cx="130.57381" id="path1267" style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#f0827d;stroke-width:3.92991;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"/>
</g>
<style type="text/css" id="style1053">
.st0{fill:#043BEA;}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,29 +1,124 @@
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;">
<path d="M12.985,0.812C13.949,0.812 14.279,0.928 14.929,1.155C15.091,1.211 15.273,1.275 15.49,1.345C19.947,2.795 23.25,7.071 23.25,12.005C23.25,12.829 23.133,13.721 22.963,14.506C22.196,17.622 20.213,20.269 17.543,21.804C16.213,22.568 14.67,23.131 13.068,23.239C12.8,23.257 11.93,23.249 11.339,23.243C11.126,23.241 10.95,23.239 10.85,23.239C5.061,22.419 0.75,18.142 0.75,12.005C0.75,10.447 1.047,8.887 1.653,7.454C2.282,5.968 3.362,4.699 4.486,3.6C5.476,2.634 6.7,2.1 7.906,1.574C8.081,1.498 8.255,1.422 8.428,1.345C9.05,1.068 9.469,1.008 9.996,0.932C10.214,0.9 10.45,0.866 10.727,0.812C11.214,0.719 11.726,0.75 12.234,0.781C12.486,0.797 12.738,0.812 12.985,0.812Z" style="fill:url(#_Linear1);fill-rule:nonzero;"/>
<path d="M12.985,0.812C13.949,0.812 14.279,0.928 14.929,1.155C15.091,1.211 15.273,1.275 15.49,1.345C19.947,2.795 23.25,7.071 23.25,12.005C23.25,12.829 23.133,13.721 22.963,14.506C22.196,17.622 20.213,20.269 17.543,21.804C16.213,22.568 14.67,23.131 13.068,23.239C12.8,23.257 11.93,23.249 11.339,23.243C11.126,23.241 10.95,23.239 10.85,23.239C5.061,22.419 0.75,18.142 0.75,12.005C0.75,10.447 1.047,8.887 1.653,7.454C2.282,5.968 3.362,4.699 4.486,3.6C5.476,2.634 6.7,2.1 7.906,1.574C8.081,1.498 8.255,1.422 8.428,1.345C9.05,1.068 9.469,1.008 9.996,0.932C10.214,0.9 10.45,0.866 10.727,0.812C11.214,0.719 11.726,0.75 12.234,0.781C12.486,0.797 12.738,0.812 12.985,0.812Z" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:1px;"/>
<path d="M11.999,0.166L15.656,0.746L18.955,2.426L21.573,5.044L23.254,8.342L23.834,11.999L23.254,15.656L21.573,18.955L18.955,21.573L15.656,23.254L11.999,23.834L8.343,23.254L5.044,21.573L2.426,18.955L0.746,15.656L0.166,11.999L0.746,8.343L2.426,5.044L5.044,2.426L8.343,0.746L11.999,0.166ZM8.549,1.381L5.436,2.966L2.967,5.436L1.381,8.549L0.834,11.999L1.381,15.45L2.967,18.562L5.436,21.032L8.549,22.619L11.999,23.166L15.45,22.619L18.562,21.032L21.032,18.562L22.619,15.45L23.166,11.999L22.619,8.549L21.032,5.436L18.562,2.966L15.45,1.381L11.999,0.834L8.549,1.381Z" style="fill:white;"/>
<path d="M11.915,3.928C11.993,3.881 12.094,3.907 12.141,3.985L14.738,8.343C14.785,8.421 14.759,8.523 14.681,8.569C14.603,8.616 14.501,8.59 14.455,8.512L11.857,4.154C11.811,4.076 11.836,3.975 11.915,3.928Z" style="fill:white;"/>
<path d="M11.999,3.904L17.36,4.484L17.325,4.812L11.999,4.236L6.674,4.812L6.639,4.484L11.999,3.904Z" style="fill:white;"/>
<path d="M9.237,8.426C9.237,8.334 9.311,8.261 9.402,8.261L14.596,8.261C14.687,8.261 14.761,8.334 14.761,8.426C14.761,8.517 14.687,8.591 14.596,8.591L9.402,8.591C9.311,8.591 9.237,8.517 9.237,8.426Z" style="fill:white;"/>
<path d="M12.083,3.928C12.161,3.975 12.187,4.076 12.14,4.154L9.544,8.512C9.497,8.59 9.396,8.616 9.318,8.569C9.24,8.523 9.214,8.421 9.261,8.343L11.857,3.985C11.903,3.907 12.004,3.881 12.083,3.928Z" style="fill:white;"/>
<path d="M8.392,0.803L11.999,3.853L15.606,0.803L17.49,4.573L17.195,4.721L15.499,1.326L11.999,4.285L8.499,1.326L6.804,4.721L6.509,4.573L8.392,0.803Z" style="fill:white;"/>
<path d="M5.143,2.563C5.217,2.509 5.32,2.525 5.374,2.599L11.999,11.719L18.625,2.599C18.679,2.525 18.782,2.509 18.856,2.563C18.929,2.616 18.946,2.719 18.892,2.793L12.133,12.097C12.102,12.14 12.052,12.165 11.999,12.165C11.947,12.165 11.897,12.14 11.866,12.097L5.107,2.793C5.053,2.719 5.07,2.616 5.143,2.563Z" style="fill:white;"/>
<path d="M9.525,8.314C9.565,8.358 9.578,8.42 9.56,8.476L7.992,13.303L12.081,16.274L16.727,18.266C16.811,18.302 16.85,18.399 16.814,18.482C16.778,18.566 16.681,18.605 16.597,18.569L11.934,16.57C11.923,16.565 11.912,16.559 11.902,16.552L7.701,13.499C7.643,13.457 7.619,13.383 7.641,13.315L9.156,8.651L4.493,9.709C4.404,9.729 4.315,9.674 4.295,9.585C4.275,9.496 4.331,9.408 4.42,9.387L9.367,8.265C9.424,8.251 9.485,8.27 9.525,8.314Z" style="fill:white;"/>
<path d="M4.347,9.426C4.416,9.366 4.52,9.373 4.58,9.442L7.922,13.259C7.982,13.328 7.975,13.432 7.907,13.492C7.838,13.552 7.734,13.545 7.674,13.477L4.332,9.659C4.272,9.591 4.279,9.486 4.347,9.426Z" style="fill:white;"/>
<path d="M6.931,4.439L4.635,9.553L4.661,9.616L4.603,9.652L3.534,14.751L7.435,18.284L12.078,20.948L15.442,22.696L16.535,18.244L21.105,18.581L20.481,14.837L20.807,14.783L21.499,18.941L16.789,18.593L15.662,23.182L11.917,21.236L7.24,18.553L3.238,14.928L0.234,11.971L4.25,9.483L2.464,5.109L6.931,4.439ZM4.215,9.893L0.765,12.03L3.254,14.48L4.215,9.893ZM4.463,9.131L6.382,4.855L2.928,5.373L4.463,9.131Z" style="fill:white;"/>
<path d="M7.814,13.202C7.904,13.211 7.971,13.291 7.963,13.382L7.502,18.433C7.494,18.524 7.414,18.591 7.323,18.583C7.232,18.574 7.165,18.494 7.174,18.403L7.634,13.352C7.642,13.261 7.723,13.194 7.814,13.202Z" style="fill:white;"/>
<path d="M12.151,16.353C12.187,16.436 12.148,16.533 12.065,16.569L7.403,18.569C7.319,18.604 7.222,18.566 7.186,18.482C7.15,18.398 7.189,18.301 7.273,18.265L11.935,16.266C12.018,16.23 12.115,16.269 12.151,16.353Z" style="fill:white;"/>
<path d="M2.893,18.581L3.517,14.837L3.191,14.783L2.499,18.941L7.211,18.594L8.336,23.182L12.075,21.24L11.923,20.947L8.556,22.696L7.465,18.244L2.893,18.581Z" style="fill:white;"/>
<path d="M12.097,11.865C12.14,11.896 12.165,11.946 12.165,11.998L12.165,23.5C12.165,23.591 12.091,23.665 12,23.665C11.909,23.665 11.835,23.591 11.835,23.5L11.835,12.226L1.115,15.709C1.029,15.737 0.936,15.69 0.908,15.603C0.879,15.517 0.927,15.423 1.013,15.395L11.949,11.842C11.999,11.825 12.054,11.834 12.097,11.865Z" style="fill:white;"/>
<path d="M17.212,4.547C17.248,4.499 17.308,4.475 17.368,4.484L21.327,5.078C21.377,5.085 21.421,5.115 21.446,5.159C21.471,5.203 21.474,5.256 21.455,5.303L19.749,9.483L23.587,11.861C23.63,11.887 23.658,11.932 23.664,11.982C23.669,12.033 23.652,12.083 23.616,12.118L20.762,14.926L20.756,14.932L20.755,14.932C20.755,14.933 20.754,14.934 20.753,14.934L16.773,18.541C16.727,18.583 16.661,18.595 16.602,18.572C16.544,18.55 16.504,18.496 16.498,18.434L16.039,13.4L14.44,8.478C14.421,8.421 14.435,8.359 14.475,8.315C14.515,8.272 14.575,8.253 14.633,8.266L19.258,9.315L17.193,4.715C17.168,4.659 17.175,4.595 17.212,4.547ZM19.237,9.649L14.843,8.652L16.269,13.04L19.237,9.649ZM16.372,13.422L16.797,18.074L20.464,14.751L19.45,9.907L16.372,13.422ZM19.784,9.893L20.744,14.48L23.234,12.03L19.784,9.893ZM19.536,9.13L21.07,5.373L17.617,4.855L19.536,9.13Z" style="fill:white;"/>
<path d="M11.842,11.947C11.87,11.861 11.963,11.813 12.05,11.842L22.987,15.395C23.074,15.423 23.121,15.517 23.093,15.603C23.065,15.69 22.972,15.737 22.885,15.709L11.948,12.155C11.861,12.127 11.814,12.034 11.842,11.947Z" style="fill:white;"/>
<path d="M16.335,13.27C16.389,13.343 16.372,13.447 16.298,13.5L12.096,16.552C12.022,16.606 11.919,16.59 11.866,16.516C11.812,16.442 11.828,16.339 11.902,16.285L16.104,13.233C16.178,13.18 16.281,13.196 16.335,13.27Z" style="fill:white;"/>
<path d="M16.58,18.276C16.653,18.234 16.746,18.254 16.796,18.322L18.892,21.208C18.945,21.282 18.929,21.385 18.855,21.439C18.782,21.492 18.678,21.476 18.625,21.402L16.616,18.636L12.081,21.237C12.002,21.282 11.901,21.255 11.856,21.176C11.81,21.097 11.838,20.996 11.917,20.951L16.58,18.276Z" style="fill:white;"/>
<path d="M11.999,0.335C12.09,0.335 12.164,0.409 12.164,0.5L12.164,4.068C12.164,4.159 12.09,4.233 11.999,4.233C11.908,4.233 11.834,4.159 11.834,4.068L11.834,0.5C11.834,0.409 11.908,0.335 11.999,0.335Z" style="fill:white;"/>
<path d="M23.093,8.396C23.121,8.483 23.073,8.576 22.987,8.604L19.594,9.706C19.507,9.735 19.414,9.687 19.386,9.601C19.358,9.514 19.405,9.421 19.492,9.393L22.885,8.29C22.971,8.262 23.064,8.309 23.093,8.396Z" style="fill:white;"/>
<path d="M7.435,18.286C7.509,18.34 7.525,18.443 7.471,18.516L5.374,21.402C5.32,21.476 5.217,21.492 5.143,21.439C5.069,21.385 5.053,21.282 5.107,21.208L7.204,18.322C7.258,18.249 7.361,18.232 7.435,18.286Z" style="fill:white;"/>
<path d="M0.908,8.396C0.936,8.309 1.029,8.262 1.115,8.29L4.508,9.393C4.595,9.421 4.642,9.514 4.614,9.601C4.586,9.687 4.493,9.735 4.406,9.706L1.013,8.604C0.927,8.576 0.879,8.483 0.908,8.396Z" style="fill:white;"/>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-14.8673,-14.7971,14.7971,-14.8673,20.4244,16.9042)"><stop offset="0" style="stop-color:rgb(239,65,54);stop-opacity:1"/><stop offset="0.01" style="stop-color:rgb(239,65,54);stop-opacity:1"/><stop offset="0.32" style="stop-color:rgb(223,81,83);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(172,11,27);stop-opacity:1"/></linearGradient>
</defs>
<svg
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
xmlns:serif="http://www.serif.com/"
style="fill-rule: evenodd; clip-rule: evenodd"
>
<path
d="M12.985,0.812C13.949,0.812 14.279,0.928 14.929,1.155C15.091,1.211 15.273,1.275 15.49,1.345C19.947,2.795 23.25,7.071 23.25,12.005C23.25,12.829 23.133,13.721 22.963,14.506C22.196,17.622 20.213,20.269 17.543,21.804C16.213,22.568 14.67,23.131 13.068,23.239C12.8,23.257 11.93,23.249 11.339,23.243C11.126,23.241 10.95,23.239 10.85,23.239C5.061,22.419 0.75,18.142 0.75,12.005C0.75,10.447 1.047,8.887 1.653,7.454C2.282,5.968 3.362,4.699 4.486,3.6C5.476,2.634 6.7,2.1 7.906,1.574C8.081,1.498 8.255,1.422 8.428,1.345C9.05,1.068 9.469,1.008 9.996,0.932C10.214,0.9 10.45,0.866 10.727,0.812C11.214,0.719 11.726,0.75 12.234,0.781C12.486,0.797 12.738,0.812 12.985,0.812Z"
fill="url(#_MarsGradient)"
/>
<path
d="M12.985,0.812C13.949,0.812 14.279,0.928 14.929,1.155C15.091,1.211 15.273,1.275 15.49,1.345C19.947,2.795 23.25,7.071 23.25,12.005C23.25,12.829 23.133,13.721 22.963,14.506C22.196,17.622 20.213,20.269 17.543,21.804C16.213,22.568 14.67,23.131 13.068,23.239C12.8,23.257 11.93,23.249 11.339,23.243C11.126,23.241 10.95,23.239 10.85,23.239C5.061,22.419 0.75,18.142 0.75,12.005C0.75,10.447 1.047,8.887 1.653,7.454C2.282,5.968 3.362,4.699 4.486,3.6C5.476,2.634 6.7,2.1 7.906,1.574C8.081,1.498 8.255,1.422 8.428,1.345C9.05,1.068 9.469,1.008 9.996,0.932C10.214,0.9 10.45,0.866 10.727,0.812C11.214,0.719 11.726,0.75 12.234,0.781C12.486,0.797 12.738,0.812 12.985,0.812Z"
fill="none"
stroke-width="1px"
stroke="#FFFFFF"
/>
<path
d="M11.999,0.166L15.656,0.746L18.955,2.426L21.573,5.044L23.254,8.342L23.834,11.999L23.254,15.656L21.573,18.955L18.955,21.573L15.656,23.254L11.999,23.834L8.343,23.254L5.044,21.573L2.426,18.955L0.746,15.656L0.166,11.999L0.746,8.343L2.426,5.044L5.044,2.426L8.343,0.746L11.999,0.166ZM8.549,1.381L5.436,2.966L2.967,5.436L1.381,8.549L0.834,11.999L1.381,15.45L2.967,18.562L5.436,21.032L8.549,22.619L11.999,23.166L15.45,22.619L18.562,21.032L21.032,18.562L22.619,15.45L23.166,11.999L22.619,8.549L21.032,5.436L18.562,2.966L15.45,1.381L11.999,0.834L8.549,1.381Z"
fill="#FFFFFF"
/>
<path
d="M11.915,3.928C11.993,3.881 12.094,3.907 12.141,3.985L14.738,8.343C14.785,8.421 14.759,8.523 14.681,8.569C14.603,8.616 14.501,8.59 14.455,8.512L11.857,4.154C11.811,4.076 11.836,3.975 11.915,3.928Z"
fill="#FFFFFF"
/>
<path
d="M11.999,3.904L17.36,4.484L17.325,4.812L11.999,4.236L6.674,4.812L6.639,4.484L11.999,3.904Z"
fill="#FFFFFF"
/>
<path
d="M9.237,8.426C9.237,8.334 9.311,8.261 9.402,8.261L14.596,8.261C14.687,8.261 14.761,8.334 14.761,8.426C14.761,8.517 14.687,8.591 14.596,8.591L9.402,8.591C9.311,8.591 9.237,8.517 9.237,8.426Z"
fill="#FFFFFF"
/>
<path
d="M12.083,3.928C12.161,3.975 12.187,4.076 12.14,4.154L9.544,8.512C9.497,8.59 9.396,8.616 9.318,8.569C9.24,8.523 9.214,8.421 9.261,8.343L11.857,3.985C11.903,3.907 12.004,3.881 12.083,3.928Z"
fill="#FFFFFF"
/>
<path
d="M8.392,0.803L11.999,3.853L15.606,0.803L17.49,4.573L17.195,4.721L15.499,1.326L11.999,4.285L8.499,1.326L6.804,4.721L6.509,4.573L8.392,0.803Z"
fill="#FFFFFF"
/>
<path
d="M5.143,2.563C5.217,2.509 5.32,2.525 5.374,2.599L11.999,11.719L18.625,2.599C18.679,2.525 18.782,2.509 18.856,2.563C18.929,2.616 18.946,2.719 18.892,2.793L12.133,12.097C12.102,12.14 12.052,12.165 11.999,12.165C11.947,12.165 11.897,12.14 11.866,12.097L5.107,2.793C5.053,2.719 5.07,2.616 5.143,2.563Z"
fill="#FFFFFF"
/>
<path
d="M9.525,8.314C9.565,8.358 9.578,8.42 9.56,8.476L7.992,13.303L12.081,16.274L16.727,18.266C16.811,18.302 16.85,18.399 16.814,18.482C16.778,18.566 16.681,18.605 16.597,18.569L11.934,16.57C11.923,16.565 11.912,16.559 11.902,16.552L7.701,13.499C7.643,13.457 7.619,13.383 7.641,13.315L9.156,8.651L4.493,9.709C4.404,9.729 4.315,9.674 4.295,9.585C4.275,9.496 4.331,9.408 4.42,9.387L9.367,8.265C9.424,8.251 9.485,8.27 9.525,8.314Z"
fill="#FFFFFF"
/>
<path
d="M4.347,9.426C4.416,9.366 4.52,9.373 4.58,9.442L7.922,13.259C7.982,13.328 7.975,13.432 7.907,13.492C7.838,13.552 7.734,13.545 7.674,13.477L4.332,9.659C4.272,9.591 4.279,9.486 4.347,9.426Z"
fill="#FFFFFF"
/>
<path
d="M6.931,4.439L4.635,9.553L4.661,9.616L4.603,9.652L3.534,14.751L7.435,18.284L12.078,20.948L15.442,22.696L16.535,18.244L21.105,18.581L20.481,14.837L20.807,14.783L21.499,18.941L16.789,18.593L15.662,23.182L11.917,21.236L7.24,18.553L3.238,14.928L0.234,11.971L4.25,9.483L2.464,5.109L6.931,4.439ZM4.215,9.893L0.765,12.03L3.254,14.48L4.215,9.893ZM4.463,9.131L6.382,4.855L2.928,5.373L4.463,9.131Z"
fill="#FFFFFF"
/>
<path
d="M7.814,13.202C7.904,13.211 7.971,13.291 7.963,13.382L7.502,18.433C7.494,18.524 7.414,18.591 7.323,18.583C7.232,18.574 7.165,18.494 7.174,18.403L7.634,13.352C7.642,13.261 7.723,13.194 7.814,13.202Z"
fill="#FFFFFF"
/>
<path
d="M12.151,16.353C12.187,16.436 12.148,16.533 12.065,16.569L7.403,18.569C7.319,18.604 7.222,18.566 7.186,18.482C7.15,18.398 7.189,18.301 7.273,18.265L11.935,16.266C12.018,16.23 12.115,16.269 12.151,16.353Z"
fill="#FFFFFF"
/>
<path
d="M2.893,18.581L3.517,14.837L3.191,14.783L2.499,18.941L7.211,18.594L8.336,23.182L12.075,21.24L11.923,20.947L8.556,22.696L7.465,18.244L2.893,18.581Z"
fill="#FFFFFF"
/>
<path
d="M12.097,11.865C12.14,11.896 12.165,11.946 12.165,11.998L12.165,23.5C12.165,23.591 12.091,23.665 12,23.665C11.909,23.665 11.835,23.591 11.835,23.5L11.835,12.226L1.115,15.709C1.029,15.737 0.936,15.69 0.908,15.603C0.879,15.517 0.927,15.423 1.013,15.395L11.949,11.842C11.999,11.825 12.054,11.834 12.097,11.865Z"
fill="#FFFFFF"
/>
<path
d="M17.212,4.547C17.248,4.499 17.308,4.475 17.368,4.484L21.327,5.078C21.377,5.085 21.421,5.115 21.446,5.159C21.471,5.203 21.474,5.256 21.455,5.303L19.749,9.483L23.587,11.861C23.63,11.887 23.658,11.932 23.664,11.982C23.669,12.033 23.652,12.083 23.616,12.118L20.762,14.926L20.756,14.932L20.755,14.932C20.755,14.933 20.754,14.934 20.753,14.934L16.773,18.541C16.727,18.583 16.661,18.595 16.602,18.572C16.544,18.55 16.504,18.496 16.498,18.434L16.039,13.4L14.44,8.478C14.421,8.421 14.435,8.359 14.475,8.315C14.515,8.272 14.575,8.253 14.633,8.266L19.258,9.315L17.193,4.715C17.168,4.659 17.175,4.595 17.212,4.547ZM19.237,9.649L14.843,8.652L16.269,13.04L19.237,9.649ZM16.372,13.422L16.797,18.074L20.464,14.751L19.45,9.907L16.372,13.422ZM19.784,9.893L20.744,14.48L23.234,12.03L19.784,9.893ZM19.536,9.13L21.07,5.373L17.617,4.855L19.536,9.13Z"
fill="#FFFFFF"
/>
<path
d="M11.842,11.947C11.87,11.861 11.963,11.813 12.05,11.842L22.987,15.395C23.074,15.423 23.121,15.517 23.093,15.603C23.065,15.69 22.972,15.737 22.885,15.709L11.948,12.155C11.861,12.127 11.814,12.034 11.842,11.947Z"
fill="#FFFFFF"
/>
<path
d="M16.335,13.27C16.389,13.343 16.372,13.447 16.298,13.5L12.096,16.552C12.022,16.606 11.919,16.59 11.866,16.516C11.812,16.442 11.828,16.339 11.902,16.285L16.104,13.233C16.178,13.18 16.281,13.196 16.335,13.27Z"
fill="#FFFFFF"
/>
<path
d="M16.58,18.276C16.653,18.234 16.746,18.254 16.796,18.322L18.892,21.208C18.945,21.282 18.929,21.385 18.855,21.439C18.782,21.492 18.678,21.476 18.625,21.402L16.616,18.636L12.081,21.237C12.002,21.282 11.901,21.255 11.856,21.176C11.81,21.097 11.838,20.996 11.917,20.951L16.58,18.276Z"
fill="#FFFFFF"
/>
<path
d="M11.999,0.335C12.09,0.335 12.164,0.409 12.164,0.5L12.164,4.068C12.164,4.159 12.09,4.233 11.999,4.233C11.908,4.233 11.834,4.159 11.834,4.068L11.834,0.5C11.834,0.409 11.908,0.335 11.999,0.335Z"
fill="#FFFFFF"
/>
<path
d="M23.093,8.396C23.121,8.483 23.073,8.576 22.987,8.604L19.594,9.706C19.507,9.735 19.414,9.687 19.386,9.601C19.358,9.514 19.405,9.421 19.492,9.393L22.885,8.29C22.971,8.262 23.064,8.309 23.093,8.396Z"
fill="#FFFFFF"
/>
<path
d="M7.435,18.286C7.509,18.34 7.525,18.443 7.471,18.516L5.374,21.402C5.32,21.476 5.217,21.492 5.143,21.439C5.069,21.385 5.053,21.282 5.107,21.208L7.204,18.322C7.258,18.249 7.361,18.232 7.435,18.286Z"
fill="#FFFFFF"
/>
<path
d="M0.908,8.396C0.936,8.309 1.029,8.262 1.115,8.29L4.508,9.393C4.595,9.421 4.642,9.514 4.614,9.601C4.586,9.687 4.493,9.735 4.406,9.706L1.013,8.604C0.927,8.576 0.879,8.483 0.908,8.396Z"
fill="#FFFFFF"
/>
<defs>
<linearGradient
id="_MarsGradient"
x1="0"
y1="0"
x2="1"
y2="0"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-14.8673,-14.7971,14.7971,-14.8673,20.4244,16.9042)"
>
<stop offset="0" stop-color="rgb(239,65,54)" stop-opacity="1" />
<stop offset="0.01" stop-color="rgb(239,65,54)" stop-opacity="1" />
<stop offset="0.32" stop-color="rgb(223,81,83)" stop-opacity="1" />
<stop offset="1" stop-color="rgb(172,11,27)" stop-opacity="1" />
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

16
src/images/ntrn.svg Normal file
View File

@ -0,0 +1,16 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 24 24">
<path
fill="#FFF"
d="M23.6,14.9C22,21.3,15.5,25.2,9,23.6C2.6,22-1.3,15.5,0.3,9.1S8.4-1.2,14.8,0.4C21.3,2,25.2,8.5,23.6,14.9
L23.6,14.9L23.6,14.9z"
/>
<path
fill="#000"
d="M12,15.1c-1.7,0-3.1-1.4-3.1-3.1c0-0.6,0.2-1.2,0.5-1.6L5.4,7.1v11.5h11.5l-3.3-3.9C13.1,15,12.5,15.1,12,15.1z
"
/>
<path
fill="#000"
d="M6.4,5.4l3.5,4.2c0.5-0.5,1.3-0.8,2-0.8c1.7,0,3.1,1.4,3.1,3.1c0,0.7-0.3,1.4-0.7,2l4.1,3.6V5.4H6.4z"
/>
</svg>

After

Width:  |  Height:  |  Size: 543 B

View File

@ -1,18 +1,25 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
<path fill="#2775CA" d="M60,120c33.2,0,60-26.8,60-60S93.2,0,60,0S0,26.8,0,60S26.8,120,60,120z"/>
<path fill="#FFFFFF" d="M76.5,69.5c0-8.8-5.3-11.8-15.7-13c-7.5-1-9-3-9-6.5c0-3.5,2.5-5.8,7.5-5.8c4.5,0,7,1.5,8.2,5.3
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 120 120">
<path fill="#2775CA" d="M60,120c33.2,0,60-26.8,60-60S93.2,0,60,0S0,26.8,0,60S26.8,120,60,120z" />
<path
fill="#FFFFFF"
d="M76.5,69.5c0-8.8-5.3-11.8-15.7-13c-7.5-1-9-3-9-6.5c0-3.5,2.5-5.8,7.5-5.8c4.5,0,7,1.5,8.2,5.3
c0.2,0.8,1,1.3,1.7,1.3h4c1,0,1.7-0.8,1.7-1.7v-0.2c-1-5.5-5.5-9.7-11.2-10.3v-6c0-1-0.8-1.7-2-2H58c-1,0-1.7,0.7-2,2v5.8
c-7.5,1-12.2,6-12.2,12.2c0,8.2,5,11.5,15.5,12.7c7,1.3,9.2,2.8,9.2,6.7c0,4-3.5,6.7-8.2,6.7c-6.5,0-8.8-2.8-9.5-6.5
c-0.2-1-1-1.5-1.7-1.5h-4.3c-1,0-1.7,0.8-1.7,1.7v0.2c1,6.2,5,10.7,13.3,12v6c0,1,0.8,1.7,2,2H62c1,0,1.7-0.8,2-2v-6
C71.5,81.5,76.5,76.2,76.5,69.5L76.5,69.5z"/>
<path fill="#FFFFFF" d="M47.3,95.8c-19.5-7-29.5-28.7-22.3-48c3.8-10.5,12-18.5,22.3-22.3c1-0.5,1.5-1.3,1.5-2.5v-3.5
C71.5,81.5,76.5,76.2,76.5,69.5L76.5,69.5z"
/>
<path
fill="#FFFFFF"
d="M47.3,95.8c-19.5-7-29.5-28.7-22.3-48c3.8-10.5,12-18.5,22.3-22.3c1-0.5,1.5-1.3,1.5-2.5v-3.5
c0-1-0.5-1.7-1.5-2c-0.2,0-0.8,0-1,0.2C22.5,25.3,9.5,50.5,17,74.3c4.5,14,15.2,24.7,29.2,29.2c1,0.5,2,0,2.3-1
c0.2-0.2,0.2-0.5,0.2-1V98C48.7,97.2,48,96.2,47.3,95.8L47.3,95.8z M73.8,17.8c-1-0.5-2,0-2.3,1c-0.2,0.2-0.2,0.5-0.2,1v3.5
c0,1,0.8,2,1.5,2.5c19.5,7,29.5,28.7,22.3,48C91.2,84.3,83,92.3,72.7,96c-1,0.5-1.5,1.3-1.5,2.5v3.5c0,1,0.5,1.7,1.5,2
c0.2,0,0.8,0,1-0.2C97.5,96.3,110.5,71,103,47.3C98.5,33,87.5,22.3,73.8,17.8L73.8,17.8z"/>
<path d="M100,120c11,0,20-9,20-20s-9-20-20-20s-20,9-20,20S89,120,100,120z"/>
<path fill="#FFFFFF" d="M109.3,87c-2,0-3.5,1.6-3.5,3.6c0,0.5,0,1.1,0,1.6c-0.3-0.2-0.5-0.5-0.6-0.7
c0.2,0,0.8,0,1-0.2C97.5,96.3,110.5,71,103,47.3C98.5,33,87.5,22.3,73.8,17.8L73.8,17.8z"
/>
<path d="M100,120c11,0,20-9,20-20s-9-20-20-20s-20,9-20,20S89,120,100,120z" />
<path
fill="#FFFFFF"
d="M109.3,87c-2,0-3.5,1.6-3.5,3.6c0,0.5,0,1.1,0,1.6c-0.3-0.2-0.5-0.5-0.6-0.7
c-2.3-3.5-6.5-5.2-10.5-4.2c-4.3,1.1-7.4,4.5-7.6,8.8c-0.2,4.5-0.1,9.1,0,13.6c0,1.9,1.8,3.4,3.7,3.3c1.9-0.1,3.4-1.6,3.5-3.5
c0-0.6,0-1.1,0-1.7c0,0,0.1,0,0.1,0c0.2,0.3,0.3,0.5,0.5,0.8c2.3,3.6,6.8,5.2,10.9,4.1c4.1-1.1,7.1-4.9,7.2-9c0.1-4.3,0-8.7,0-13
C113,88.6,111.3,87,109.3,87z M93.4,95.9c-0.1,0.4-0.1,0.9-0.1,1.3c0,4,0,7.9,0,11.9c0,1.6-1,2.8-2.5,2.8c-1.6,0.1-2.7-1-2.7-2.7
@ -21,5 +28,6 @@
C95.6,93.1,93.9,94.1,93.4,95.9z M111.9,104c-0.1,4-3.5,7.4-7.5,7.9c-4.7,0.6-8.9-2.3-9.9-6.9c-0.2-1.1-0.2-2.2-0.2-3.3
c0-1.6,0-3.1,0-4.7c0-1.6,1.1-2.8,2.6-2.8c1.5,0,2.6,1.2,2.6,2.8c0,2,0,4,0,6.1c0,1.7,1,3,2.7,3.5c1.5,0.4,3.2-0.2,4-1.6
c0.3-0.6,0.5-1.3,0.5-1.9c0.1-2,0-4,0-6c0-2.1,0-4.2,0-6.3c0-1.1,0.5-2,1.5-2.5c1-0.4,1.9-0.3,2.7,0.3c0.7,0.5,1,1.3,1,2.1
C112,95.1,112.1,99.5,111.9,104z"/>
C112,95.1,112.1,99.5,111.9,104z"
/>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,340 +1,340 @@
<svg fill='none' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
<svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
d='M22.8084 4.42014C22.5667 3.50503 21.7897 2.58992 20.3912 1.57122C19.2689 0.759705 18.0775 0.293518 17.1279 0.293518C16.9379 0.293518 16.7653 0.310784 16.5926 0.345317C16.1609 0.431648 15.7811 0.742439 15.5394 1.20863C15.2458 1.76114 15.1768 2.50359 15.3667 2.95251C15.4358 3.09064 15.5221 3.2633 15.6257 3.4187C14.7106 3.97122 14.1926 4.12661 14.1235 4.14388C16.5063 4.93812 18.4919 6.59568 19.735 8.75395L19.7523 8.54676C19.8041 7.97697 19.9768 7.32086 20.2185 6.64748C20.4602 6.71654 20.702 6.75107 20.9437 6.75107C21.5825 6.75107 22.135 6.49208 22.4804 6.02589C22.8257 5.55971 22.9638 4.93812 22.8084 4.42014Z'
fill='#5E12A0'
d="M22.8084 4.42014C22.5667 3.50503 21.7897 2.58992 20.3912 1.57122C19.2689 0.759705 18.0775 0.293518 17.1279 0.293518C16.9379 0.293518 16.7653 0.310784 16.5926 0.345317C16.1609 0.431648 15.7811 0.742439 15.5394 1.20863C15.2458 1.76114 15.1768 2.50359 15.3667 2.95251C15.4358 3.09064 15.5221 3.2633 15.6257 3.4187C14.7106 3.97122 14.1926 4.12661 14.1235 4.14388C16.5063 4.93812 18.4919 6.59568 19.735 8.75395L19.7523 8.54676C19.8041 7.97697 19.9768 7.32086 20.2185 6.64748C20.4602 6.71654 20.702 6.75107 20.9437 6.75107C21.5825 6.75107 22.135 6.49208 22.4804 6.02589C22.8257 5.55971 22.9638 4.93812 22.8084 4.42014Z"
fill="#5E12A0"
></path>
<path
d='M20.3225 6.14679C21.8937 6.57844 22.5326 5.36981 22.3254 4.5583C22.1009 3.74679 21.3757 2.91801 20.098 1.98564C18.8203 1.05326 17.5254 0.673409 16.6966 0.846071C15.8678 1.01873 15.6261 2.27916 15.8333 2.76262C15.9196 2.95255 16.1096 3.2288 16.3685 3.5396C16.0405 3.76406 15.7297 3.93672 15.4707 4.09211C17.0592 4.80003 18.4405 5.90506 19.4765 7.28636C19.5973 6.82017 19.77 6.40578 19.9254 6.04319C20.0462 6.06046 20.1844 6.09499 20.3225 6.14679Z'
fill='url(#paint0_radial_8766_48743)'
d="M20.3225 6.14679C21.8937 6.57844 22.5326 5.36981 22.3254 4.5583C22.1009 3.74679 21.3757 2.91801 20.098 1.98564C18.8203 1.05326 17.5254 0.673409 16.6966 0.846071C15.8678 1.01873 15.6261 2.27916 15.8333 2.76262C15.9196 2.95255 16.1096 3.2288 16.3685 3.5396C16.0405 3.76406 15.7297 3.93672 15.4707 4.09211C17.0592 4.80003 18.4405 5.90506 19.4765 7.28636C19.5973 6.82017 19.77 6.40578 19.9254 6.04319C20.0462 6.06046 20.1844 6.09499 20.3225 6.14679Z"
fill="url(#paint0_radial_8766_48743)"
></path>
<path
d='M11.3266 23.0676C16.6572 23.0676 20.9784 18.7464 20.9784 13.4158C20.9784 8.08525 16.6572 3.76404 11.3266 3.76404C5.99601 3.76404 1.6748 8.08525 1.6748 13.4158C1.6748 18.7464 5.99601 23.0676 11.3266 23.0676Z'
fill='url(#paint1_radial_8766_48743)'
d="M11.3266 23.0676C16.6572 23.0676 20.9784 18.7464 20.9784 13.4158C20.9784 8.08525 16.6572 3.76404 11.3266 3.76404C5.99601 3.76404 1.6748 8.08525 1.6748 13.4158C1.6748 18.7464 5.99601 23.0676 11.3266 23.0676Z"
fill="url(#paint1_radial_8766_48743)"
></path>
<path
d='M21.5307 3.76403C20.2185 2.38274 19.1134 2.02015 17.784 1.72662C16.748 1.4849 17.0242 0.897845 18.2847 1.01871C17.6804 0.811514 17.1106 0.759716 16.6962 0.846047C15.8674 1.01871 15.6257 2.27914 15.8329 2.76259C15.9192 2.95252 16.1091 3.22878 16.3681 3.53957C15.9019 3.85036 15.5048 4.07482 15.1768 4.24749C15.3322 4.31655 15.5221 4.40288 15.7465 4.52375C16.3336 4.83454 16.9724 5.35252 16.9724 5.35252C16.0055 4.52375 16.2127 4.14389 17.5422 3.21151C17.9566 2.91799 18.7163 2.95252 19.4242 3.31511C20.1322 3.6777 20.9609 4.59281 20.9609 4.59281L20.1667 6.11223C20.2185 6.1295 20.2703 6.14677 20.3221 6.16403C20.8228 6.30216 21.2199 6.26763 21.5307 6.14677C21.8933 5.92231 22.8429 5.16259 21.5307 3.76403Z'
fill='#A98698'
fill-opacity='0.6'
d="M21.5307 3.76403C20.2185 2.38274 19.1134 2.02015 17.784 1.72662C16.748 1.4849 17.0242 0.897845 18.2847 1.01871C17.6804 0.811514 17.1106 0.759716 16.6962 0.846047C15.8674 1.01871 15.6257 2.27914 15.8329 2.76259C15.9192 2.95252 16.1091 3.22878 16.3681 3.53957C15.9019 3.85036 15.5048 4.07482 15.1768 4.24749C15.3322 4.31655 15.5221 4.40288 15.7465 4.52375C16.3336 4.83454 16.9724 5.35252 16.9724 5.35252C16.0055 4.52375 16.2127 4.14389 17.5422 3.21151C17.9566 2.91799 18.7163 2.95252 19.4242 3.31511C20.1322 3.6777 20.9609 4.59281 20.9609 4.59281L20.1667 6.11223C20.2185 6.1295 20.2703 6.14677 20.3221 6.16403C20.8228 6.30216 21.2199 6.26763 21.5307 6.14677C21.8933 5.92231 22.8429 5.16259 21.5307 3.76403Z"
fill="#A98698"
fill-opacity="0.6"
></path>
<path
d='M17.7671 2.55539C18.1124 2.69352 18.5613 2.93525 19.1138 3.29784C19.7699 3.72949 20.3397 4.21295 20.7023 4.5928C20.098 5.38705 19.7009 6.47482 19.4592 7.23453C19.58 7.40719 19.7181 7.57985 19.839 7.75252C19.9599 7.32086 20.1671 6.68201 20.4433 6.04316C20.5124 6.06043 20.5987 6.06043 20.6851 6.06043C20.8922 6.06043 21.134 6.0259 21.3239 5.8705C21.462 5.7669 21.6174 5.57698 21.6002 5.23165C21.6002 4.90359 21.3412 4.48921 20.8059 3.98849C20.4261 3.6259 19.9081 3.22878 19.3901 2.86619C17.9052 1.88201 16.8692 1.60575 16.403 2.07194C16.0922 2.38273 16.1268 2.76259 16.2304 3.03885C15.6779 3.40144 15.2117 3.66043 14.9009 3.83309C15.1081 3.90216 15.298 3.98849 15.5052 4.07482C16.0577 3.78129 16.852 3.28057 17.7671 2.55539ZM21.0304 5.02446C21.0822 5.11079 21.0994 5.19712 21.0994 5.24892C21.0994 5.40431 21.0476 5.45611 21.0131 5.49065C20.944 5.54244 20.8059 5.57698 20.6851 5.57698C20.7886 5.36978 20.9095 5.19712 21.0304 5.02446ZM16.7656 2.4518C16.8174 2.4 16.9556 2.36547 17.18 2.4C17.0074 2.53813 16.8347 2.65899 16.662 2.77985C16.6448 2.65899 16.662 2.53813 16.7656 2.4518Z'
fill='#5E12A0'
d="M17.7671 2.55539C18.1124 2.69352 18.5613 2.93525 19.1138 3.29784C19.7699 3.72949 20.3397 4.21295 20.7023 4.5928C20.098 5.38705 19.7009 6.47482 19.4592 7.23453C19.58 7.40719 19.7181 7.57985 19.839 7.75252C19.9599 7.32086 20.1671 6.68201 20.4433 6.04316C20.5124 6.06043 20.5987 6.06043 20.6851 6.06043C20.8922 6.06043 21.134 6.0259 21.3239 5.8705C21.462 5.7669 21.6174 5.57698 21.6002 5.23165C21.6002 4.90359 21.3412 4.48921 20.8059 3.98849C20.4261 3.6259 19.9081 3.22878 19.3901 2.86619C17.9052 1.88201 16.8692 1.60575 16.403 2.07194C16.0922 2.38273 16.1268 2.76259 16.2304 3.03885C15.6779 3.40144 15.2117 3.66043 14.9009 3.83309C15.1081 3.90216 15.298 3.98849 15.5052 4.07482C16.0577 3.78129 16.852 3.28057 17.7671 2.55539ZM21.0304 5.02446C21.0822 5.11079 21.0994 5.19712 21.0994 5.24892C21.0994 5.40431 21.0476 5.45611 21.0131 5.49065C20.944 5.54244 20.8059 5.57698 20.6851 5.57698C20.7886 5.36978 20.9095 5.19712 21.0304 5.02446ZM16.7656 2.4518C16.8174 2.4 16.9556 2.36547 17.18 2.4C17.0074 2.53813 16.8347 2.65899 16.662 2.77985C16.6448 2.65899 16.662 2.53813 16.7656 2.4518Z"
fill="#5E12A0"
></path>
<path
d='M11.3266 3.19427C5.68052 3.19427 1.10498 7.76981 1.10498 13.4159C1.10498 19.0619 5.68052 23.6374 11.3266 23.6374C16.9726 23.6374 21.5481 19.0619 21.5481 13.4159C21.5481 7.76981 16.9553 3.19427 11.3266 3.19427ZM11.3266 23.0677C5.99131 23.0677 1.67476 18.7511 1.67476 13.4159C1.67476 8.08061 5.99131 3.76406 11.3266 3.76406C16.6618 3.76406 20.9784 8.08061 20.9784 13.4159C20.9784 18.7511 16.6445 23.0677 11.3266 23.0677Z'
fill='#5E12A0'
d="M11.3266 3.19427C5.68052 3.19427 1.10498 7.76981 1.10498 13.4159C1.10498 19.0619 5.68052 23.6374 11.3266 23.6374C16.9726 23.6374 21.5481 19.0619 21.5481 13.4159C21.5481 7.76981 16.9553 3.19427 11.3266 3.19427ZM11.3266 23.0677C5.99131 23.0677 1.67476 18.7511 1.67476 13.4159C1.67476 8.08061 5.99131 3.76406 11.3266 3.76406C16.6618 3.76406 20.9784 8.08061 20.9784 13.4159C20.9784 18.7511 16.6445 23.0677 11.3266 23.0677Z"
fill="#5E12A0"
></path>
<path
d='M11.3266 23.0676C16.6572 23.0676 20.9784 18.7464 20.9784 13.4158C20.9784 8.08525 16.6572 3.76404 11.3266 3.76404C5.99601 3.76404 1.6748 8.08525 1.6748 13.4158C1.6748 18.7464 5.99601 23.0676 11.3266 23.0676Z'
fill='url(#paint2_linear_8766_48743)'
d="M11.3266 23.0676C16.6572 23.0676 20.9784 18.7464 20.9784 13.4158C20.9784 8.08525 16.6572 3.76404 11.3266 3.76404C5.99601 3.76404 1.6748 8.08525 1.6748 13.4158C1.6748 18.7464 5.99601 23.0676 11.3266 23.0676Z"
fill="url(#paint2_linear_8766_48743)"
></path>
<path
d='M11.2577 21.8935C5.99153 21.0475 2.41743 16.0921 3.28074 10.8259C3.6606 8.49494 4.8347 6.50933 6.49225 5.07623C4.07499 6.47479 2.2793 8.90933 1.79585 11.8791C0.949806 17.1453 4.52391 22.1007 9.77283 22.9467C12.7081 23.4302 15.5397 22.5151 17.6289 20.7194C15.7815 21.7899 13.5369 22.2561 11.2577 21.8935Z'
fill='#A98698'
fill-opacity='0.6'
d="M11.2577 21.8935C5.99153 21.0475 2.41743 16.0921 3.28074 10.8259C3.6606 8.49494 4.8347 6.50933 6.49225 5.07623C4.07499 6.47479 2.2793 8.90933 1.79585 11.8791C0.949806 17.1453 4.52391 22.1007 9.77283 22.9467C12.7081 23.4302 15.5397 22.5151 17.6289 20.7194C15.7815 21.7899 13.5369 22.2561 11.2577 21.8935Z"
fill="#A98698"
fill-opacity="0.6"
></path>
<path
d='M12.8631 3.90216C10.4285 3.50504 8.06307 4.05756 6.12926 5.28346C6.09473 5.31799 6.0602 5.35252 6.0602 5.35252C6.80264 4.9036 7.89041 4.50648 7.89041 4.50648C5.09329 6.1295 4.22998 7.97698 4.22998 7.97698C5.31775 5.87051 8.51199 4.38562 11.0156 4.28202C13.5192 4.17842 15.1595 4.92087 17.1624 6.52662C19.1652 8.14964 20.3739 11.4648 20.253 14.0892C20.1494 16.7137 18.7681 18.8374 18.7681 18.8374C19.7177 17.6115 20.2875 16.7137 20.6501 15.7986C20.7192 15.5223 20.7883 15.246 20.8228 14.9525C21.6861 9.7036 18.1293 4.74821 12.8631 3.90216Z'
fill='url(#paint3_linear_8766_48743)'
d="M12.8631 3.90216C10.4285 3.50504 8.06307 4.05756 6.12926 5.28346C6.09473 5.31799 6.0602 5.35252 6.0602 5.35252C6.80264 4.9036 7.89041 4.50648 7.89041 4.50648C5.09329 6.1295 4.22998 7.97698 4.22998 7.97698C5.31775 5.87051 8.51199 4.38562 11.0156 4.28202C13.5192 4.17842 15.1595 4.92087 17.1624 6.52662C19.1652 8.14964 20.3739 11.4648 20.253 14.0892C20.1494 16.7137 18.7681 18.8374 18.7681 18.8374C19.7177 17.6115 20.2875 16.7137 20.6501 15.7986C20.7192 15.5223 20.7883 15.246 20.8228 14.9525C21.6861 9.7036 18.1293 4.74821 12.8631 3.90216Z"
fill="url(#paint3_linear_8766_48743)"
></path>
<path
d='M20.4951 13.3295C20.4951 18.3885 16.3857 22.4978 11.3267 22.4978C6.26773 22.4978 2.14111 18.3885 2.14111 13.3295H20.4951Z'
fill='url(#paint4_linear_8766_48743)'
d="M20.4951 13.3295C20.4951 18.3885 16.3857 22.4978 11.3267 22.4978C6.26773 22.4978 2.14111 18.3885 2.14111 13.3295H20.4951Z"
fill="url(#paint4_linear_8766_48743)"
></path>
<path
d='M19.7696 13.3295C19.7696 18.2676 15.8675 22.3079 10.9639 22.4978H11.3265C16.3855 22.4978 20.4948 18.3885 20.4948 13.3295H19.7696Z'
fill='url(#paint5_linear_8766_48743)'
d="M19.7696 13.3295C19.7696 18.2676 15.8675 22.3079 10.9639 22.4978H11.3265C16.3855 22.4978 20.4948 18.3885 20.4948 13.3295H19.7696Z"
fill="url(#paint5_linear_8766_48743)"
></path>
<path
d='M3.43608 13.3295H2.14111C2.14111 18.3885 6.25047 22.4978 11.3095 22.4978C11.5339 22.4978 11.7411 22.4978 11.9483 22.4805C7.20011 22.1352 3.43608 18.164 3.43608 13.3295Z'
fill='url(#paint6_linear_8766_48743)'
d="M3.43608 13.3295H2.14111C2.14111 18.3885 6.25047 22.4978 11.3095 22.4978C11.5339 22.4978 11.7411 22.4978 11.9483 22.4805C7.20011 22.1352 3.43608 18.164 3.43608 13.3295Z"
fill="url(#paint6_linear_8766_48743)"
></path>
<path
d='M20.4778 13.4158C20.4778 12.3626 18.6476 11.7583 16.2131 11.5511C14.4519 11.413 12.6735 11.5856 10.6361 12.2072C8.87493 12.7252 7.28644 12.6389 6.1296 12.5007C3.55694 12.2072 2.14111 12.1727 2.14111 13.4158C2.14111 15.2115 5.80155 17.4561 11.2922 16.6792C14.072 16.282 15.5051 15.4705 17.1454 14.918C18.9238 14.331 20.4778 14.3482 20.4778 13.4158Z'
fill='url(#paint7_linear_8766_48743)'
d="M20.4778 13.4158C20.4778 12.3626 18.6476 11.7583 16.2131 11.5511C14.4519 11.413 12.6735 11.5856 10.6361 12.2072C8.87493 12.7252 7.28644 12.6389 6.1296 12.5007C3.55694 12.2072 2.14111 12.1727 2.14111 13.4158C2.14111 15.2115 5.80155 17.4561 11.2922 16.6792C14.072 16.282 15.5051 15.4705 17.1454 14.918C18.9238 14.331 20.4778 14.3482 20.4778 13.4158Z"
fill="url(#paint7_linear_8766_48743)"
></path>
<path
d='M14.3308 9.06476C15.1891 9.06476 15.8848 8.36911 15.8848 7.5108C15.8848 6.6525 15.1891 5.95685 14.3308 5.95685C13.4725 5.95685 12.7769 6.6525 12.7769 7.5108C12.7769 8.36911 13.4725 9.06476 14.3308 9.06476Z'
fill='white'
d="M14.3308 9.06476C15.1891 9.06476 15.8848 8.36911 15.8848 7.5108C15.8848 6.6525 15.1891 5.95685 14.3308 5.95685C13.4725 5.95685 12.7769 6.6525 12.7769 7.5108C12.7769 8.36911 13.4725 9.06476 14.3308 9.06476Z"
fill="white"
></path>
<path
d='M16.869 10.2216C17.2314 10.2216 17.5251 9.9279 17.5251 9.56548C17.5251 9.20306 17.2314 8.90936 16.869 8.90936C16.5066 8.90936 16.2129 9.20306 16.2129 9.56548C16.2129 9.9279 16.5066 10.2216 16.869 10.2216Z'
fill='white'
d="M16.869 10.2216C17.2314 10.2216 17.5251 9.9279 17.5251 9.56548C17.5251 9.20306 17.2314 8.90936 16.869 8.90936C16.5066 8.90936 16.2129 9.20306 16.2129 9.56548C16.2129 9.9279 16.5066 10.2216 16.869 10.2216Z"
fill="white"
></path>
<path
d='M19.2175 6.2676H19.1829C19.0793 6.25034 19.0103 6.14674 19.0275 6.02588C19.1829 5.23163 19.8391 4.47192 19.8736 4.43739C19.9427 4.35106 20.0808 4.35106 20.1498 4.42012C20.2362 4.48919 20.2362 4.62732 20.1671 4.69638C20.1498 4.71365 19.5455 5.42156 19.4074 6.11221C19.3901 6.2158 19.3038 6.2676 19.2175 6.2676Z'
fill='url(#paint8_linear_8766_48743)'
d="M19.2175 6.2676H19.1829C19.0793 6.25034 19.0103 6.14674 19.0275 6.02588C19.1829 5.23163 19.8391 4.47192 19.8736 4.43739C19.9427 4.35106 20.0808 4.35106 20.1498 4.42012C20.2362 4.48919 20.2362 4.62732 20.1671 4.69638C20.1498 4.71365 19.5455 5.42156 19.4074 6.11221C19.3901 6.2158 19.3038 6.2676 19.2175 6.2676Z"
fill="url(#paint8_linear_8766_48743)"
></path>
<path
d='M10.6876 20.6158C10.9545 20.6158 11.171 20.3993 11.171 20.1324C11.171 19.8654 10.9545 19.6489 10.6876 19.6489C10.4206 19.6489 10.2041 19.8654 10.2041 20.1324C10.2041 20.3993 10.4206 20.6158 10.6876 20.6158Z'
fill='white'
fill-opacity='0.2'
d="M10.6876 20.6158C10.9545 20.6158 11.171 20.3993 11.171 20.1324C11.171 19.8654 10.9545 19.6489 10.6876 19.6489C10.4206 19.6489 10.2041 19.8654 10.2041 20.1324C10.2041 20.3993 10.4206 20.6158 10.6876 20.6158Z"
fill="white"
fill-opacity="0.2"
></path>
<path
d='M10.4117 20.4432C10.2218 20.2532 10.2218 19.9425 10.4117 19.7525C10.4462 19.718 10.4808 19.7007 10.5153 19.6662C10.4462 19.6835 10.3944 19.718 10.3426 19.7698C10.1527 19.9597 10.1527 20.2705 10.3426 20.4604C10.498 20.6158 10.7398 20.6504 10.9297 20.5468C10.757 20.6158 10.5498 20.5813 10.4117 20.4432Z'
fill='url(#paint9_linear_8766_48743)'
d="M10.4117 20.4432C10.2218 20.2532 10.2218 19.9425 10.4117 19.7525C10.4462 19.718 10.4808 19.7007 10.5153 19.6662C10.4462 19.6835 10.3944 19.718 10.3426 19.7698C10.1527 19.9597 10.1527 20.2705 10.3426 20.4604C10.498 20.6158 10.7398 20.6504 10.9297 20.5468C10.757 20.6158 10.5498 20.5813 10.4117 20.4432Z"
fill="url(#paint9_linear_8766_48743)"
></path>
<path
d='M10.8604 19.9942C10.9176 19.9942 10.964 19.9478 10.964 19.8906C10.964 19.8335 10.9176 19.787 10.8604 19.787C10.8033 19.787 10.7568 19.8335 10.7568 19.8906C10.7568 19.9478 10.8033 19.9942 10.8604 19.9942Z'
fill='white'
fill-opacity='0.3'
d="M10.8604 19.9942C10.9176 19.9942 10.964 19.9478 10.964 19.8906C10.964 19.8335 10.9176 19.787 10.8604 19.787C10.8033 19.787 10.7568 19.8335 10.7568 19.8906C10.7568 19.9478 10.8033 19.9942 10.8604 19.9942Z"
fill="white"
fill-opacity="0.3"
></path>
<path
d='M13.2086 20.3741C13.4755 20.3741 13.692 20.1576 13.692 19.8906C13.692 19.6237 13.4755 19.4072 13.2086 19.4072C12.9416 19.4072 12.7251 19.6237 12.7251 19.8906C12.7251 20.1576 12.9416 20.3741 13.2086 20.3741Z'
fill='white'
fill-opacity='0.2'
d="M13.2086 20.3741C13.4755 20.3741 13.692 20.1576 13.692 19.8906C13.692 19.6237 13.4755 19.4072 13.2086 19.4072C12.9416 19.4072 12.7251 19.6237 12.7251 19.8906C12.7251 20.1576 12.9416 20.3741 13.2086 20.3741Z"
fill="white"
fill-opacity="0.2"
></path>
<path
d='M12.9322 20.2014C12.7423 20.0115 12.7423 19.7007 12.9322 19.5108C12.9667 19.4762 13.0013 19.459 13.0358 19.4244C12.9667 19.4417 12.9149 19.4762 12.8631 19.528C12.6732 19.718 12.6732 20.0288 12.8631 20.2187C13.0185 20.3741 13.2603 20.4086 13.4502 20.305C13.2775 20.3741 13.0703 20.3395 12.9322 20.2014Z'
fill='url(#paint10_linear_8766_48743)'
d="M12.9322 20.2014C12.7423 20.0115 12.7423 19.7007 12.9322 19.5108C12.9667 19.4762 13.0013 19.459 13.0358 19.4244C12.9667 19.4417 12.9149 19.4762 12.8631 19.528C12.6732 19.718 12.6732 20.0288 12.8631 20.2187C13.0185 20.3741 13.2603 20.4086 13.4502 20.305C13.2775 20.3741 13.0703 20.3395 12.9322 20.2014Z"
fill="url(#paint10_linear_8766_48743)"
></path>
<path
d='M13.3814 19.7525C13.4386 19.7525 13.485 19.7061 13.485 19.6489C13.485 19.5918 13.4386 19.5453 13.3814 19.5453C13.3243 19.5453 13.2778 19.5918 13.2778 19.6489C13.2778 19.7061 13.3243 19.7525 13.3814 19.7525Z'
fill='white'
fill-opacity='0.3'
d="M13.3814 19.7525C13.4386 19.7525 13.485 19.7061 13.485 19.6489C13.485 19.5918 13.4386 19.5453 13.3814 19.5453C13.3243 19.5453 13.2778 19.5918 13.2778 19.6489C13.2778 19.7061 13.3243 19.7525 13.3814 19.7525Z"
fill="white"
fill-opacity="0.3"
></path>
<path
d='M11.9656 21.4964C12.1659 21.4964 12.3282 21.3341 12.3282 21.1338C12.3282 20.9335 12.1659 20.7712 11.9656 20.7712C11.7653 20.7712 11.603 20.9335 11.603 21.1338C11.603 21.3341 11.7653 21.4964 11.9656 21.4964Z'
fill='white'
fill-opacity='0.2'
d="M11.9656 21.4964C12.1659 21.4964 12.3282 21.3341 12.3282 21.1338C12.3282 20.9335 12.1659 20.7712 11.9656 20.7712C11.7653 20.7712 11.603 20.9335 11.603 21.1338C11.603 21.3341 11.7653 21.4964 11.9656 21.4964Z"
fill="white"
fill-opacity="0.2"
></path>
<path
d='M11.7584 21.3583C11.6203 21.2202 11.6203 20.9784 11.7584 20.8403C11.7757 20.823 11.8102 20.8058 11.8275 20.7885C11.7757 20.8058 11.7412 20.8403 11.7066 20.8748C11.5685 21.013 11.5685 21.2547 11.7066 21.3928C11.8275 21.5137 12.0002 21.531 12.1555 21.4446C12.0174 21.4964 11.862 21.4619 11.7584 21.3583Z'
fill='url(#paint11_linear_8766_48743)'
d="M11.7584 21.3583C11.6203 21.2202 11.6203 20.9784 11.7584 20.8403C11.7757 20.823 11.8102 20.8058 11.8275 20.7885C11.7757 20.8058 11.7412 20.8403 11.7066 20.8748C11.5685 21.013 11.5685 21.2547 11.7066 21.3928C11.8275 21.5137 12.0002 21.531 12.1555 21.4446C12.0174 21.4964 11.862 21.4619 11.7584 21.3583Z"
fill="url(#paint11_linear_8766_48743)"
></path>
<path
d='M12.0862 21.0129C12.1243 21.0129 12.1552 20.982 12.1552 20.9439C12.1552 20.9057 12.1243 20.8748 12.0862 20.8748C12.048 20.8748 12.0171 20.9057 12.0171 20.9439C12.0171 20.982 12.048 21.0129 12.0862 21.0129Z'
fill='white'
fill-opacity='0.3'
d="M12.0862 21.0129C12.1243 21.0129 12.1552 20.982 12.1552 20.9439C12.1552 20.9057 12.1243 20.8748 12.0862 20.8748C12.048 20.8748 12.0171 20.9057 12.0171 20.9439C12.0171 20.982 12.048 21.0129 12.0862 21.0129Z"
fill="white"
fill-opacity="0.3"
></path>
<path
d='M14.1927 21.2374C14.393 21.2374 14.5553 21.0751 14.5553 20.8748C14.5553 20.6745 14.393 20.5122 14.1927 20.5122C13.9924 20.5122 13.8301 20.6745 13.8301 20.8748C13.8301 21.0751 13.9924 21.2374 14.1927 21.2374Z'
fill='white'
fill-opacity='0.2'
d="M14.1927 21.2374C14.393 21.2374 14.5553 21.0751 14.5553 20.8748C14.5553 20.6745 14.393 20.5122 14.1927 20.5122C13.9924 20.5122 13.8301 20.6745 13.8301 20.8748C13.8301 21.0751 13.9924 21.2374 14.1927 21.2374Z"
fill="white"
fill-opacity="0.2"
></path>
<path
d='M13.9855 21.0993C13.8473 20.9611 13.8473 20.7194 13.9855 20.5813C14.0027 20.564 14.0373 20.5467 14.0545 20.5295C14.0027 20.5467 13.9682 20.5813 13.9337 20.6158C13.7955 20.7539 13.7955 20.9957 13.9337 21.1338C14.0545 21.2547 14.2272 21.2719 14.3826 21.1856C14.2445 21.2374 14.0891 21.2029 13.9855 21.0993Z'
fill='url(#paint12_linear_8766_48743)'
d="M13.9855 21.0993C13.8473 20.9611 13.8473 20.7194 13.9855 20.5813C14.0027 20.564 14.0373 20.5467 14.0545 20.5295C14.0027 20.5467 13.9682 20.5813 13.9337 20.6158C13.7955 20.7539 13.7955 20.9957 13.9337 21.1338C14.0545 21.2547 14.2272 21.2719 14.3826 21.1856C14.2445 21.2374 14.0891 21.2029 13.9855 21.0993Z"
fill="url(#paint12_linear_8766_48743)"
></path>
<path
d='M14.3137 20.754C14.3519 20.754 14.3828 20.7231 14.3828 20.6849C14.3828 20.6468 14.3519 20.6158 14.3137 20.6158C14.2755 20.6158 14.2446 20.6468 14.2446 20.6849C14.2446 20.7231 14.2755 20.754 14.3137 20.754Z'
fill='white'
fill-opacity='0.3'
d="M14.3137 20.754C14.3519 20.754 14.3828 20.7231 14.3828 20.6849C14.3828 20.6468 14.3519 20.6158 14.3137 20.6158C14.2755 20.6158 14.2446 20.6468 14.2446 20.6849C14.2446 20.7231 14.2755 20.754 14.3137 20.754Z"
fill="white"
fill-opacity="0.3"
></path>
<path
d='M8.63311 20.4432C9.07185 20.4432 9.42736 20.0877 9.42736 19.6489C9.42736 19.2104 9.07185 18.8547 8.63311 18.8547C8.19455 18.8547 7.83887 19.2104 7.83887 19.6489C7.83887 20.0877 8.19455 20.4432 8.63311 20.4432Z'
fill='white'
fill-opacity='0.2'
d="M8.63311 20.4432C9.07185 20.4432 9.42736 20.0877 9.42736 19.6489C9.42736 19.2104 9.07185 18.8547 8.63311 18.8547C8.19455 18.8547 7.83887 19.2104 7.83887 19.6489C7.83887 20.0877 8.19455 20.4432 8.63311 20.4432Z"
fill="white"
fill-opacity="0.2"
></path>
<path
d='M8.18435 20.1497C7.87356 19.8389 7.87356 19.3381 8.18435 19.0274C8.23615 18.9756 8.28794 18.941 8.35701 18.9065C8.25341 18.941 8.16708 19.0101 8.08075 19.0792C7.76996 19.3899 7.76996 19.8907 8.08075 20.2015C8.33974 20.4605 8.73687 20.5122 9.04766 20.3223C8.75413 20.4432 8.40881 20.3914 8.18435 20.1497Z'
fill='url(#paint13_linear_8766_48743)'
d="M8.18435 20.1497C7.87356 19.8389 7.87356 19.3381 8.18435 19.0274C8.23615 18.9756 8.28794 18.941 8.35701 18.9065C8.25341 18.941 8.16708 19.0101 8.08075 19.0792C7.76996 19.3899 7.76996 19.8907 8.08075 20.2015C8.33974 20.4605 8.73687 20.5122 9.04766 20.3223C8.75413 20.4432 8.40881 20.3914 8.18435 20.1497Z"
fill="url(#paint13_linear_8766_48743)"
></path>
<path
d='M8.90948 19.4072C9.00479 19.4072 9.08214 19.3299 9.08214 19.2346C9.08214 19.1392 9.00479 19.0619 8.90948 19.0619C8.81417 19.0619 8.73682 19.1392 8.73682 19.2346C8.73682 19.3299 8.81417 19.4072 8.90948 19.4072Z'
fill='white'
fill-opacity='0.3'
d="M8.90948 19.4072C9.00479 19.4072 9.08214 19.3299 9.08214 19.2346C9.08214 19.1392 9.00479 19.0619 8.90948 19.0619C8.81417 19.0619 8.73682 19.1392 8.73682 19.2346C8.73682 19.3299 8.81417 19.4072 8.90948 19.4072Z"
fill="white"
fill-opacity="0.3"
></path>
<path
d='M15.7293 18.4921C16.168 18.4921 16.5235 18.1366 16.5235 17.6979C16.5235 17.2593 16.168 16.9036 15.7293 16.9036C15.2907 16.9036 14.9351 17.2593 14.9351 17.6979C14.9351 18.1366 15.2907 18.4921 15.7293 18.4921Z'
fill='white'
fill-opacity='0.2'
d="M15.7293 18.4921C16.168 18.4921 16.5235 18.1366 16.5235 17.6979C16.5235 17.2593 16.168 16.9036 15.7293 16.9036C15.2907 16.9036 14.9351 17.2593 14.9351 17.6979C14.9351 18.1366 15.2907 18.4921 15.7293 18.4921Z"
fill="white"
fill-opacity="0.2"
></path>
<path
d='M15.2634 18.1985C14.9527 17.8878 14.9527 17.387 15.2634 17.0762C15.3152 17.0244 15.367 16.9899 15.4361 16.9554C15.3325 16.9899 15.2462 17.059 15.1599 17.128C14.8491 17.4388 14.8491 17.9396 15.1599 18.2503C15.4188 18.5093 15.816 18.5611 16.1268 18.3712C15.8332 18.4921 15.5052 18.4403 15.2634 18.1985Z'
fill='url(#paint14_linear_8766_48743)'
d="M15.2634 18.1985C14.9527 17.8878 14.9527 17.387 15.2634 17.0762C15.3152 17.0244 15.367 16.9899 15.4361 16.9554C15.3325 16.9899 15.2462 17.059 15.1599 17.128C14.8491 17.4388 14.8491 17.9396 15.1599 18.2503C15.4188 18.5093 15.816 18.5611 16.1268 18.3712C15.8332 18.4921 15.5052 18.4403 15.2634 18.1985Z"
fill="url(#paint14_linear_8766_48743)"
></path>
<path
d='M16.0057 17.4561C16.101 17.4561 16.1783 17.3788 16.1783 17.2834C16.1783 17.1881 16.101 17.1108 16.0057 17.1108C15.9104 17.1108 15.833 17.1881 15.833 17.2834C15.833 17.3788 15.9104 17.4561 16.0057 17.4561Z'
fill='white'
fill-opacity='0.3'
d="M16.0057 17.4561C16.101 17.4561 16.1783 17.3788 16.1783 17.2834C16.1783 17.1881 16.101 17.1108 16.0057 17.1108C15.9104 17.1108 15.833 17.1881 15.833 17.2834C15.833 17.3788 15.9104 17.4561 16.0057 17.4561Z"
fill="white"
fill-opacity="0.3"
></path>
<defs>
<radialGradient
cx='0'
cy='0'
gradientTransform='translate(22.0104 3.47051) scale(7.71702 7.71702)'
gradientUnits='userSpaceOnUse'
id='paint0_radial_8766_48743'
r='1'
cx="0"
cy="0"
gradientTransform="translate(22.0104 3.47051) scale(7.71702 7.71702)"
gradientUnits="userSpaceOnUse"
id="paint0_radial_8766_48743"
r="1"
>
<stop stop-color='#FFEAFF' stop-opacity='0.6'></stop>
<stop offset='0.68' stop-color='#A087C9'></stop>
<stop offset='1' stop-color='#10002F'></stop>
<stop stop-color="#FFEAFF" stop-opacity="0.6"></stop>
<stop offset="0.68" stop-color="#A087C9"></stop>
<stop offset="1" stop-color="#10002F"></stop>
</radialGradient>
<radialGradient
cx='0'
cy='0'
gradientTransform='translate(17.7169 6.76169) scale(18.8808)'
gradientUnits='userSpaceOnUse'
id='paint1_radial_8766_48743'
r='1'
cx="0"
cy="0"
gradientTransform="translate(17.7169 6.76169) scale(18.8808)"
gradientUnits="userSpaceOnUse"
id="paint1_radial_8766_48743"
r="1"
>
<stop stop-color='#FFEAFF' stop-opacity='0.6'></stop>
<stop offset='0.68' stop-color='#A087C9'></stop>
<stop offset='1' stop-color='#10002F'></stop>
<stop stop-color="#FFEAFF" stop-opacity="0.6"></stop>
<stop offset="0.68" stop-color="#A087C9"></stop>
<stop offset="1" stop-color="#10002F"></stop>
</radialGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint2_linear_8766_48743'
x1='9.77838'
x2='12.8655'
y1='22.9307'
y2='3.8849'
gradientUnits="userSpaceOnUse"
id="paint2_linear_8766_48743"
x1="9.77838"
x2="12.8655"
y1="22.9307"
y2="3.8849"
>
<stop stop-color='#81FFFF' stop-opacity='0.6'></stop>
<stop offset='0.62' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="#81FFFF" stop-opacity="0.6"></stop>
<stop offset="0.62" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint3_linear_8766_48743'
x1='18.1284'
x2='10.1473'
y1='6.861'
y2='14.1839'
gradientUnits="userSpaceOnUse"
id="paint3_linear_8766_48743"
x1="18.1284"
x2="10.1473"
y1="6.861"
y2="14.1839"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint4_linear_8766_48743'
x1='2.14889'
x2='20.4906'
y1='17.9083'
y2='17.9083'
gradientUnits="userSpaceOnUse"
id="paint4_linear_8766_48743"
x1="2.14889"
x2="20.4906"
y1="17.9083"
y2="17.9083"
>
<stop stop-color='#0002E9'></stop>
<stop offset='1' stop-color='#FF00C7'></stop>
<stop stop-color="#0002E9"></stop>
<stop offset="1" stop-color="#FF00C7"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint5_linear_8766_48743'
x1='21.3586'
x2='11.3753'
y1='14.134'
y2='23.5688'
gradientUnits="userSpaceOnUse"
id="paint5_linear_8766_48743"
x1="21.3586"
x2="11.3753"
y1="14.134"
y2="23.5688"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint6_linear_8766_48743'
x1='2.14889'
x2='11.9616'
y1='17.9083'
y2='17.9083'
gradientUnits="userSpaceOnUse"
id="paint6_linear_8766_48743"
x1="2.14889"
x2="11.9616"
y1="17.9083"
y2="17.9083"
>
<stop stop-color='#000292' stop-opacity='0.7'></stop>
<stop offset='1' stop-color='#7D00C7' stop-opacity='0.7'></stop>
<stop stop-color="#000292" stop-opacity="0.7"></stop>
<stop offset="1" stop-color="#7D00C7" stop-opacity="0.7"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint7_linear_8766_48743'
x1='2.1612'
x2='20.4784'
y1='14.1775'
y2='14.1775'
gradientUnits="userSpaceOnUse"
id="paint7_linear_8766_48743"
x1="2.1612"
x2="20.4784"
y1="14.1775"
y2="14.1775"
>
<stop stop-color='#000292'></stop>
<stop offset='1' stop-color='#BE00C7'></stop>
<stop stop-color="#000292"></stop>
<stop offset="1" stop-color="#BE00C7"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint8_linear_8766_48743'
x1='20.1778'
x2='18.8614'
y1='4.3533'
y2='6.49258'
gradientUnits="userSpaceOnUse"
id="paint8_linear_8766_48743"
x1="20.1778"
x2="18.8614"
y1="4.3533"
y2="6.49258"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint9_linear_8766_48743'
x1='10.1997'
x2='10.9302'
y1='20.1472'
y2='20.1472'
gradientUnits="userSpaceOnUse"
id="paint9_linear_8766_48743"
x1="10.1997"
x2="10.9302"
y1="20.1472"
y2="20.1472"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint10_linear_8766_48743'
x1='12.7185'
x2='13.449'
y1='19.9022'
y2='19.9022'
gradientUnits="userSpaceOnUse"
id="paint10_linear_8766_48743"
x1="12.7185"
x2="13.449"
y1="19.9022"
y2="19.9022"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint11_linear_8766_48743'
x1='11.6008'
x2='12.1492'
y1='21.138'
y2='21.138'
gradientUnits="userSpaceOnUse"
id="paint11_linear_8766_48743"
x1="11.6008"
x2="12.1492"
y1="21.138"
y2="21.138"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint12_linear_8766_48743'
x1='13.8204'
x2='14.3688'
y1='20.8783'
y2='20.8783'
gradientUnits="userSpaceOnUse"
id="paint12_linear_8766_48743"
x1="13.8204"
x2="14.3688"
y1="20.8783"
y2="20.8783"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint13_linear_8766_48743'
x1='7.83973'
x2='9.03272'
y1='19.6691'
y2='19.6691'
gradientUnits="userSpaceOnUse"
id="paint13_linear_8766_48743"
x1="7.83973"
x2="9.03272"
y1="19.6691"
y2="19.6691"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
<linearGradient
gradientUnits='userSpaceOnUse'
id='paint14_linear_8766_48743'
x1='14.9254'
x2='16.1184'
y1='17.7175'
y2='17.7175'
gradientUnits="userSpaceOnUse"
id="paint14_linear_8766_48743"
x1="14.9254"
x2="16.1184"
y1="17.7175"
y2="17.7175"
>
<stop stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.29' stop-color='white' stop-opacity='0.6'></stop>
<stop offset='0.78' stop-color='white' stop-opacity='0'></stop>
<stop offset='1' stop-color='white' stop-opacity='0'></stop>
<stop stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.29" stop-color="white" stop-opacity="0.6"></stop>
<stop offset="0.78" stop-color="white" stop-opacity="0"></stop>
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
</linearGradient>
</defs>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -1,8 +1,9 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 2500 2500" style="enable-background:new 0 0 2500 2500;" xml:space="preserve">
<circle style="fill:#E50571;" cx="1250" cy="1250" r="1250"/>
<circle style="fill:#FFFFFF;" cx="1250" cy="1250" r="128.6"/>
<path style="fill:#FFFFFF;" d="M1709.1,1253.5c336.5-233.9,543.2-454.9,491.6-544.9c-33.3-58.1-168.1-50.8-359.4,8.1
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 2500 2500">
<circle fill="#e50571" cx="1250" cy="1250" r="1250" />
<circle fill="#ffffff" cx="1250" cy="1250" r="128.6" />
<path
fill="#ffffff"
d="M1709.1,1253.5c336.5-233.9,543.2-454.9,491.6-544.9c-33.3-58.1-168.1-50.8-359.4,8.1
c-13-22.6-36.8-37.7-64.1-37.7c-41.2,0-74.6,34.5-74.6,77.2c0,2.8,0.2,5.6,0.4,8.3c-69.8,26.5-144.5,58.1-222.5,94.3
c-35.3-409.1-124.1-699.3-228-699.3c-103.7,0-192.4,289.3-227.8,697.4c-370.9-173.9-665.9-242-718-152.1
c-32.5,56.3,35.9,164.2,173.9,294.7c-1.5,6.1-2.3,12.5-2.3,19.1c0,42.6,33.4,77.2,74.6,77.2c10.5,0,20.5-2.3,29.6-6.3
@ -34,5 +35,6 @@
c0-41.1-31-74.7-70.2-77c-12.9-83.4-22.1-174.2-28.5-265.2c57.8-27.8,117.3-58,177.7-90.4c61.7,33.4,122.3,64.5,181.2,93.1
C1416.1,1800.5,1393.7,1929,1393.7,1929z M2147.6,1782.8c-51.1,23.4-188.1-11.5-188.1-11.5c-180.4-48.4-345.3-113.9-475.1-173.2
c4.9-65.8,8.4-134.4,10.5-205.1c59.6-36.5,116.7-73.3,170.8-109.9c414.9,300.9,482,436.8,492.5,477.1
C2160.7,1769.5,2156.1,1778.9,2147.6,1782.8z"/>
C2160.7,1769.5,2156.1,1778.9,2147.6,1782.8z"
/>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

39
src/libs/chainId.ts Normal file
View File

@ -0,0 +1,39 @@
import { ChainInfoID } from '@marsprotocol/wallet-connector'
import { CHAIN_ID_KEY, SUPPORTED_CHAINS } from 'constants/appConstants'
export const getCurrentChainId = () => {
let chainId = SUPPORTED_CHAINS[0].chainId
if (window) {
const subdomain = window.location.hostname.split('.')[0]
switch (subdomain) {
case 'osmosis':
chainId = ChainInfoID.Osmosis1
break
case 'neutron':
chainId = ChainInfoID.Neutron
break
case 'testnet-osmosis':
chainId = ChainInfoID.OsmosisTestnet
break
case 'testnet-neutron':
chainId = ChainInfoID.NeutronTestnet
break
}
if (chainId != SUPPORTED_CHAINS[0].chainId) return chainId
}
if (localStorage.getItem(CHAIN_ID_KEY) !== null) {
const isValidChainId = SUPPORTED_CHAINS.find(
(chain) => chain.chainId === localStorage.getItem(CHAIN_ID_KEY),
)
if (isValidChainId) chainId = localStorage.getItem(CHAIN_ID_KEY) as ChainInfoID
}
return chainId
}

View File

@ -1,9 +1,12 @@
import { WalletID } from '@marsprotocol/wallet-connector'
import { NETWORK } from 'constants/env'
import { ChainInfoID, WalletID } from '@marsprotocol/wallet-connector'
import { SUPPORTED_CHAINS } from 'constants/appConstants'
import { DocURL } from 'types/enums/docURL'
export function getCouncilLink(currentProvider?: WalletID): string {
if (NETWORK !== 'mainnet') return DocURL.COUNCIL_TESTNET_URL
export function getCouncilLink(currentNetwork: ChainInfoID, currentProvider?: WalletID): string {
const isTestnet =
SUPPORTED_CHAINS.find((chain) => chain.chainId === currentNetwork)?.type === 'testnet'
if (isTestnet) return DocURL.COUNCIL_TESTNET_URL
if (!currentProvider) return DocURL.COUNCIL_URL

50
src/libs/networkConfig.ts Normal file
View File

@ -0,0 +1,50 @@
import {
NETWORK_CONFIG as osmosisTestnetConfig,
VAULT_CONFIGS as osmosisTestnetVaultConfig,
} from '../configs/osmo-test-5'
import {
NETWORK_CONFIG as osmosisMainnetConfig,
VAULT_CONFIGS as osmosisMainnetVaultConfig,
} from '../configs/osmosis-1'
import {
NETWORK_CONFIG as neutronTestnetConfig,
VAULT_CONFIGS as neutronTestnetVaultConfig,
} from '../configs/pion-1'
export const getNetworkConfig = (network: string): NetworkConfig => {
let networkConfig
switch (network) {
case 'osmo-test-5':
networkConfig = osmosisTestnetConfig
break
case 'pion-1':
networkConfig = neutronTestnetConfig
break
default:
networkConfig = osmosisMainnetConfig
}
return networkConfig
}
export const getNetworkVaultConfig = (network: string): Vault[] => {
let vaultConfig
switch (network) {
case 'osmo-test-5':
vaultConfig = osmosisTestnetVaultConfig
break
case 'pion-1':
vaultConfig = neutronTestnetVaultConfig
break
default:
vaultConfig = osmosisMainnetVaultConfig
}
return vaultConfig
}

View File

@ -21,16 +21,16 @@ export const lookup = (amount: number, symbol: string, decimals: number): number
return demagnify(value.toNumber(), decimals)
}
export const findAssetByDenom = (denom: string, assets: Asset[]) =>
export const findAssetByDenom = (denom: string, assets: Asset[] | OtherAsset[]) =>
assets.find((asset) => asset.denom.toLowerCase() === denom.toLowerCase())
export const lookupSymbol = (denom: string, assets: Asset[]) =>
export const lookupSymbol = (denom: string, assets: Asset[] | OtherAsset[]) =>
assets.find((asset) => asset.denom.toLowerCase() === denom.toLowerCase())?.symbol || ''
export const lookupDecimals = (denom: string, assets: Asset[]) =>
export const lookupDecimals = (denom: string, assets: Asset[] | OtherAsset[]) =>
assets.find((asset) => asset.denom === denom)?.decimals || 6
export const lookupDenomBySymbol = (symbol: string, assets: Asset[]) =>
export const lookupDenomBySymbol = (symbol: string, assets: Asset[] | OtherAsset[]) =>
assets.find((asset) => asset.symbol.toLowerCase() === symbol.toLowerCase())?.denom || ''
export const format: Formatter = (amount, symbol, decimals): string => {

17
src/libs/pyth.ts Normal file
View File

@ -0,0 +1,17 @@
import { MsgExecuteContract } from '@marsprotocol/wallet-connector'
export const getPythVaaMessage = (
pythVaa: VaaInformation,
baseCurrencyDenom: string,
pythContractAddress?: string,
sender?: string,
): MsgExecuteContract | undefined => {
if (!sender || pythVaa.data.length === 0 || !pythContractAddress) return
return new MsgExecuteContract({
sender,
contract: pythContractAddress,
msg: { update_price_feeds: { data: pythVaa.data } },
funds: [{ denom: baseCurrencyDenom, amount: String(pythVaa.data.length) }],
})
}

View File

@ -17,13 +17,13 @@ export default function Document() {
<meta content='summary_large_image' name='twitter:card' />
<meta content='@mars_protocol' name='twitter:site' />
<meta content='@mars_protocol' name='twitter:creator' />
<meta content='https://osmosis.marsprotocol.io' property='og:url' />
<meta content='Mars Protocol - Osmosis Outpost' property='og:title' />
<meta content='https://app.marsprotocol.io' property='og:url' />
<meta content='Mars Protocol - Outpost' property='og:title' />
<meta
content="Lend, borrow and earn on the galaxy's most powerful credit protocol or enter the Fields of Mars for advanced DeFi strategies."
property='og:description'
/>
<meta content='https://osmosis.marsprotocol.io/banner.png' property='og:image' />
<meta content='https://app.marsprotocol.io/banner.png' property='og:image' />
<meta content='Mars Protocol' property='og:site_name' />
<meta content='#ffffff' name='msapplication-TileColor' />
<meta content='#ffffff' name='theme-color' />

View File

@ -5,7 +5,6 @@ import {
UnlockedNotification,
UnlockingNotification,
} from 'components/fields'
import { FIELDS_FEATURE } from 'constants/appConstants'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import useStore from 'store'
@ -21,8 +20,10 @@ const Fields = () => {
const creditManagerClient = useStore((s) => s.creditManagerClient)
const getVaults = useStore((s) => s.getVaults)
const userWalletAddress = useStore((s) => s.userWalletAddress)
const networkConfig = useStore((s) => s.networkConfig)
useEffect(() => {
if (!networkConfig.isFieldsEnabled) return
if (!getVaults || !accountNftClient || !client || !creditManagerClient || !userWalletAddress)
return
if (userWalletAddress && prefUserWalletAddress !== userWalletAddress) {
@ -31,10 +32,17 @@ const Fields = () => {
} else {
getVaults()
}
}, [getVaults, client, accountNftClient, creditManagerClient, userWalletAddress])
}, [
getVaults,
client,
accountNftClient,
creditManagerClient,
userWalletAddress,
networkConfig.isFieldsEnabled,
])
useEffect(() => {
if (!FIELDS_FEATURE) {
if (!networkConfig.isFieldsEnabled) {
router.push('/')
}
})

View File

@ -25,5 +25,18 @@
a {
display: inline-block;
}
.checkbox {
padding-top: 0;
@include typoXS;
&:before {
top: 0;
}
&:after {
top: space(0.75);
}
}
}
}

View File

@ -72,7 +72,8 @@ const Unlock = () => {
<Checkbox
onChecked={handleChange}
text={t('fields.disclaimers.dontShowAgain')}
className={'xs'}
className={styles.checkbox}
name='fields-disclaimer'
/>
</div>
</Card>

View File

@ -58,6 +58,16 @@
}
}
}
.loader {
opacity: 0.6;
height: rem-calc(200);
@include padding(0, 0, 10);
flex: 0 0 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
@media only screen and (max-width: $bpMediumHigh) {
.markets {

View File

@ -1,5 +1,13 @@
/* eslint-disable jsx-a11y/anchor-is-valid */
import { Backdrop, Card, Highlight, Notification, Title, Tutorial } from 'components/common'
import {
Backdrop,
Card,
CircularProgress,
Highlight,
Notification,
Title,
Tutorial,
} from 'components/common'
import { AssetTable, Portfolio, useBorrowColumns, useDepositColumns } from 'components/redbank'
import { RED_BANK_TUTORIAL_KEY } from 'constants/appConstants'
import {
@ -21,6 +29,8 @@ const RedBank = () => {
// ------------------
const { t } = useTranslation()
const redBankAssets = useStore((s) => s.redBankAssets)
const redBankState = useStore((s) => s.redBankState)
const setRedBankState = useStore((s) => s.setRedBankState)
const defaultDepositColumns = useDepositColumns()
const defaultBorrowColumns = useBorrowColumns()
@ -67,9 +77,27 @@ const RedBank = () => {
</Trans>
)
useEffect(() => {
if (
redBankAssets.length === 0 ||
marketInfo.length === 0 ||
userBalancesState !== State.READY ||
redBankState === State.READY
)
return
setRedBankState(State.READY)
}, [redBankAssets, marketInfo, redBankState, userBalancesState, setRedBankState])
const borrowBalance = Number(balanceSum(redBankAssets, 'borrowBalanceBaseCurrency'))
const showLiquidationWarning = borrowBalance >= maxBorrowLimit && borrowBalance > 0
const showLiquidationWarning =
borrowBalance >= maxBorrowLimit && borrowBalance > 0 && redBankState === State.READY
const loader = (
<div className={styles.loader}>
<CircularProgress size={40} />
</div>
)
const depositCard = (
<Card
@ -77,7 +105,11 @@ const RedBank = () => {
title={t('redbank.myDeposits')}
tooltip={<Trans i18nKey='redbank.tooltips.deposit.market.connected' />}
>
<AssetTable columns={defaultDepositColumns} data={redBankAssets} type='deposit' />
{redBankState === State.READY ? (
<AssetTable columns={defaultDepositColumns} data={redBankAssets} type='deposit' />
) : (
loader
)}
</Card>
)
@ -87,7 +119,11 @@ const RedBank = () => {
title={t('redbank.myBorrowings')}
tooltip={<Trans i18nKey='redbank.tooltips.borrow.market.connected' />}
>
<AssetTable columns={defaultBorrowColumns} data={redBankAssets} type='borrow' />
{redBankState === State.READY ? (
<AssetTable columns={defaultBorrowColumns} data={redBankAssets} type='borrow' />
) : (
loader
)}
</Card>
)
@ -108,7 +144,7 @@ const RedBank = () => {
return (
<div className={styles.markets}>
<Backdrop show={showTutorial} />
<Backdrop show={showTutorial && redBankState === State.READY} />
<Notification
content={maxLtvExceeded}
showNotification={showLiquidationWarning}

View File

@ -1,6 +1,7 @@
import { LcdClient } from '@cosmjs/launchpad'
import { Coin, StdFee } from '@cosmjs/stargate'
import {
ChainInfoID,
SimplifiedChainInfo,
TxBroadcastResult,
WalletClient,
@ -9,7 +10,6 @@ import { BlockHeightData } from 'hooks/queries/useBlockHeight'
import { DepositAndDebtData } from 'hooks/queries/useDepositAndDebt'
import { UserBalanceData } from 'hooks/queries/useUserBalance'
import { UserIcnsData } from 'hooks/queries/useUserIcns'
import { Network } from 'types/enums/network'
import { ContractMsg } from 'types/types'
export interface CommonSlice {
@ -24,11 +24,10 @@ export interface CommonSlice {
symbol: string
decimals: number
}
baseToDisplayCurrencyRatio?: number
chainInfo?: SimplifiedChainInfo
client?: WalletClient
currencyAssets: (Asset | OtherAsset)[]
currentNetwork: Network
currentNetwork: ChainInfoID
marketDebts: Coin[]
enableAnimations?: boolean
errors: {
@ -36,12 +35,11 @@ export interface CommonSlice {
query: boolean
server: boolean
}
isNetworkLoaded: boolean
latestBlockHeight: number
lcdClient?: LcdClient
marketDeposits: Coin[]
networkConfig?: NetworkConfig
otherAssets: Asset[]
networkConfig: NetworkConfig
otherAssets: OtherAsset[]
queryErrors: string[]
acceptedTermsOfService: boolean
slippage: number
@ -65,6 +63,7 @@ export interface CommonSlice {
fee: StdFee
sender?: string
}) => Promise<TxBroadcastResult | undefined>
getAdditionalDecimals(denom: string): number
loadNetworkConfig: () => void
queryContract: <T>(
contractAddress: string,
@ -76,14 +75,12 @@ export interface CommonSlice {
// SETTERS
// ------------------
setChainInfo: (chainInfo: SimplifiedChainInfo) => void
setCurrentNetwork: (network: Network) => void
setCurrentNetwork: (network: ChainInfoID) => void
setTutorialStep: (type: 'fields' | 'redbank', step?: number) => void
setLcdClient: (rpc: string, chainID: string) => void
setLcdClient: (rpc: string, chainId: string) => void
setNetworkError: (isError: boolean) => void
setClient: (client: WalletClient) => void
setQueryError: (name: string, isError: boolean) => void
setServerError: (isError: boolean) => void
setUserIcns: (icns: string) => void
setUserWalletAddress: (address: string) => void
// ------------------
// QUERY RELATED

View File

@ -1,5 +1,4 @@
import { Coin } from '@cosmjs/stargate'
import { MarsOracleData } from 'hooks/queries/useMarsOracle'
import { State } from 'types/enums'
export interface OraclesSlice {
@ -8,18 +7,26 @@ export interface OraclesSlice {
// ------------------
exchangeRates?: Coin[]
exchangeRatesState: State
assetPricesUSD?: Coin[]
assetPricesUSDState: State
basePriceState: State
migrationInProgress: boolean
pythVaa: VaaInformation
// ------------------
// GENERAL FUNCTIONS
// ------------------
handleMigration: () => void
convertToDisplayCurrency: (coin: Coin) => number
getExchangeRate: (denom1: string, denom2?: string) => number
calculateExchangeRates: () => void
// ------------------
// SETTERS
// ------------------
setExchangeRatesState: (state: State) => void
setPythVaa: (sources: PriceSource[]) => void
// ------------------
// QUERY RELATED
// ------------------
previousMarsOracleQueryData?: MarsOracleData
processMarsOracleQuery: (data: MarsOracleData) => void
previousMarsOracleQueryData?: OracleData
processMarsOracleQuery: (data: OracleData) => void
}

View File

@ -1,22 +1,23 @@
import { LcdClient } from '@cosmjs/launchpad'
import { Coin } from '@cosmjs/stargate'
import {
ChainInfoID,
MsgExecuteContract,
SimplifiedChainInfo,
TxBroadcastResult,
WalletClient,
} from '@marsprotocol/wallet-connector'
import BigNumber from 'bignumber.js'
import { DISPLAY_CURRENCY_KEY } from 'constants/appConstants'
import { DISPLAY_CURRENCY_KEY, SUPPORTED_CHAINS } from 'constants/appConstants'
import { BlockHeightData } from 'hooks/queries/useBlockHeight'
import { DepositAndDebtData } from 'hooks/queries/useDepositAndDebt'
import { UserBalanceData } from 'hooks/queries/useUserBalance'
import { serializeUrl } from 'libs/parse'
import { getNetworkConfig, getNetworkVaultConfig } from 'libs/networkConfig'
import { demagnify, magnify, serializeUrl } from 'libs/parse'
import { getPythVaaMessage } from 'libs/pyth'
import isEqual from 'lodash.isequal'
import { isMobile } from 'react-device-detect'
import { CommonSlice } from 'store/interfaces/common.interface'
import { OraclesSlice } from 'store/interfaces/oracles.interface'
import { Network } from 'types/enums/network'
import { GetState } from 'zustand'
import { NamedSet } from 'zustand/middleware'
@ -33,14 +34,14 @@ const commonSlice = (
decimals: 6,
},
currencyAssets: [],
currentNetwork: Network.TESTNET,
currentNetwork: SUPPORTED_CHAINS[0].chainId,
errors: {
network: false,
query: false,
server: false,
},
isNetworkLoaded: false,
latestBlockHeight: 0,
networkConfig: getNetworkConfig(SUPPORTED_CHAINS[0].chainId),
marketDeposits: [],
marketDebts: [],
otherAssets: [],
@ -59,56 +60,85 @@ const commonSlice = (
// ------------------
convertToBaseCurrency: (coin: Coin) => {
const exchangeRates = get().exchangeRates
if (!exchangeRates || !coin) return 0
const exchangeRate = exchangeRates?.find(
(exchangeRate) => exchangeRate.denom === coin.denom,
)?.amount
if (!exchangeRate) return 0
const assetPricesUSD = get().assetPricesUSD
const baseCurrency = get().baseCurrency
const assets = [...get().whitelistedAssets, ...get().otherAssets]
const baseDecimals = get().baseAsset?.decimals ?? 0
const coinDecimals = assets.find((currency) => currency.denom === coin.denom)?.decimals ?? 0
const asset = assets.find((asset) => asset.denom === coin.denom)
const additionalDecimals = coinDecimals - baseDecimals
if (!exchangeRates || !assetPricesUSD || !coin || !asset) return 0
return new BigNumber(coin.amount)
.times(exchangeRate)
.shiftedBy(-1 * additionalDecimals)
.toNumber()
const additionalDecimals = asset.decimals - baseCurrency.decimals
if (coin.denom === baseCurrency.denom) return new BigNumber(coin.amount).toNumber()
const baseAssetPrice = assetPricesUSD?.find(
(assetPrice) => assetPrice.denom === baseCurrency.denom,
)?.amount
const assetPrice = assetPricesUSD?.find((assetPrice) => assetPrice.denom === coin.denom)?.amount
if (!baseAssetPrice || !assetPrice) return 0
return demagnify(
new BigNumber(coin.amount).times(assetPrice).dividedBy(baseAssetPrice).toNumber(),
additionalDecimals,
)
},
convertValueToAmount: (coin: Coin) => {
const exchangeRates = get().exchangeRates
const baseCurrency = get().baseCurrency
const whitelistedAssets = get().whitelistedAssets
const asset = whitelistedAssets.find((asset) => asset.denom === coin.denom)
const additionalDecimals = (asset?.decimals || 6) - baseCurrency.decimals
if (!exchangeRates || !coin) return 0
const exchangeRate = exchangeRates?.find(
(exchangeRate) => exchangeRate.denom === coin.denom,
)?.amount
if (!exchangeRate) return 0
return new BigNumber(coin.amount).div(exchangeRate).toNumber()
const baseExchangeRate = exchangeRates?.find(
(exchangeRate) => exchangeRate.denom === baseCurrency.denom,
)?.amount
if (!exchangeRate || !baseExchangeRate) return 0
return magnify(
new BigNumber(coin.amount).div(exchangeRate).times(baseExchangeRate).toNumber(),
additionalDecimals,
)
},
executeMsg: async (
options: StrategyExecuteMsgOptions,
): Promise<TxBroadcastResult | undefined> => {
const client = get().client!
const networkConfig = get().networkConfig
const baseCurrencyDenom = networkConfig.assets.base.denom
const pythContractAddress = networkConfig.contracts?.pyth
const pythVaaMessage = getPythVaaMessage(
get().pythVaa,
baseCurrencyDenom,
pythContractAddress,
get().userWalletAddress,
)
if (!options.sender) options.sender = get().userWalletAddress
const messages = [
new MsgExecuteContract({
sender: options.sender,
contract: options.contract,
msg: options.msg,
funds: options.funds,
}),
]
if (pythVaaMessage) messages.unshift(pythVaaMessage)
const broadcastOptions = {
messages: [
new MsgExecuteContract({
sender: options.sender,
contract: options.contract,
msg: options.msg,
funds: options.funds,
}),
],
messages,
feeAmount: options.fee.amount[0].amount,
gasLimit: options.fee.gas,
memo: undefined,
wallet: client.recentWallet,
wallet: client.connectedWallet,
mobile: isMobile,
}
@ -118,31 +148,47 @@ const commonSlice = (
console.error('transaction', e)
}
},
loadNetworkConfig: async () => {
try {
const config = await import(`../../configs/${get().currentNetwork}.ts`)
getAdditionalDecimals: (denom: string) => {
const assets = [...get().whitelistedAssets, ...get().otherAssets]
const assetDecimals = assets.find((asset) => asset.denom === denom)?.decimals
const baseCurrencyDecimals = get().baseCurrency.decimals
if (!assetDecimals) return 0
config.NETWORK_CONFIG.hiveUrl = serializeUrl(config.NETWORK_CONFIG.hiveUrl)
config.NETWORK_CONFIG.rpcUrl = serializeUrl(config.NETWORK_CONFIG.rpcUrl)
config.NETWORK_CONFIG.restUrl = serializeUrl(config.NETWORK_CONFIG.restUrl)
return assetDecimals - baseCurrencyDecimals
},
loadNetworkConfig: () => {
const networkConfig = getNetworkConfig(get().currentNetwork)
const vaultConfig = getNetworkVaultConfig(get().currentNetwork)
const storageDisplayCurrency = localStorage.getItem(DISPLAY_CURRENCY_KEY)
if (storageDisplayCurrency) {
config.NETWORK_CONFIG.displayCurrency = JSON.parse(storageDisplayCurrency)
networkConfig.hiveUrl = serializeUrl(networkConfig.hiveUrl)
networkConfig.rpcUrl = serializeUrl(networkConfig.rpcUrl)
networkConfig.restUrl = serializeUrl(networkConfig.restUrl)
const storageDisplayCurrency = localStorage.getItem(DISPLAY_CURRENCY_KEY)
if (storageDisplayCurrency) {
const displayCurrency = networkConfig.assets.currencies.find(
(currency) => currency.denom === JSON.parse(storageDisplayCurrency).denom,
)
if (displayCurrency) {
networkConfig.displayCurrency = JSON.parse(storageDisplayCurrency)
} else {
localStorage.setItem(DISPLAY_CURRENCY_KEY, JSON.stringify(networkConfig.displayCurrency))
}
set({
otherAssets: config.NETWORK_CONFIG.assets.other,
whitelistedAssets: config.NETWORK_CONFIG.assets.whitelist,
currencyAssets: config.NETWORK_CONFIG.assets.currencies,
networkConfig: config.NETWORK_CONFIG,
isNetworkLoaded: true,
baseAsset: config.NETWORK_CONFIG.assets.base,
vaultConfigs: config.VAULT_CONFIGS,
})
} catch (e) {
set({ isNetworkLoaded: false })
}
set({
networkConfig: networkConfig,
otherAssets: networkConfig.assets.other,
whitelistedAssets: networkConfig.assets.whitelist,
currencyAssets: networkConfig.assets.currencies,
vaultConfigs: vaultConfig,
baseCurrency: networkConfig.assets.base,
marketDebts: [],
marketDeposits: [],
userBalances: [],
userMarsTokenBalances: [],
userUnclaimedRewards: '0',
})
},
queryContract: async <T>(contractAddress: string, queryMsg: object, retries = 3) => {
let attempts = 0
@ -167,11 +213,11 @@ const commonSlice = (
})
},
setChainInfo: (chainInfo: SimplifiedChainInfo) => {
if (chainInfo?.rpc) chainInfo.rpc = serializeUrl(chainInfo.rpc)
if (chainInfo?.rest) chainInfo.rest = serializeUrl(chainInfo.rest)
chainInfo.rpc = serializeUrl(get().networkConfig.rpcUrl)
chainInfo.rest = serializeUrl(get().networkConfig.restUrl)
set({ chainInfo })
},
setCurrentNetwork: (network: Network) => set({ currentNetwork: network }),
setCurrentNetwork: (network: ChainInfoID) => set({ currentNetwork: network }),
setNetworkError: (isError: boolean) => {
const errors = get().errors
if (isError !== errors.network) {
@ -179,7 +225,6 @@ const commonSlice = (
set({ errors })
}
},
setClient: (client: WalletClient) => set({ client }),
setQueryError: (name: string, isError: boolean) => {
const errors = get().errors
const queryErrors = get().queryErrors
@ -208,7 +253,6 @@ const commonSlice = (
set({ tutorialSteps })
},
setUserWalletAddress: (address: string) => set({ userWalletAddress: address }),
setUserIcns: (icns: string) => set({ userIcns: icns }),
// -------------------
// QUERY RELATED
// -------------------

View File

@ -1,8 +1,8 @@
import { Coin } from '@cosmjs/stargate'
import BigNumber from 'bignumber.js'
import { updateExchangeRate } from 'functions/updateExchangeRate'
import { MarsOracleData } from 'hooks/queries/useMarsOracle'
import { findAssetByDenom, lookup } from 'libs/parse'
import { updateExchangeRate } from 'functions'
import { updateAssetPrices } from 'functions/updateAssetPrices'
import { findAssetByDenom, lookup, magnify } from 'libs/parse'
import isEqual from 'lodash.isequal'
import { OraclesSlice } from 'store/interfaces/oracles.interface'
import { Store } from 'store/interfaces/store.interface'
@ -15,72 +15,158 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
// VARIABLES
// ------------------
exchangeRatesState: State.INITIALISING,
assetPricesUSDState: State.INITIALISING,
basePriceState: State.INITIALISING,
migrationInProgress: false,
pythVaa: {
priceFeeds: [],
data: [],
},
// ------------------
// GENERAL FUNCTIONS
// ------------------
convertToDisplayCurrency: (coin: Coin) => {
const whitelistedAssets = get().whitelistedAssets
const exchangeRates = get().exchangeRates
const assetPricesUSD = get().assetPricesUSD
const otherAssets = get().otherAssets
const baseCurrency = get().baseCurrency
const networkConfig = get().networkConfig
const displayCurrency = networkConfig?.displayCurrency
const displayCurrency = networkConfig.displayCurrency
const exchangeRatesState = get().exchangeRatesState
const assets: Asset[] = [...whitelistedAssets, ...otherAssets]
const assetPricesUSDState = get().assetPricesUSDState
const assets: OtherAsset[] = [...whitelistedAssets, ...otherAssets]
if (
!coin ||
exchangeRatesState === State.INITIALISING ||
!exchangeRates?.find((rate) => rate.denom === displayCurrency.denom) ||
assetPricesUSDState === State.INITIALISING ||
!assetPricesUSD ||
!exchangeRates ||
!assets.length ||
!displayCurrency
) {
return 0
}
if (coin.denom.toLowerCase() === displayCurrency.denom.toLowerCase()) {
if (coin.denom === displayCurrency.denom) {
const displayAsset = findAssetByDenom(displayCurrency.denom, assets)
if (!displayAsset) return 0
return lookup(Number(coin.amount), displayAsset.symbol, displayAsset.decimals)
}
const assetToBaseRatio = Number(
exchangeRates.find((exchangeRate) => exchangeRate.denom === coin.denom)?.amount,
)
const baseToDisplayCurrencyRatio = get().baseToDisplayCurrencyRatio
const assetInfo = assets.find((asset) => asset.denom === coin.denom)
if (!assetToBaseRatio || !baseToDisplayCurrencyRatio || !assetInfo) return 0
const assetPrice = Number(
assetPricesUSD.find((assetPrice) => assetPrice.denom === coin.denom)?.amount,
)
if (!assetInfo || !assetPrice) return 0
const decimals = assetInfo.decimals
let amount = 0
if (coin.denom === baseCurrency.denom) {
amount = new BigNumber(coin.amount)
if (displayCurrency.denom === 'usd') {
const amount = new BigNumber(coin.amount)
.dividedBy(10 ** decimals)
.times(baseToDisplayCurrencyRatio)
.toNumber()
} else {
amount = new BigNumber(coin.amount)
.dividedBy(10 ** decimals)
.times(assetToBaseRatio)
.times(baseToDisplayCurrencyRatio)
.times(assetPrice)
.toNumber()
return amount < 0.01 ? 0 : amount
}
const exchangeRate = Number(
exchangeRates.find((exchangeRate) => exchangeRate.denom === coin.denom)?.amount,
)
if (!exchangeRate) return 0
const amount = new BigNumber(coin.amount)
.dividedBy(10 ** decimals)
.times(exchangeRate)
.toNumber()
// Prevent extremely small numbers
return amount < 0.005 ? 0 : amount
return amount < 0.001 ? 0 : amount
},
getExchangeRate: (denom1: string, denom2?: string) => {
const assets = [...get().whitelistedAssets, ...get().otherAssets]
if (!denom2) {
denom2 = get().baseAsset?.denom
denom2 = get().baseCurrency?.denom
}
const exchangeRates = get().exchangeRates
const asset1 = exchangeRates?.find((coin) => coin.denom === denom1)
const asset2 = exchangeRates?.find((coin) => coin.denom === denom2)
if (asset1 && asset2) {
return new BigNumber(asset1.amount).div(asset2.amount).toNumber()
const asset1 = assets.find((asset) => asset.denom === denom1)
const asset2 = assets.find((asset) => asset.denom === denom2)
const assetPricesUSD = get().assetPricesUSD
const asset1Price = assetPricesUSD?.find((coin) => coin.denom === denom1)?.amount
const asset2Price = assetPricesUSD?.find((coin) => coin.denom === denom2)?.amount
if (asset1Price && asset1 && asset2Price && asset2) {
return new BigNumber(magnify(Number(asset1Price), asset1.decimals))
.div(magnify(Number(asset2Price), asset2.decimals))
.toNumber()
}
return 1
},
calculateExchangeRates: () => {
const assetPricesUSD = get().assetPricesUSD
const displayCurrency = get().networkConfig.displayCurrency
let exchangeRates: Coin[] = get().exchangeRates ?? []
if (!displayCurrency || !assetPricesUSD) return
const displayCurrencyPrice = assetPricesUSD?.find(
(asset) => asset.denom === displayCurrency.denom,
) ?? { denom: displayCurrency.denom, amount: '1' }
assetPricesUSD.forEach((asset) => {
if (asset.denom === displayCurrency.denom) {
exchangeRates = updateExchangeRate({ denom: asset.denom, amount: '1' }, exchangeRates)
} else {
exchangeRates = updateExchangeRate(
{
denom: asset.denom,
amount: new BigNumber(asset.amount).div(displayCurrencyPrice.amount).toString(),
},
exchangeRates,
)
}
})
set({
exchangeRates,
exchangeRatesState: State.READY,
})
},
handleMigration: () => {
if (!get().migrationInProgress) return
set({
exchangeRates: [],
exchangeRatesState: State.INITIALISING,
assetPricesUSD: [],
assetPricesUSDState: State.INITIALISING,
basePriceState: State.INITIALISING,
})
},
setPythVaa: (sources: PriceSource[]) => {
if (!sources || sources.length === 0) return
const whitelistedAssets = get().whitelistedAssets
const otherAssets = get().otherAssets
const allAssets = [...whitelistedAssets, ...otherAssets]
if (allAssets.length === 0) return
const pythAssetFeedIds: string[] = []
allAssets.forEach((asset) => {
const priceSource = sources.find((source) => source.denom === asset.denom)?.price_source
const isPyth = priceSource && !!(priceSource as PythPriceSource).pyth
if (isPyth) {
pythAssetFeedIds.push((priceSource as PythPriceSource).pyth.price_feed_id)
}
})
if (pythAssetFeedIds.length === 0) return
const data = get().pythVaa.data
set({ pythVaa: { priceFeeds: pythAssetFeedIds, data } })
},
// ------------------
// SETTERS
// ------------------
@ -89,55 +175,72 @@ const oraclesSlice = (set: NamedSet<Store>, get: GetState<Store>): OraclesSlice
// ------------------
// QUERY RELATED
// ------------------
processMarsOracleQuery: (data: MarsOracleData) => {
processMarsOracleQuery: (data: OracleData) => {
if (isEqual(data, get().previousMarsOracleQueryData)) return
const wasmQueryResults = data.prices
const exchangeRates: Coin[] = get().exchangeRates ?? []
const baseCurrency = get().baseCurrency
const networkConfig = get().networkConfig
const displayCurrency = networkConfig?.displayCurrency
const migrationInProgress = data.sources.price_sources.length === 0
set({ migrationInProgress })
if (migrationInProgress) {
get().handleMigration()
return
}
get().setPythVaa(data.sources.price_sources)
const pricesQueryResult = data.prices
const oracleBaseDenom = data.oracle.config.base_denom.toLocaleLowerCase()
let assetPricesUSD: Coin[] = get().assetPricesUSD ?? []
get()
.whitelistedAssets?.filter((asset: Asset) => !!asset.denom)
.forEach((asset: Asset) => {
const denom = asset.denom
const hasBaseCurrency = exchangeRates?.find(
(ratesAsset) => ratesAsset.denom === baseCurrency.denom,
)
if (denom === baseCurrency.denom && !hasBaseCurrency) {
exchangeRates.push({ denom, amount: '1' })
return
}
const id = asset.id
const exchangeRateResult = wasmQueryResults[`${id}`].price || '0.00'
const additionalDecimals =
asset.decimals > get().baseCurrency.decimals
? asset.decimals - get().baseCurrency.decimals
: 0
// Fix for a LCDClientError object instead of string
const exchangeRate: Coin = {
denom,
amount:
typeof exchangeRateResult === 'string'
? new BigNumber(exchangeRateResult).times(10 ** additionalDecimals).toString() ||
'0.00'
: '0.00',
const queryResult = pricesQueryResult[`${id}`]?.price ?? '0.00'
// Non-USD denominated oracle prices
if (oracleBaseDenom.toLowerCase().indexOf('usd') === -1) {
const baseCurrencyPrice = assetPricesUSD.find(
(assetPrice) => assetPrice.denom === oracleBaseDenom,
)
if (baseCurrencyPrice && denom !== oracleBaseDenom) {
const additionalDecimals =
asset.decimals > get().baseCurrency.decimals
? asset.decimals - get().baseCurrency.decimals
: 0
const assetPrice = {
denom,
amount:
typeof queryResult === 'string'
? new BigNumber(queryResult)
.times(10 ** additionalDecimals)
.times(baseCurrencyPrice.amount)
.toString() || '0.00'
: '0.00',
}
assetPricesUSD = updateAssetPrices(assetPrice, assetPricesUSD)
}
} else {
// USD denominated oracle prices
const assetPrice = {
denom,
amount: typeof queryResult === 'string' ? queryResult : '0.00',
}
assetPricesUSD = updateAssetPrices(assetPrice, assetPricesUSD)
}
if (asset.denom === displayCurrency.denom) {
set({
baseToDisplayCurrencyRatio: 1 / Number(exchangeRate.amount),
})
}
updateExchangeRate(exchangeRate, exchangeRates)
})
set({
previousMarsOracleQueryData: data,
exchangeRatesState: State.READY,
exchangeRates,
assetPricesUSD,
assetPricesUSDState: State.READY,
})
get().calculateExchangeRates()
},
})

View File

@ -62,12 +62,7 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
// SETTERS
// ------------------
setRedBankAssets: () => {
if (
get().exchangeRatesState !== State.READY ||
get().userBalancesState !== State.READY ||
get().redBankState !== State.READY
)
return
if (get().exchangeRatesState !== State.READY || get().userBalancesState !== State.READY) return
const redBankAssets: RedBankAsset[] = []
const marketAssetLiquidity: Coin[] = []
const whitelistedAssets = get().whitelistedAssets
@ -137,7 +132,7 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
// QUERY RELATED
// ------------------
processRedBankQuery: (data: RedBankData, whitelistedAssets: Asset[]) => {
if (isEqual(data, get().previousRedBankQueryData)) return
if (isEqual(data, get().previousRedBankQueryData) && get().marketInfo.length) return
const userUnclaimedRewards = data.rbwasmkey.unclaimedRewards
const marketInfo: Market[] = []
@ -164,7 +159,6 @@ const redBankSlice = (set: NamedSet<Store>, get: GetState<Store>): RedBankSlice
marketIncentiveInfo,
previousRedBankQueryData: data,
userUnclaimedRewards,
redBankState: State.READY,
})
},
findCollateral: (denom: string) => {

View File

@ -1,7 +1,7 @@
import BigNumber from 'bignumber.js'
import { findByDenom } from 'functions'
import { getAmountsFromActiveVault, getLeverageFromValues } from 'functions/fields'
import { convertAprToApy, leverageToLtv } from 'libs/parse'
import { convertAprToApy, demagnify, leverageToLtv, magnify } from 'libs/parse'
import moment from 'moment'
import { Store } from 'store/interfaces/store.interface'
import { Options, VaultsSlice } from 'store/interfaces/vaults.interface.'
@ -67,7 +67,7 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
)
const newCreditAccounts = await Promise.all(promises).then((result) =>
result.map((value) => value as Positions).filter((positions) => positions.vaults.length),
result.map((value) => value as Positions).filter((positions) => positions?.vaults.length),
)
set({ creditAccounts: newCreditAccounts })
@ -163,10 +163,10 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
const vaultAddresses = get().vaultConfigs.map((vault) => vault.address)
const networkConfig = get().networkConfig
if (!networkConfig) return null
if (!networkConfig.apolloAprUrl) return null
try {
const response = await fetch(networkConfig!.apolloAprUrl)
const response = await fetch(networkConfig.apolloAprUrl)
if (response.ok) {
const data: ApolloAprResponse[] = await response.json()
@ -377,40 +377,53 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
}
const borrowedDenom = debt?.denom || ''
const secondaryUSDPrice = Number(
get().assetPricesUSD?.find((coin) => coin.denom === vaultConfig.denoms.secondary)
?.amount || 1,
)
const primaryUSDPrice = Number(
get().assetPricesUSD?.find((coin) => coin.denom === vaultConfig.denoms.primary)
?.amount || 1,
)
const primaryAsset = get().whitelistedAssets.find(
(asset) => asset.denom === vaultConfig.denoms.primary,
)
const secondaryAsset = get().whitelistedAssets.find(
(asset) => asset.denom === vaultConfig.denoms.secondary,
)
if (borrowedDenom === vaultConfig.denoms.primary) {
if (borrowedPrimaryAmount > primaryAmount) {
const swapped = Math.round(
get().convertToBaseCurrency({
denom: borrowedDenom,
amount: (borrowedPrimaryAmount - primaryAmount).toString(),
}),
const swapAmount = demagnify(
borrowedPrimaryAmount - primaryAmount,
primaryAsset?.decimals ?? 6,
)
const primaryToSwapValue = swapAmount * primaryUSDPrice
const secondaryNeeded = magnify(
primaryToSwapValue / secondaryUSDPrice,
secondaryAsset?.decimals ?? 6,
)
const rate = Number(
get().exchangeRates?.find((coin) => coin.denom === vaultConfig.denoms.secondary)
?.amount ?? 0,
)
primarySupplyAmount = 0
secondarySupplyAmount = Math.floor(secondaryAmount - swapped / rate)
secondarySupplyAmount = Math.floor(secondaryAmount - secondaryNeeded)
} else {
primarySupplyAmount = primaryAmount - borrowedPrimaryAmount
secondarySupplyAmount = secondaryAmount
}
} else if (borrowedDenom === vaultConfig.denoms.secondary) {
if (borrowedSecondaryAmount > secondaryAmount) {
const swapped = Math.round(
get().convertToBaseCurrency({
denom: borrowedDenom,
amount: (borrowedSecondaryAmount - secondaryAmount).toString(),
}),
const swapAmount = demagnify(
borrowedSecondaryAmount - secondaryAmount,
secondaryAsset?.decimals ?? 6,
)
const rate = Number(
get().exchangeRates?.find((coin) => coin.denom === vaultConfig.denoms.primary)
?.amount ?? 0,
const secondaryToSwapValue = swapAmount * secondaryUSDPrice
const primaryNeeded = magnify(
secondaryToSwapValue / primaryUSDPrice,
primaryAsset?.decimals ?? 6,
)
secondarySupplyAmount = 0
primarySupplyAmount = Math.floor(primaryAmount - swapped / rate)
primarySupplyAmount = Math.floor(primaryAmount - primaryNeeded)
} else {
secondarySupplyAmount = secondaryAmount - borrowedSecondaryAmount
primarySupplyAmount = primaryAmount
@ -516,7 +529,6 @@ export const vaultsSlice = (set: NamedSet<Store>, get: GetState<Store>): VaultsS
availableVaults: Vault[]
},
)
set({ activeVaults, availableVaults, isLoading: false })
get().getApys(options)
},

View File

@ -11,6 +11,7 @@
weth: $colorTokenWETH;
juno: $colorTokenJUNO;
statom: $colorTokenStATOM;
ntrn: $colorTokenNTRN;
/* COLORS */
success: $colorInfoProfit;

Some files were not shown because too many files have changed in this diff Show More