react-query#UseQueryResult TypeScript Examples
The following examples show how to use
react-query#UseQueryResult.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: nativeBalances.ts From anchor-web-app with Apache License 2.0 | 6 votes |
export function useEvmNativeBalanceQuery(
walletAddress?: EVMAddr,
): UseQueryResult<u<Eth> | undefined> {
const { queryErrorReporter } = useApp();
const { nativeWalletAddress } = useAccount();
const { provider } = useEvmWallet();
return useQuery(
[
EVM_QUERY_KEY.EVM_NATIVE_BALANCES,
walletAddress ?? (nativeWalletAddress as EVMAddr | undefined),
(walletAddress: EVMAddr): Promise<BigNumber> | undefined => {
if (!provider) {
return;
}
return provider.getBalance(walletAddress);
},
],
queryFn,
{
refetchInterval: REFETCH_INTERVAL,
keepPreviousData: true,
onError: queryErrorReporter,
},
);
}
Example #2
Source File: usePoolAPY.ts From rari-dApp with GNU Affero General Public License v3.0 | 6 votes |
usePoolsAPY = (pools: PoolInterface[]) => {
const { rari } = useRari();
const poolAPYs: UseQueryResult[] = useQueries(
pools.map(({ type: poolType }) => {
return {
queryKey: poolType + " apy",
queryFn: () => fetchPoolAPY(rari, poolType),
};
})
);
return useMemo(() => {
return !poolAPYs.length ? [] : poolAPYs.map(({ data: poolAPY }) => poolAPY);
}, [poolAPYs]);
}
Example #3
Source File: EditPage.tsx From frontend with MIT License | 6 votes |
export default function EditPage() {
const { t } = useTranslation('transfer')
const router = useRouter()
const id = String(router.query.id)
const { data: transfer }: UseQueryResult<TransferResponse> = useTransfer(id)
const { data: campaigns }: UseQueryResult<CampaignResponse[]> = useCampaignList()
return (
<AdminLayout>
<AdminContainer title={t('transfers')}>
<Container maxWidth="md" sx={{ py: 5 }}>
{transfer && campaigns && <EditForm transfer={transfer} campaigns={campaigns} id={id} />}
</Container>
</AdminContainer>
</AdminLayout>
)
}
Example #4
Source File: useAxiosQuery.ts From nextclade with MIT License | 6 votes |
export function useAxiosQuery<TData = unknown>(
url: string,
options?: UseAxiosQueryOptions<TData>,
): UseQueryResult<TData, Error> {
return useQuery<TData, Error>(
url,
async () => {
if (options?.delay) {
await new Promise((resolve) => {
setInterval(resolve, options.delay)
})
}
return axiosFetch(url)
},
{
staleTime: Number.POSITIVE_INFINITY,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: true,
refetchInterval: Number.POSITIVE_INFINITY,
...options,
},
)
}
Example #5
Source File: use-get-vaults.tsx From interbtc-ui with Apache License 2.0 | 6 votes |
useGetVaults = ({ address }: { address: string; }): Array<VaultExt<BitcoinUnit>> => {
// TODO: can we handle this check at the application level rather than in components and utilties?
// https://www.notion.so/interlay/Handle-api-loaded-check-at-application-level-38fe5d146c8143a88cef2dde7b0e19d8
const { bridgeLoaded } = useSelector((state: StoreType) => state.general);
// TODO: updating react-query to > 3.28.0 will allow us to type this properly
const vaults = useQueries<Array<UseQueryResult<unknown, unknown>>>(
VAULT_COLLATERAL.map(token => {
return {
queryKey: ['vaults', address, token],
queryFn: () => getVaults(newAccountId(window.bridge.api, address), token),
options: {
enabled: !!bridgeLoaded
}
};
})
);
return parseVaults(vaults);
}
Example #6
Source File: balance.ts From anchor-web-app with Apache License 2.0 | 6 votes |
export function useAncBalanceQuery(
walletAddress: HumanAddr | undefined | null,
): UseQueryResult<AncBalance | undefined> {
const { queryClient, contractAddress, queryErrorReporter } =
useAnchorWebapp();
const result = useQuery(
[
ANCHOR_QUERY_KEY.ANC_BALANCE,
walletAddress ?? undefined,
contractAddress.cw20.ANC,
queryClient,
],
queryFn,
{
refetchInterval: !!walletAddress && 1000 * 60 * 2,
enabled: !!walletAddress,
keepPreviousData: true,
onError: queryErrorReporter,
},
);
return walletAddress ? result : EMPTY_QUERY_RESULT;
}
Example #7
Source File: Form.tsx From frontend with MIT License | 5 votes |
export default function EditForm() {
const router = useRouter()
const queryClient = useQueryClient()
const { t } = useTranslation()
let id = router.query.id
let initialValues: VaultInput = {
name: '',
currency: '',
campaignId: '',
}
if (id) {
id = String(id)
const { data }: UseQueryResult<VaultResponse> = useVault(id)
initialValues = {
name: data?.name,
currency: data?.currency,
campaignId: data?.campaignId,
}
}
const mutationFn = id ? useEditVault(id) : useCreateVault()
const mutation = useMutation<AxiosResponse<VaultResponse>, AxiosError<ApiErrors>, VaultInput>({
mutationFn,
onError: () => AlertStore.show(t('vaults:alerts:error'), 'error'),
onSuccess: () => {
if (id) queryClient.invalidateQueries(endpoints.vaults.getVault(String(id)).url)
AlertStore.show(id ? t('vaults:alerts:edit') : t('vaults:alerts:create'), 'success')
router.push(routes.admin.vaults.index)
},
})
async function onSubmit(data: VaultInput) {
mutation.mutate(data)
}
return (
<GenericForm
onSubmit={onSubmit}
initialValues={initialValues}
validationSchema={validationSchema}>
<Box sx={{ marginTop: '5%', height: '62.6vh' }}>
<Typography variant="h5" component="h2" sx={{ marginBottom: 2, textAlign: 'center' }}>
{id ? t('vaults:edit-form-heading') : t('vaults:form-heading')}
</Typography>
<Grid container spacing={2} sx={{ width: 600, margin: '0 auto' }}>
<Grid item xs={6}>
<FormTextField type="text" label={t('vaults:name')} name="name" />
</Grid>
{id ? (
<></>
) : (
<>
<Grid item xs={6}>
<CurrencySelect />
</Grid>
<Grid item xs={6}>
<FormTextField type="text" label={t('vaults:campaignId')} name="campaignId" />
</Grid>
</>
)}
<Grid item xs={6}>
<SubmitButton fullWidth label={t('vaults:cta:submit')} />
</Grid>
<Grid item xs={6}>
<Link href={routes.admin.vaults.index} passHref>
<Button>{t('vaults:cta:cancel')}</Button>
</Link>
</Grid>
</Grid>
</Box>
</GenericForm>
)
}
Example #8
Source File: useQuery.ts From react-starter-boilerplate with MIT License | 5 votes |
useQuery = <TData = unknown, TError = unknown>(
queryKey: QueryKey,
options?: UseQueryOptions<TData, TError>,
): UseQueryResult<TData, TError> => {
const { queryFn } = useApiClient();
const _queryFn = useMemo(() => queryFn<TData>(), [queryFn]);
return useRqQuery<TData, TError, TData, QueryKey>(queryKey, _queryFn, options);
}
Example #9
Source File: EditForm.tsx From frontend with MIT License | 5 votes |
export default function EditForm() {
const router = useRouter()
const id = String(router.query.id)
const { t } = useTranslation()
const { data }: UseQueryResult<CityResponse> = useCity(String(id))
const initialValues: CityInput = {
name: data?.name,
postalCode: data?.postalCode,
countryId: data?.countryId,
}
const mutationFn = id ? useEditCity(id) : useCreateCity()
const mutation = useMutation<AxiosResponse<CityResponse>, AxiosError<ApiErrors>, CityInput>({
mutationFn,
onError: () => AlertStore.show(t('cities:alerts:error'), 'error'),
onSuccess: () => {
AlertStore.show(t('cities:alerts:edit'), 'success')
router.push(routes.admin.cities.home)
},
})
async function onSubmit(values: CityInput) {
const data = {
name: values.name,
postalCode: values.postalCode,
countryId: values.countryId,
}
mutation.mutate(data)
}
return (
<GenericForm
onSubmit={onSubmit}
initialValues={initialValues}
validationSchema={validationSchema}>
<Box sx={{ marginTop: '5%', height: '62.6vh' }}>
<Typography variant="h5" component="h2" sx={{ marginBottom: 2, textAlign: 'center' }}>
{id ? t('cities:edit-form-heading') : t('cities:form-heading')}
</Typography>
<Grid container spacing={2} sx={{ width: 600, margin: '0 auto' }}>
<Grid item xs={12}>
<FormTextField type="text" label="Cities: Име" name="name" autoComplete="name" />
</Grid>
<Grid item xs={12}>
<FormTextField
type="string"
label="Cities:Пощенски код"
name="postalCode"
autoComplete="postal-code"
/>
</Grid>
<Grid item xs={12}>
<SelectCountry />
</Grid>
<Grid item xs={6}>
<SubmitButton fullWidth label={t('cities:cta:submit')} />
</Grid>
<Grid item xs={6}>
<Link href={routes.admin.cities.home} passHref>
<Button fullWidth>{t('cities:cta:cancel')}</Button>
</Link>
</Grid>
</Grid>
</Box>
</GenericForm>
)
}
Example #10
Source File: use-get-vaults.tsx From interbtc-ui with Apache License 2.0 | 5 votes |
parseVaults = (vaults: Array<UseQueryResult<unknown, unknown>>): Array<VaultExt<BitcoinUnit>> =>
vaults.filter(vault => !vault.isLoading && vault.isSuccess).map(vault => vault.data as VaultExt<BitcoinUnit>)
Example #11
Source File: useEthersNetworkQuery.ts From crust-apps with Apache License 2.0 | 5 votes |
useEthersNetworkQuery = (): UseQueryResult<ethers.providers.Network> => {
const { instance, provider } = useEthers();
return useQuery(
[EthersNetworkQueryKey, provider?.network, instance],
async () => await provider?.getNetwork()
);
}
Example #12
Source File: Grid.tsx From frontend with MIT License | 4 votes |
export default function Grid() {
const { t } = useTranslation('recurring-donation')
const { data }: UseQueryResult<RecurringDonationResponse[]> = useRecurringDonationList()
const [pageSize, setPageSize] = useState(5)
const commonProps: Partial<GridColDef> = {
align: 'left',
width: 150,
headerAlign: 'left',
}
const columns: GridColumns = [
{
field: 'status',
headerName: t('recurring-donation:status'),
flex: 1.5,
...commonProps,
},
{
field: 'currency',
headerName: t('currency'),
flex: 1.5,
...commonProps,
},
{
field: 'amount',
headerName: t('amount'),
flex: 1.5,
...commonProps,
},
{
field: 'extSubscriptionId',
headerName: t('extSubscriptionId'),
...commonProps,
width: 300,
},
{
field: 'extCustomerId',
headerName: t('extCustomerId'),
...commonProps,
width: 300,
},
{
field: 'personId',
headerName: t('personId'),
...commonProps,
width: 300,
},
{
field: 'vaultId',
headerName: t('vaultId'),
...commonProps,
width: 300,
},
{
field: 'actions',
headerName: t('actions'),
width: 120,
type: 'actions',
headerAlign: 'center',
renderCell: (params: GridRenderCellParams): React.ReactNode => {
return (
<GridActions
modalStore={ModalStore}
id={params.row.id}
name={params.row.name}
editLink={routes.admin.recurringDonation.view(params.row.id)}
/>
)
},
},
]
return (
<>
<Box sx={{ marginTop: '2%', mx: 'auto', width: 700 }}>
<DataGrid
style={{
background: 'white',
position: 'absolute',
height: 'calc(100vh - 300px)',
border: 'none',
width: 'calc(100% - 48px)',
left: '24px',
overflowY: 'auto',
overflowX: 'hidden',
borderRadius: '0 0 13px 13px',
}}
rows={data || []}
columns={columns}
rowsPerPageOptions={[5, 10]}
pageSize={pageSize}
onPageSizeChange={(newPageSize) => setPageSize(newPageSize)}
disableSelectionOnClick
/>
</Box>
<DetailsModal />
<DeleteModal />
</>
)
}
Example #13
Source File: client.tsx From mui-toolpad with MIT License | 4 votes |
function QueryEditor({
appId,
connectionId,
value,
onChange,
}: QueryEditorProps<GoogleSheetsApiQuery>) {
const [spreadsheetQuery, setSpreadsheetQuery] = React.useState<string | null>(null);
const debouncedSpreadsheetQuery = useDebounced(spreadsheetQuery, 300);
const fetchedFiles: UseQueryResult<GoogleDriveFiles> = client.useQuery('dataSourceFetchPrivate', [
appId,
connectionId,
{
type: GoogleSheetsPrivateQueryType.FILES_LIST,
spreadsheetQuery: debouncedSpreadsheetQuery,
},
]);
const fetchedFile: UseQueryResult<GoogleDriveFile> = client.useQuery(
'dataSourceFetchPrivate',
value.spreadsheetId
? [
appId,
connectionId,
{
type: GoogleSheetsPrivateQueryType.FILE_GET,
spreadsheetId: value.spreadsheetId,
},
]
: null,
);
const fetchedSpreadsheet: UseQueryResult<GoogleSpreadsheet> = client.useQuery(
'dataSourceFetchPrivate',
value.spreadsheetId
? [
appId,
connectionId,
{
type: GoogleSheetsPrivateQueryType.FETCH_SPREADSHEET,
spreadsheetId: value.spreadsheetId,
},
]
: null,
);
const selectedSheet = React.useMemo(
() =>
fetchedSpreadsheet.data?.sheets?.find(
(sheet) => sheet.properties?.title === value.sheetName,
) ?? null,
[fetchedSpreadsheet, value],
);
const handleSpreadsheetChange = React.useCallback(
(event, newValue: GoogleDriveFile | null) => {
onChange({
...value,
sheetName: null,
spreadsheetId: newValue?.id ?? null,
});
},
[onChange, value],
);
const handleSheetChange = React.useCallback(
(event, newValue: GoogleSheet | null) => {
onChange({
...value,
sheetName: newValue?.properties?.title ?? null,
});
},
[onChange, value],
);
const handleRangeChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
onChange({
...value,
ranges: event.target.value,
});
},
[onChange, value],
);
const handleTransformChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
onChange({
...value,
headerRow: event.target.checked,
});
},
[onChange, value],
);
const handleSpreadsheetInput = React.useCallback(
(event: React.SyntheticEvent, input: string, reason: string) => {
if (reason === 'input') {
setSpreadsheetQuery(input);
}
},
[],
);
return (
<Stack direction="column" gap={2}>
<Autocomplete
fullWidth
value={fetchedFile.data ?? null}
loading={fetchedFiles.isLoading}
loadingText={'Loading...'}
options={fetchedFiles.data?.files ?? []}
getOptionLabel={(option: GoogleDriveFile) => option.name ?? ''}
onInputChange={handleSpreadsheetInput}
onChange={handleSpreadsheetChange}
isOptionEqualToValue={(option: GoogleDriveFile, val: GoogleDriveFile) =>
option.id === val.id
}
renderInput={(params) => <TextField {...params} label="Select spreadsheet" />}
renderOption={(props, option) => {
return (
<li {...props} key={option.id}>
{option.name}
</li>
);
}}
/>
<Autocomplete
fullWidth
loading={fetchedSpreadsheet.isLoading}
value={selectedSheet}
loadingText={'Loading...'}
options={fetchedSpreadsheet.data?.sheets ?? []}
getOptionLabel={(option: GoogleSheet) => option.properties?.title ?? ''}
onChange={handleSheetChange}
renderInput={(params) => <TextField {...params} label="Select sheet" />}
renderOption={(props, option) => {
return (
<li {...props} key={option?.properties?.sheetId}>
{option?.properties?.title}
</li>
);
}}
/>
<TextField
label="Range"
helperText={`In the form of A1:Z999`}
value={value.ranges}
disabled={!value.sheetName}
onChange={handleRangeChange}
/>
<FormControlLabel
label="First row contains column headers"
control={
<Checkbox
checked={value.headerRow}
onChange={handleTransformChange}
inputProps={{ 'aria-label': 'controlled' }}
/>
}
/>
</Stack>
);
}
Example #14
Source File: AmountSelect.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
StatsColumn = ({
color,
mode,
assets,
index,
amount,
symbol,
enableAsCollateral,
}: {
color: string;
mode: Mode;
assets: USDPricedFuseAsset[];
index: number;
amount: number;
symbol: string;
enableAsCollateral: boolean;
}) => {
const { t } = useTranslation();
const { rari, fuse } = useRari();
const { data: updatedAssets }: UseQueryResult<USDPricedFuseAsset[]> =
useQuery(
mode + " " + index + " " + JSON.stringify(assets) + " " + amount,
async () => {
const ethPrice: number = fuse.web3.utils.fromWei(
await rari.getEthUsdPriceBN()
) as any;
const assetToBeUpdated = assets[index];
const interestRateModel = await fuse.getInterestRateModel(
assetToBeUpdated.cToken
);
let updatedAsset: USDPricedFuseAsset;
if (mode === Mode.SUPPLY) {
const supplyBalance =
parseInt(assetToBeUpdated.supplyBalance as any) + amount;
const totalSupply =
parseInt(assetToBeUpdated.totalSupply as any) + amount;
updatedAsset = {
...assetToBeUpdated,
supplyBalance,
supplyBalanceUSD:
((supplyBalance * assetToBeUpdated.underlyingPrice) / 1e36) *
ethPrice,
totalSupply,
supplyRatePerBlock: interestRateModel.getSupplyRate(
fuse.web3.utils.toBN(
totalSupply > 0
? new BigNumber(assetToBeUpdated.totalBorrow)
.dividedBy(totalSupply.toString())
.multipliedBy(1e18)
.toFixed(0)
: 0
)
),
};
} else if (mode === Mode.WITHDRAW) {
const supplyBalance =
parseInt(assetToBeUpdated.supplyBalance as any) - amount;
const totalSupply =
parseInt(assetToBeUpdated.totalSupply as any) - amount;
updatedAsset = {
...assetToBeUpdated,
supplyBalance,
supplyBalanceUSD:
((supplyBalance * assetToBeUpdated.underlyingPrice) / 1e36) *
ethPrice,
totalSupply,
supplyRatePerBlock: interestRateModel.getSupplyRate(
fuse.web3.utils.toBN(
totalSupply > 0
? new BigNumber(assetToBeUpdated.totalBorrow)
.dividedBy(totalSupply.toString())
.multipliedBy(1e18)
.toFixed(0)
: 0
)
),
};
} else if (mode === Mode.BORROW) {
const borrowBalance =
parseInt(assetToBeUpdated.borrowBalance as any) + amount;
const totalBorrow =
parseInt(assetToBeUpdated.totalBorrow as any) + amount;
updatedAsset = {
...assetToBeUpdated,
borrowBalance,
borrowBalanceUSD:
((borrowBalance * assetToBeUpdated.underlyingPrice) / 1e36) *
ethPrice,
totalBorrow,
borrowRatePerBlock: interestRateModel.getBorrowRate(
fuse.web3.utils.toBN(
assetToBeUpdated.totalSupply > 0
? new BigNumber(totalBorrow.toString())
.dividedBy(assetToBeUpdated.totalSupply)
.multipliedBy(1e18)
.toFixed(0)
: 0
)
),
};
} else if (mode === Mode.REPAY) {
const borrowBalance =
parseInt(assetToBeUpdated.borrowBalance as any) - amount;
const totalBorrow =
parseInt(assetToBeUpdated.totalBorrow as any) - amount;
updatedAsset = {
...assetToBeUpdated,
borrowBalance,
borrowBalanceUSD:
((borrowBalance * assetToBeUpdated.underlyingPrice) / 1e36) *
ethPrice,
totalBorrow,
borrowRatePerBlock: interestRateModel.getBorrowRate(
fuse.web3.utils.toBN(
assetToBeUpdated.totalSupply > 0
? new BigNumber(totalBorrow.toString())
.dividedBy(assetToBeUpdated.totalSupply)
.multipliedBy(1e18)
.toFixed(0)
: 0
)
),
};
}
return assets.map((value, _index) => {
if (_index === index) {
return updatedAsset;
} else {
return value;
}
});
}
);
const asset = assets[index];
const updatedAsset = updatedAssets ? updatedAssets[index] : null;
const borrowLimit = useBorrowLimit(assets);
const updatedBorrowLimit = useBorrowLimit(
updatedAssets ?? [],
enableAsCollateral
? {
ignoreIsEnabledCheckFor: asset.cToken,
}
: undefined
);
const isSupplyingOrWithdrawing =
mode === Mode.SUPPLY || mode === Mode.WITHDRAW;
const supplyAPY = convertMantissaToAPY(asset.supplyRatePerBlock, 365);
const borrowAPY = convertMantissaToAPY(asset.borrowRatePerBlock, 365);
const updatedSupplyAPY = convertMantissaToAPY(
updatedAsset?.supplyRatePerBlock ?? 0,
365
);
const updatedBorrowAPY = convertMantissaToAPY(
updatedAsset?.borrowRatePerBlock ?? 0,
365
);
// If the difference is greater than a 0.1 percentage point change, alert the user
const updatedAPYDiffIsLarge = isSupplyingOrWithdrawing
? Math.abs(updatedSupplyAPY - supplyAPY) > 0.1
: Math.abs(updatedBorrowAPY - borrowAPY) > 0.1;
return (
<DashboardBox width="100%" height="190px" mt={4}>
{updatedAsset ? (
<Column
mainAxisAlignment="space-between"
crossAxisAlignment="flex-start"
expand
py={3}
px={4}
fontSize="lg"
>
<Row
mainAxisAlignment="space-between"
crossAxisAlignment="center"
width="100%"
color={color}
>
<Text fontWeight="bold" flexShrink={0}>
{t("Supply Balance")}:
</Text>
<Text
fontWeight="bold"
flexShrink={0}
fontSize={isSupplyingOrWithdrawing ? "sm" : "lg"}
>
{smallUsdFormatter(
asset.supplyBalance / 10 ** asset.underlyingDecimals
).replace("$", "")}
{isSupplyingOrWithdrawing ? (
<>
{" → "}
{smallUsdFormatter(
updatedAsset!.supplyBalance /
10 ** updatedAsset!.underlyingDecimals
).replace("$", "")}
</>
) : null}{" "}
{symbol}
</Text>
</Row>
<Row
mainAxisAlignment="space-between"
crossAxisAlignment="center"
width="100%"
>
<Text fontWeight="bold" flexShrink={0}>
{isSupplyingOrWithdrawing ? t("Supply APY") : t("Borrow APY")}:
</Text>
<Text
fontWeight="bold"
fontSize={updatedAPYDiffIsLarge ? "sm" : "lg"}
>
{isSupplyingOrWithdrawing
? supplyAPY.toFixed(2)
: borrowAPY.toFixed(2)}
%
{updatedAPYDiffIsLarge ? (
<>
{" → "}
{isSupplyingOrWithdrawing
? updatedSupplyAPY.toFixed(2)
: updatedBorrowAPY.toFixed(2)}
%
</>
) : null}
</Text>
</Row>
<Row
mainAxisAlignment="space-between"
crossAxisAlignment="center"
width="100%"
>
<Text fontWeight="bold" flexShrink={0}>
{t("Borrow Limit")}:
</Text>
<Text
fontWeight="bold"
fontSize={isSupplyingOrWithdrawing ? "sm" : "lg"}
>
{smallUsdFormatter(borrowLimit)}
{isSupplyingOrWithdrawing ? (
<>
{" → "} {smallUsdFormatter(updatedBorrowLimit)}
</>
) : null}{" "}
</Text>
</Row>
<Row
mainAxisAlignment="space-between"
crossAxisAlignment="center"
width="100%"
>
<Text fontWeight="bold">{t("Debt Balance")}:</Text>
<Text
fontWeight="bold"
fontSize={!isSupplyingOrWithdrawing ? "sm" : "lg"}
>
{smallUsdFormatter(asset.borrowBalanceUSD)}
{!isSupplyingOrWithdrawing ? (
<>
{" → "}
{smallUsdFormatter(updatedAsset.borrowBalanceUSD)}
</>
) : null}
</Text>
</Row>
</Column>
) : (
<Center expand>
<Spinner />
</Center>
)}
</DashboardBox>
);
}