Commit edd30e9a authored by Max Alekseenko's avatar Max Alekseenko Committed by GitHub

Merits: activity cards and tracking (#2662)

parent 8e52e6a5
...@@ -6,7 +6,7 @@ on: ...@@ -6,7 +6,7 @@ on:
envs_preset: envs_preset:
description: ENVs preset description: ENVs preset
required: false required: false
default: "" default: main
type: choice type: choice
options: options:
- none - none
...@@ -22,6 +22,7 @@ on: ...@@ -22,6 +22,7 @@ on:
- eth_goerli - eth_goerli
- filecoin - filecoin
- immutable - immutable
- main
- mekong - mekong
- neon_devnet - neon_devnet
- optimism - optimism
......
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.2929 9.87888C11.6834 10.2694 12.3166 10.2694 12.7071 9.87888L16.243 6.34299C16.6335 5.95252 17.2665 5.95252 17.657 6.34299C18.0475 6.73345 18.0475 7.36652 17.657 7.75699L14.1211 11.2929C13.7306 11.6834 13.7306 12.3166 14.1211 12.7071L17.657 16.243C18.0475 16.6335 18.0475 17.2665 17.657 17.657C17.2665 18.0475 16.6335 18.0475 16.243 17.657L12.7071 14.1211C12.3166 13.7306 11.6834 13.7306 11.2929 14.1211L7.75699 17.657C7.36652 18.0475 6.73345 18.0475 6.34299 17.657C5.95252 17.2665 5.95252 16.6335 6.34299 16.243L9.87888 12.7071C10.2694 12.3166 10.2694 11.6834 9.87888 11.2929L6.34299 7.75699C5.95252 7.36652 5.95252 6.73345 6.34299 6.34299C6.73345 5.95252 7.36652 5.95252 7.75699 6.34299L11.2929 9.87888Z" fill="currentColor"/> <path d="M11.293 9.879a1 1 0 0 0 1.414 0l3.536-3.536a1 1 0 1 1 1.414 1.414l-3.536 3.536a1 1 0 0 0 0 1.414l3.536 3.536a1 1 0 1 1-1.414 1.414l-3.536-3.536a1 1 0 0 0-1.414 0l-3.536 3.536a1 1 0 1 1-1.414-1.414l3.536-3.536a1 1 0 0 0 0-1.414L6.343 7.757a1 1 0 1 1 1.414-1.414l3.536 3.536Z" fill="currentColor"/>
</svg> </svg>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.99984 18.3334C5.39734 18.3334 1.6665 14.6026 1.6665 10.0001C1.6665 5.39758 5.39734 1.66675 9.99984 1.66675C14.6023 1.66675 18.3332 5.39758 18.3332 10.0001C18.3332 14.6026 14.6023 18.3334 9.99984 18.3334ZM9.1665 9.16675V14.1667H10.8332V9.16675H9.1665ZM9.1665 5.83342V7.50008H10.8332V5.83342H9.1665Z" fill="currentColor"/> <path d="M10 18.333a8.333 8.333 0 1 1 0-16.666 8.333 8.333 0 1 1 0 16.666Zm-.834-9.166v5h1.667v-5H9.166Zm0-3.334V7.5h1.667V5.833H9.166Z" fill="currentColor"/>
</svg> </svg>
import type * as bens from '@blockscout/bens-types'; import type * as bens from '@blockscout/bens-types';
import type * as rewards from '@blockscout/points-types';
import type * as stats from '@blockscout/stats-types'; import type * as stats from '@blockscout/stats-types';
import type * as visualizer from '@blockscout/visualizer-types'; import type * as visualizer from '@blockscout/visualizer-types';
import { getFeaturePayload } from 'configs/app/features/types'; import { getFeaturePayload } from 'configs/app/features/types';
...@@ -99,17 +100,6 @@ import type { ...@@ -99,17 +100,6 @@ import type {
} from 'types/api/optimisticL2'; } from 'types/api/optimisticL2';
import type { Pool, PoolsResponse } from 'types/api/pools'; import type { Pool, PoolsResponse } from 'types/api/pools';
import type { RawTracesResponse } from 'types/api/rawTrace'; import type { RawTracesResponse } from 'types/api/rawTrace';
import type {
RewardsConfigResponse,
RewardsCheckRefCodeResponse,
RewardsNonceResponse,
RewardsCheckUserResponse,
RewardsLoginResponse,
RewardsUserBalancesResponse,
RewardsUserDailyCheckResponse,
RewardsUserDailyClaimResponse,
RewardsUserReferralsResponse,
} from 'types/api/rewards';
import type { import type {
ScrollL2BatchesResponse, ScrollL2BatchesResponse,
ScrollL2TxnBatch, ScrollL2TxnBatch,
...@@ -444,6 +434,47 @@ export const RESOURCES = { ...@@ -444,6 +434,47 @@ export const RESOURCES = {
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint, endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath, basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
}, },
rewards_user_check_activity_pass: {
path: '/api/v1/activity/check-pass',
filterFields: [ 'address' as const ],
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
},
rewards_user_activity: {
path: '/api/v1/user/activity/rewards',
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
},
rewards_user_activity_track_tx: {
path: '/api/v1/user/activity/track/transaction',
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
},
rewards_user_activity_track_tx_confirm: {
path: '/api/v1/activity/track/transaction/confirm',
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
},
rewards_user_activity_track_contract: {
path: '/api/v1/user/activity/track/contract',
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
},
rewards_user_activity_track_contract_confirm: {
path: '/api/v1/activity/track/contract/confirm',
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
},
rewards_user_activity_track_usage: {
path: '/api/v1/user/activity/track/usage',
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
},
rewards_instances: {
path: '/api/v1/instances',
endpoint: getFeaturePayload(config.features.rewards)?.api.endpoint,
basePath: getFeaturePayload(config.features.rewards)?.api.basePath,
},
// BLOCKS, TXS // BLOCKS, TXS
blocks: { blocks: {
...@@ -1446,15 +1477,20 @@ Q extends 'contract_mud_system_info' ? SmartContractMudSystemInfo : ...@@ -1446,15 +1477,20 @@ Q extends 'contract_mud_system_info' ? SmartContractMudSystemInfo :
Q extends 'address_epoch_rewards' ? AddressEpochRewardsResponse : Q extends 'address_epoch_rewards' ? AddressEpochRewardsResponse :
Q extends 'withdrawals' ? WithdrawalsResponse : Q extends 'withdrawals' ? WithdrawalsResponse :
Q extends 'withdrawals_counters' ? WithdrawalsCounters : Q extends 'withdrawals_counters' ? WithdrawalsCounters :
Q extends 'rewards_config' ? RewardsConfigResponse : Q extends 'rewards_config' ? rewards.GetConfigResponse :
Q extends 'rewards_check_ref_code' ? RewardsCheckRefCodeResponse : Q extends 'rewards_check_ref_code' ? rewards.AuthCodeResponse :
Q extends 'rewards_nonce' ? RewardsNonceResponse : Q extends 'rewards_nonce' ? rewards.AuthNonceResponse :
Q extends 'rewards_check_user' ? RewardsCheckUserResponse : Q extends 'rewards_check_user' ? rewards.AuthUserResponse :
Q extends 'rewards_login' ? RewardsLoginResponse : Q extends 'rewards_login' ? rewards.AuthLoginResponse :
Q extends 'rewards_user_balances' ? RewardsUserBalancesResponse : Q extends 'rewards_user_balances' ? rewards.GetUserBalancesResponse :
Q extends 'rewards_user_daily_check' ? RewardsUserDailyCheckResponse : Q extends 'rewards_user_daily_check' ? rewards.DailyRewardCheckResponse :
Q extends 'rewards_user_daily_claim' ? RewardsUserDailyClaimResponse : Q extends 'rewards_user_daily_claim' ? rewards.DailyRewardClaimResponse :
Q extends 'rewards_user_referrals' ? RewardsUserReferralsResponse : Q extends 'rewards_user_referrals' ? rewards.GetReferralDataResponse :
Q extends 'rewards_user_check_activity_pass' ? rewards.CheckActivityPassResponse :
Q extends 'rewards_user_activity' ? rewards.GetActivityRewardsResponse :
Q extends 'rewards_user_activity_track_tx' ? rewards.PreSubmitTransactionResponse :
Q extends 'rewards_user_activity_track_contract' ? rewards.PreVerifyContractResponse :
Q extends 'rewards_instances' ? rewards.GetInstancesResponse :
Q extends 'token_transfers_all' ? TokenTransferResponse : Q extends 'token_transfers_all' ? TokenTransferResponse :
Q extends 'address_xstar_score' ? AddressXStarResponse : Q extends 'address_xstar_score' ? AddressXStarResponse :
Q extends 'advanced_filter' ? AdvancedFilterResponse : Q extends 'advanced_filter' ? AdvancedFilterResponse :
......
...@@ -5,13 +5,7 @@ import { useRouter } from 'next/router'; ...@@ -5,13 +5,7 @@ import { useRouter } from 'next/router';
import React, { createContext, useContext, useEffect, useMemo, useCallback } from 'react'; import React, { createContext, useContext, useEffect, useMemo, useCallback } from 'react';
import { useSignMessage, useSwitchChain } from 'wagmi'; import { useSignMessage, useSwitchChain } from 'wagmi';
import type { import type * as rewards from '@blockscout/points-types';
RewardsUserBalancesResponse, RewardsUserDailyCheckResponse,
RewardsNonceResponse, RewardsCheckUserResponse,
RewardsLoginResponse, RewardsCheckRefCodeResponse,
RewardsUserDailyClaimResponse, RewardsUserReferralsResponse,
RewardsConfigResponse,
} from 'types/api/rewards';
import config from 'configs/app'; import config from 'configs/app';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
...@@ -34,18 +28,18 @@ type ContextQueryResult<Response> = ...@@ -34,18 +28,18 @@ type ContextQueryResult<Response> =
Pick<UseQueryResult<Response, ResourceError<unknown>>, 'data' | 'isLoading' | 'refetch' | 'isPending' | 'isFetching' | 'isError'>; Pick<UseQueryResult<Response, ResourceError<unknown>>, 'data' | 'isLoading' | 'refetch' | 'isPending' | 'isFetching' | 'isError'>;
type TRewardsContext = { type TRewardsContext = {
balancesQuery: ContextQueryResult<RewardsUserBalancesResponse>; balancesQuery: ContextQueryResult<rewards.GetUserBalancesResponse>;
dailyRewardQuery: ContextQueryResult<RewardsUserDailyCheckResponse>; dailyRewardQuery: ContextQueryResult<rewards.DailyRewardCheckResponse>;
referralsQuery: ContextQueryResult<RewardsUserReferralsResponse>; referralsQuery: ContextQueryResult<rewards.GetReferralDataResponse>;
rewardsConfigQuery: ContextQueryResult<RewardsConfigResponse>; rewardsConfigQuery: ContextQueryResult<rewards.GetConfigResponse>;
checkUserQuery: ContextQueryResult<RewardsCheckUserResponse>; checkUserQuery: ContextQueryResult<rewards.AuthUserResponse>;
apiToken: string | undefined; apiToken: string | undefined;
isInitialized: boolean; isInitialized: boolean;
isLoginModalOpen: boolean; isLoginModalOpen: boolean;
openLoginModal: () => void; openLoginModal: () => void;
closeLoginModal: () => void; closeLoginModal: () => void;
saveApiToken: (token: string | undefined) => void; saveApiToken: (token: string | undefined) => void;
login: (refCode: string) => Promise<{ isNewUser: boolean; reward: string | null; invalidRefCodeError?: boolean }>; login: (refCode: string) => Promise<{ isNewUser: boolean; reward?: string; invalidRefCodeError?: boolean }>;
claim: () => Promise<void>; claim: () => Promise<void>;
}; };
...@@ -70,7 +64,7 @@ const initialState = { ...@@ -70,7 +64,7 @@ const initialState = {
openLoginModal: () => {}, openLoginModal: () => {},
closeLoginModal: () => {}, closeLoginModal: () => {},
saveApiToken: () => {}, saveApiToken: () => {},
login: async() => ({ isNewUser: false, reward: null }), login: async() => ({ isNewUser: false }),
claim: async() => {}, claim: async() => {},
}; };
...@@ -209,16 +203,15 @@ export function RewardsContextProvider({ children }: Props) { ...@@ -209,16 +203,15 @@ export function RewardsContextProvider({ children }: Props) {
throw new Error(); throw new Error();
} }
const [ nonceResponse, checkCodeResponse ] = await Promise.all([ const [ nonceResponse, checkCodeResponse ] = await Promise.all([
apiFetch('rewards_nonce') as Promise<RewardsNonceResponse>, apiFetch('rewards_nonce') as Promise<rewards.AuthNonceResponse>,
refCode ? refCode ?
apiFetch('rewards_check_ref_code', { pathParams: { code: refCode } }) as Promise<RewardsCheckRefCodeResponse> : apiFetch('rewards_check_ref_code', { pathParams: { code: refCode } }) as Promise<rewards.AuthCodeResponse> :
Promise.resolve({ valid: true, reward: null }), Promise.resolve({ valid: true, reward: undefined }),
]); ]);
if (!checkCodeResponse.valid) { if (!checkCodeResponse.valid) {
return { return {
invalidRefCodeError: true, invalidRefCodeError: true,
isNewUser: false, isNewUser: false,
reward: null,
}; };
} }
await switchChainAsync({ chainId: Number(config.chain.id) }); await switchChainAsync({ chainId: Number(config.chain.id) });
...@@ -233,7 +226,7 @@ export function RewardsContextProvider({ children }: Props) { ...@@ -233,7 +226,7 @@ export function RewardsContextProvider({ children }: Props) {
signature, signature,
}, },
}, },
}) as RewardsLoginResponse; }) as rewards.AuthLoginResponse;
saveApiToken(loginResponse.token); saveApiToken(loginResponse.token);
return { return {
isNewUser: loginResponse.created, isNewUser: loginResponse.created,
...@@ -253,7 +246,7 @@ export function RewardsContextProvider({ children }: Props) { ...@@ -253,7 +246,7 @@ export function RewardsContextProvider({ children }: Props) {
method: 'POST', method: 'POST',
...fetchParams, ...fetchParams,
}, },
}) as RewardsUserDailyClaimResponse; }) as rewards.DailyRewardClaimResponse;
} catch (_error) { } catch (_error) {
errorToast(_error); errorToast(_error);
throw _error; throw _error;
......
import { useCallback, useRef, useEffect } from 'react';
import type { PreSubmitTransactionResponse, PreVerifyContractResponse } from '@blockscout/points-types';
import config from 'configs/app';
import useApiFetch from 'lib/api/useApiFetch';
import useApiQuery from 'lib/api/useApiQuery';
import { MINUTE } from 'lib/consts';
import { useRewardsContext } from 'lib/contexts/rewards';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
const feature = config.features.rewards;
const LAST_EXPLORE_TIME_KEY = 'rewards_activity_last_explore_time';
type RewardsActivityEndpoint =
| 'rewards_user_activity_track_tx'
| 'rewards_user_activity_track_tx_confirm'
| 'rewards_user_activity_track_contract'
| 'rewards_user_activity_track_contract_confirm'
| 'rewards_user_activity_track_usage';
export default function useRewardsActivity() {
const { apiToken } = useRewardsContext();
const apiFetch = useApiFetch();
const lastExploreTime = useRef<number>(0);
const profileQuery = useProfileQuery();
const checkActivityPassQuery = useApiQuery('rewards_user_check_activity_pass', {
queryOptions: {
enabled: feature.isEnabled && Boolean(apiToken) && Boolean(profileQuery.data?.address_hash),
},
queryParams: {
address: profileQuery.data?.address_hash ?? '',
},
});
useEffect(() => {
try {
const storedTime = window.localStorage.getItem(LAST_EXPLORE_TIME_KEY);
if (storedTime) {
lastExploreTime.current = Number(storedTime);
}
} catch {}
}, []);
const makeRequest = useCallback(async(endpoint: RewardsActivityEndpoint, params: Record<string, string>) => {
if (!apiToken || !checkActivityPassQuery.data?.is_valid) {
return;
}
try {
return await apiFetch(endpoint, {
fetchParams: {
method: 'POST',
body: params,
headers: { Authorization: `Bearer ${ apiToken }` },
},
});
} catch {}
}, [ apiFetch, checkActivityPassQuery.data, apiToken ]);
const trackTransaction = useCallback(async(from: string, to: string) => {
return (
await makeRequest('rewards_user_activity_track_tx', {
from_address: from,
to_address: to,
chain_id: config.chain.id ?? '',
})
) as PreSubmitTransactionResponse | undefined;
}, [ makeRequest ]);
const trackTransactionConfirm = useCallback((hash: string, token: string) =>
makeRequest('rewards_user_activity_track_tx_confirm', { tx_hash: hash, token }),
[ makeRequest ],
);
const trackContract = useCallback(async(address: string) => {
return (
await makeRequest('rewards_user_activity_track_contract', {
address,
chain_id: config.chain.id ?? '',
})
) as PreVerifyContractResponse | undefined;
}, [ makeRequest ]);
const trackContractConfirm = useCallback((token: string) =>
makeRequest('rewards_user_activity_track_contract_confirm', { token }),
[ makeRequest ],
);
const trackUsage = useCallback((action: string) => {
// check here because this function is called on page load
if (!apiToken || !checkActivityPassQuery.data?.is_valid) {
return;
}
if (action === 'explore') {
const now = Date.now();
if (now - lastExploreTime.current < 5 * MINUTE) {
return;
}
lastExploreTime.current = now;
try {
window.localStorage.setItem(LAST_EXPLORE_TIME_KEY, String(now));
} catch {}
}
return makeRequest('rewards_user_activity_track_usage', {
action,
chain_id: config.chain.id ?? '',
});
}, [ makeRequest, apiToken, checkActivityPassQuery.data ]);
return {
trackTransaction,
trackTransactionConfirm,
trackContract,
trackContractConfirm,
trackUsage,
};
}
...@@ -3,6 +3,8 @@ import type { AddEthereumChainParameter } from 'viem'; ...@@ -3,6 +3,8 @@ import type { AddEthereumChainParameter } from 'viem';
import config from 'configs/app'; import config from 'configs/app';
import { SECOND } from '../consts';
import useRewardsActivity from '../hooks/useRewardsActivity';
import useProvider from './useProvider'; import useProvider from './useProvider';
import { getHexadecimalChainId } from './utils'; import { getHexadecimalChainId } from './utils';
...@@ -26,15 +28,23 @@ function getParams(): AddEthereumChainParameter { ...@@ -26,15 +28,23 @@ function getParams(): AddEthereumChainParameter {
export default function useAddChain() { export default function useAddChain() {
const { wallet, provider } = useProvider(); const { wallet, provider } = useProvider();
const { trackUsage } = useRewardsActivity();
return React.useCallback(() => { return React.useCallback(async() => {
if (!wallet || !provider) { if (!wallet || !provider) {
throw new Error('Wallet or provider not found'); throw new Error('Wallet or provider not found');
} }
return provider.request({ const start = Date.now();
await provider.request({
method: 'wallet_addEthereumChain', method: 'wallet_addEthereumChain',
params: [ getParams() ], params: [ getParams() ],
}); });
}, [ wallet, provider ]);
// if network is already added, the promise resolves immediately
if (Date.now() - start > SECOND) {
await trackUsage('add_network');
}
}, [ wallet, provider, trackUsage ]);
} }
import type { GetActivityRewardsResponse } from '@blockscout/points-types';
export const base: GetActivityRewardsResponse = {
items: [
{
date: '2025-03-10',
end_date: '2025-03-16',
activity: 'sent_transactions',
amount: '60',
percentile: 0.5,
is_pending: true,
},
{
date: '2025-03-10',
end_date: '2025-03-16',
activity: 'verified_contracts',
amount: '40',
percentile: 0.3,
is_pending: true,
},
{
date: '2025-03-10',
end_date: '2025-03-16',
activity: 'blockscout_usage',
amount: '80',
percentile: 0.8,
is_pending: true,
},
],
last_week: [
{
date: '2025-03-03',
end_date: '2025-03-09',
activity: 'sent_transactions',
amount: '40',
percentile: 0.25,
is_pending: false,
},
{
date: '2025-03-03',
end_date: '2025-03-09',
activity: 'verified_contracts',
amount: '60',
percentile: 0.6,
is_pending: false,
},
{
date: '2025-03-03',
end_date: '2025-03-09',
activity: 'blockscout_usage',
amount: '100',
percentile: 0.95,
is_pending: false,
},
],
};
import type { RewardsUserBalancesResponse } from 'types/api/rewards'; import type { GetUserBalancesResponse } from '@blockscout/points-types';
export const base: RewardsUserBalancesResponse = { export const base: GetUserBalancesResponse = {
total: '250', total: '250',
staked: '0', staked: '0',
unstaked: '0', unstaked: '0',
......
import type { RewardsUserDailyCheckResponse } from 'types/api/rewards'; import type { DailyRewardCheckResponse } from '@blockscout/points-types';
export const base: RewardsUserDailyCheckResponse = { export const base: DailyRewardCheckResponse = {
available: true, available: true,
daily_reward: '10', daily_reward: '10',
streak_reward: '10', streak_reward: '10',
......
import type { RewardsUserReferralsResponse } from 'types/api/rewards'; import type { GetReferralDataResponse } from '@blockscout/points-types';
export const base: RewardsUserReferralsResponse = { export const base: GetReferralDataResponse = {
code: 'QWERTY', code: 'QWERTY',
link: 'https://example.com?ref=QWERTY', link: 'https://example.com?ref=QWERTY',
referrals: '15', referrals: '15',
......
import type { RewardsConfigResponse } from 'types/api/rewards'; import type { GetConfigResponse } from '@blockscout/points-types';
export const base: RewardsConfigResponse = { export const base: GetConfigResponse = {
rewards: { rewards: {
registration: '100', registration: '100',
registration_with_referral: '200', registration_with_referral: '200',
daily_claim: '10', daily_claim: '10',
referral_share: '0.1', referral_share: '0.1',
streak_bonuses: {},
sent_transactions_activity_rewards: {
'1': '100',
},
verified_contracts_activity_rewards: {
'1': '100',
},
blockscout_usage_activity_rewards: {
'1': '100',
},
blockscout_activity_pass_id: '1',
}, },
auth: { auth: {
shared_siwe_login: true, shared_siwe_login: true,
}, },
activity: {
sent_transactions_activity_enabled: true,
verified_contracts_activity_enabled: true,
blockscout_usage_activity_enabled: true,
},
}; };
...@@ -22,6 +22,7 @@ import { SocketProvider } from 'lib/socket/context'; ...@@ -22,6 +22,7 @@ import { SocketProvider } from 'lib/socket/context';
import { Provider as ChakraProvider } from 'toolkit/chakra/provider'; import { Provider as ChakraProvider } from 'toolkit/chakra/provider';
import { Toaster } from 'toolkit/chakra/toaster'; import { Toaster } from 'toolkit/chakra/toaster';
import RewardsLoginModal from 'ui/rewards/login/RewardsLoginModal'; import RewardsLoginModal from 'ui/rewards/login/RewardsLoginModal';
import RewardsActivityTracker from 'ui/rewards/RewardsActivityTracker';
import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary'; import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary';
import AppErrorGlobalContainer from 'ui/shared/AppError/AppErrorGlobalContainer'; import AppErrorGlobalContainer from 'ui/shared/AppError/AppErrorGlobalContainer';
import GoogleAnalytics from 'ui/shared/GoogleAnalytics'; import GoogleAnalytics from 'ui/shared/GoogleAnalytics';
...@@ -87,7 +88,12 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) { ...@@ -87,7 +88,12 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
<SettingsContextProvider> <SettingsContextProvider>
{ getLayout(<Component { ...pageProps }/>) } { getLayout(<Component { ...pageProps }/>) }
<Toaster/> <Toaster/>
{ config.features.rewards.isEnabled && <RewardsLoginModal/> } { config.features.rewards.isEnabled && (
<>
<RewardsLoginModal/>
<RewardsActivityTracker/>
</>
) }
</SettingsContextProvider> </SettingsContextProvider>
</MarketplaceContextProvider> </MarketplaceContextProvider>
</RewardsContextProvider> </RewardsContextProvider>
......
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 82 86" fill="none">
<path d="M48.24 3.608a14.19 14.19 0 0 0-14.202 0L10.603 17.154A14.19 14.19 0 0 0 3.514 29.44v27.12a14.19 14.19 0 0 0 7.089 12.286l23.435 13.546a14.19 14.19 0 0 0 14.203 0l23.435-13.546a14.19 14.19 0 0 0 7.088-12.286V29.44a14.19 14.19 0 0 0-7.088-12.286L48.24 3.608Z" fill="#ECF5FF" stroke="#A7BFDA" stroke-width=".86"/>
<path d="M41.14 2.133V43L5.784 22.564a13.751 13.751 0 0 1 5.03-5.035l.003-.002L34.253 3.98a13.751 13.751 0 0 1 6.886-1.847Z" fill="#F8FBFF"/>
<path d="M3.944 29.44v27.12c0 2.457.655 4.82 1.841 6.876L41.14 43 5.785 22.564a13.751 13.751 0 0 0-1.84 6.876Z" fill="url(#a)"/>
<path d="M78.334 56.571v-27.12c0-2.457-.654-4.82-1.84-6.876L41.138 43.011l35.354 20.436a13.75 13.75 0 0 0 1.841-6.876Z" fill="#E0EEFF"/>
<path d="M41.14 2.15v40.867L76.492 22.58a13.75 13.75 0 0 0-5.033-5.038L48.025 3.997A13.751 13.751 0 0 0 41.14 2.15Z" fill="url(#b)"/>
<path d="M10.815 68.472a13.751 13.751 0 0 1-5.03-5.036L41.14 43v40.867a13.75 13.75 0 0 1-6.884-1.847h-.002L10.818 68.473l-.003-.001Z" fill="url(#c)"/>
<path d="M48.025 82.02 71.46 68.473a13.752 13.752 0 0 0 5.033-5.037L41.14 43v40.867c2.378 0 4.756-.616 6.886-1.847Z" fill="#D1E5FE"/>
<path d="M35.114 8.643a12.04 12.04 0 0 1 12.05 0l20.692 11.96a12.04 12.04 0 0 1 6.015 10.424v23.946c0 4.299-2.293 8.272-6.015 10.424l-20.691 11.96a12.04 12.04 0 0 1-12.051 0l-20.692-11.96a12.04 12.04 0 0 1-6.014-10.424V31.027c0-4.3 2.292-8.272 6.014-10.424l20.692-11.96Z" fill="#A7BFDA"/>
<path d="M47.38 8.27a12.47 12.47 0 0 0-12.481 0L14.207 20.231a12.47 12.47 0 0 0-6.23 10.796v23.946a12.47 12.47 0 0 0 6.23 10.796L34.9 77.729a12.47 12.47 0 0 0 12.48 0l20.693-11.96A12.47 12.47 0 0 0 74.3 54.973V31.027a12.47 12.47 0 0 0-6.23-10.796L47.38 8.271Z" stroke="#F8FBFF" stroke-width=".86"/>
<path d="M35.33 9.015a11.61 11.61 0 0 1 11.62 0l20.691 11.96a11.61 11.61 0 0 1 5.8 10.052v23.946a11.61 11.61 0 0 1-5.8 10.051L46.95 76.984a11.61 11.61 0 0 1-11.62 0l-20.691-11.96a11.61 11.61 0 0 1-5.8-10.051V31.027a11.61 11.61 0 0 1 5.8-10.052l20.691-11.96Z" stroke="#A7BFDA" stroke-width=".86"/>
<path d="M35.166 8.643a12.04 12.04 0 0 1 12.05 0l20.692 11.96a12.04 12.04 0 0 1 6.015 10.424v23.946c0 4.299-2.293 8.272-6.015 10.424l-20.692 11.96a12.04 12.04 0 0 1-12.05 0l-20.692-11.96A12.04 12.04 0 0 1 8.46 54.973V31.027c0-4.3 2.293-8.272 6.015-10.424l20.692-11.96Z" fill="#FFBA0D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.46 50.673v4.3c0 4.299 2.292 8.272 6.014 10.424l20.692 11.96a12.04 12.04 0 0 0 12.05 0l20.692-11.96a12.04 12.04 0 0 0 6.015-10.424v-4.3c0 4.299-2.293 8.272-6.015 10.423l-20.692 11.96a12.04 12.04 0 0 1-12.05 0l-20.692-11.96A12.04 12.04 0 0 1 8.46 50.673Z" fill="#E1910E"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.115 8.643a12.04 12.04 0 0 1 12.05 0l20.692 11.96a12.04 12.04 0 0 1 6.015 10.424v2.58c0-4.3-2.292-8.272-6.015-10.424l-20.691-11.96a12.04 12.04 0 0 0-12.05 0l-20.692 11.96a12.04 12.04 0 0 0-6.015 10.424v-2.58c0-4.3 2.292-8.272 6.014-10.424l20.692-11.96Z" fill="#FFD57C"/>
<path d="M35.38 9.015a11.61 11.61 0 0 1 11.621 0l20.692 11.96a11.61 11.61 0 0 1 5.8 10.052v23.946a11.61 11.61 0 0 1-5.8 10.051L47 76.984a11.61 11.61 0 0 1-11.62 0l-20.692-11.96a11.61 11.61 0 0 1-5.8-10.051V31.027a11.61 11.61 0 0 1 5.8-10.052l20.692-11.96Z" stroke="#A05500" stroke-width=".86"/>
<g filter="url(#d)">
<path d="M44.364 50.74v-12.9l-1.72 1.72v9.46l1.72 1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M44.365 37.84h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M42.644 49.02v-9.46h-3.01v9.46h3.01Z" fill="#B77CFF" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m39.634 44.667 3.01 3.01v-5.053l-3.01-3.01v5.053Z" fill="#DABCFF"/>
<path d="M37.915 50.74h6.45l-1.72-1.72h-3.01l-1.72 1.72ZM37.915 37.84v12.9l1.72-1.72v-9.46l-1.72-1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M37.915 37.84h6.45m-6.45 0v12.9m0-12.9 1.72 1.72m4.73-1.72v12.9m0-12.9-1.72 1.72m1.72 11.18h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-9.46m0 9.46h-3.01m0 0v-9.46m0 0h3.01" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
</g>
<g filter="url(#e)" stroke="#50119C" stroke-width=".86" stroke-linejoin="round">
<path d="M37.484 30.745v-6.45l-1.72 1.72v3.01l1.72 1.72Z" fill="#A964FD"/>
<path d="M37.485 24.295h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD"/>
<path d="M35.764 29.025v-3.01h-3.01v3.01h3.01Z" fill="#B77CFF"/>
<path d="M31.035 30.745h6.45l-1.72-1.72h-3.01l-1.72 1.72Z" fill="#7A2CDA"/>
<path d="M31.035 24.295v6.45l1.72-1.72v-3.01l-1.72-1.72Z" fill="#7A2CDA"/>
<path d="M31.035 24.295h6.45m-6.45 0v6.45m0-6.45 1.72 1.72m4.73-1.72v6.45m0-6.45-1.72 1.72m1.72 4.73h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-3.01m0 3.01h-3.01m0 0v-3.01m0 0h3.01"/>
</g>
<g filter="url(#f)" stroke="#50119C" stroke-width=".86" stroke-linejoin="round">
<path d="M51.46 30.745v-6.45l-1.72 1.72v3.01l1.72 1.72ZM51.46 24.295h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD"/>
<path d="M49.739 29.025v-3.01h-3.01v3.01h3.01Z" fill="#B77CFF"/>
<path d="M45.01 30.745h6.45l-1.72-1.72h-3.01l-1.72 1.72ZM45.01 24.295v6.45l1.72-1.72v-3.01l-1.72-1.72Z" fill="#7A2CDA"/>
<path d="M45.01 24.295h6.45m-6.45 0v6.45m0-6.45 1.72 1.72m4.73-1.72v6.45m0-6.45-1.72 1.72m1.72 4.73h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-3.01m0 3.01h-3.01m0 0v-3.01m0 0h3.01"/>
</g>
<g filter="url(#g)">
<path d="M31.035 57.405v-26.66l-1.72 1.72v23.22l1.72 1.72ZM31.035 30.745h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M29.314 55.685v-23.22h-3.01v23.22h3.01Z" fill="#B77CFF" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m26.305 51.641 3.01 3.01v-3.307l-3.01-3.01v3.307Zm0-4.084 3.01 3.01v-1.463l-3.01-3.01v1.463Z" fill="#DABCFF"/>
<path d="M24.584 57.405h6.45l-1.72-1.72h-3.01l-1.72 1.72ZM24.584 30.745v26.66l1.72-1.72v-23.22l-1.72-1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M24.584 30.745h6.45m-6.45 0v26.66m0-26.66 1.72 1.72m4.73-1.72v26.66m0-26.66-1.72 1.72m1.72 24.94h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-23.22m0 23.22h-3.01m0 0v-23.22m0 0h3.01" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
</g>
<g filter="url(#h)">
<path d="M57.91 57.405v-26.66l-1.72 1.72v23.22l1.72 1.72ZM57.91 30.745h-6.45l1.72 1.72h3.01l1.72-1.72Z" fill="#A964FD" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M56.19 55.685v-23.22h-3.01v23.22h3.01Z" fill="#B77CFF" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="m53.18 41.237 3.01 3.01V40.94l-3.01-3.01v3.307Zm0-4.084 3.01 3.01V38.7l-3.01-3.01v1.463Z" fill="#DABCFF"/>
<path d="M51.46 57.405h6.45l-1.72-1.72h-3.01l-1.72 1.72ZM51.46 30.745v26.66l1.72-1.72v-23.22l-1.72-1.72Z" fill="#7A2CDA" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
<path d="M51.46 30.745h6.45m-6.45 0v26.66m0-26.66 1.72 1.72m4.73-1.72v26.66m0-26.66-1.72 1.72m1.72 24.94h-6.45m6.45 0-1.72-1.72m-4.73 1.72 1.72-1.72m3.01 0v-23.22m0 23.22h-3.01m0 0v-23.22m0 0h3.01" stroke="#50119C" stroke-width=".86" stroke-linejoin="round"/>
</g>
<g style="mix-blend-mode:color-burn">
<mask id="i" maskUnits="userSpaceOnUse" x="1.204" y="13.265" width="23" height="61" fill="#000">
<path fill="#fff" d="M1.204 13.265h23v61h-23z"/>
<path d="M18.533 19.338c-.609 1.258-1.689 1.917-2.886 2.396-.138.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198a57.93 57.93 0 0 1 1.414-1.757c.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.059.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.57.499-3.18.619-4.79.36-.158-.06-.295-.08-.452-.12a46.466 46.466 0 0 0-1.865 7.127c.314-.46.589-.978.864-1.438.687-1.177 1.55-2.116 2.866-2.575a9.09 9.09 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.299-.51 1.098-1.139 2.056-2.16 2.695-1.217.819-2.591 1.218-4.024 1.358-.452.04-.943.08-1.414.12a50.87 50.87 0 0 0-.707 7.367c.079-.08.098-.2.138-.32.157-.46.334-.938.51-1.437.55-1.438 1.473-2.536 2.867-3.195.961-.44 1.982-.699 3.023-.858.177 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.438-.883 2.815-2.1 3.754-1.277 1.058-2.769 1.717-4.398 2.076-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .588 7.527c.177-.819.315-1.597.472-2.376.255-1.098.785-2.077 1.63-2.815 1.06-.899 2.296-1.478 3.592-1.957.137 0 .275-.08.49-.12-.02.72-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.729 2.535-4.516 3.154-.059 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.04-.399 0-.778.02-1.177.02-1.318.235-2.556 1.04-3.614a8.461 8.461 0 0 1 2.356-2.097c.471-.319.942-.598 1.472-.858.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.059-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.715.334-.26.668-.54 1.021-.859.49 1.178.766 2.316.805 3.474 0 .659-.04 1.318-.295 1.957a11.52 11.52 0 0 1-3.102 4.492c-.157.12-.137.2-.058.36a55.328 55.328 0 0 0 3.003 4.472s-.196.399-1.511-.46c-.314-.459-.629-.898-.923-1.397-.609-.979-1.217-1.957-1.787-2.955-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.319-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.099-.2l.118-.08c1.374-.459 2.788-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.452.459.726.659-.02-.08-.059-.16-.098-.24a53.49 53.49 0 0 1-2.395-5.69c-.059-.2-.137-.24-.334-.24-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.4 2.238 1.218 3.023 2.296.197.24.354.479.51.719-.49-2.137-.98-4.293-1.472-6.43-.785-.199-1.63-.359-2.414-.618-1.218-.42-2.356-1.018-3.26-1.997-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.376.118.2.216.399.354.619-.197-2.137-.275-4.253-.118-6.39-1.06-.319-2.022-.738-2.906-1.317-1.295-.859-2.414-1.877-2.885-3.434a9.274 9.274 0 0 1-.432-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.942.399 1.805.898 2.532 1.677.628.678.962 1.497 1.237 2.336.117.399.215.798.373 1.178 0-.12.02-.16.02-.28.176-2.056.45-4.093.863-6.11.04-.199.02-.359-.216-.439A9.502 9.502 0 0 1 6.97 30.18c-.688-1.058-.845-2.216-.825-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.687 2.815.039.3.039.62.117.899l.06-.24c.51-2.057 1.118-4.133 1.904-6.13.078-.2.078-.319-.099-.419-1.354-.978-2.375-2.216-3.121-3.753-.59-1.218-.589-2.456-.334-3.714.079-.459.196-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.58-.098 1.218-.137 1.917.039-.08.059-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.195-2.455.158-.62.393-1.258.845-1.717.53-.58 1.158-1.018 1.826-1.398.353-.24.706-.4 1.08-.579.058 0 .097.04.156.04-.02.3-.078.58-.098.878-.04 1.099-.294 2.197-.785 3.155Z"/>
</mask>
<path d="M18.533 19.338c-.609 1.258-1.689 1.917-2.886 2.396-.138.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198a57.93 57.93 0 0 1 1.414-1.757c.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.059.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.57.499-3.18.619-4.79.36-.158-.06-.295-.08-.452-.12a46.466 46.466 0 0 0-1.865 7.127c.314-.46.589-.978.864-1.438.687-1.177 1.55-2.116 2.866-2.575a9.09 9.09 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.299-.51 1.098-1.139 2.056-2.16 2.695-1.217.819-2.591 1.218-4.024 1.358-.452.04-.943.08-1.414.12a50.87 50.87 0 0 0-.707 7.367c.079-.08.098-.2.138-.32.157-.46.334-.938.51-1.437.55-1.438 1.473-2.536 2.867-3.195.961-.44 1.982-.699 3.023-.858.177 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.438-.883 2.815-2.1 3.754-1.277 1.058-2.769 1.717-4.398 2.076-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .588 7.527c.177-.819.315-1.597.472-2.376.255-1.098.785-2.077 1.63-2.815 1.06-.899 2.296-1.478 3.592-1.957.137 0 .275-.08.49-.12-.02.72-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.729 2.535-4.516 3.154-.059 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.04-.399 0-.778.02-1.177.02-1.318.235-2.556 1.04-3.614a8.461 8.461 0 0 1 2.356-2.097c.471-.319.942-.598 1.472-.858.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.059-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.715.334-.26.668-.54 1.021-.859.49 1.178.766 2.316.805 3.474 0 .659-.04 1.318-.295 1.957a11.52 11.52 0 0 1-3.102 4.492c-.157.12-.137.2-.058.36a55.328 55.328 0 0 0 3.003 4.472s-.196.399-1.511-.46c-.314-.459-.629-.898-.923-1.397-.609-.979-1.217-1.957-1.787-2.955-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.319-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.099-.2l.118-.08c1.374-.459 2.788-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.452.459.726.659-.02-.08-.059-.16-.098-.24a53.49 53.49 0 0 1-2.395-5.69c-.059-.2-.137-.24-.334-.24-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.4 2.238 1.218 3.023 2.296.197.24.354.479.51.719-.49-2.137-.98-4.293-1.472-6.43-.785-.199-1.63-.359-2.414-.618-1.218-.42-2.356-1.018-3.26-1.997-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.376.118.2.216.399.354.619-.197-2.137-.275-4.253-.118-6.39-1.06-.319-2.022-.738-2.906-1.317-1.295-.859-2.414-1.877-2.885-3.434a9.274 9.274 0 0 1-.432-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.942.399 1.805.898 2.532 1.677.628.678.962 1.497 1.237 2.336.117.399.215.798.373 1.178 0-.12.02-.16.02-.28.176-2.056.45-4.093.863-6.11.04-.199.02-.359-.216-.439A9.502 9.502 0 0 1 6.97 30.18c-.688-1.058-.845-2.216-.825-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.687 2.815.039.3.039.62.117.899l.06-.24c.51-2.057 1.118-4.133 1.904-6.13.078-.2.078-.319-.099-.419-1.354-.978-2.375-2.216-3.121-3.753-.59-1.218-.589-2.456-.334-3.714.079-.459.196-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.58-.098 1.218-.137 1.917.039-.08.059-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.195-2.455.158-.62.393-1.258.845-1.717.53-.58 1.158-1.018 1.826-1.398.353-.24.706-.4 1.08-.579.058 0 .097.04.156.04-.02.3-.078.58-.098.878-.04 1.099-.294 2.197-.785 3.155Z" fill="#000" fill-opacity=".16"/>
<path d="M18.533 19.338c-.609 1.258-1.689 1.917-2.886 2.396-.138.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198a57.93 57.93 0 0 1 1.414-1.757c.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.059.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.57.499-3.18.619-4.79.36-.158-.06-.295-.08-.452-.12a46.466 46.466 0 0 0-1.865 7.127c.314-.46.589-.978.864-1.438.687-1.177 1.55-2.116 2.866-2.575a9.09 9.09 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.299-.51 1.098-1.139 2.056-2.16 2.695-1.217.819-2.591 1.218-4.024 1.358-.452.04-.943.08-1.414.12a50.87 50.87 0 0 0-.707 7.367c.079-.08.098-.2.138-.32.157-.46.334-.938.51-1.437.55-1.438 1.473-2.536 2.867-3.195.961-.44 1.982-.699 3.023-.858.177 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.438-.883 2.815-2.1 3.754-1.277 1.058-2.769 1.717-4.398 2.076-.157.02-.314.02-.51.06a40.27 40.27 0 0 0 .588 7.527c.177-.819.315-1.597.472-2.376.255-1.098.785-2.077 1.63-2.815 1.06-.899 2.296-1.478 3.592-1.957.137 0 .275-.08.49-.12-.02.72-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.729 2.535-4.516 3.154-.059 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.04-.399 0-.778.02-1.177.02-1.318.235-2.556 1.04-3.614a8.461 8.461 0 0 1 2.356-2.097c.471-.319.942-.598 1.472-.858.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.059-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.715.334-.26.668-.54 1.021-.859.49 1.178.766 2.316.805 3.474 0 .659-.04 1.318-.295 1.957a11.52 11.52 0 0 1-3.102 4.492c-.157.12-.137.2-.058.36a55.328 55.328 0 0 0 3.003 4.472s-.196.399-1.511-.46c-.314-.459-.629-.898-.923-1.397-.609-.979-1.217-1.957-1.787-2.955-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.319-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.099-.2l.118-.08c1.374-.459 2.788-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.452.459.726.659-.02-.08-.059-.16-.098-.24a53.49 53.49 0 0 1-2.395-5.69c-.059-.2-.137-.24-.334-.24-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.4 2.238 1.218 3.023 2.296.197.24.354.479.51.719-.49-2.137-.98-4.293-1.472-6.43-.785-.199-1.63-.359-2.414-.618-1.218-.42-2.356-1.018-3.26-1.997-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.376.118.2.216.399.354.619-.197-2.137-.275-4.253-.118-6.39-1.06-.319-2.022-.738-2.906-1.317-1.295-.859-2.414-1.877-2.885-3.434a9.274 9.274 0 0 1-.432-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.942.399 1.805.898 2.532 1.677.628.678.962 1.497 1.237 2.336.117.399.215.798.373 1.178 0-.12.02-.16.02-.28.176-2.056.45-4.093.863-6.11.04-.199.02-.359-.216-.439A9.502 9.502 0 0 1 6.97 30.18c-.688-1.058-.845-2.216-.825-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.687 2.815.039.3.039.62.117.899l.06-.24c.51-2.057 1.118-4.133 1.904-6.13.078-.2.078-.319-.099-.419-1.354-.978-2.375-2.216-3.121-3.753-.59-1.218-.589-2.456-.334-3.714.079-.459.196-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.58-.098 1.218-.137 1.917.039-.08.059-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.195-2.455.158-.62.393-1.258.845-1.717.53-.58 1.158-1.018 1.826-1.398.353-.24.706-.4 1.08-.579.058 0 .097.04.156.04-.02.3-.078.58-.098.878-.04 1.099-.294 2.197-.785 3.155Z" stroke="#000" stroke-opacity=".16" stroke-width="2.15" stroke-linejoin="round" mask="url(#i)"/>
</g>
<path d="M17.243 18.478c-.608 1.258-1.688 1.917-2.886 2.396-.137.08-.274.2-.333.32-.452 1.018-.884 2.076-1.316 3.074-.157.38-.275.739-.451 1.198.51-.659.962-1.218 1.413-1.757.825-.978 1.806-1.717 3.122-1.917 1.335-.22 2.67-.1 3.985.24.04.04.059.04.138.08-.334.499-.629 1.018-.943 1.477-.687.899-1.512 1.637-2.61 2.037-1.571.499-3.181.619-4.791.359-.157-.06-.295-.08-.452-.12a46.477 46.477 0 0 0-1.865 7.128c.314-.46.59-.978.864-1.438.687-1.178 1.551-2.116 2.866-2.575a9.092 9.092 0 0 1 3.083-.52c.333 0 .687.04 1.099.04-.196.48-.334.9-.49 1.298-.511 1.099-1.14 2.057-2.16 2.696-1.217.818-2.592 1.218-4.025 1.357-.451.04-.942.08-1.413.12a50.867 50.867 0 0 0-.707 7.368c.078-.08.098-.2.137-.32.157-.46.334-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.962-.44 1.983-.699 3.023-.858.177 0 .354-.04.55-.08v.24c-.04.219-.078.498-.137.778-.334 1.437-.884 2.815-2.101 3.753-1.276 1.059-2.768 1.718-4.398 2.077-.157.02-.314.02-.51.06-.04 2.535.157 5.031.589 7.527.177-.819.314-1.598.471-2.376.255-1.098.785-2.077 1.63-2.815 1.06-.899 2.296-1.478 3.592-1.957.138 0 .275-.08.491-.12-.02.719-.04 1.338-.118 1.957-.137 1.138-.451 2.176-1.178 3.035-1.236 1.437-2.729 2.535-4.515 3.154-.059 0-.118.04-.196.08.451 2.316 1.06 4.572 1.884 6.748.04-.399 0-.778.02-1.178.02-1.317.236-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097 11.9 11.9 0 0 1 1.473-.858c.059.22.078.42.117.579.275 1.637.275 3.234-.55 4.712-.686 1.218-1.629 2.236-2.728 3.094-.412.32-.825.58-1.257.859.805 2.096 1.728 4.133 2.828 6.07 0-.12 0-.2-.02-.28-.06-.54-.138-1.138-.197-1.677a5.277 5.277 0 0 1 .59-2.895c.569-1.038 1.334-1.937 2.238-2.716.333-.26.667-.539 1.02-.858.491 1.178.766 2.316.805 3.474 0 .659-.039 1.318-.294 1.956a11.52 11.52 0 0 1-3.102 4.493c-.157.12-.137.2-.059.36a55.327 55.327 0 0 0 3.004 4.471s-.197.4-1.512-.459c-.314-.459-.628-.898-.923-1.397a90.378 90.378 0 0 1-1.786-2.955c-.118-.26-.236-.34-.51-.26-1.728.4-3.476.4-5.183-.08-1.218-.32-2.2-1.098-3.004-2.036-.354-.42-.668-.939-1.001-1.358-.02-.08-.06-.12-.099-.2l.118-.08c1.374-.459 2.788-.698 4.221-.578 1.433.08 2.592.778 3.613 1.797.235.24.451.459.726.658-.02-.08-.059-.16-.098-.24a53.463 53.463 0 0 1-2.395-5.69c-.06-.199-.138-.239-.334-.239-1.708.12-3.377-.2-4.948-.898-1.217-.54-2.06-1.478-2.709-2.616-.314-.499-.55-1.078-.844-1.697.57 0 1.08-.08 1.59-.08.982-.04 1.963.04 2.925.3 1.316.399 2.239 1.218 3.024 2.296.196.24.353.479.51.718-.49-2.136-.981-4.292-1.472-6.428-.785-.2-1.63-.36-2.415-.62-1.217-.419-2.356-1.018-3.259-1.996-.785-.858-1.59-2.735-1.688-3.893h.039c1.688.02 3.318.34 4.79 1.278.903.539 1.473 1.437 1.944 2.376.118.2.216.399.353.618-.196-2.136-.275-4.252-.118-6.388-1.06-.32-2.022-.74-2.905-1.318-1.296-.859-2.415-1.877-2.886-3.434a9.274 9.274 0 0 1-.432-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.942.399 1.806.898 2.532 1.677.628.678.962 1.497 1.237 2.336.118.399.216.798.373 1.177 0-.12.02-.16.02-.279.176-2.056.451-4.093.863-6.11.04-.2.02-.359-.216-.439A9.502 9.502 0 0 1 5.68 29.32c-.687-1.058-.844-2.216-.825-3.474 0-.459.06-.898.118-1.437.59.32 1.158.559 1.65.858 1.099.64 2.06 1.418 2.689 2.536.49.858.609 1.837.687 2.815.04.3.04.619.118.898l.059-.24c.51-2.056 1.119-4.132 1.904-6.128.079-.2.079-.32-.098-.42-1.355-.978-2.376-2.216-3.122-3.753-.589-1.218-.589-2.456-.333-3.714.078-.46.196-.878.314-1.338l.039-.04c.864.54 1.669 1.159 2.356 1.937 1.06 1.138 1.63 2.456 1.511 4.093-.039.58-.098 1.218-.137 1.917.04-.08.059-.12.079-.2.432-.898.864-1.797 1.295-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.196-2.455.157-.62.393-1.258.844-1.717.53-.58 1.158-1.019 1.826-1.398.353-.24.707-.4 1.08-.579.059 0 .098.04.157.04-.02.3-.079.579-.098.878-.04 1.099-.295 2.197-.786 3.155Z" fill="#FFD57C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.897 50.047c-1.26 3.726-2.24 5.921-4.306 8.904l-.622-1.43a2.804 2.804 0 0 1-.007.07c-.07-.187-.139-.373-.206-.56l-.071-.164-.045-.164a41.595 41.595 0 0 1-1.431-5.213l-.03-.105-.015-.112c-.03-.143-.058-.287-.086-.431l.023-.012-.161-1.127-.039.18a40.272 40.272 0 0 1-.589-7.526c.046-.01.09-.017.132-.023l.063-1.312-.022.075c-.027.092-.053.179-.114.241.059-2.495.294-4.951.707-7.367l.045-.004.277-1.196a7.991 7.991 0 0 1-.146.222 46.476 46.476 0 0 1 1.866-7.128l.139.033c.103.023.203.045.312.087 1.61.26 3.22.14 4.79-.36 1.1-.399 1.924-1.137 2.611-2.036.165-.24.324-.497.486-.759l.046-.074c-2.923 1.732-5.053 2.57-8.135 3.108l.42-1.075c-.172.215-.348.44-.532.677.073-.19.136-.362.196-.527.085-.233.163-.448.256-.671.176-.409.353-.827.531-1.25.257-.608.517-1.223.784-1.825a.726.726 0 0 1 .203-.23h-.265a257.17 257.17 0 0 1-.802 1.685 63.337 63.337 0 0 0-1.866 4.691 56.278 56.278 0 0 0-1.118 3.937l-.059.24a1.244 1.244 0 0 1-.005-.019c-.785 3.807-1.117 7.949-1.336 10.7l-.045.557c-.046 1.659.036 3.31.188 4.973l-.09-.149c.089.786.204 1.612.342 2.453l.72 3.147.736 3.214a35.164 35.164 0 0 0-.072-.11c.215.752.44 1.46.67 2.1.095.025.146.086.188.227a54.16 54.16 0 0 0 1.117 2.883c.45 1.022.864 1.935 1.253 2.756l.025.05.058.125c.366.765.71 1.447 1.044 2.06.042.047.078.11.115.192.245.429.497.855.753 1.278.324.501.64 1.022.933 1.515l.1.161c.24.408.494.775.75 1.146l.173.252c1.316.859 1.512.46 1.512.46a55.325 55.325 0 0 1-3.004-4.473c-.07-.143-.093-.222.015-.323l-1.016-1.815v.002c.02.08.02.16.02.28-1.1-1.937-2.022-3.974-2.827-6.07l.14-.09c.381-.247.749-.484 1.116-.769 1.1-.858 2.042-1.877 2.729-3.094.825-1.478.825-3.075.55-4.712a3.384 3.384 0 0 1-.044-.225 8.635 8.635 0 0 0-.028-.151Zm2.019 6.741c-.755 4.362-1.306 6.716-2.54 9.8a11.522 11.522 0 0 0 3.027-4.426c.255-.639.295-1.297.295-1.956-.04-1.14-.306-2.26-.782-3.418Zm-4.635 9.679c-3.288-.513-5.542-1.555-8.849-3.39.114.152.226.312.34.473.18.258.362.518.556.749.805.938 1.787 1.717 3.004 2.036 1.63.458 3.297.478 4.949.132Zm-3.407-8.086c-2.815-1.035-4.77-2.366-8.195-5.008l.12.26c.202.44.391.853.623 1.222.648 1.138 1.492 2.077 2.71 2.616 1.507.67 3.106.992 4.742.91ZM8.768 49.87c-2.84-1.502-4.332-3.052-6.77-6.411-.055-.002-.11-.003-.166-.003h-.039c.098 1.158.903 3.035 1.688 3.893.903.978 2.042 1.577 3.26 1.997.533.176 1.093.306 1.644.434l.383.09Zm-.312-8.64c-2.329-1.938-3.622-3.769-5.678-7.464a16.062 16.062 0 0 1-.189-.07l-.01.027-.006.158c-.004.075-.007.123.005.171.02.858.177 1.717.432 2.536.471 1.557 1.59 2.575 2.886 3.434.787.515 1.635.904 2.56 1.209Zm1.045-8.499c-1.973-2.34-3.042-4.092-4.542-8.194l-.013.116c-.048.432-.09.805-.09 1.193-.02 1.258.137 2.416.824 3.474a9.499 9.499 0 0 0 3.821 3.411Zm2.6-7.899.012.001c-1.854-3.366-2.53-5.368-3.279-8.884a73.3 73.3 0 0 1-.054.21c-.096.37-.188.722-.253 1.102-.255 1.258-.255 2.496.334 3.714.746 1.537 1.766 2.775 3.121 3.753a.318.318 0 0 1 .119.104ZM18.089 14.8c-.983 2.306-1.84 3.829-3.644 6.038 1.163-.476 2.205-1.133 2.799-2.36.49-.958.745-2.056.785-3.155a6.268 6.268 0 0 1 .06-.523Zm-.102 14.161c-2.762 2.514-4.66 3.892-7.419 4.969.314-.026.627-.052.923-.079 1.433-.14 2.808-.539 4.025-1.357 1.02-.64 1.649-1.598 2.16-2.696.066-.168.128-.34.193-.517l.118-.32Zm-1.53 6.738c-2.631 3.117-4.301 4.833-6.996 6.633.068-.009.132-.014.194-.019l.168-.016c1.629-.36 3.121-1.018 4.397-2.077 1.217-.938 1.767-2.316 2.1-3.753.04-.186.07-.373.098-.541l.038-.227Zm-.38 7.236c-2.143 3.5-3.571 5.613-5.66 7.776 1.724-.627 3.169-1.705 4.373-3.103.726-.859 1.04-1.897 1.177-3.035.067-.526.091-1.051.11-1.638Z" fill="#E1910E"/>
<mask id="j" maskUnits="userSpaceOnUse" x="-.085" y="12.405" width="23" height="61" fill="#000">
<path fill="#fff" d="M-.085 12.405h23v61h-23z"/>
<path d="M17.244 18.478c-.609 1.258-1.689 1.917-2.886 2.396-.138.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198.51-.659.962-1.218 1.414-1.757.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.059.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.571.499-3.18.619-4.79.359-.158-.06-.295-.08-.452-.12a46.489 46.489 0 0 0-1.865 7.128c.314-.46.589-.978.864-1.438.687-1.178 1.55-2.116 2.866-2.575a9.092 9.092 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.298-.51 1.099-1.139 2.057-2.16 2.696-1.217.818-2.591 1.218-4.024 1.357-.452.04-.943.08-1.414.12a50.865 50.865 0 0 0-.707 7.368c.079-.08.098-.2.138-.32.157-.46.333-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.961-.44 1.982-.699 3.023-.858.176 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.437-.883 2.815-2.1 3.753-1.277 1.059-2.769 1.718-4.398 2.077-.157.02-.314.02-.51.06-.04 2.535.156 5.031.588 7.527.177-.819.315-1.598.472-2.376.255-1.098.785-2.077 1.629-2.815 1.06-.899 2.297-1.478 3.593-1.957.137 0 .275-.08.49-.12-.02.719-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.73 2.535-4.516 3.154-.058 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.039-.399 0-.778.02-1.178.019-1.317.235-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097 11.9 11.9 0 0 1 1.472-.858c.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.059-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.716.334-.26.668-.539 1.02-.858.492 1.178.767 2.316.806 3.474 0 .659-.04 1.318-.295 1.956a11.52 11.52 0 0 1-3.101 4.493c-.158.12-.138.2-.06.36a55.327 55.327 0 0 0 3.004 4.471s-.196.4-1.511-.459c-.314-.459-.629-.898-.923-1.397a90.378 90.378 0 0 1-1.787-2.955c-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.32-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.1-.2l.119-.08c1.374-.459 2.787-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.452.459.726.658-.02-.08-.059-.16-.098-.24a53.484 53.484 0 0 1-2.395-5.69c-.059-.199-.137-.239-.334-.239-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.399 2.238 1.218 3.023 2.296.197.24.354.479.51.718-.49-2.136-.98-4.292-1.472-6.428-.785-.2-1.63-.36-2.414-.62-1.218-.419-2.356-1.018-3.26-1.996-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.376.118.2.216.399.354.618-.197-2.136-.275-4.252-.118-6.388-1.06-.32-2.022-.74-2.906-1.318-1.295-.859-2.414-1.877-2.886-3.434a9.274 9.274 0 0 1-.431-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.941.399 1.805.898 2.532 1.677.628.678.962 1.497 1.236 2.336.118.399.216.798.373 1.177 0-.12.02-.16.02-.279.177-2.056.452-4.093.864-6.11.04-.2.02-.359-.216-.439A9.502 9.502 0 0 1 5.68 29.32c-.687-1.058-.844-2.216-.824-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.687 2.815.039.3.039.619.117.898l.06-.24c.51-2.056 1.118-4.132 1.904-6.128.078-.2.078-.32-.099-.42-1.354-.978-2.375-2.216-3.121-3.753-.59-1.218-.59-2.456-.334-3.714.079-.46.196-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.58-.098 1.218-.137 1.917.039-.08.058-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.195-2.455.157-.62.393-1.258.845-1.717.53-.58 1.158-1.019 1.825-1.398.354-.24.707-.4 1.08-.579.06 0 .098.04.157.04-.02.3-.078.579-.098.878-.04 1.099-.294 2.197-.785 3.155Z"/>
</mask>
<path d="M17.244 18.478c-.609 1.258-1.689 1.917-2.886 2.396-.138.08-.275.2-.334.32-.451 1.018-.883 2.076-1.315 3.074-.157.38-.275.739-.452 1.198.51-.659.962-1.218 1.414-1.757.824-.978 1.806-1.717 3.121-1.917 1.335-.22 2.67-.1 3.986.24.039.04.059.04.137.08-.334.499-.628 1.018-.942 1.477-.687.899-1.512 1.637-2.611 2.037-1.571.499-3.18.619-4.79.359-.158-.06-.295-.08-.452-.12a46.489 46.489 0 0 0-1.865 7.128c.314-.46.589-.978.864-1.438.687-1.178 1.55-2.116 2.866-2.575a9.092 9.092 0 0 1 3.082-.52c.334 0 .687.04 1.1.04-.197.48-.334.9-.491 1.298-.51 1.099-1.139 2.057-2.16 2.696-1.217.818-2.591 1.218-4.024 1.357-.452.04-.943.08-1.414.12a50.865 50.865 0 0 0-.707 7.368c.079-.08.098-.2.138-.32.157-.46.333-.938.51-1.438.55-1.437 1.473-2.535 2.867-3.194.961-.44 1.982-.699 3.023-.858.176 0 .353-.04.55-.08v.24c-.04.219-.079.498-.138.778-.334 1.437-.883 2.815-2.1 3.753-1.277 1.059-2.769 1.718-4.398 2.077-.157.02-.314.02-.51.06-.04 2.535.156 5.031.588 7.527.177-.819.315-1.598.472-2.376.255-1.098.785-2.077 1.629-2.815 1.06-.899 2.297-1.478 3.593-1.957.137 0 .275-.08.49-.12-.02.719-.039 1.338-.117 1.957-.138 1.138-.452 2.176-1.178 3.035-1.237 1.437-2.73 2.535-4.516 3.154-.058 0-.117.04-.196.08.452 2.316 1.06 4.572 1.885 6.748.039-.399 0-.778.02-1.178.019-1.317.235-2.555 1.04-3.613a8.461 8.461 0 0 1 2.356-2.097 11.9 11.9 0 0 1 1.472-.858c.06.22.079.42.118.579.275 1.637.275 3.234-.55 4.712-.687 1.218-1.63 2.236-2.729 3.094-.412.32-.824.58-1.256.859.805 2.096 1.728 4.133 2.827 6.07 0-.12 0-.2-.02-.28-.059-.54-.137-1.138-.196-1.677a5.277 5.277 0 0 1 .589-2.895c.57-1.038 1.335-1.937 2.238-2.716.334-.26.668-.539 1.02-.858.492 1.178.767 2.316.806 3.474 0 .659-.04 1.318-.295 1.956a11.52 11.52 0 0 1-3.101 4.493c-.158.12-.138.2-.06.36a55.327 55.327 0 0 0 3.004 4.471s-.196.4-1.511-.459c-.314-.459-.629-.898-.923-1.397a90.378 90.378 0 0 1-1.787-2.955c-.117-.26-.235-.34-.51-.26-1.728.4-3.475.4-5.183-.08-1.217-.32-2.199-1.098-3.004-2.036-.353-.42-.667-.939-1-1.358-.02-.08-.06-.12-.1-.2l.119-.08c1.374-.459 2.787-.698 4.22-.578 1.434.08 2.592.778 3.613 1.797.236.24.452.459.726.658-.02-.08-.059-.16-.098-.24a53.484 53.484 0 0 1-2.395-5.69c-.059-.199-.137-.239-.334-.239-1.708.12-3.376-.2-4.947-.898-1.217-.54-2.061-1.478-2.71-2.616-.313-.499-.549-1.078-.843-1.697.569 0 1.08-.08 1.59-.08.981-.04 1.963.04 2.925.3 1.315.399 2.238 1.218 3.023 2.296.197.24.354.479.51.718-.49-2.136-.98-4.292-1.472-6.428-.785-.2-1.63-.36-2.414-.62-1.218-.419-2.356-1.018-3.26-1.996-.785-.858-1.59-2.735-1.688-3.893h.04c1.688.02 3.317.34 4.79 1.278.903.539 1.472 1.437 1.943 2.376.118.2.216.399.354.618-.197-2.136-.275-4.252-.118-6.388-1.06-.32-2.022-.74-2.906-1.318-1.295-.859-2.414-1.877-2.886-3.434a9.274 9.274 0 0 1-.431-2.536c-.02-.08 0-.16 0-.36.746.28 1.472.48 2.16.7.941.399 1.805.898 2.532 1.677.628.678.962 1.497 1.236 2.336.118.399.216.798.373 1.177 0-.12.02-.16.02-.279.177-2.056.452-4.093.864-6.11.04-.2.02-.359-.216-.439A9.502 9.502 0 0 1 5.68 29.32c-.687-1.058-.844-2.216-.824-3.474 0-.459.059-.898.118-1.437.589.32 1.158.559 1.649.858 1.1.64 2.061 1.418 2.69 2.536.49.858.608 1.837.687 2.815.039.3.039.619.117.898l.06-.24c.51-2.056 1.118-4.132 1.904-6.128.078-.2.078-.32-.099-.42-1.354-.978-2.375-2.216-3.121-3.753-.59-1.218-.59-2.456-.334-3.714.079-.46.196-.878.314-1.338l.04-.04c.863.54 1.668 1.159 2.355 1.937 1.06 1.138 1.63 2.456 1.512 4.093-.04.58-.098 1.218-.137 1.917.039-.08.058-.12.078-.2.432-.898.864-1.797 1.296-2.715.04-.12.04-.24.04-.36-.04-.818-.02-1.637.195-2.455.157-.62.393-1.258.845-1.717.53-.58 1.158-1.019 1.825-1.398.354-.24.707-.4 1.08-.579.06 0 .098.04.157.04-.02.3-.078.579-.098.878-.04 1.099-.294 2.197-.785 3.155Z" stroke="#A05500" stroke-width="2.15" stroke-linejoin="round" mask="url(#j)"/>
<g style="mix-blend-mode:color-burn">
<mask id="k" maskUnits="userSpaceOnUse" x="58.059" y="13.265" width="23" height="61" fill="#000">
<path fill="#fff" d="M58.059 13.265h23v61h-23z"/>
<path d="M63.73 19.338c.609 1.258 1.689 1.917 2.886 2.396.138.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.452 1.198a58.085 58.085 0 0 0-1.414-1.757c-.824-.978-1.806-1.717-3.121-1.917-1.335-.22-2.67-.1-3.986.24-.039.04-.058.04-.137.08.334.499.628 1.018.942 1.477.688.899 1.512 1.637 2.611 2.037 1.571.499 3.18.619 4.79.36.158-.06.295-.08.452-.12a46.466 46.466 0 0 1 1.865 7.127c-.314-.46-.589-.978-.863-1.438-.688-1.177-1.551-2.116-2.867-2.575a9.09 9.09 0 0 0-3.082-.52c-.334 0-.687.04-1.1.04.197.48.334.9.491 1.299.51 1.098 1.14 2.056 2.16 2.695 1.217.819 2.591 1.218 4.025 1.358.451.04.942.08 1.413.12.412 2.415.648 4.87.707 7.367-.079-.08-.098-.2-.138-.32-.157-.46-.333-.938-.51-1.437-.55-1.438-1.472-2.536-2.866-3.195-.962-.44-1.983-.699-3.024-.858-.176 0-.353-.04-.55-.08v.24c.04.219.08.498.138.778.334 1.438.883 2.815 2.1 3.754 1.277 1.058 2.769 1.717 4.398 2.076.157.02.314.02.51.06a40.27 40.27 0 0 1-.588 7.527c-.177-.819-.314-1.597-.471-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.137 0-.274-.08-.49-.12.02.72.039 1.338.117 1.957.138 1.138.452 2.176 1.178 3.035 1.237 1.437 2.73 2.535 4.516 3.154.059 0 .117.04.196.08-.451 2.316-1.06 4.572-1.885 6.748-.039-.399 0-.778-.02-1.177-.019-1.318-.235-2.556-1.04-3.614a8.462 8.462 0 0 0-2.356-2.097c-.47-.319-.942-.598-1.472-.858-.059.22-.079.42-.118.579-.275 1.637-.275 3.234.55 4.712.687 1.218 1.63 2.236 2.729 3.094.412.32.824.58 1.256.859-.805 2.096-1.727 4.133-2.827 6.07 0-.12 0-.2.02-.28.059-.54.137-1.138.196-1.677a5.277 5.277 0 0 0-.589-2.895c-.57-1.038-1.335-1.937-2.238-2.715-.334-.26-.667-.54-1.02-.859-.492 1.178-.767 2.316-.806 3.474 0 .659.04 1.318.295 1.957a11.52 11.52 0 0 0 3.102 4.492c.157.12.137.2.059.36a55.354 55.354 0 0 1-3.004 4.472s.196.399 1.511-.46c.315-.459.629-.898.923-1.397.609-.979 1.217-1.957 1.787-2.955.118-.26.235-.34.51-.26 1.728.4 3.475.4 5.183-.08 1.217-.319 2.199-1.098 3.004-2.036.353-.42.667-.939 1.001-1.358.02-.08.059-.12.098-.2l-.118-.08c-1.374-.459-2.787-.698-4.22-.578-1.434.08-2.592.778-3.613 1.797-.235.24-.451.459-.726.659.02-.08.059-.16.098-.24a53.47 53.47 0 0 0 2.395-5.69c.059-.2.137-.24.334-.24 1.708.12 3.377-.2 4.947-.898 1.217-.54 2.061-1.478 2.71-2.616.313-.499.55-1.078.844-1.697-.57 0-1.08-.08-1.59-.08-.982-.04-1.964.04-2.926.3-1.315.4-2.238 1.218-3.023 2.296-.197.24-.354.479-.51.719.49-2.137.981-4.293 1.472-6.43.785-.199 1.63-.359 2.415-.618 1.217-.42 2.355-1.018 3.259-1.997.785-.858 1.59-2.735 1.688-3.893h-.04c-1.688.02-3.317.34-4.79 1.278-.903.539-1.472 1.437-1.943 2.376-.118.2-.216.399-.354.619.197-2.137.275-4.253.118-6.39 1.06-.319 2.022-.738 2.906-1.317 1.295-.859 2.415-1.877 2.886-3.434a9.277 9.277 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.473.48-2.16.7-.942.399-1.806.898-2.532 1.677-.629.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.178 0-.12-.02-.16-.02-.28a53.172 53.172 0 0 0-.864-6.11c-.04-.199-.02-.359.216-.439a9.502 9.502 0 0 0 3.868-3.434c.687-1.058.844-2.216.824-3.474 0-.459-.059-.898-.118-1.437-.588.32-1.158.559-1.649.858-1.1.64-2.061 1.418-2.69 2.536-.49.858-.608 1.837-.686 2.815-.04.3-.04.62-.118.899l-.06-.24c-.51-2.057-1.118-4.133-1.903-6.13-.079-.2-.079-.319.098-.419 1.354-.978 2.375-2.216 3.121-3.753.59-1.218.59-2.456.334-3.714-.079-.459-.196-.878-.314-1.338l-.04-.04c-.863.54-1.668 1.159-2.355 1.937-1.06 1.138-1.63 2.456-1.512 4.093.04.58.098 1.218.138 1.917a.84.84 0 0 1-.079-.2c-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.04-.818.02-1.637-.196-2.455-.157-.62-.393-1.258-.845-1.717-.53-.58-1.158-1.018-1.825-1.398-.354-.24-.707-.4-1.08-.579-.059 0-.098.04-.157.04.02.3.078.58.098.878.04 1.099.294 2.197.785 3.155Z"/>
</mask>
<path d="M63.73 19.338c.609 1.258 1.689 1.917 2.886 2.396.138.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.452 1.198a58.085 58.085 0 0 0-1.414-1.757c-.824-.978-1.806-1.717-3.121-1.917-1.335-.22-2.67-.1-3.986.24-.039.04-.058.04-.137.08.334.499.628 1.018.942 1.477.688.899 1.512 1.637 2.611 2.037 1.571.499 3.18.619 4.79.36.158-.06.295-.08.452-.12a46.466 46.466 0 0 1 1.865 7.127c-.314-.46-.589-.978-.863-1.438-.688-1.177-1.551-2.116-2.867-2.575a9.09 9.09 0 0 0-3.082-.52c-.334 0-.687.04-1.1.04.197.48.334.9.491 1.299.51 1.098 1.14 2.056 2.16 2.695 1.217.819 2.591 1.218 4.025 1.358.451.04.942.08 1.413.12.412 2.415.648 4.87.707 7.367-.079-.08-.098-.2-.138-.32-.157-.46-.333-.938-.51-1.437-.55-1.438-1.472-2.536-2.866-3.195-.962-.44-1.983-.699-3.024-.858-.176 0-.353-.04-.55-.08v.24c.04.219.08.498.138.778.334 1.438.883 2.815 2.1 3.754 1.277 1.058 2.769 1.717 4.398 2.076.157.02.314.02.51.06a40.27 40.27 0 0 1-.588 7.527c-.177-.819-.314-1.597-.471-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.137 0-.274-.08-.49-.12.02.72.039 1.338.117 1.957.138 1.138.452 2.176 1.178 3.035 1.237 1.437 2.73 2.535 4.516 3.154.059 0 .117.04.196.08-.451 2.316-1.06 4.572-1.885 6.748-.039-.399 0-.778-.02-1.177-.019-1.318-.235-2.556-1.04-3.614a8.462 8.462 0 0 0-2.356-2.097c-.47-.319-.942-.598-1.472-.858-.059.22-.079.42-.118.579-.275 1.637-.275 3.234.55 4.712.687 1.218 1.63 2.236 2.729 3.094.412.32.824.58 1.256.859-.805 2.096-1.727 4.133-2.827 6.07 0-.12 0-.2.02-.28.059-.54.137-1.138.196-1.677a5.277 5.277 0 0 0-.589-2.895c-.57-1.038-1.335-1.937-2.238-2.715-.334-.26-.667-.54-1.02-.859-.492 1.178-.767 2.316-.806 3.474 0 .659.04 1.318.295 1.957a11.52 11.52 0 0 0 3.102 4.492c.157.12.137.2.059.36a55.354 55.354 0 0 1-3.004 4.472s.196.399 1.511-.46c.315-.459.629-.898.923-1.397.609-.979 1.217-1.957 1.787-2.955.118-.26.235-.34.51-.26 1.728.4 3.475.4 5.183-.08 1.217-.319 2.199-1.098 3.004-2.036.353-.42.667-.939 1.001-1.358.02-.08.059-.12.098-.2l-.118-.08c-1.374-.459-2.787-.698-4.22-.578-1.434.08-2.592.778-3.613 1.797-.235.24-.451.459-.726.659.02-.08.059-.16.098-.24a53.47 53.47 0 0 0 2.395-5.69c.059-.2.137-.24.334-.24 1.708.12 3.377-.2 4.947-.898 1.217-.54 2.061-1.478 2.71-2.616.313-.499.55-1.078.844-1.697-.57 0-1.08-.08-1.59-.08-.982-.04-1.964.04-2.926.3-1.315.4-2.238 1.218-3.023 2.296-.197.24-.354.479-.51.719.49-2.137.981-4.293 1.472-6.43.785-.199 1.63-.359 2.415-.618 1.217-.42 2.355-1.018 3.259-1.997.785-.858 1.59-2.735 1.688-3.893h-.04c-1.688.02-3.317.34-4.79 1.278-.903.539-1.472 1.437-1.943 2.376-.118.2-.216.399-.354.619.197-2.137.275-4.253.118-6.39 1.06-.319 2.022-.738 2.906-1.317 1.295-.859 2.415-1.877 2.886-3.434a9.277 9.277 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.473.48-2.16.7-.942.399-1.806.898-2.532 1.677-.629.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.178 0-.12-.02-.16-.02-.28a53.172 53.172 0 0 0-.864-6.11c-.04-.199-.02-.359.216-.439a9.502 9.502 0 0 0 3.868-3.434c.687-1.058.844-2.216.824-3.474 0-.459-.059-.898-.118-1.437-.588.32-1.158.559-1.649.858-1.1.64-2.061 1.418-2.69 2.536-.49.858-.608 1.837-.686 2.815-.04.3-.04.62-.118.899l-.06-.24c-.51-2.057-1.118-4.133-1.903-6.13-.079-.2-.079-.319.098-.419 1.354-.978 2.375-2.216 3.121-3.753.59-1.218.59-2.456.334-3.714-.079-.459-.196-.878-.314-1.338l-.04-.04c-.863.54-1.668 1.159-2.355 1.937-1.06 1.138-1.63 2.456-1.512 4.093.04.58.098 1.218.138 1.917a.84.84 0 0 1-.079-.2c-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.04-.818.02-1.637-.196-2.455-.157-.62-.393-1.258-.845-1.717-.53-.58-1.158-1.018-1.825-1.398-.354-.24-.707-.4-1.08-.579-.059 0-.098.04-.157.04.02.3.078.58.098.878.04 1.099.294 2.197.785 3.155Z" fill="#000" fill-opacity=".16"/>
<path d="M63.73 19.338c.609 1.258 1.689 1.917 2.886 2.396.138.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.452 1.198a58.085 58.085 0 0 0-1.414-1.757c-.824-.978-1.806-1.717-3.121-1.917-1.335-.22-2.67-.1-3.986.24-.039.04-.058.04-.137.08.334.499.628 1.018.942 1.477.688.899 1.512 1.637 2.611 2.037 1.571.499 3.18.619 4.79.36.158-.06.295-.08.452-.12a46.466 46.466 0 0 1 1.865 7.127c-.314-.46-.589-.978-.863-1.438-.688-1.177-1.551-2.116-2.867-2.575a9.09 9.09 0 0 0-3.082-.52c-.334 0-.687.04-1.1.04.197.48.334.9.491 1.299.51 1.098 1.14 2.056 2.16 2.695 1.217.819 2.591 1.218 4.025 1.358.451.04.942.08 1.413.12.412 2.415.648 4.87.707 7.367-.079-.08-.098-.2-.138-.32-.157-.46-.333-.938-.51-1.437-.55-1.438-1.472-2.536-2.866-3.195-.962-.44-1.983-.699-3.024-.858-.176 0-.353-.04-.55-.08v.24c.04.219.08.498.138.778.334 1.438.883 2.815 2.1 3.754 1.277 1.058 2.769 1.717 4.398 2.076.157.02.314.02.51.06a40.27 40.27 0 0 1-.588 7.527c-.177-.819-.314-1.597-.471-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.137 0-.274-.08-.49-.12.02.72.039 1.338.117 1.957.138 1.138.452 2.176 1.178 3.035 1.237 1.437 2.73 2.535 4.516 3.154.059 0 .117.04.196.08-.451 2.316-1.06 4.572-1.885 6.748-.039-.399 0-.778-.02-1.177-.019-1.318-.235-2.556-1.04-3.614a8.462 8.462 0 0 0-2.356-2.097c-.47-.319-.942-.598-1.472-.858-.059.22-.079.42-.118.579-.275 1.637-.275 3.234.55 4.712.687 1.218 1.63 2.236 2.729 3.094.412.32.824.58 1.256.859-.805 2.096-1.727 4.133-2.827 6.07 0-.12 0-.2.02-.28.059-.54.137-1.138.196-1.677a5.277 5.277 0 0 0-.589-2.895c-.57-1.038-1.335-1.937-2.238-2.715-.334-.26-.667-.54-1.02-.859-.492 1.178-.767 2.316-.806 3.474 0 .659.04 1.318.295 1.957a11.52 11.52 0 0 0 3.102 4.492c.157.12.137.2.059.36a55.354 55.354 0 0 1-3.004 4.472s.196.399 1.511-.46c.315-.459.629-.898.923-1.397.609-.979 1.217-1.957 1.787-2.955.118-.26.235-.34.51-.26 1.728.4 3.475.4 5.183-.08 1.217-.319 2.199-1.098 3.004-2.036.353-.42.667-.939 1.001-1.358.02-.08.059-.12.098-.2l-.118-.08c-1.374-.459-2.787-.698-4.22-.578-1.434.08-2.592.778-3.613 1.797-.235.24-.451.459-.726.659.02-.08.059-.16.098-.24a53.47 53.47 0 0 0 2.395-5.69c.059-.2.137-.24.334-.24 1.708.12 3.377-.2 4.947-.898 1.217-.54 2.061-1.478 2.71-2.616.313-.499.55-1.078.844-1.697-.57 0-1.08-.08-1.59-.08-.982-.04-1.964.04-2.926.3-1.315.4-2.238 1.218-3.023 2.296-.197.24-.354.479-.51.719.49-2.137.981-4.293 1.472-6.43.785-.199 1.63-.359 2.415-.618 1.217-.42 2.355-1.018 3.259-1.997.785-.858 1.59-2.735 1.688-3.893h-.04c-1.688.02-3.317.34-4.79 1.278-.903.539-1.472 1.437-1.943 2.376-.118.2-.216.399-.354.619.197-2.137.275-4.253.118-6.39 1.06-.319 2.022-.738 2.906-1.317 1.295-.859 2.415-1.877 2.886-3.434a9.277 9.277 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.473.48-2.16.7-.942.399-1.806.898-2.532 1.677-.629.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.178 0-.12-.02-.16-.02-.28a53.172 53.172 0 0 0-.864-6.11c-.04-.199-.02-.359.216-.439a9.502 9.502 0 0 0 3.868-3.434c.687-1.058.844-2.216.824-3.474 0-.459-.059-.898-.118-1.437-.588.32-1.158.559-1.649.858-1.1.64-2.061 1.418-2.69 2.536-.49.858-.608 1.837-.686 2.815-.04.3-.04.62-.118.899l-.06-.24c-.51-2.057-1.118-4.133-1.903-6.13-.079-.2-.079-.319.098-.419 1.354-.978 2.375-2.216 3.121-3.753.59-1.218.59-2.456.334-3.714-.079-.459-.196-.878-.314-1.338l-.04-.04c-.863.54-1.668 1.159-2.355 1.937-1.06 1.138-1.63 2.456-1.512 4.093.04.58.098 1.218.138 1.917a.84.84 0 0 1-.079-.2c-.432-.898-.864-1.797-1.296-2.715-.039-.12-.039-.24-.039-.36.04-.818.02-1.637-.196-2.455-.157-.62-.393-1.258-.845-1.717-.53-.58-1.158-1.018-1.825-1.398-.354-.24-.707-.4-1.08-.579-.059 0-.098.04-.157.04.02.3.078.58.098.878.04 1.099.294 2.197.785 3.155Z" stroke="#000" stroke-opacity=".16" stroke-width="2.15" stroke-linejoin="round" mask="url(#k)"/>
</g>
<path d="M65.02 18.478c.61 1.258 1.69 1.917 2.887 2.396.137.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.451 1.198a57.93 57.93 0 0 0-1.413-1.757c-.825-.978-1.806-1.717-3.122-1.917-1.335-.22-2.67-.1-3.985.24-.04.04-.059.04-.137.08.333.499.628 1.018.942 1.477.687.899 1.512 1.637 2.611 2.037 1.57.499 3.18.619 4.79.359.157-.06.295-.08.452-.12a46.466 46.466 0 0 1 1.865 7.128c-.314-.46-.59-.978-.864-1.438-.687-1.178-1.55-2.116-2.866-2.575a9.093 9.093 0 0 0-3.082-.52c-.334 0-.688.04-1.1.04.196.48.334.9.49 1.298.511 1.099 1.14 2.057 2.16 2.696 1.218.818 2.592 1.218 4.025 1.357.452.04.942.08 1.414.12.412 2.416.648 4.872.706 7.368-.078-.08-.098-.2-.137-.32-.157-.46-.334-.938-.51-1.438-.55-1.437-1.473-2.535-2.867-3.194-.962-.44-1.983-.699-3.023-.858-.177 0-.354-.04-.55-.08v.24c.04.219.079.498.138.778.333 1.437.883 2.815 2.1 3.753 1.276 1.059 2.768 1.718 4.398 2.077.157.02.314.02.51.06a40.27 40.27 0 0 1-.589 7.527c-.176-.819-.314-1.598-.47-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.138 0-.275-.08-.49-.12.019.719.038 1.338.117 1.957.137 1.138.452 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.515 3.154.06 0 .118.04.197.08-.452 2.316-1.06 4.572-1.885 6.748-.04-.399 0-.778-.02-1.178-.02-1.317-.235-2.555-1.04-3.613a8.461 8.461 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.472-.858-.06.22-.08.42-.118.579-.275 1.637-.275 3.234.55 4.712.686 1.218 1.629 2.236 2.728 3.094.413.32.825.58 1.257.859-.805 2.096-1.728 4.133-2.827 6.07 0-.12 0-.2.02-.28.058-.54.137-1.138.196-1.677a5.277 5.277 0 0 0-.59-2.895c-.569-1.038-1.334-1.937-2.237-2.716-.334-.26-.668-.539-1.021-.858-.491 1.178-.766 2.316-.805 3.474 0 .659.04 1.318.294 1.956a11.52 11.52 0 0 0 3.102 4.493c.157.12.138.2.06.36a55.328 55.328 0 0 1-3.005 4.471s.197.4 1.512-.459c.314-.459.628-.898.923-1.397a90.557 90.557 0 0 0 1.786-2.955c.118-.26.236-.34.51-.26 1.728.4 3.476.4 5.184-.08 1.217-.32 2.198-1.098 3.003-2.036.354-.42.668-.939 1.002-1.358.02-.08.058-.12.098-.2l-.118-.08c-1.374-.459-2.788-.698-4.221-.578-1.433.08-2.591.778-3.612 1.797-.236.24-.452.459-.727.658.02-.08.06-.16.099-.24a53.463 53.463 0 0 0 2.395-5.69c.058-.199.137-.239.333-.239 1.708.12 3.377-.2 4.948-.898 1.217-.54 2.061-1.478 2.709-2.616.314-.499.55-1.078.844-1.697-.57 0-1.08-.08-1.59-.08-.982-.04-1.963.04-2.925.3-1.316.399-2.238 1.218-3.024 2.296-.196.24-.353.479-.51.718.49-2.136.981-4.292 1.472-6.428.786-.2 1.63-.36 2.415-.62 1.217-.419 2.356-1.018 3.259-1.996.785-.858 1.59-2.735 1.688-3.893h-.039c-1.688.02-3.318.34-4.79 1.278-.903.539-1.473 1.437-1.944 2.376-.117.2-.216.399-.353.618.196-2.136.275-4.252.118-6.388 1.06-.32 2.022-.74 2.905-1.318 1.296-.859 2.415-1.877 2.886-3.434a9.274 9.274 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.472.48-2.16.7-.942.399-1.806.898-2.532 1.677-.628.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.177 0-.12-.02-.16-.02-.279a53.172 53.172 0 0 0-.863-6.11c-.04-.2-.02-.359.216-.439a9.502 9.502 0 0 0 3.867-3.434c.687-1.058.844-2.216.825-3.474 0-.459-.06-.898-.118-1.437-.589.32-1.158.559-1.65.858-1.099.64-2.06 1.418-2.689 2.536-.49.858-.608 1.837-.687 2.815-.04.3-.04.619-.118.898l-.059-.24c-.51-2.056-1.119-4.132-1.904-6.128-.078-.2-.078-.32.098-.42 1.355-.978 2.376-2.216 3.122-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.197-.878-.315-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.63 2.456-1.511 4.093.039.58.098 1.218.137 1.917-.04-.08-.059-.12-.078-.2-.432-.898-.864-1.797-1.296-2.715-.04-.12-.04-.24-.04-.36.04-.818.02-1.637-.196-2.455-.157-.62-.392-1.258-.844-1.717-.53-.58-1.158-1.019-1.826-1.398-.353-.24-.706-.4-1.08-.579-.058 0-.098.04-.157.04.02.3.079.579.099.878.039 1.099.294 2.197.785 3.155Z" fill="#FFD57C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M65.368 50.048c1.26 3.725 2.24 5.92 4.306 8.903l.622-1.432.007.071c.071-.188.14-.376.209-.566l.068-.157.043-.157a41.608 41.608 0 0 0 1.435-5.228l.027-.097.015-.104c.03-.146.059-.292.087-.439a1.65 1.65 0 0 1-.023-.012l.161-1.128.04.182a40.27 40.27 0 0 0 .588-7.527 2.055 2.055 0 0 0-.132-.023l-.064-1.314c.009.026.016.052.023.077.027.092.053.179.114.242a50.868 50.868 0 0 0-.707-7.368l-.045-.004-.278-1.197c.048.076.097.15.147.223a46.477 46.477 0 0 0-1.865-7.128 4.692 4.692 0 0 1-.14.033c-.103.023-.203.045-.312.087-1.61.26-3.22.14-4.79-.36-1.1-.399-1.924-1.137-2.611-2.036-.165-.24-.324-.497-.486-.759l-.046-.074c2.923 1.732 5.053 2.57 8.135 3.108l-.42-1.076c.171.215.348.44.532.678-.073-.19-.136-.362-.195-.526a16.395 16.395 0 0 0-.256-.672c-.177-.409-.354-.827-.532-1.25-.257-.608-.517-1.223-.784-1.825a.725.725 0 0 0-.203-.23h.266c.264.562.53 1.118.794 1.67.583 1.313 1.28 3.001 1.88 4.729a56.373 56.373 0 0 1 1.111 3.914l.06.24c0-.006.002-.012.004-.018.785 3.807 1.116 7.948 1.336 10.698l.046.568c.045 1.655-.037 3.303-.19 4.963.032-.05.062-.1.09-.148a49.259 49.259 0 0 1-.342 2.46c-.24 1.043-.48 2.09-.719 3.139-.245 1.073-.49 2.146-.736 3.214l.072-.11c-.215.752-.44 1.46-.67 2.1-.095.025-.146.086-.188.227-.34.96-.71 1.916-1.107 2.86-.46 1.044-.881 1.974-1.277 2.809l-.01.02a43.56 43.56 0 0 1-1.103 2.186.764.764 0 0 0-.115.19c-.242.426-.492.848-.746 1.267-.33.51-.653 1.042-.95 1.544l-.09.144c-.24.408-.494.775-.75 1.146l-.173.252c-1.316.859-1.512.46-1.512.46a55.345 55.345 0 0 0 3.004-4.473c.07-.143.093-.222-.016-.323l1.017-1.816v.003c-.02.08-.02.16-.02.28 1.1-1.937 2.023-3.974 2.828-6.07l-.14-.09a15.432 15.432 0 0 1-1.117-.769c-1.1-.858-2.042-1.877-2.729-3.094-.824-1.478-.824-3.075-.55-4.712.017-.068.03-.144.045-.225l.027-.15Zm-2.02 6.741c.756 4.36 1.307 6.715 2.541 9.798a11.522 11.522 0 0 1-3.027-4.425c-.255-.638-.294-1.297-.294-1.956.038-1.14.305-2.26.78-3.417Zm4.636 9.678c3.288-.513 5.542-1.555 8.85-3.39-.115.151-.227.312-.34.473-.18.258-.363.518-.557.749-.805.938-1.786 1.717-3.004 2.036-1.63.458-3.297.479-4.949.132Zm3.407-8.086c2.815-1.035 4.77-2.366 8.195-5.008l-.12.26c-.202.44-.391.853-.623 1.222-.648 1.138-1.492 2.077-2.71 2.616-1.507.67-3.106.992-4.742.91Zm2.105-8.512c2.841-1.502 4.333-3.052 6.77-6.411l.167-.003h.039c-.098 1.159-.903 3.035-1.688 3.893-.903.978-2.042 1.577-3.26 1.997-.532.176-1.093.306-1.644.434l-.384.09Zm.312-8.64c2.33-1.937 3.623-3.769 5.679-7.464l.189-.07.011.028c0 .064.003.115.005.157.004.075.007.123-.005.171a9.274 9.274 0 0 1-.432 2.536c-.471 1.557-1.59 2.575-2.886 3.434-.787.515-1.636.904-2.56 1.209Zm-1.045-8.498c1.973-2.34 3.043-4.093 4.543-8.196l.013.117c.049.432.09.805.09 1.193.02 1.258-.137 2.416-.824 3.474a9.498 9.498 0 0 1-3.822 3.412Zm-2.598-7.9-.013.002c1.854-3.367 2.529-5.369 3.279-8.886l.054.21c.097.37.188.723.253 1.103.256 1.258.256 2.496-.333 3.714-.746 1.537-1.767 2.775-3.122 3.753a.316.316 0 0 0-.118.104Zm-5.989-10.03c.983 2.306 1.84 3.828 3.643 6.037-1.162-.476-2.204-1.133-2.797-2.36-.491-.958-.746-2.056-.786-3.155-.01-.15-.03-.294-.049-.439l-.01-.082Zm.103 14.16c2.761 2.514 4.659 3.892 7.418 4.969-.314-.026-.627-.052-.923-.079-1.433-.14-2.808-.539-4.025-1.357-1.02-.64-1.649-1.598-2.16-2.696-.065-.168-.128-.34-.193-.517l-.117-.32Zm1.53 6.739c2.63 3.116 4.3 4.832 6.994 6.632-.068-.009-.131-.014-.193-.019a3.842 3.842 0 0 1-.167-.016c-1.63-.36-3.122-1.018-4.398-2.077-1.217-.938-1.767-2.316-2.1-3.753a12.05 12.05 0 0 1-.098-.541l-.038-.226Zm.38 7.236c2.142 3.5 3.57 5.612 5.658 7.775-1.723-.627-3.168-1.705-4.371-3.103-.727-.859-1.04-1.897-1.178-3.035a16.97 16.97 0 0 1-.109-1.637Z" fill="#E1910E"/>
<mask id="l" maskUnits="userSpaceOnUse" x="59.35" y="12.405" width="23" height="61" fill="#000">
<path fill="#fff" d="M59.35 12.405h23v61h-23z"/>
<path d="M65.02 18.478c.61 1.258 1.69 1.917 2.887 2.396.137.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.451 1.198a57.93 57.93 0 0 0-1.413-1.757c-.825-.978-1.806-1.717-3.122-1.917-1.335-.22-2.67-.1-3.985.24-.04.04-.059.04-.137.08.333.499.628 1.018.942 1.477.687.899 1.512 1.637 2.611 2.037 1.57.499 3.18.619 4.79.359.157-.06.295-.08.452-.12a46.466 46.466 0 0 1 1.865 7.128c-.314-.46-.59-.978-.864-1.438-.687-1.178-1.55-2.116-2.866-2.575a9.093 9.093 0 0 0-3.082-.52c-.334 0-.688.04-1.1.04.196.48.334.9.49 1.298.511 1.099 1.14 2.057 2.16 2.696 1.218.818 2.592 1.218 4.025 1.357.452.04.942.08 1.414.12.412 2.416.648 4.872.706 7.368-.078-.08-.098-.2-.137-.32-.157-.46-.334-.938-.51-1.438-.55-1.437-1.473-2.535-2.867-3.194-.962-.44-1.983-.699-3.023-.858-.177 0-.354-.04-.55-.08v.24c.04.219.079.498.138.778.333 1.437.883 2.815 2.1 3.753 1.276 1.059 2.768 1.718 4.398 2.077.157.02.314.02.51.06a40.27 40.27 0 0 1-.589 7.527c-.176-.819-.314-1.598-.47-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.138 0-.275-.08-.49-.12.019.719.038 1.338.117 1.957.137 1.138.452 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.515 3.154.06 0 .118.04.197.08-.452 2.316-1.06 4.572-1.885 6.748-.04-.399 0-.778-.02-1.178-.02-1.317-.235-2.555-1.04-3.613a8.461 8.461 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.472-.858-.06.22-.08.42-.118.579-.275 1.637-.275 3.234.55 4.712.686 1.218 1.629 2.236 2.728 3.094.413.32.825.58 1.257.859-.805 2.096-1.728 4.133-2.827 6.07 0-.12 0-.2.02-.28.058-.54.137-1.138.196-1.677a5.277 5.277 0 0 0-.59-2.895c-.569-1.038-1.334-1.937-2.237-2.716-.334-.26-.668-.539-1.021-.858-.491 1.178-.766 2.316-.805 3.474 0 .659.04 1.318.294 1.956a11.52 11.52 0 0 0 3.102 4.493c.157.12.138.2.06.36a55.328 55.328 0 0 1-3.005 4.471s.197.4 1.512-.459c.314-.459.628-.898.923-1.397a90.557 90.557 0 0 0 1.786-2.955c.118-.26.236-.34.51-.26 1.728.4 3.476.4 5.184-.08 1.217-.32 2.198-1.098 3.003-2.036.354-.42.668-.939 1.002-1.358.02-.08.058-.12.098-.2l-.118-.08c-1.374-.459-2.788-.698-4.221-.578-1.433.08-2.591.778-3.612 1.797-.236.24-.452.459-.727.658.02-.08.06-.16.099-.24a53.463 53.463 0 0 0 2.395-5.69c.058-.199.137-.239.333-.239 1.708.12 3.377-.2 4.948-.898 1.217-.54 2.061-1.478 2.709-2.616.314-.499.55-1.078.844-1.697-.57 0-1.08-.08-1.59-.08-.982-.04-1.963.04-2.925.3-1.316.399-2.238 1.218-3.024 2.296-.196.24-.353.479-.51.718.49-2.136.981-4.292 1.472-6.428.786-.2 1.63-.36 2.415-.62 1.217-.419 2.356-1.018 3.259-1.996.785-.858 1.59-2.735 1.688-3.893h-.039c-1.688.02-3.318.34-4.79 1.278-.903.539-1.473 1.437-1.944 2.376-.117.2-.216.399-.353.618.196-2.136.275-4.252.118-6.388 1.06-.32 2.022-.74 2.905-1.318 1.296-.859 2.415-1.877 2.886-3.434a9.274 9.274 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.472.48-2.16.7-.942.399-1.806.898-2.532 1.677-.628.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.177 0-.12-.02-.16-.02-.279a53.172 53.172 0 0 0-.863-6.11c-.04-.2-.02-.359.216-.439a9.502 9.502 0 0 0 3.867-3.434c.687-1.058.844-2.216.825-3.474 0-.459-.06-.898-.118-1.437-.589.32-1.158.559-1.65.858-1.099.64-2.06 1.418-2.689 2.536-.49.858-.608 1.837-.687 2.815-.04.3-.04.619-.118.898l-.059-.24c-.51-2.056-1.119-4.132-1.904-6.128-.078-.2-.078-.32.098-.42 1.355-.978 2.376-2.216 3.122-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.197-.878-.315-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.63 2.456-1.511 4.093.039.58.098 1.218.137 1.917-.04-.08-.059-.12-.078-.2-.432-.898-.864-1.797-1.296-2.715-.04-.12-.04-.24-.04-.36.04-.818.02-1.637-.196-2.455-.157-.62-.392-1.258-.844-1.717-.53-.58-1.158-1.019-1.826-1.398-.353-.24-.706-.4-1.08-.579-.058 0-.098.04-.157.04.02.3.079.579.099.878.039 1.099.294 2.197.785 3.155Z"/>
</mask>
<path d="M65.02 18.478c.61 1.258 1.69 1.917 2.887 2.396.137.08.275.2.334.32.451 1.018.883 2.076 1.315 3.074.157.38.275.739.451 1.198a57.93 57.93 0 0 0-1.413-1.757c-.825-.978-1.806-1.717-3.122-1.917-1.335-.22-2.67-.1-3.985.24-.04.04-.059.04-.137.08.333.499.628 1.018.942 1.477.687.899 1.512 1.637 2.611 2.037 1.57.499 3.18.619 4.79.359.157-.06.295-.08.452-.12a46.466 46.466 0 0 1 1.865 7.128c-.314-.46-.59-.978-.864-1.438-.687-1.178-1.55-2.116-2.866-2.575a9.093 9.093 0 0 0-3.082-.52c-.334 0-.688.04-1.1.04.196.48.334.9.49 1.298.511 1.099 1.14 2.057 2.16 2.696 1.218.818 2.592 1.218 4.025 1.357.452.04.942.08 1.414.12.412 2.416.648 4.872.706 7.368-.078-.08-.098-.2-.137-.32-.157-.46-.334-.938-.51-1.438-.55-1.437-1.473-2.535-2.867-3.194-.962-.44-1.983-.699-3.023-.858-.177 0-.354-.04-.55-.08v.24c.04.219.079.498.138.778.333 1.437.883 2.815 2.1 3.753 1.276 1.059 2.768 1.718 4.398 2.077.157.02.314.02.51.06a40.27 40.27 0 0 1-.589 7.527c-.176-.819-.314-1.598-.47-2.376-.256-1.098-.786-2.077-1.63-2.815-1.06-.899-2.297-1.478-3.593-1.957-.138 0-.275-.08-.49-.12.019.719.038 1.338.117 1.957.137 1.138.452 2.176 1.178 3.035 1.237 1.437 2.729 2.535 4.515 3.154.06 0 .118.04.197.08-.452 2.316-1.06 4.572-1.885 6.748-.04-.399 0-.778-.02-1.178-.02-1.317-.235-2.555-1.04-3.613a8.461 8.461 0 0 0-2.356-2.097c-.471-.32-.942-.599-1.472-.858-.06.22-.08.42-.118.579-.275 1.637-.275 3.234.55 4.712.686 1.218 1.629 2.236 2.728 3.094.413.32.825.58 1.257.859-.805 2.096-1.728 4.133-2.827 6.07 0-.12 0-.2.02-.28.058-.54.137-1.138.196-1.677a5.277 5.277 0 0 0-.59-2.895c-.569-1.038-1.334-1.937-2.237-2.716-.334-.26-.668-.539-1.021-.858-.491 1.178-.766 2.316-.805 3.474 0 .659.04 1.318.294 1.956a11.52 11.52 0 0 0 3.102 4.493c.157.12.138.2.06.36a55.328 55.328 0 0 1-3.005 4.471s.197.4 1.512-.459c.314-.459.628-.898.923-1.397a90.557 90.557 0 0 0 1.786-2.955c.118-.26.236-.34.51-.26 1.728.4 3.476.4 5.184-.08 1.217-.32 2.198-1.098 3.003-2.036.354-.42.668-.939 1.002-1.358.02-.08.058-.12.098-.2l-.118-.08c-1.374-.459-2.788-.698-4.221-.578-1.433.08-2.591.778-3.612 1.797-.236.24-.452.459-.727.658.02-.08.06-.16.099-.24a53.463 53.463 0 0 0 2.395-5.69c.058-.199.137-.239.333-.239 1.708.12 3.377-.2 4.948-.898 1.217-.54 2.061-1.478 2.709-2.616.314-.499.55-1.078.844-1.697-.57 0-1.08-.08-1.59-.08-.982-.04-1.963.04-2.925.3-1.316.399-2.238 1.218-3.024 2.296-.196.24-.353.479-.51.718.49-2.136.981-4.292 1.472-6.428.786-.2 1.63-.36 2.415-.62 1.217-.419 2.356-1.018 3.259-1.996.785-.858 1.59-2.735 1.688-3.893h-.039c-1.688.02-3.318.34-4.79 1.278-.903.539-1.473 1.437-1.944 2.376-.117.2-.216.399-.353.618.196-2.136.275-4.252.118-6.388 1.06-.32 2.022-.74 2.905-1.318 1.296-.859 2.415-1.877 2.886-3.434a9.274 9.274 0 0 0 .432-2.536c.02-.08 0-.16 0-.36-.746.28-1.472.48-2.16.7-.942.399-1.806.898-2.532 1.677-.628.678-.962 1.497-1.237 2.336-.118.399-.216.798-.373 1.177 0-.12-.02-.16-.02-.279a53.172 53.172 0 0 0-.863-6.11c-.04-.2-.02-.359.216-.439a9.502 9.502 0 0 0 3.867-3.434c.687-1.058.844-2.216.825-3.474 0-.459-.06-.898-.118-1.437-.589.32-1.158.559-1.65.858-1.099.64-2.06 1.418-2.689 2.536-.49.858-.608 1.837-.687 2.815-.04.3-.04.619-.118.898l-.059-.24c-.51-2.056-1.119-4.132-1.904-6.128-.078-.2-.078-.32.098-.42 1.355-.978 2.376-2.216 3.122-3.753.589-1.218.589-2.456.334-3.714-.079-.46-.197-.878-.315-1.338l-.039-.04c-.864.54-1.669 1.159-2.356 1.937-1.06 1.138-1.63 2.456-1.511 4.093.039.58.098 1.218.137 1.917-.04-.08-.059-.12-.078-.2-.432-.898-.864-1.797-1.296-2.715-.04-.12-.04-.24-.04-.36.04-.818.02-1.637-.196-2.455-.157-.62-.392-1.258-.844-1.717-.53-.58-1.158-1.019-1.826-1.398-.353-.24-.706-.4-1.08-.579-.058 0-.098.04-.157.04.02.3.079.579.099.878.039 1.099.294 2.197.785 3.155Z" stroke="#A05500" stroke-width="2.15" stroke-linejoin="round" mask="url(#l)"/>
<defs>
<filter id="d" x="37.484" y="37.41" width="7.31" height="15.48" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2467_19888"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2467_19888" result="shape"/>
</filter>
<filter id="e" x="30.605" y="23.865" width="7.31" height="9.03" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2467_19888"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2467_19888" result="shape"/>
</filter>
<filter id="f" x="44.579" y="23.865" width="7.31" height="9.03" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2467_19888"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2467_19888" result="shape"/>
</filter>
<filter id="g" x="24.154" y="30.315" width="7.31" height="29.24" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2467_19888"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2467_19888" result="shape"/>
</filter>
<filter id="h" x="51.029" y="30.315" width="7.31" height="29.24" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.72"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0.882353 0 0 0 0 0.568627 0 0 0 0 0.054902 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_2467_19888"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_2467_19888" result="shape"/>
</filter>
<linearGradient id="a" x1="22.542" y1="22.564" x2="22.542" y2="63.436" gradientUnits="userSpaceOnUse">
<stop stop-color="#E0EEFF"/>
<stop offset="1" stop-color="#F8FBFF"/>
</linearGradient>
<linearGradient id="b" x1="41.139" y1="4.192" x2="76.399" y2="4.192" gradientUnits="userSpaceOnUse">
<stop stop-color="#E0EEFF"/>
<stop offset="1" stop-color="#F8FBFF"/>
</linearGradient>
<linearGradient id="c" x1="6.632" y1="63.425" x2="41.139" y2="63.425" gradientUnits="userSpaceOnUse">
<stop stop-color="#D1E5FE"/>
<stop offset="1" stop-color="#F8FBFF"/>
</linearGradient>
</defs>
</svg>
This source diff could not be displayed because it is too large. You can view the blob instead.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 268 184" fill="none">
<path d="M11.856.536a4 4 0 0 1 4 0l9.857 5.69a4 4 0 0 1 2 3.465v11.38a4 4 0 0 1-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L2 24.537a4 4 0 0 1-2-3.464V9.69a4 4 0 0 1 2-3.464L11.856.536Z" fill="url(#a)"/>
<path d="M55.856 21.536a4 4 0 0 0-4 0L42 27.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4 4 0 0 0 2-3.464V30.69a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#b)"/>
<path d="M55.856 65.536a4 4 0 0 0-4 0L42 71.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4 4 0 0 0 2-3.464V74.69a4 4 0 0 0-2-3.465l-9.857-5.69Z" fill="url(#c)"/>
<path d="M51.856 109.536a3.998 3.998 0 0 1 4 0l9.857 5.691a4 4 0 0 1 2 3.464v11.381a4 4 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L42 133.536a4 4 0 0 1-2-3.464v-11.381a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#d)"/>
<path d="M55.856 153.536a3.998 3.998 0 0 0-4 0L42 159.227a4 4 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4 4 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#e)"/>
<path d="M15.856 44.536a4 4 0 0 0-4 0L2 50.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4 4 0 0 0 2-3.464V53.69a4 4 0 0 0-2-3.465l-9.857-5.69Z" fill="url(#f)"/>
<path d="M11.856 88.536a4 4 0 0 1 4 0l9.857 5.69a4 4 0 0 1 2 3.465v11.381a4 4 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L2 112.536a4 4 0 0 1-2-3.464V97.691a4 4 0 0 1 2-3.465l9.856-5.69Z" fill="url(#g)"/>
<path d="M15.856 132.536a3.998 3.998 0 0 0-4 0L2 138.227a4 4 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4 4 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#h)"/>
<path d="M91.856.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L82 24.537a4 4 0 0 1-2-3.464V9.69a4 4 0 0 1 2-3.464L91.856.536Z" fill="url(#i)"/>
<path d="M95.856 44.536a4 4 0 0 0-4 0L82 50.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V53.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#j)"/>
<path d="M91.856 88.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L82 112.536a4 4 0 0 1-2-3.464V97.691a4 4 0 0 1 2-3.465l9.856-5.69Z" fill="url(#k)"/>
<path d="M95.856 132.536a3.998 3.998 0 0 0-4 0L82 138.227a4 4 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#l)"/>
<path d="M131.856 21.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L122 45.537a4 4 0 0 1-2-3.464V30.69a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#m)"/>
<path d="M135.856 65.536a4 4 0 0 0-4 0L122 71.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V74.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#n)"/>
<path d="M131.856 109.536a3.998 3.998 0 0 1 4 0l9.857 5.691a4 4 0 0 1 2 3.464v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L122 133.536a4 4 0 0 1-2-3.464v-11.381c0-1.429.762-2.75 2-3.464l9.856-5.691Z" fill="url(#o)"/>
<path d="M135.856 153.536a3.998 3.998 0 0 0-4 0L122 159.227a3.998 3.998 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#p)"/>
<path d="M171.856.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L162 24.537a4 4 0 0 1-2-3.464V9.69a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#q)"/>
<path d="M175.856 44.536a4 4 0 0 0-4 0L162 50.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V53.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#r)"/>
<path d="M171.856 88.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L162 112.536a4 4 0 0 1-2-3.464V97.691a4 4 0 0 1 2-3.465l9.856-5.69Z" fill="url(#s)"/>
<path d="M175.856 132.536a3.998 3.998 0 0 0-4 0L162 138.227a3.998 3.998 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#t)"/>
<path d="M211.856 21.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L202 45.537a4 4 0 0 1-2-3.464V30.69a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#u)"/>
<path d="M215.856 65.536a4 4 0 0 0-4 0L202 71.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V74.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#v)"/>
<path d="M211.856 109.536a3.998 3.998 0 0 1 4 0l9.857 5.691a4 4 0 0 1 2 3.464v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L202 133.536a4 4 0 0 1-2-3.464v-11.381c0-1.429.762-2.75 2-3.464l9.856-5.691Z" fill="url(#w)"/>
<path d="M215.856 153.536a3.998 3.998 0 0 0-4 0L202 159.227a3.998 3.998 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#x)"/>
<path d="M251.856.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L242 24.537a4 4 0 0 1-2-3.464V9.69a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#y)"/>
<path d="M255.856 44.536a4 4 0 0 0-4 0L242 50.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V53.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#z)"/>
<path d="M251.856 88.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L242 112.536a4 4 0 0 1-2-3.464V97.691a4 4 0 0 1 2-3.465l9.856-5.69Z" fill="url(#A)"/>
<path d="M255.856 132.536a3.998 3.998 0 0 0-4 0L242 138.227a3.998 3.998 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#B)"/>
<defs>
<radialGradient id="a" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="b" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="c" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="d" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="e" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="f" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="g" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="h" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="i" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="j" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="k" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="l" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="m" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="n" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="o" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="p" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="q" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="r" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="s" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="t" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="u" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="v" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="w" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="x" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="y" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="z" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="A" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
<radialGradient id="B" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#FFDC94"/>
<stop offset="1" stop-color="#FFEFCE"/>
</radialGradient>
</defs>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 268 184" fill="none">
<path d="M11.856.536a4 4 0 0 1 4 0l9.857 5.69a4 4 0 0 1 2 3.465v11.38a4 4 0 0 1-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L2 24.537a4 4 0 0 1-2-3.464V9.69a4 4 0 0 1 2-3.464L11.856.536Z" fill="url(#a)"/>
<path d="M55.856 21.536a4 4 0 0 0-4 0L42 27.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4 4 0 0 0 2-3.464V30.69a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#b)"/>
<path d="M55.856 65.536a4 4 0 0 0-4 0L42 71.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4 4 0 0 0 2-3.464V74.69a4 4 0 0 0-2-3.465l-9.857-5.69Z" fill="url(#c)"/>
<path d="M51.856 109.536a3.998 3.998 0 0 1 4 0l9.857 5.691a4 4 0 0 1 2 3.464v11.381a4 4 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L42 133.536a4 4 0 0 1-2-3.464v-11.381a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#d)"/>
<path d="M55.856 153.536a3.998 3.998 0 0 0-4 0L42 159.227a4 4 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4 4 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#e)"/>
<path d="M15.856 44.536a4 4 0 0 0-4 0L2 50.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4 4 0 0 0 2-3.464V53.69a4 4 0 0 0-2-3.465l-9.857-5.69Z" fill="url(#f)"/>
<path d="M11.856 88.536a4 4 0 0 1 4 0l9.857 5.69a4 4 0 0 1 2 3.465v11.381a4 4 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L2 112.536a4 4 0 0 1-2-3.464V97.691a4 4 0 0 1 2-3.465l9.856-5.69Z" fill="url(#g)"/>
<path d="M15.856 132.536a3.998 3.998 0 0 0-4 0L2 138.227a4 4 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4 4 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#h)"/>
<path d="M91.856.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L82 24.537a4 4 0 0 1-2-3.464V9.69a4 4 0 0 1 2-3.464L91.856.536Z" fill="url(#i)"/>
<path d="M95.856 44.536a4 4 0 0 0-4 0L82 50.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V53.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#j)"/>
<path d="M91.856 88.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L82 112.536a4 4 0 0 1-2-3.464V97.691a4 4 0 0 1 2-3.465l9.856-5.69Z" fill="url(#k)"/>
<path d="M95.856 132.536a3.998 3.998 0 0 0-4 0L82 138.227a4 4 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#l)"/>
<path d="M131.856 21.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L122 45.537a4 4 0 0 1-2-3.464V30.69a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#m)"/>
<path d="M135.856 65.536a4 4 0 0 0-4 0L122 71.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V74.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#n)"/>
<path d="M131.856 109.536a3.998 3.998 0 0 1 4 0l9.857 5.691a4 4 0 0 1 2 3.464v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L122 133.536a4 4 0 0 1-2-3.464v-11.381c0-1.429.762-2.75 2-3.464l9.856-5.691Z" fill="url(#o)"/>
<path d="M135.856 153.536a3.998 3.998 0 0 0-4 0L122 159.227a3.998 3.998 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#p)"/>
<path d="M171.856.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L162 24.537a4 4 0 0 1-2-3.464V9.69a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#q)"/>
<path d="M175.856 44.536a4 4 0 0 0-4 0L162 50.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V53.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#r)"/>
<path d="M171.856 88.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L162 112.536a4 4 0 0 1-2-3.464V97.691a4 4 0 0 1 2-3.465l9.856-5.69Z" fill="url(#s)"/>
<path d="M175.856 132.536a3.998 3.998 0 0 0-4 0L162 138.227a3.998 3.998 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#t)"/>
<path d="M211.856 21.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L202 45.537a4 4 0 0 1-2-3.464V30.69a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#u)"/>
<path d="M215.856 65.536a4 4 0 0 0-4 0L202 71.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V74.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#v)"/>
<path d="M211.856 109.536a3.998 3.998 0 0 1 4 0l9.857 5.691a4 4 0 0 1 2 3.464v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L202 133.536a4 4 0 0 1-2-3.464v-11.381c0-1.429.762-2.75 2-3.464l9.856-5.691Z" fill="url(#w)"/>
<path d="M215.856 153.536a3.998 3.998 0 0 0-4 0L202 159.227a3.998 3.998 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#x)"/>
<path d="M251.856.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.38c0 1.43-.763 2.75-2 3.465l-9.857 5.69a4 4 0 0 1-4 0L242 24.537a4 4 0 0 1-2-3.464V9.69a4 4 0 0 1 2-3.464l9.856-5.691Z" fill="url(#y)"/>
<path d="M255.856 44.536a4 4 0 0 0-4 0L242 50.226a4 4 0 0 0-2 3.465v11.38a4 4 0 0 0 2 3.465l9.856 5.69a4 4 0 0 0 4 0l9.857-5.69a4.001 4.001 0 0 0 2-3.464V53.69c0-1.43-.763-2.75-2-3.465l-9.857-5.69Z" fill="url(#z)"/>
<path d="M251.856 88.536a4 4 0 0 1 4 0l9.857 5.69c1.237.715 2 2.036 2 3.465v11.381a4.002 4.002 0 0 1-2 3.464l-9.857 5.691a4.003 4.003 0 0 1-4 0L242 112.536a4 4 0 0 1-2-3.464V97.691a4 4 0 0 1 2-3.465l9.856-5.69Z" fill="url(#A)"/>
<path d="M255.856 132.536a3.998 3.998 0 0 0-4 0L242 138.227a3.998 3.998 0 0 0-2 3.464v11.381a4 4 0 0 0 2 3.464l9.856 5.691a4.003 4.003 0 0 0 4 0l9.857-5.691a4.002 4.002 0 0 0 2-3.464v-11.381a4 4 0 0 0-2-3.464l-9.857-5.691Z" fill="url(#B)"/>
<defs>
<radialGradient id="a" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="b" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="c" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="d" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="e" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="f" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="g" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="h" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="i" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="j" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="k" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="l" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="m" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="n" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="o" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="p" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="q" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="r" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="s" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="t" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="u" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="v" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="w" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="x" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="y" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="z" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="A" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
<radialGradient id="B" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 112.553 -148.453 0 129.985 91.882)">
<stop stop-color="#C37300"/>
<stop offset="1" stop-color="#E1910E"/>
</radialGradient>
</defs>
</svg>
import type { GetActivityRewardsResponse } from '@blockscout/points-types';
export const USER_ACTIVITY: GetActivityRewardsResponse = {
items: [
{
date: '2025-03-10',
end_date: '2025-03-16',
activity: 'sent_transactions',
amount: '60',
percentile: 0.5,
is_pending: true,
},
{
date: '2025-03-10',
end_date: '2025-03-16',
activity: 'verified_contracts',
amount: '40',
percentile: 0.3,
is_pending: true,
},
{
date: '2025-03-10',
end_date: '2025-03-16',
activity: 'blockscout_usage',
amount: '80',
percentile: 0.8,
is_pending: true,
},
],
last_week: [
{
date: '2025-03-03',
end_date: '2025-03-09',
activity: 'sent_transactions',
amount: '40',
percentile: 0.25,
is_pending: false,
},
{
date: '2025-03-03',
end_date: '2025-03-09',
activity: 'verified_contracts',
amount: '60',
percentile: 0.6,
is_pending: false,
},
{
date: '2025-03-03',
end_date: '2025-03-09',
activity: 'blockscout_usage',
amount: '100',
percentile: 0.95,
is_pending: false,
},
],
};
export type RewardsConfigResponse = {
rewards: {
registration: string;
registration_with_referral: string;
daily_claim: string;
referral_share: string;
};
auth: {
shared_siwe_login: boolean;
};
};
export type RewardsCheckRefCodeResponse = {
valid: boolean;
is_custom: boolean;
reward: string | null;
};
export type RewardsNonceResponse = {
nonce: string;
merits_login_nonce?: string;
};
export type RewardsCheckUserResponse = {
exists: boolean;
};
export type RewardsLoginResponse = {
created: boolean;
token: string;
};
export type RewardsUserBalancesResponse = {
total: string;
staked: string;
unstaked: string;
total_staking_rewards: string;
total_referral_rewards: string;
pending_referral_rewards: string;
};
export type RewardsUserDailyCheckResponse = {
available: boolean;
daily_reward: string;
streak_reward: string;
pending_referral_rewards: string;
total_reward: string;
date: string;
reset_at: string;
streak: string;
};
export type RewardsUserDailyClaimResponse = {
daily_reward: string;
streak_reward: string;
pending_referral_rewards: string;
total_reward: string;
streak: string;
};
export type RewardsUserReferralsResponse = {
code: string;
link: string;
referrals: string;
};
...@@ -68,7 +68,7 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => { ...@@ -68,7 +68,7 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
const content = ( const content = (
<> <>
<Heading size="sm">External libraries ({ data.length })</Heading> <Heading size="sm" level="3">External libraries ({ data.length })</Heading>
<Alert status="warning" mt={ 4 }> <Alert status="warning" mt={ 4 }>
The linked library{ apos }s source code may not be the real one. The linked library{ apos }s source code may not be the real one.
Check the source code at the library address (if any) if you want to be sure in case if there is any library linked Check the source code at the library address (if any) if you want to be sure in case if there is any library linked
......
...@@ -5,6 +5,7 @@ import { useAccount, useWalletClient, useSwitchChain } from 'wagmi'; ...@@ -5,6 +5,7 @@ import { useAccount, useWalletClient, useSwitchChain } from 'wagmi';
import type { FormSubmitResult, SmartContractMethod } from './types'; import type { FormSubmitResult, SmartContractMethod } from './types';
import config from 'configs/app'; import config from 'configs/app';
import useRewardsActivity from 'lib/hooks/useRewardsActivity';
import { getNativeCoinValue } from './utils'; import { getNativeCoinValue } from './utils';
...@@ -18,6 +19,7 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise ...@@ -18,6 +19,7 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise
const { data: walletClient } = useWalletClient(); const { data: walletClient } = useWalletClient();
const { isConnected, chainId, address: account } = useAccount(); const { isConnected, chainId, address: account } = useAccount();
const { switchChainAsync } = useSwitchChain(); const { switchChainAsync } = useSwitchChain();
const { trackTransaction, trackTransactionConfirm } = useRewardsActivity();
return React.useCallback(async({ args, item, addressHash }) => { return React.useCallback(async({ args, item, addressHash }) => {
if (!isConnected) { if (!isConnected) {
...@@ -33,6 +35,7 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise ...@@ -33,6 +35,7 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise
} }
const address = getAddress(addressHash); const address = getAddress(addressHash);
const activityResponse = await trackTransaction(account ?? '', address);
if (item.type === 'receive' || item.type === 'fallback') { if (item.type === 'receive' || item.type === 'fallback') {
const value = getNativeCoinValue(args[0]); const value = getNativeCoinValue(args[0]);
...@@ -40,6 +43,11 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise ...@@ -40,6 +43,11 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise
to: address, to: address,
value, value,
}); });
if (activityResponse?.token) {
await trackTransactionConfirm(hash, activityResponse.token);
}
return { source: 'wallet_client', data: { hash } }; return { source: 'wallet_client', data: { hash } };
} }
...@@ -68,6 +76,10 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise ...@@ -68,6 +76,10 @@ export default function useCallMethodWalletClient(): (params: Params) => Promise
account, account,
}); });
if (activityResponse?.token) {
await trackTransactionConfirm(hash, activityResponse.token);
}
return { source: 'wallet_client', data: { hash } }; return { source: 'wallet_client', data: { hash } };
}, [ chainId, isConnected, switchChainAsync, walletClient, account ]); }, [ chainId, isConnected, switchChainAsync, walletClient, account, trackTransaction, trackTransactionConfirm ]);
} }
...@@ -14,6 +14,7 @@ import useApiFetch from 'lib/api/useApiFetch'; ...@@ -14,6 +14,7 @@ import useApiFetch from 'lib/api/useApiFetch';
import capitalizeFirstLetter from 'lib/capitalizeFirstLetter'; import capitalizeFirstLetter from 'lib/capitalizeFirstLetter';
import delay from 'lib/delay'; import delay from 'lib/delay';
import getErrorObjStatusCode from 'lib/errors/getErrorObjStatusCode'; import getErrorObjStatusCode from 'lib/errors/getErrorObjStatusCode';
import useRewardsActivity from 'lib/hooks/useRewardsActivity';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
...@@ -49,9 +50,10 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro ...@@ -49,9 +50,10 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
const { handleSubmit, watch, formState, setError, reset, getFieldState, getValues, clearErrors } = formApi; const { handleSubmit, watch, formState, setError, reset, getFieldState, getValues, clearErrors } = formApi;
const submitPromiseResolver = React.useRef<(value: unknown) => void>(); const submitPromiseResolver = React.useRef<(value: unknown) => void>();
const methodNameRef = React.useRef<string>(); const methodNameRef = React.useRef<string>();
const activityToken = React.useRef<string | undefined>();
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
const { trackContract, trackContractConfirm } = useRewardsActivity();
const onFormSubmit: SubmitHandler<FormFields> = React.useCallback(async(data) => { const onFormSubmit: SubmitHandler<FormFields> = React.useCallback(async(data) => {
const body = prepareRequestBody(data); const body = prepareRequestBody(data);
...@@ -75,6 +77,8 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro ...@@ -75,6 +77,8 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
} }
try { try {
const activityResponse = await trackContract(data.address);
activityToken.current = activityResponse?.token;
await apiFetch('contract_verification_via', { await apiFetch('contract_verification_via', {
pathParams: { method: data.method[0], hash: data.address.toLowerCase() }, pathParams: { method: data.method[0], hash: data.address.toLowerCase() },
fetchParams: { fetchParams: {
...@@ -89,7 +93,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro ...@@ -89,7 +93,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
return new Promise((resolve) => { return new Promise((resolve) => {
submitPromiseResolver.current = resolve; submitPromiseResolver.current = resolve;
}); });
}, [ apiFetch, hash, setError ]); }, [ apiFetch, hash, setError, trackContract ]);
const handleFormChange = React.useCallback(() => { const handleFormChange = React.useCallback(() => {
clearErrors('root'); clearErrors('root');
...@@ -127,8 +131,13 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro ...@@ -127,8 +131,13 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
{ send_immediately: true }, { send_immediately: true },
); );
if (activityToken.current) {
await trackContractConfirm(activityToken.current);
activityToken.current = undefined;
}
window.location.assign(route({ pathname: '/address/[hash]', query: { hash: address, tab: 'contract' } })); window.location.assign(route({ pathname: '/address/[hash]', query: { hash: address, tab: 'contract' } }));
}, [ setError, address, getValues ]); }, [ setError, address, getValues, trackContractConfirm ]);
const handleSocketError = React.useCallback(() => { const handleSocketError = React.useCallback(() => {
if (!formState.isSubmitting) { if (!formState.isSubmitting) {
......
...@@ -4,6 +4,7 @@ import type { Account, SignTypedDataParameters } from 'viem'; ...@@ -4,6 +4,7 @@ import type { Account, SignTypedDataParameters } from 'viem';
import { useAccount, useSendTransaction, useSwitchChain, useSignMessage, useSignTypedData } from 'wagmi'; import { useAccount, useSendTransaction, useSwitchChain, useSignMessage, useSignTypedData } from 'wagmi';
import config from 'configs/app'; import config from 'configs/app';
import useRewardsActivity from 'lib/hooks/useRewardsActivity';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
type SendTransactionArgs = { type SendTransactionArgs = {
...@@ -27,6 +28,7 @@ export default function useMarketplaceWallet(appId: string) { ...@@ -27,6 +28,7 @@ export default function useMarketplaceWallet(appId: string) {
const { signMessageAsync } = useSignMessage(); const { signMessageAsync } = useSignMessage();
const { signTypedDataAsync } = useSignTypedData(); const { signTypedDataAsync } = useSignTypedData();
const { switchChainAsync } = useSwitchChain(); const { switchChainAsync } = useSwitchChain();
const { trackTransaction, trackTransactionConfirm } = useRewardsActivity();
const logEvent = useCallback((event: mixpanel.EventPayload<mixpanel.EventTypes.WALLET_ACTION>['Action']) => { const logEvent = useCallback((event: mixpanel.EventPayload<mixpanel.EventTypes.WALLET_ACTION>['Action']) => {
mixpanel.logEvent( mixpanel.logEvent(
...@@ -43,10 +45,14 @@ export default function useMarketplaceWallet(appId: string) { ...@@ -43,10 +45,14 @@ export default function useMarketplaceWallet(appId: string) {
const sendTransaction = useCallback(async(transaction: SendTransactionArgs) => { const sendTransaction = useCallback(async(transaction: SendTransactionArgs) => {
await switchNetwork(); await switchNetwork();
const activityResponse = await trackTransaction(address ?? '', transaction.to);
const tx = await sendTransactionAsync(transaction); const tx = await sendTransactionAsync(transaction);
if (activityResponse?.token) {
await trackTransactionConfirm(tx, activityResponse.token);
}
logEvent('Send Transaction'); logEvent('Send Transaction');
return tx; return tx;
}, [ sendTransactionAsync, switchNetwork, logEvent ]); }, [ sendTransactionAsync, switchNetwork, logEvent, trackTransaction, trackTransactionConfirm, address ]);
const signMessage = useCallback(async(message: string) => { const signMessage = useCallback(async(message: string) => {
await switchNetwork(); await switchNetwork();
......
import type { BrowserContext } from '@playwright/test'; import type { BrowserContext } from '@playwright/test';
import React from 'react'; import React from 'react';
import * as activityMock from 'mocks/rewards/activity';
import * as rewardsBalanceMock from 'mocks/rewards/balance'; import * as rewardsBalanceMock from 'mocks/rewards/balance';
import * as dailyRewardMock from 'mocks/rewards/dailyReward'; import * as dailyRewardMock from 'mocks/rewards/dailyReward';
import * as referralsMock from 'mocks/rewards/referrals'; import * as referralsMock from 'mocks/rewards/referrals';
...@@ -25,19 +26,25 @@ testWithAuth.beforeEach(async({ mockEnvs, mockApiResponse }) => { ...@@ -25,19 +26,25 @@ testWithAuth.beforeEach(async({ mockEnvs, mockApiResponse }) => {
await mockApiResponse('user_info', profileMock.withEmailAndWallet); await mockApiResponse('user_info', profileMock.withEmailAndWallet);
}); });
testWithAuth('base view +@dark-mode +@mobile', async({ page, render, mockApiResponse }) => { const testTab = (tab: 'tasks' | 'referrals' | 'resources') =>
await mockApiResponse('rewards_user_balances', rewardsBalanceMock.base); testWithAuth(`${ tab } tab +@dark-mode +@mobile`, async({ page, render, mockApiResponse }, testInfo) => {
await mockApiResponse('rewards_user_daily_check', dailyRewardMock.base); await mockApiResponse('rewards_user_balances', rewardsBalanceMock.base);
await mockApiResponse('rewards_user_referrals', referralsMock.base); await mockApiResponse('rewards_user_daily_check', dailyRewardMock.base);
await mockApiResponse('rewards_config', rewardsConfigMock.base); await mockApiResponse('rewards_user_referrals', referralsMock.base);
await mockApiResponse('rewards_config', rewardsConfigMock.base);
await mockApiResponse('rewards_user_activity', activityMock.base);
const component = await render(<RewardsDashboard/>); const component = await render(<RewardsDashboard/>, { hooksConfig: { router: { query: { tab } } } });
await expect(component).toHaveScreenshot({ await expect(component).toHaveScreenshot(testInfo.project.name === 'mobile' ? {} : {
mask: [ page.locator(pwConfig.adsBannerSelector) ], mask: [ page.locator(pwConfig.adsBannerSelector) ],
maskColor: pwConfig.maskColor, maskColor: pwConfig.maskColor,
});
}); });
});
testTab('tasks');
testTab('referrals');
testTab('resources');
testWithAuth('with error', async({ page, render }) => { testWithAuth('with error', async({ page, render }) => {
const component = await render(<RewardsDashboard/>); const component = await render(<RewardsDashboard/>);
......
...@@ -6,12 +6,13 @@ import { useRewardsContext } from 'lib/contexts/rewards'; ...@@ -6,12 +6,13 @@ import { useRewardsContext } from 'lib/contexts/rewards';
import { apos } from 'lib/html-entities'; import { apos } from 'lib/html-entities';
import { Alert } from 'toolkit/chakra/alert'; import { Alert } from 'toolkit/chakra/alert';
import { Link } from 'toolkit/chakra/link'; import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton'; import RoutedTabs from 'toolkit/components/RoutedTabs/RoutedTabs';
import DailyRewardClaimButton from 'ui/rewards/dashboard/DailyRewardClaimButton'; import DailyRewardClaimButton from 'ui/rewards/dashboard/DailyRewardClaimButton';
import RewardsDashboardCard from 'ui/rewards/dashboard/RewardsDashboardCard'; import RewardsDashboardCard from 'ui/rewards/dashboard/RewardsDashboardCard';
import RewardsDashboardCardValue from 'ui/rewards/dashboard/RewardsDashboardCardValue'; import RewardsDashboardCardValue from 'ui/rewards/dashboard/RewardsDashboardCardValue';
import RewardsDashboardInfoCard from 'ui/rewards/dashboard/RewardsDashboardInfoCard'; import ReferralsTab from 'ui/rewards/dashboard/tabs/ReferralsTab';
import RewardsReadOnlyInputWithCopy from 'ui/rewards/RewardsReadOnlyInputWithCopy'; import ResourcesTab from 'ui/rewards/dashboard/tabs/ResourcesTab';
import TasksTab from 'ui/rewards/dashboard/tabs/TasksTab';
import AdBanner from 'ui/shared/ad/AdBanner'; import AdBanner from 'ui/shared/ad/AdBanner';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import useRedirectForInvalidAuthToken from 'ui/snippets/auth/useRedirectForInvalidAuthToken'; import useRedirectForInvalidAuthToken from 'ui/snippets/auth/useRedirectForInvalidAuthToken';
...@@ -66,7 +67,8 @@ const RewardsDashboard = () => { ...@@ -66,7 +67,8 @@ const RewardsDashboard = () => {
<RewardsDashboardCard <RewardsDashboardCard
title="All Merits" title="All Merits"
description="Claim your daily Merits and any Merits received from referrals." description="Claim your daily Merits and any Merits received from referrals."
direction="column-reverse" contentDirection="column-reverse"
cardValueStyle={{ minH: { base: '64px', md: '88px' } }}
contentAfter={ <DailyRewardClaimButton/> } contentAfter={ <DailyRewardClaimButton/> }
hint={ ( hint={ (
<> <>
...@@ -86,7 +88,8 @@ const RewardsDashboard = () => { ...@@ -86,7 +88,8 @@ const RewardsDashboard = () => {
<RewardsDashboardCard <RewardsDashboardCard
title="Referrals" title="Referrals"
description="Total number of users who have joined the program using your code or referral link." description="Total number of users who have joined the program using your code or referral link."
direction="column-reverse" contentDirection="column-reverse"
cardValueStyle={{ minH: { base: '64px', md: '88px' } }}
> >
<RewardsDashboardCardValue <RewardsDashboardCardValue
value={ referralsQuery.data?.referrals ? value={ referralsQuery.data?.referrals ?
...@@ -114,7 +117,8 @@ const RewardsDashboard = () => { ...@@ -114,7 +117,8 @@ const RewardsDashboard = () => {
to learn how your streak number affects daily rewards to learn how your streak number affects daily rewards
</> </>
) } ) }
direction="column-reverse" contentDirection="column-reverse"
cardValueStyle={{ minH: { base: '64px', md: '88px' } }}
> >
<RewardsDashboardCardValue <RewardsDashboardCardValue
value={ value={
...@@ -126,94 +130,26 @@ const RewardsDashboard = () => { ...@@ -126,94 +130,26 @@ const RewardsDashboard = () => {
/> />
</RewardsDashboardCard> </RewardsDashboardCard>
</Flex> </Flex>
<Flex w="full" gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}> <RoutedTabs
<RewardsDashboardCard w="full"
title="Referral program" tabs={ [
description={ ( {
<> id: 'tasks',
Refer friends and boost your Merits! You receive a{ ' ' } title: 'Tasks',
<Skeleton as="span" loading={ rewardsConfigQuery.isPending }> component: <TasksTab/>,
{ rewardsConfigQuery.data?.rewards.referral_share ? },
`${ Number(rewardsConfigQuery.data?.rewards.referral_share) * 100 }%` : {
'N/A' id: 'referrals',
} title: 'Referrals',
</Skeleton> component: <ReferralsTab/>,
{ ' ' }bonus on all Merits earned by your referrals. },
</> {
) } id: 'resources',
> title: 'Resources',
<Flex component: <ResourcesTab/>,
flex={ 1 } },
gap={{ base: 2, lg: 6 }} ] }
px={{ base: 4, lg: 6 }} />
py={{ base: 4, lg: 0 }}
flexDirection={{ base: 'column', lg: 'row' }}
>
<RewardsReadOnlyInputWithCopy
label="Referral link"
value={ referralsQuery.data?.link || 'N/A' }
isLoading={ referralsQuery.isPending }
flex={ 2 }
/>
<RewardsReadOnlyInputWithCopy
label="Referral code"
value={ referralsQuery.data?.code || 'N/A' }
isLoading={ referralsQuery.isPending }
flex={ 1 }
/>
</Flex>
</RewardsDashboardCard>
<RewardsDashboardInfoCard
title="Badges"
description={ `Collect limited and legendary badges by completing different Blockscout related tasks.
Go to the badges website to see what${ apos }s available and start your collection today.` }
imageSrc="/static/merits/badges.svg"
imageWidth="260px"
imageHeight="86px"
linkText="View badges"
linkHref={ `https://merits.blockscout.com/?tab=badges&utm_source=${ config.chain.id }&utm_medium=badges` }
/>
</Flex>
<Flex w="full" gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}>
<RewardsDashboardInfoCard
title="Blockscout campaigns"
description="Join Blockscout activities to earn bonus Merits and exclusive rewards from our partners!"
imageSrc="/static/merits/campaigns.svg"
imageWidth="180px"
imageHeight="76px"
linkText="Check campaigns"
linkHref={ `https://merits.blockscout.com/?tab=campaigns&utm_source=${ config.chain.id }&utm_medium=campaigns` }
/>
<RewardsDashboardInfoCard
title="Use your Merits"
description="Spend your Merits to get exclusive discounts and offers across several web3 products!"
imageSrc="/static/merits/offers.svg"
imageWidth="180px"
imageHeight="86px"
linkText="Check offers"
linkHref={ `https://merits.blockscout.com/?tab=redeem&utm_source=${ config.chain.id }&utm_medium=redeem` }
/>
</Flex>
<Flex w="full" gap={ 6 } flexDirection={{ base: 'column', md: 'row' }}>
<RewardsDashboardCard
title="Activity"
description="Earn Merits for your everyday Blockscout activities. You deserve to be rewarded for choosing open-source public goods!"
availableSoon
blurFilter
>
<RewardsDashboardCardValue label="Activity" value="0%"/>
<RewardsDashboardCardValue label="Received" value="0" withIcon/>
</RewardsDashboardCard>
<RewardsDashboardCard
title="Verify contracts"
description="Verified contracts are so important for transparency and interaction. Verify your contracts on Blockscout and receive Merits for your efforts." // eslint-disable-line max-len
availableSoon
blurFilter
>
<RewardsDashboardCardValue label="Activity" value="0%"/>
<RewardsDashboardCardValue label="Received" value="0" withIcon/>
</RewardsDashboardCard>
</Flex>
</Flex> </Flex>
</> </>
); );
......
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import useRewardsActivity from 'lib/hooks/useRewardsActivity';
const RewardsActivityTracker = () => {
const router = useRouter();
const { trackUsage } = useRewardsActivity();
useEffect(() => {
trackUsage('explore');
}, [ router.pathname, router.query, trackUsage ]);
return null;
};
export default RewardsActivityTracker;
import { Flex, Text } from '@chakra-ui/react';
import config from 'configs/app';
import { useRewardsContext } from 'lib/contexts/rewards';
import { useColorModeValue } from 'toolkit/chakra/color-mode';
import { Heading } from 'toolkit/chakra/heading';
import { Image } from 'toolkit/chakra/image';
import { Link } from 'toolkit/chakra/link';
const feature = config.features.rewards;
export default function RewardsActivityPassCard() {
const { rewardsConfigQuery } = useRewardsContext();
const backgroundImage = useColorModeValue('/static/merits/cells.svg', '/static/merits/cells_dark.svg');
const activityPassUrl = feature.isEnabled ?
`${ feature.api.endpoint }/?tab=spend&id=${ rewardsConfigQuery.data?.rewards?.blockscout_activity_pass_id }&utm_source=blockscout&utm_medium=tasks` :
undefined;
return (
<Flex
p={{ base: 1.5, md: 2 }}
border="1px solid"
borderColor={{ _light: 'gray.200', _dark: 'whiteAlpha.200' }}
borderRadius="lg"
gap={{ base: 1, md: 10 }}
flexDirection={{ base: 'column', md: 'row' }}
>
<Flex flex={ 1 } flexDirection="column" p={ 3 } gap={ 2 }>
<Heading level="3">
Activity pass
</Heading>
<Text textStyle="sm">
Grab your{ ' ' }
<Link external href={ activityPassUrl } loading={ rewardsConfigQuery.isLoading }>
Activity pass
</Link>{ ' ' }
then engage with various Blockscout products and features to earn Merits every day!{ ' ' }
<Link external href="https://docs.blockscout.com/using-blockscout/merits/activity-pass">
Learn more
</Link>
</Text>
</Flex>
<Flex
flex={{ base: 'none', md: 1 }}
flexDirection={{ base: 'column', md: 'row' }}
justifyContent="space-between"
alignItems="center"
h={{ base: '160px', md: '120px' }}
pr={{ base: 0, md: 8 }}
pl={{ base: 0, md: '86px' }}
pt={{ base: 4, md: 0 }}
pb={{ base: 3, md: 0 }}
borderRadius="base"
backgroundColor={{ _light: '#FFEFCE', _dark: '#E1910E' }}
overflow="hidden"
position="relative"
>
<Image
src={ backgroundImage }
alt="Background"
width="268px"
height="184px"
position="absolute"
top="-20px"
left={{ base: 'calc(50% - 134px)', md: '-8px' }}
/>
<Image
src="/static/merits/activity_pass.svg"
alt="Activity pass"
width="79px"
height="86px"
zIndex={ 1 }
/>
<Link
external
href={ activityPassUrl }
variant="underlaid"
fontWeight="500"
backgroundColor={{ _light: '#FFD57C', _dark: '#FFBA0D' }}
color="#2B1A3F"
iconColor="rgba(43, 26, 63, 0.3)"
_hover={{ color: 'link.primary.hover' }}
flexShrink={ 0 }
zIndex={ 1 }
>
Grab Activity pass
</Link>
</Flex>
</Flex>
);
}
...@@ -2,6 +2,7 @@ import { Flex, Text } from '@chakra-ui/react'; ...@@ -2,6 +2,7 @@ import { Flex, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Badge } from 'toolkit/chakra/badge'; import { Badge } from 'toolkit/chakra/badge';
import { Heading } from 'toolkit/chakra/heading';
import Hint from 'ui/shared/Hint'; import Hint from 'ui/shared/Hint';
type Props = { type Props = {
...@@ -11,38 +12,47 @@ type Props = { ...@@ -11,38 +12,47 @@ type Props = {
availableSoon?: boolean; availableSoon?: boolean;
blurFilter?: boolean; blurFilter?: boolean;
contentAfter?: React.ReactNode; contentAfter?: React.ReactNode;
direction?: 'column' | 'column-reverse' | 'row'; contentDirection?: 'column' | 'column-reverse' | 'row';
reverse?: boolean; reverse?: boolean;
children?: React.ReactNode; children?: React.ReactNode;
label?: string;
isLoading?: boolean;
cardValueStyle?: object;
}; };
const RewardsDashboardCard = ({ const RewardsDashboardCard = ({
title, description, hint, availableSoon, contentAfter, title, description, availableSoon, contentAfter, cardValueStyle, hint,
direction = 'column', children, blurFilter, contentDirection = 'column', children, blurFilter, label, isLoading,
}: Props) => { }: Props) => {
return ( return (
<Flex <Flex
flexDirection={{ base: direction === 'row' ? 'column' : direction, md: direction }} as="section"
justifyContent={ direction === 'column-reverse' ? 'flex-end' : 'flex-start' } flexDirection={{ base: contentDirection === 'row' ? 'column' : contentDirection, md: contentDirection }}
justifyContent={ contentDirection === 'column-reverse' ? 'flex-end' : 'flex-start' }
p={{ base: 1.5, md: 2 }} p={{ base: 1.5, md: 2 }}
border="1px solid" border="1px solid"
borderColor={{ _light: 'gray.200', _dark: 'whiteAlpha.200' }} borderColor={{ _light: 'gray.200', _dark: 'whiteAlpha.200' }}
borderRadius="lg" borderRadius="lg"
gap={{ base: 1, md: direction === 'row' ? 10 : 1 }} gap={{ base: 4, md: contentDirection === 'row' ? 10 : 4 }}
w={ direction === 'row' ? 'full' : 'auto' } w={ contentDirection === 'row' ? 'full' : 'auto' }
flex={ direction !== 'row' ? 1 : '0 1 auto' } flex={ contentDirection !== 'row' ? 1 : '0 1 auto' }
> >
<Flex <Flex
flexDirection="column" flexDirection="column"
gap={ 2 } gap={ 2 }
p={{ base: 1.5, md: 3 }} px={{ base: 1.5, md: 3 }}
w={{ base: 'full', md: direction === 'row' ? '340px' : 'full' }} pb={ contentDirection === 'column-reverse' ? { base: 1.5, md: 3 } : 0 }
pt={ contentDirection === 'column-reverse' ? 0 : { base: 1.5, md: 3 } }
w={{ base: 'full', md: contentDirection === 'row' ? '340px' : 'full' }}
> >
<Flex alignItems="center" gap={ 2 }> { label && <Badge loading={ isLoading }>{ label }</Badge> }
<Text fontSize={{ base: 'md', md: 'lg' }} fontWeight="500">{ title }</Text> { title && (
{ hint && <Hint label={ hint }/> } <Flex alignItems="center" gap={ 2 }>
{ availableSoon && <Badge colorPalette="blue">Available soon</Badge> } <Heading level="3">{ title }</Heading>
</Flex> { hint && <Hint label={ hint }/> }
{ availableSoon && <Badge colorPalette="blue">Available soon</Badge> }
</Flex>
) }
<Text as="div" fontSize="sm"> <Text as="div" fontSize="sm">
{ description } { description }
</Text> </Text>
...@@ -53,10 +63,12 @@ const RewardsDashboardCard = ({ ...@@ -53,10 +63,12 @@ const RewardsDashboardCard = ({
justifyContent="space-around" justifyContent="space-around"
borderRadius={{ base: 'lg', md: '8px' }} borderRadius={{ base: 'lg', md: '8px' }}
backgroundColor={{ _light: 'gray.50', _dark: 'whiteAlpha.50' }} backgroundColor={{ _light: 'gray.50', _dark: 'whiteAlpha.50' }}
minH={{ base: '80px', md: '128px' }} minH={{ base: '104px', md: '128px' }}
mt={ contentDirection === 'column' ? 'auto' : 0 }
filter="auto" filter="auto"
blur={ blurFilter ? '4px' : '0' } blur={ blurFilter ? '4px' : '0' }
flex={ direction === 'row' ? 1 : '0 1 auto' } flex={ contentDirection === 'row' ? 1 : '0 1 auto' }
{ ...cardValueStyle }
> >
{ children } { children }
</Flex> </Flex>
......
import { Flex, Text } from '@chakra-ui/react'; import { Flex, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Heading } from 'toolkit/chakra/heading';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import Hint from 'ui/shared/Hint'; import Hint from 'ui/shared/Hint';
...@@ -12,16 +13,15 @@ type Props = { ...@@ -12,16 +13,15 @@ type Props = {
withIcon?: boolean; withIcon?: boolean;
hint?: string | React.ReactNode; hint?: string | React.ReactNode;
isLoading?: boolean; isLoading?: boolean;
bottomText?: string;
}; };
const RewardsDashboardCard = ({ label, value, withIcon, hint, isLoading }: Props) => ( const RewardsDashboardCard = ({ label, value, withIcon, hint, isLoading, bottomText }: Props) => (
<Flex key={ label } flexDirection="column" alignItems="center" gap={ 2 }> <Flex key={ label } flexDirection="column" alignItems="center" gap={ 2 }>
{ label && ( { label && (
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>
{ hint && ( { hint && <Hint label={ hint }/> }
<Hint label={ hint }/> <Text textStyle="xs" fontWeight="500" color="text.secondary">
) }
<Text fontSize="xs" fontWeight="500" color="text.secondary">
{ label } { label }
</Text> </Text>
</Flex> </Flex>
...@@ -35,10 +35,17 @@ const RewardsDashboardCard = ({ label, value, withIcon, hint, isLoading }: Props ...@@ -35,10 +35,17 @@ const RewardsDashboardCard = ({ label, value, withIcon, hint, isLoading }: Props
minW="100px" minW="100px"
> >
{ withIcon && <MeritsIcon boxSize={ 8 }/> } { withIcon && <MeritsIcon boxSize={ 8 }/> }
<Text fontSize={{ base: '24px', md: '32px' }} lineHeight={{ base: '24px', md: 1.5 }} fontWeight="500"> <Heading level="1">
{ value } { value }
</Text> </Heading>
</Skeleton> </Skeleton>
{ bottomText && (
<Skeleton loading={ isLoading }>
<Text textStyle="xs" fontWeight="500" color="text.secondary">
{ bottomText }
</Text>
</Skeleton>
) }
</Flex> </Flex>
); );
......
import { Flex, Text } from '@chakra-ui/react';
import React from 'react';
import type { GetInstancesResponse } from '@blockscout/points-types';
import { DialogBody, DialogContent, DialogRoot, DialogHeader } from 'toolkit/chakra/dialog';
import { Image } from 'toolkit/chakra/image';
import { Link } from 'toolkit/chakra/link';
import IconSvg from 'ui/shared/IconSvg';
type Props = {
isOpen: boolean;
onClose: () => void;
items: GetInstancesResponse['items'] | undefined;
};
const RewardsInstancesModal = ({ isOpen, onClose, items }: Props) => {
const handleOpenChange = React.useCallback(({ open }: { open: boolean }) => {
if (!open) {
onClose();
}
}, [ onClose ]);
return (
<DialogRoot
open={ isOpen }
onOpenChange={ handleOpenChange }
size={{ lgDown: 'full', lg: 'sm' }}
>
<DialogContent>
<DialogHeader>
Choose explorer
</DialogHeader>
<DialogBody>
<Flex flexDir="column" gap={ 6 }>
<Text>
Choose Blockscout explorer that you want to interact with and earn
Merits
</Text>
<Flex flexWrap="wrap" gap={ 2 }>
{ items?.map((instance) => (
<Link
external
noIcon
key={ instance.chain_id }
href={ instance.domain }
display="flex"
gap={ 2 }
alignItems="center"
p={ 2 }
bgColor={{ _light: 'blackAlpha.50', _dark: 'whiteAlpha.100' }}
borderRadius="base"
>
<Image
src={ instance.details?.icon_url }
alt={ instance.name }
boxSize={ 5 }
flexShrink={ 0 }
fallback={ (
<IconSvg
name="networks/icon-placeholder"
boxSize={ 5 }
color="text.secondary"
/>
) }
/>
<Text
textStyle="sm"
fontWeight="500"
color="text.primary"
_groupHover={{ color: 'inherit' }}
>
{ instance.name }
</Text>
</Link>
)) }
</Flex>
</Flex>
</DialogBody>
</DialogContent>
</DialogRoot>
);
};
export default RewardsInstancesModal;
import { Text } from '@chakra-ui/react';
import React from 'react';
import { DialogBody, DialogContent, DialogRoot, DialogHeader } from 'toolkit/chakra/dialog';
type Props = {
isOpen: boolean;
onClose: () => void;
title: string;
children: React.ReactNode;
};
const RewardsTaskDetailsModal = ({ isOpen, onClose, title, children }: Props) => {
const handleOpenChange = React.useCallback(({ open }: { open: boolean }) => {
if (!open) {
onClose();
}
}, [ onClose ]);
return (
<DialogRoot
open={ isOpen }
onOpenChange={ handleOpenChange }
size={{ lgDown: 'full', lg: 'sm' }}
>
<DialogContent>
<DialogHeader>
{ title }
</DialogHeader>
<DialogBody>
<Text>{ children }</Text>
<Text textStyle="sm" color="text.secondary" mt={ 3 }>
Note: Merits are only earned on supported networks where the program is active.
</Text>
</DialogBody>
</DialogContent>
</DialogRoot>
);
};
export default RewardsTaskDetailsModal;
import { Flex } from '@chakra-ui/react';
import { useRewardsContext } from 'lib/contexts/rewards';
import { Skeleton } from 'toolkit/chakra/skeleton';
import RewardsReadOnlyInputWithCopy from '../../RewardsReadOnlyInputWithCopy';
import RewardsDashboardCard from '../RewardsDashboardCard';
export default function ReferralsTab() {
const { rewardsConfigQuery, referralsQuery } = useRewardsContext();
return (
<RewardsDashboardCard
title="Referral program"
description={ (
<>
Refer friends and boost your Merits! You receive a{ ' ' }
<Skeleton as="span" loading={ rewardsConfigQuery.isPending }>
{ rewardsConfigQuery.data?.rewards?.referral_share ?
`${ Number(rewardsConfigQuery.data.rewards.referral_share) * 100 }%` :
'N/A'
}
</Skeleton>
{ ' ' }bonus on all Merits earned by your referrals.
</>
) }
contentDirection="row"
>
<Flex
flex={ 1 }
gap={{ base: 2, lg: 6 }}
px={{ base: 4, lg: 6 }}
py={{ base: 4, lg: 0 }}
flexDirection={{ base: 'column', lg: 'row' }}
>
<RewardsReadOnlyInputWithCopy
label="Referral link"
value={ referralsQuery.data?.link || 'N/A' }
isLoading={ referralsQuery.isPending }
flex={ 2 }
/>
<RewardsReadOnlyInputWithCopy
label="Referral code"
value={ referralsQuery.data?.code || 'N/A' }
isLoading={ referralsQuery.isPending }
flex={ 1 }
/>
</Flex>
</RewardsDashboardCard>
);
}
import { Grid } from '@chakra-ui/react';
import config from 'configs/app';
import { apos } from 'lib/html-entities';
import RewardsDashboardInfoCard from '../RewardsDashboardInfoCard';
export default function ResourcesTab() {
return (
<Grid
w="full"
gap={ 6 }
templateColumns={{ base: '1fr', md: 'repeat(2, 1fr)' }}
>
<RewardsDashboardInfoCard
title="Badges"
description={ `Collect limited and legendary badges by completing different Blockscout related tasks.
Go to the badges website to see what${ apos }s available and start your collection today.` }
imageSrc="/static/merits/badges.svg"
imageWidth="180px"
imageHeight="86px"
linkText="View badges"
linkHref={ `https://merits.blockscout.com/?tab=badges&utm_source=${ config.chain.id }&utm_medium=badges` }
/>
<RewardsDashboardInfoCard
title="Blockscout campaigns"
description="Join Blockscout activities to earn bonus Merits and exclusive rewards from our partners!"
imageSrc="/static/merits/campaigns.svg"
imageWidth="180px"
imageHeight="76px"
linkText="Check campaigns"
linkHref={ `https://merits.blockscout.com/?tab=campaigns&utm_source=${ config.chain.id }&utm_medium=campaigns` }
/>
<RewardsDashboardInfoCard
title="Use your Merits"
description="Spend your Merits to get exclusive discounts and offers across several web3 products!"
imageSrc="/static/merits/offers.svg"
imageWidth="180px"
imageHeight="86px"
linkText="Check offers"
linkHref={ `https://merits.blockscout.com/?tab=redeem&utm_source=${ config.chain.id }&utm_medium=redeem` }
/>
</Grid>
);
}
import { Flex, Text, chakra } from '@chakra-ui/react';
import { useCallback, useMemo, useState } from 'react';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import useApiQuery from 'lib/api/useApiQuery';
import { useRewardsContext } from 'lib/contexts/rewards';
import dayjs from 'lib/date/dayjs';
import useIsMobile from 'lib/hooks/useIsMobile';
import { mdash } from 'lib/html-entities';
import { USER_ACTIVITY } from 'stubs/rewards';
import { Button } from 'toolkit/chakra/button';
import { Heading } from 'toolkit/chakra/heading';
import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import Hint from 'ui/shared/Hint';
import IconSvg from 'ui/shared/IconSvg';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
import MeritsIcon from '../../MeritsIcon';
import RewardsActivityPassCard from '../RewardsActivityPassCard';
import RewardsInstancesModal from '../RewardsInstancesModal';
import RewardsTaskDetailsModal from '../RewardsTaskDetailsModal';
const feature = config.features.rewards;
function getMaxAmount(rewards: Record<string, string> | undefined) {
if (!rewards) {
return 0;
}
const values = Object.values(rewards).map(Number);
if (values.length === 0) {
return 0;
}
return Math.max(...values);
}
export default function TasksTab() {
const { apiToken, rewardsConfigQuery } = useRewardsContext();
const explorersModal = useDisclosure();
const taskDetailsModal = useDisclosure();
const isMobile = useIsMobile();
const [ selectedTaskIndex, setSelectedTaskIndex ] = useState<number>(0);
const profileQuery = useProfileQuery();
const checkActivityPassQuery = useApiQuery('rewards_user_check_activity_pass', {
queryOptions: {
enabled: feature.isEnabled && Boolean(apiToken) && Boolean(profileQuery.data?.address_hash),
},
queryParams: {
address: profileQuery.data?.address_hash ?? '',
},
});
const activityQuery = useApiQuery('rewards_user_activity', {
queryOptions: {
enabled: Boolean(apiToken) && feature.isEnabled,
placeholderData: USER_ACTIVITY,
},
fetchParams: { headers: { Authorization: `Bearer ${ apiToken }` } },
});
const instancesQuery = useApiQuery('rewards_instances', {
queryOptions: { enabled: feature.isEnabled },
});
const period = useMemo(() => {
if (!activityQuery.data) {
return undefined;
}
const item = activityQuery.data.items[0];
const startDate = dayjs(item.date).format('MMM D');
const endDate = dayjs(item.end_date).format('MMM D, YYYY');
return `${ startDate } - ${ endDate }`;
}, [ activityQuery ]);
const activities = useMemo(() => {
const calcActivity = (type: string) => {
const current = activityQuery.data?.items.find((item) => item.activity === type);
const previous = activityQuery.data?.last_week.find((item) => item.activity === type);
const currentAmount = Number(current?.amount || 0);
const previousAmount = Number(previous?.amount || 0);
const currentPercentile = (current?.percentile || 0) * 100;
const previousPercentile = (previous?.percentile || 0) * 100;
const amountDiff = currentAmount - previousAmount;
const percentileDiff = currentPercentile - previousPercentile;
return {
amount: currentAmount,
percentile: `${ currentPercentile }%`,
amountDiff: `${ amountDiff >= 0 ? '+' : '' }${ amountDiff }`,
percentileDiff: `${ percentileDiff >= 0 ? '+' : '' }${ percentileDiff }%`,
};
};
return {
transactions: calcActivity('sent_transactions'),
contracts: calcActivity('verified_contracts'),
usage: calcActivity('blockscout_usage'),
};
}, [ activityQuery.data ]);
const tasks = useMemo(() => (
[
{
title: 'Blockscout activity',
description: (
<>
Use Blockscout tools like{ ' ' }
<Link external href="https://revoke.blockscout.com?utm_source=blockscout&utm_medium=transactions-task">
Revokescout
</Link> or{ ' ' }
<Link external href="https://swap.blockscout.com?utm_source=blockscout&utm_medium=transactions-task">
Swapscout
</Link>, or{ ' ' }
<Link href={ route({ pathname: '/verified-contracts' }) }>
interact with smart contracts
</Link>{ ' ' }
to start earning Merits.
</>
),
percentile: activities.transactions?.percentile,
percentileDiff: activities.transactions?.percentileDiff,
amount: activities.transactions?.amount,
amountDiff: activities.transactions?.amountDiff,
maxAmount: getMaxAmount(rewardsConfigQuery.data?.rewards?.sent_transactions_activity_rewards),
},
{
title: 'Contracts verification',
description: (
<>
Log in to your Blockscout account and{ ' ' }
<Link href={ route({ pathname: '/contract-verification' }) }>
verify a smart contract
</Link>{ ' ' }
using Blockscout website to earn Merits.
</>
),
percentile: activities.contracts?.percentile,
percentileDiff: activities.contracts?.percentileDiff,
amount: activities.contracts?.amount,
amountDiff: activities.contracts?.amountDiff,
maxAmount: getMaxAmount(rewardsConfigQuery.data?.rewards?.verified_contracts_activity_rewards),
},
{
title: 'Blockscout usage',
description: (
<>
Use Blockscout explorers in your daily routine { mdash } check transactions, explore addresses,
or add tokens/networks to MetaMask via Blockscout.
</>
),
percentile: activities.usage?.percentile,
percentileDiff: activities.usage?.percentileDiff,
amount: activities.usage?.amount,
amountDiff: activities.usage?.amountDiff,
maxAmount: getMaxAmount(rewardsConfigQuery.data?.rewards?.blockscout_usage_activity_rewards),
},
]
), [ rewardsConfigQuery, activities ]);
const labels = {
period: { text: `Period: ${ period }`, hint: 'Current Merits period. All metrics reset weekly' },
performanceRank: { text: 'Performance rank', hint: 'Your rank across task groups compared to others. Higher rank = more Merits' },
meritsEarned: { text: 'Merits earned', hint: 'Estimated Merits based on your current rank. Final amount may change' },
};
const labelComponents = Object.fromEntries(Object.entries(labels).map(([ key, value ], index) => [ key, (
<Flex key={ index } flex={ 1 } alignItems="center" gap={ 1 } _first={{ minW: { base: 'auto', md: '200px' } }}>
<Text
textStyle={{ base: 'sm', md: 'xs' }}
color={{ base: 'text.primary', md: 'text.secondary' }}
fontWeight="500"
>
{ value.text }
</Text>
<Hint label={ value.hint }/>
</Flex>
) ]));
const openTaskDetails = useCallback((index: number) => () => {
setSelectedTaskIndex(index);
taskDetailsModal.onOpen();
}, [ taskDetailsModal ]);
const isActivityDataLoading = activityQuery.isPlaceholderData || checkActivityPassQuery.isPending;
if (checkActivityPassQuery.data && !checkActivityPassQuery.data.is_valid) {
return <RewardsActivityPassCard/>;
}
return (
<>
<Flex
p={{ base: 1.5, md: 2 }}
border="1px solid"
borderColor={{ _light: 'gray.200', _dark: 'whiteAlpha.200' }}
borderRadius="lg"
gap={{ base: 4, md: 10 }}
flexDirection={{ base: 'column', md: 'row' }}
>
<Flex
display={{ base: 'contents', md: 'flex' }}
flexDirection="column"
w="340px"
p={ 3 }
pr={ 0 }
>
<Flex flexDirection="column" p={{ base: 1.5, md: 0 }} pb={ 0 }>
<Heading level="3" mb={ 2 }>Tasks</Heading>
<Text textStyle="sm" mb={{ base: 2, md: 4 }}>
Use Blockscout and related products daily to earn Merits. Check each task for details and how to get started.
</Text>
<Flex alignItems="center" gap={ 3 } mb={{ base: 0, md: 4 }}>
<Button
loadingSkeleton={ instancesQuery.isLoading }
onClick={ explorersModal.onOpen }
>
Earn
</Button>
<Link
external
href="https://docs.blockscout.com/using-blockscout/merits/activity-pass"
fontSize="md"
fontWeight="500"
textAlign="center"
>
Learn more
</Link>
</Flex>
</Flex>
<Flex
flexDirection="column"
gap={ 2.5 }
mt="auto"
order={{ base: 3, md: 'auto' }}
px={{ base: 1.5, md: 0 }}
>
<IconSvg name="status/warning" boxSize={ 6 } color="gray.500"/>
<Text textStyle="sm">
<chakra.span fontWeight="600">Your current Merit count is not final!</chakra.span><br/>
Merits are calculated based on the activity of all users and may increase or decrease by the end of the period.
</Text>
</Flex>
</Flex>
<Flex display={{ base: 'flex', md: 'none' }} justifyContent="space-between" px={ 3 }>
<Flex alignItems="center" gap={ 1 }>
<Text textStyle="sm" fontWeight="500">
Period
</Text>
<Hint label={ labels.period.hint }/>
</Flex>
<Text textStyle="sm" fontWeight="500" color="text.secondary">
{ period }
</Text>
</Flex>
<Flex
display={{ base: 'contents', md: 'flex' }}
flex={ 1 }
flexDirection="column"
gap={ 1 }
>
<Flex p={ 3 } gap={ 8 } display={{ base: 'none', md: 'flex' }}>
{ Object.values(labelComponents) }
</Flex>
<Flex flexDirection="column" gap={{ base: 1.5, md: 1 }}>
{ tasks.map((item, index) => (
<Flex
key={ index }
flexDirection={{ base: 'column', md: 'row' }}
px={ 3 }
py={ 4 }
gap={{ base: 6, md: 8 }}
borderRadius={{ base: 'lg', md: '8px' }}
backgroundColor={{ _light: 'gray.50', _dark: 'whiteAlpha.50' }}
>
<Flex
flex={ 1 }
flexDirection={{ base: 'row', md: 'column' }}
gap={ 2 }
alignItems={{ base: 'center', md: 'flex-start' }}
justifyContent={{ base: 'space-between', md: 'flex-start' }}
minW={{ base: 'auto', md: '200px' }}
>
<Text textStyle="sm" fontWeight={{ base: '700', md: '500' }}>
{ item.title }
</Text>
<Link
textStyle={{ base: 'sm', md: 'xs' }}
fontWeight={{ base: '400', md: '500' }}
onClick={ openTaskDetails(index) }
>
Task details
</Link>
</Flex>
<Flex display={{ base: 'flex', md: 'contents' }} gap={ 8 }>
<Flex flex={ 1 } flexDirection="column" gap={ 2 } alignItems="flex-start">
<Flex display={{ base: 'flex', md: 'none' }}>
{ labelComponents.performanceRank }
</Flex>
<Skeleton loading={ isActivityDataLoading }>
<Heading level="3">
{ item.percentile }
</Heading>
</Skeleton>
<Skeleton loading={ isActivityDataLoading }>
<Text textStyle={{ base: 'sm', md: 'xs' }} color="text.secondary" fontWeight="500">
{ item.percentileDiff } vs { isMobile ? 'prev.' : 'previous' } week
</Text>
</Skeleton>
</Flex>
<Flex flex={ 1 } flexDirection="column" gap={ 2 } alignItems="flex-start">
<Flex display={{ base: 'flex', md: 'none' }}>
{ labelComponents.meritsEarned }
</Flex>
<Skeleton
loading={ isActivityDataLoading }
display="flex"
alignItems="center"
>
<MeritsIcon boxSize={ 6 } mr={ 2 }/>
<Heading level="3" mr={{ base: 0, md: 2 }}>
{ item.amount }
</Heading>
<Text textStyle="sm" color="gray.400" fontWeight="500" alignSelf="flex-end" display={{ base: 'none', md: 'inline' }}>
/{ item.maxAmount }
</Text>
<Heading level="3" display={{ base: 'inline', md: 'none' }} color="text.secondary">
/{ item.maxAmount }
</Heading>
</Skeleton>
<Skeleton loading={ isActivityDataLoading }>
<Text textStyle={{ base: 'sm', md: 'xs' }} color="text.secondary" fontWeight="500">
{ item.amountDiff } vs { isMobile ? 'prev.' : 'previous' } week
</Text>
</Skeleton>
</Flex>
</Flex>
</Flex>
)) }
</Flex>
<Flex
p={{ base: 1.5, md: 3 }}
order={{ base: 4, md: 'auto' }}
>
<Text textStyle="xs" color="text.secondary" fontWeight="500">
Metrics are not updated in real time. Please allow up to one hour for your Performance Rank and earned Merits to reflect recent activity.
If you experience any issues, feel free to reach out on{ ' ' }
<Link external href="https://discord.gg/blockscout">
Discord
</Link>
</Text>
</Flex>
</Flex>
</Flex>
<RewardsInstancesModal
isOpen={ explorersModal.open }
onClose={ explorersModal.onClose }
items={ instancesQuery.data?.items }
/>
<RewardsTaskDetailsModal
isOpen={ taskDetailsModal.open }
onClose={ taskDetailsModal.onClose }
title={ tasks[selectedTaskIndex].title }
>
{ tasks[selectedTaskIndex].description }
</RewardsTaskDetailsModal>
</>
);
}
...@@ -26,7 +26,7 @@ const RewardsLoginModal = () => { ...@@ -26,7 +26,7 @@ const RewardsLoginModal = () => {
const [ isLoginStep, setIsLoginStep ] = React.useState(true); const [ isLoginStep, setIsLoginStep ] = React.useState(true);
const [ isReferral, setIsReferral ] = React.useState(false); const [ isReferral, setIsReferral ] = React.useState(false);
const [ customReferralReward, setCustomReferralReward ] = React.useState<string | null>(null); const [ customReferralReward, setCustomReferralReward ] = React.useState<string | undefined>();
const [ authModalInitialScreen, setAuthModalInitialScreen ] = React.useState<Screen>(); const [ authModalInitialScreen, setAuthModalInitialScreen ] = React.useState<Screen>();
const authModal = useDisclosure(); const authModal = useDisclosure();
...@@ -34,11 +34,11 @@ const RewardsLoginModal = () => { ...@@ -34,11 +34,11 @@ const RewardsLoginModal = () => {
if (!isLoginModalOpen) { if (!isLoginModalOpen) {
setIsLoginStep(true); setIsLoginStep(true);
setIsReferral(false); setIsReferral(false);
setCustomReferralReward(null); setCustomReferralReward(undefined);
} }
}, [ isLoginModalOpen ]); }, [ isLoginModalOpen ]);
const goNext = useCallback((isReferral: boolean, reward: string | null) => { const goNext = useCallback((isReferral: boolean, reward: string | undefined) => {
setIsReferral(isReferral); setIsReferral(isReferral);
setCustomReferralReward(reward); setCustomReferralReward(reward);
setIsLoginStep(false); setIsLoginStep(false);
......
...@@ -13,16 +13,16 @@ import RewardsReadOnlyInputWithCopy from '../../RewardsReadOnlyInputWithCopy'; ...@@ -13,16 +13,16 @@ import RewardsReadOnlyInputWithCopy from '../../RewardsReadOnlyInputWithCopy';
type Props = { type Props = {
isReferral: boolean; isReferral: boolean;
customReferralReward: string | null; customReferralReward: string | undefined;
}; };
const CongratsStepContent = ({ isReferral, customReferralReward }: Props) => { const CongratsStepContent = ({ isReferral, customReferralReward }: Props) => {
const { referralsQuery, rewardsConfigQuery } = useRewardsContext(); const { referralsQuery, rewardsConfigQuery } = useRewardsContext();
const registrationReward = Number(rewardsConfigQuery.data?.rewards.registration); const registrationReward = Number(rewardsConfigQuery.data?.rewards?.registration);
const registrationWithReferralReward = customReferralReward ? const registrationWithReferralReward = customReferralReward ?
Number(customReferralReward) + registrationReward : Number(customReferralReward) + registrationReward :
Number(rewardsConfigQuery.data?.rewards.registration_with_referral); Number(rewardsConfigQuery.data?.rewards?.registration_with_referral);
const referralReward = registrationWithReferralReward - registrationReward; const referralReward = registrationWithReferralReward - registrationReward;
const refLink = referralsQuery.data?.link || 'N/A'; const refLink = referralsQuery.data?.link || 'N/A';
...@@ -94,8 +94,8 @@ const CongratsStepContent = ({ isReferral, customReferralReward }: Props) => { ...@@ -94,8 +94,8 @@ const CongratsStepContent = ({ isReferral, customReferralReward }: Props) => {
<Text fontSize="md" mt={ 2 }> <Text fontSize="md" mt={ 2 }>
Receive a{ ' ' } Receive a{ ' ' }
<Skeleton as="span" loading={ rewardsConfigQuery.isLoading }> <Skeleton as="span" loading={ rewardsConfigQuery.isLoading }>
{ rewardsConfigQuery.data?.rewards.referral_share ? { rewardsConfigQuery.data?.rewards?.referral_share ?
`${ Number(rewardsConfigQuery.data?.rewards.referral_share) * 100 }%` : `${ Number(rewardsConfigQuery.data.rewards.referral_share) * 100 }%` :
'N/A' 'N/A'
} }
</Skeleton> </Skeleton>
......
...@@ -18,7 +18,7 @@ import { Switch } from 'toolkit/chakra/switch'; ...@@ -18,7 +18,7 @@ import { Switch } from 'toolkit/chakra/switch';
import useProfileQuery from 'ui/snippets/auth/useProfileQuery'; import useProfileQuery from 'ui/snippets/auth/useProfileQuery';
type Props = { type Props = {
goNext: (isReferral: boolean, reward: string | null) => void; goNext: (isReferral: boolean, reward: string | undefined) => void;
closeModal: () => void; closeModal: () => void;
openAuthModal: (isAuth: boolean, trySharedLogin?: boolean) => void; openAuthModal: (isAuth: boolean, trySharedLogin?: boolean) => void;
}; };
...@@ -48,7 +48,7 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => { ...@@ -48,7 +48,7 @@ const LoginStepContent = ({ goNext, closeModal, openAuthModal }: Props) => {
isConnected && !isAddressMismatch && !checkUserQuery.isFetching && !checkUserQuery.data?.exists, isConnected && !isAddressMismatch && !checkUserQuery.isFetching && !checkUserQuery.data?.exists,
[ isConnected, isAddressMismatch, checkUserQuery ]); [ isConnected, isAddressMismatch, checkUserQuery ]);
const canTrySharedLogin = rewardsConfigQuery.data?.auth.shared_siwe_login && checkUserQuery.data?.exists !== false && !isLoggedIntoAccountWithWallet; const canTrySharedLogin = rewardsConfigQuery.data?.auth?.shared_siwe_login && checkUserQuery.data?.exists !== false && !isLoggedIntoAccountWithWallet;
const handleRefCodeChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => { const handleRefCodeChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setRefCode(event.target.value); setRefCode(event.target.value);
......
...@@ -6,6 +6,7 @@ import type { TokenInfo } from 'types/api/token'; ...@@ -6,6 +6,7 @@ import type { TokenInfo } from 'types/api/token';
import config from 'configs/app'; import config from 'configs/app';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import useRewardsActivity from 'lib/hooks/useRewardsActivity';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
import useProvider from 'lib/web3/useProvider'; import useProvider from 'lib/web3/useProvider';
import useSwitchOrAddChain from 'lib/web3/useSwitchOrAddChain'; import useSwitchOrAddChain from 'lib/web3/useSwitchOrAddChain';
...@@ -62,6 +63,7 @@ const AddressAddToWallet = ({ className, token, tokenId, isLoading, variant = 'i ...@@ -62,6 +63,7 @@ const AddressAddToWallet = ({ className, token, tokenId, isLoading, variant = 'i
const { provider, wallet } = useProvider(); const { provider, wallet } = useProvider();
const switchOrAddChain = useSwitchOrAddChain(); const switchOrAddChain = useSwitchOrAddChain();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const { trackUsage } = useRewardsActivity();
const handleClick = React.useCallback(async() => { const handleClick = React.useCallback(async() => {
if (!wallet) { if (!wallet) {
...@@ -89,6 +91,8 @@ const AddressAddToWallet = ({ className, token, tokenId, isLoading, variant = 'i ...@@ -89,6 +91,8 @@ const AddressAddToWallet = ({ className, token, tokenId, isLoading, variant = 'i
description: 'Successfully added token to your wallet', description: 'Successfully added token to your wallet',
}); });
await trackUsage('add_token');
mixpanel.logEvent(mixpanel.EventTypes.ADD_TO_WALLET, { mixpanel.logEvent(mixpanel.EventTypes.ADD_TO_WALLET, {
Target: 'token', Target: 'token',
Wallet: wallet, Wallet: wallet,
...@@ -101,7 +105,7 @@ const AddressAddToWallet = ({ className, token, tokenId, isLoading, variant = 'i ...@@ -101,7 +105,7 @@ const AddressAddToWallet = ({ className, token, tokenId, isLoading, variant = 'i
description: (error as Error)?.message || 'Something went wrong', description: (error as Error)?.message || 'Something went wrong',
}); });
} }
}, [ wallet, token, tokenId, switchOrAddChain, provider ]); }, [ wallet, token, tokenId, switchOrAddChain, provider, trackUsage ]);
if (!provider || !wallet) { if (!provider || !wallet) {
return null; return null;
......
import React from 'react'; import React from 'react';
import { useSignMessage, useSwitchChain } from 'wagmi'; import { useSignMessage, useSwitchChain } from 'wagmi';
import type * as rewards from '@blockscout/points-types';
import type { UserInfo } from 'types/api/account'; import type { UserInfo } from 'types/api/account';
import type { RewardsCheckUserResponse, RewardsConfigResponse, RewardsLoginResponse, RewardsNonceResponse } from 'types/api/rewards';
import config from 'configs/app'; import config from 'configs/app';
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
...@@ -65,12 +65,12 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log ...@@ -65,12 +65,12 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log
throw new Error('User already has logged in to rewards'); throw new Error('User already has logged in to rewards');
} }
const rewardsConfig = await apiFetch('rewards_config') as RewardsConfigResponse; const rewardsConfig = await apiFetch('rewards_config') as rewards.GetConfigResponse;
if (!rewardsConfig.auth.shared_siwe_login) { if (!rewardsConfig.auth?.shared_siwe_login) {
throw new Error('Shared SIWE login is not enabled'); throw new Error('Shared SIWE login is not enabled');
} }
const rewardsCheckUser = await apiFetch('rewards_check_user', { pathParams: { address } }) as RewardsCheckUserResponse; const rewardsCheckUser = await apiFetch('rewards_check_user', { pathParams: { address } }) as rewards.AuthUserResponse;
if (!rewardsCheckUser.exists) { if (!rewardsCheckUser.exists) {
throw new Error('Rewards user does not exist'); throw new Error('Rewards user does not exist');
} }
...@@ -78,7 +78,7 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log ...@@ -78,7 +78,7 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log
const nonceConfig = await apiFetch( const nonceConfig = await apiFetch(
'rewards_nonce', 'rewards_nonce',
{ queryParams: { blockscout_login_address: address, blockscout_login_chain_id: config.chain.id } }, { queryParams: { blockscout_login_address: address, blockscout_login_chain_id: config.chain.id } },
) as RewardsNonceResponse; ) as rewards.AuthNonceResponse;
if (!nonceConfig.merits_login_nonce || !nonceConfig.nonce) { if (!nonceConfig.merits_login_nonce || !nonceConfig.nonce) {
throw new Error('Cannot get merits login nonce'); throw new Error('Cannot get merits login nonce');
} }
...@@ -127,7 +127,7 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log ...@@ -127,7 +127,7 @@ function useSignInWithWallet({ onSuccess, onError, source = 'Login', isAuth, log
signature, signature,
}, },
}, },
}) as RewardsLoginResponse : undefined; }) as rewards.AuthLoginResponse : undefined;
if (!('name' in authResponse)) { if (!('name' in authResponse)) {
throw Error('Something went wrong'); throw Error('Something went wrong');
......
...@@ -1536,6 +1536,11 @@ ...@@ -1536,6 +1536,11 @@
resolved "https://registry.yarnpkg.com/@blockscout/bens-types/-/bens-types-1.4.1.tgz#9182a79d9015b7fa2339edf0bfa3cd0c32045e66" resolved "https://registry.yarnpkg.com/@blockscout/bens-types/-/bens-types-1.4.1.tgz#9182a79d9015b7fa2339edf0bfa3cd0c32045e66"
integrity sha512-TlZ1HVdZ2Cswm/CcvNoxS+Ydiht/YGaLo//PJR/UmkmihlEFoY4HfVJvVcUnOQXi+Si7FwJ486DPii889nTJsQ== integrity sha512-TlZ1HVdZ2Cswm/CcvNoxS+Ydiht/YGaLo//PJR/UmkmihlEFoY4HfVJvVcUnOQXi+Si7FwJ486DPii889nTJsQ==
"@blockscout/points-types@1.3.0-alpha.1":
version "1.3.0-alpha.1"
resolved "https://registry.yarnpkg.com/@blockscout/points-types/-/points-types-1.3.0-alpha.1.tgz#d1f255de6ccfa09b8a938ffe17f6aedd559273a3"
integrity sha512-yZcxvPpS1JT79dZrzSeP4r3BM5cqSnsVnclCIpJMUO3qBRWEytVfDGXcqNacwqp3342Im8RB/YPLKAuJGc+CrA==
"@blockscout/stats-types@2.5.0-alpha": "@blockscout/stats-types@2.5.0-alpha":
version "2.5.0-alpha" version "2.5.0-alpha"
resolved "https://registry.yarnpkg.com/@blockscout/stats-types/-/stats-types-2.5.0-alpha.tgz#e34698577a337ce08b176d8709f89f185d9d9359" resolved "https://registry.yarnpkg.com/@blockscout/stats-types/-/stats-types-2.5.0-alpha.tgz#e34698577a337ce08b176d8709f89f185d9d9359"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment