aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-07-05 00:51:17 +0800
committerGitHub <noreply@github.com>2018-07-05 00:51:17 +0800
commit5176d929fa6d3c6ce414448ea2441bd450f04e3c (patch)
tree6ea9d1f9c9506bee42dbbe0543a8c407c6c5d05e /packages
parentade620f4f7d9ac1e5726681aefcbddf742915a84 (diff)
parent8adc6f0faadb46f88c1f9738b04039d037cfbcb9 (diff)
downloaddexon-0x-contracts-5176d929fa6d3c6ce414448ea2441bd450f04e3c.tar.gz
dexon-0x-contracts-5176d929fa6d3c6ce414448ea2441bd450f04e3c.tar.zst
dexon-0x-contracts-5176d929fa6d3c6ce414448ea2441bd450f04e3c.zip
Merge pull request #817 from 0xProject/remove-web3
Remove Web3 Dependencies (exept for in web3-wrapper)
Diffstat (limited to 'packages')
-rw-r--r--packages/contracts/package.json3
-rw-r--r--packages/dev-utils/package.json1
-rw-r--r--packages/dev-utils/src/web3_factory.ts5
-rw-r--r--packages/sol-compiler/package.json1
-rw-r--r--packages/subproviders/package.json3
-rw-r--r--packages/subproviders/src/index.ts2
-rw-r--r--packages/subproviders/src/subproviders/signer.ts (renamed from packages/subproviders/src/subproviders/injected_web3.ts)45
-rw-r--r--packages/testnet-faucets/package.json2
-rw-r--r--packages/testnet-faucets/src/ts/dispense_asset_tasks.ts15
-rw-r--r--packages/testnet-faucets/src/ts/handler.ts17
-rw-r--r--packages/utils/package.json3
-rw-r--r--packages/website/package.json1
-rw-r--r--packages/website/ts/blockchain.ts29
-rw-r--r--packages/website/ts/containers/subproviders_documentation.ts3
-rw-r--r--packages/website/ts/types.ts13
-rw-r--r--packages/website/ts/utils/analytics.ts11
16 files changed, 92 insertions, 62 deletions
diff --git a/packages/contracts/package.json b/packages/contracts/package.json
index 01f2320d0..448871c23 100644
--- a/packages/contracts/package.json
+++ b/packages/contracts/package.json
@@ -85,7 +85,6 @@
"ethereumjs-abi": "^0.6.4",
"ethereumjs-util": "^5.1.1",
"ethers": "3.0.22",
- "lodash": "^4.17.4",
- "web3": "^0.20.0"
+ "lodash": "^4.17.4"
}
}
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index ebb2aeb41..15f8d6ab0 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -52,7 +52,6 @@
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/web3-wrapper": "^0.7.1",
"lodash": "^4.17.4",
- "web3": "^0.20.0",
"web3-provider-engine": "14.0.6"
},
"publishConfig": {
diff --git a/packages/dev-utils/src/web3_factory.ts b/packages/dev-utils/src/web3_factory.ts
index 47eef4cbd..362a6c3c6 100644
--- a/packages/dev-utils/src/web3_factory.ts
+++ b/packages/dev-utils/src/web3_factory.ts
@@ -1,8 +1,3 @@
-// HACK: web3 injects XMLHttpRequest into the global scope and ProviderEngine checks XMLHttpRequest
-// to know whether it is running in a browser or node environment. We need it to be undefined since
-// we are not running in a browser env.
-// Filed issue: https://github.com/ethereum/web3.js/issues/844
-(global as any).XMLHttpRequest = undefined;
import ProviderEngine = require('web3-provider-engine');
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json
index 2c1fa41b3..d5a2e6e77 100644
--- a/packages/sol-compiler/package.json
+++ b/packages/sol-compiler/package.json
@@ -93,7 +93,6 @@
"require-from-string": "^2.0.1",
"semver": "^5.5.0",
"solc": "^0.4.23",
- "web3": "^0.20.0",
"web3-eth-abi": "^1.0.0-beta.24",
"yargs": "^10.0.3"
},
diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json
index 076129636..8eca91dc7 100644
--- a/packages/subproviders/package.json
+++ b/packages/subproviders/package.json
@@ -42,6 +42,8 @@
"dependencies": {
"@0xproject/assert": "^0.2.12",
"@0xproject/types": "^1.0.0",
+ "@0xproject/web3-wrapper": "^0.7.1",
+ "@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.1",
"@ledgerhq/hw-app-eth": "^4.3.0",
"@ledgerhq/hw-transport-u2f": "^4.3.0",
@@ -55,7 +57,6 @@
"hdkey": "^0.7.1",
"lodash": "^4.17.4",
"semaphore-async-await": "^1.5.1",
- "web3": "^0.20.0",
"web3-provider-engine": "14.0.6"
},
"devDependencies": {
diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts
index 802a27cb1..71d643f14 100644
--- a/packages/subproviders/src/index.ts
+++ b/packages/subproviders/src/index.ts
@@ -7,7 +7,7 @@ import { LedgerEthereumClient } from './types';
export { prependSubprovider } from './utils/subprovider_utils';
export { EmptyWalletSubprovider } from './subproviders/empty_wallet_subprovider';
export { FakeGasEstimateSubprovider } from './subproviders/fake_gas_estimate_subprovider';
-export { InjectedWeb3Subprovider } from './subproviders/injected_web3';
+export { SignerSubprovider } from './subproviders/signer';
export { RedundantSubprovider } from './subproviders/redundant_subprovider';
export { LedgerSubprovider } from './subproviders/ledger';
export { GanacheSubprovider } from './subproviders/ganache';
diff --git a/packages/subproviders/src/subproviders/injected_web3.ts b/packages/subproviders/src/subproviders/signer.ts
index 2691dec53..08a9daceb 100644
--- a/packages/subproviders/src/subproviders/injected_web3.ts
+++ b/packages/subproviders/src/subproviders/signer.ts
@@ -1,5 +1,5 @@
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { JSONRPCRequestPayload, Provider } from 'ethereum-types';
-import * as Web3 from 'web3';
import { Callback, ErrorCallback } from '../types';
@@ -7,19 +7,19 @@ import { Subprovider } from './subprovider';
/**
* This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine)
- * subprovider interface. It forwards JSON RPC requests involving user accounts (getAccounts,
- * sendTransaction, etc...) to the provider instance supplied at instantiation. All other requests
+ * subprovider interface. It forwards JSON RPC requests involving the domain of a signer (getAccounts,
+ * sendTransaction, signMessage etc...) to the provider instance supplied at instantiation. All other requests
* are passed onwards for subsequent subproviders to handle.
*/
-export class InjectedWeb3Subprovider extends Subprovider {
- private _injectedWeb3: Web3;
+export class SignerSubprovider extends Subprovider {
+ private _web3Wrapper: Web3Wrapper;
/**
- * Instantiates a new InjectedWeb3Subprovider
+ * Instantiates a new SignerSubprovider
* @param provider Web3 provider that should handle all user account related requests
*/
constructor(provider: Provider) {
super();
- this._injectedWeb3 = new Web3(provider);
+ this._web3Wrapper = new Web3Wrapper(provider);
}
/**
* This method conforms to the web3-provider-engine interface.
@@ -33,22 +33,39 @@ export class InjectedWeb3Subprovider extends Subprovider {
public async handleRequest(payload: JSONRPCRequestPayload, next: Callback, end: ErrorCallback): Promise<void> {
switch (payload.method) {
case 'web3_clientVersion':
- this._injectedWeb3.version.getNode(end);
+ try {
+ const nodeVersion = await this._web3Wrapper.getNodeVersionAsync();
+ end(null, nodeVersion);
+ } catch (err) {
+ end(err);
+ }
return;
case 'eth_accounts':
- this._injectedWeb3.eth.getAccounts(end);
+ try {
+ const accounts = await this._web3Wrapper.getAvailableAddressesAsync();
+ end(null, accounts);
+ } catch (err) {
+ end(err);
+ }
return;
-
case 'eth_sendTransaction':
const [txParams] = payload.params;
- this._injectedWeb3.eth.sendTransaction(txParams, end);
+ try {
+ const txHash = await this._web3Wrapper.sendTransactionAsync(txParams);
+ end(null, txHash);
+ } catch (err) {
+ end(err);
+ }
return;
-
case 'eth_sign':
const [address, message] = payload.params;
- this._injectedWeb3.eth.sign(address, message, end);
+ try {
+ const signature = await this._web3Wrapper.signMessageAsync(address, message);
+ end(null, signature);
+ } catch (err) {
+ end(err);
+ }
return;
-
default:
next();
return;
diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json
index 0ec62f097..5acd4ae35 100644
--- a/packages/testnet-faucets/package.json
+++ b/packages/testnet-faucets/package.json
@@ -20,6 +20,7 @@
"dependencies": {
"0x.js": "^0.38.0",
"@0xproject/subproviders": "^0.10.4",
+ "@0xproject/web3-wrapper": "^0.7.1",
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/utils": "^0.7.1",
"body-parser": "^1.17.1",
@@ -28,7 +29,6 @@
"express": "^4.15.2",
"lodash": "^4.17.4",
"rollbar": "^0.6.5",
- "web3": "^0.20.0",
"web3-provider-engine": "14.0.6"
},
"devDependencies": {
diff --git a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts
index 41b6c90cd..3af5ca747 100644
--- a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts
+++ b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts
@@ -1,7 +1,7 @@
import { ZeroEx } from '0x.js';
-import { BigNumber, logUtils, promisify } from '@0xproject/utils';
+import { BigNumber, logUtils } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as _ from 'lodash';
-import * as Web3 from 'web3';
import { configs } from './configs';
@@ -13,22 +13,21 @@ const DISPENSE_MAX_AMOUNT_ETHER = 2;
type AsyncTask = () => Promise<void>;
export const dispenseAssetTasks = {
- dispenseEtherTask(recipientAddress: string, web3: Web3): AsyncTask {
+ dispenseEtherTask(recipientAddress: string, web3Wrapper: Web3Wrapper): AsyncTask {
return async () => {
logUtils.log(`Processing ETH ${recipientAddress}`);
- const userBalance = await promisify<BigNumber>(web3.eth.getBalance)(recipientAddress);
- const maxAmountInWei = new BigNumber(web3.toWei(DISPENSE_MAX_AMOUNT_ETHER, 'ether'));
+ const userBalance = await web3Wrapper.getBalanceInWeiAsync(recipientAddress);
+ const maxAmountInWei = Web3Wrapper.toWei(new BigNumber(DISPENSE_MAX_AMOUNT_ETHER));
if (userBalance.greaterThanOrEqualTo(maxAmountInWei)) {
logUtils.log(
`User exceeded ETH balance maximum (${maxAmountInWei}) ${recipientAddress} ${userBalance} `,
);
return;
}
- const sendTransactionAsync = promisify(web3.eth.sendTransaction);
- const txHash = await sendTransactionAsync({
+ const txHash = await web3Wrapper.sendTransactionAsync({
from: configs.DISPENSER_ADDRESS,
to: recipientAddress,
- value: web3.toWei(DISPENSE_AMOUNT_ETHER, 'ether'),
+ value: Web3Wrapper.toWei(new BigNumber(DISPENSE_AMOUNT_ETHER)),
});
logUtils.log(`Sent ${DISPENSE_AMOUNT_ETHER} ETH to ${recipientAddress} tx: ${txHash}`);
};
diff --git a/packages/testnet-faucets/src/ts/handler.ts b/packages/testnet-faucets/src/ts/handler.ts
index 3a60d396c..6d26691d6 100644
--- a/packages/testnet-faucets/src/ts/handler.ts
+++ b/packages/testnet-faucets/src/ts/handler.ts
@@ -1,15 +1,10 @@
import { Order, ZeroEx } from '0x.js';
import { BigNumber, logUtils } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Provider } from 'ethereum-types';
import * as express from 'express';
import * as _ from 'lodash';
-import * as Web3 from 'web3';
-// HACK: web3 injects XMLHttpRequest into the global scope and ProviderEngine checks XMLHttpRequest
-// to know whether it is running in a browser or node environment. We need it to be undefined since
-// we are not running in a browser env.
-// Filed issue: https://github.com/ethereum/web3.js/issues/844
-(global as any).XMLHttpRequest = undefined;
import { NonceTrackerSubprovider, PrivateKeyWalletSubprovider } from '@0xproject/subproviders';
import ProviderEngine = require('web3-provider-engine');
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
@@ -22,7 +17,7 @@ import { rpcUrls } from './rpc_urls';
interface NetworkConfig {
dispatchQueue: DispatchQueue;
- web3: Web3;
+ web3Wrapper: Web3Wrapper;
zeroEx: ZeroEx;
}
@@ -58,15 +53,15 @@ export class Handler {
constructor() {
_.forIn(rpcUrls, (rpcUrl: string, networkId: string) => {
const providerObj = Handler._createProviderEngine(rpcUrl);
- const web3 = new Web3(providerObj);
+ const web3Wrapper = new Web3Wrapper(providerObj);
const zeroExConfig = {
networkId: +networkId,
};
- const zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
+ const zeroEx = new ZeroEx(providerObj, zeroExConfig);
const dispatchQueue = new DispatchQueue();
this._networkConfigByNetworkId[networkId] = {
dispatchQueue,
- web3,
+ web3Wrapper,
zeroEx,
};
});
@@ -106,7 +101,7 @@ export class Handler {
let dispenserTask;
switch (requestedAssetType) {
case RequestedAssetType.ETH:
- dispenserTask = dispenseAssetTasks.dispenseEtherTask(recipient, networkConfig.web3);
+ dispenserTask = dispenseAssetTasks.dispenseEtherTask(recipient, networkConfig.web3Wrapper);
break;
case RequestedAssetType.WETH:
case RequestedAssetType.ZRX:
diff --git a/packages/utils/package.json b/packages/utils/package.json
index f10594de5..0ba7a7ba4 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -42,8 +42,7 @@
"bignumber.js": "~4.1.0",
"ethers": "3.0.22",
"js-sha3": "^0.7.0",
- "lodash": "^4.17.4",
- "web3": "^0.20.0"
+ "lodash": "^4.17.4"
},
"publishConfig": {
"access": "public"
diff --git a/packages/website/package.json b/packages/website/package.json
index 1bfc385b5..a5768a60b 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -58,7 +58,6 @@
"styled-components": "^3.3.0",
"thenby": "^1.2.3",
"truffle-contract": "2.0.1",
- "web3": "^0.20.0",
"web3-provider-engine": "14.0.6",
"whatwg-fetch": "^2.0.3",
"xml-js": "^1.6.4"
diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts
index b59306974..cc2afa28a 100644
--- a/packages/website/ts/blockchain.ts
+++ b/packages/website/ts/blockchain.ts
@@ -12,10 +12,10 @@ import {
import { isValidOrderHash, signOrderHashAsync } from '@0xproject/order-utils';
import { EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared';
import {
- InjectedWeb3Subprovider,
ledgerEthereumBrowserClientFactoryAsync,
LedgerSubprovider,
RedundantSubprovider,
+ SignerSubprovider,
Subprovider,
} from '@0xproject/subproviders';
import {
@@ -46,6 +46,7 @@ import {
Fill,
InjectedProviderObservable,
InjectedProviderUpdate,
+ InjectedWeb3,
Order as PortalOrder,
Providers,
ProviderType,
@@ -59,7 +60,6 @@ import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
import { errorReporter } from 'ts/utils/error_reporter';
import { utils } from 'ts/utils/utils';
-import Web3 = require('web3');
import ProviderEngine = require('web3-provider-engine');
import FilterSubprovider = require('web3-provider-engine/subproviders/filters');
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
@@ -97,8 +97,19 @@ export class Blockchain {
}
return providerNameIfExists;
}
- private static _getInjectedWeb3(): any {
- return (window as any).web3;
+ private static _getInjectedWeb3(): InjectedWeb3 {
+ const injectedWeb3IfExists = (window as any).web3;
+ // Our core assumptions about the injected web3 object is that it has the following
+ // properties and methods.
+ if (
+ _.isUndefined(injectedWeb3IfExists) ||
+ _.isUndefined(injectedWeb3IfExists.version) ||
+ _.isUndefined(injectedWeb3IfExists.version.getNetwork) ||
+ _.isUndefined(injectedWeb3IfExists.currentProvider)
+ ) {
+ return undefined;
+ }
+ return injectedWeb3IfExists;
}
private static async _getInjectedWeb3ProviderNetworkIdIfExistsAsync(): Promise<number | undefined> {
// Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in
@@ -119,7 +130,7 @@ export class Blockchain {
return networkIdIfExists;
}
private static async _getProviderAsync(
- injectedWeb3: Web3,
+ injectedWeb3: InjectedWeb3,
networkIdIfExists: number,
shouldUserLedgerProvider: boolean = false,
): Promise<[Provider, LedgerSubprovider | undefined]> {
@@ -153,7 +164,7 @@ export class Blockchain {
// We catch all requests involving a users account and send it to the injectedWeb3
// instance. All other requests go to the public hosted node.
const provider = new ProviderEngine();
- provider.addProvider(new InjectedWeb3Subprovider(injectedWeb3.currentProvider));
+ provider.addProvider(new SignerSubprovider(injectedWeb3.currentProvider));
provider.addProvider(new FilterSubprovider());
const rpcSubproviders = _.map(publicNodeUrlsIfExistsForNetworkId, publicNodeUrl => {
return new RpcSubprovider({
@@ -834,10 +845,10 @@ export class Blockchain {
this._dispatcher.updateNetworkId(networkId);
await this._rehydrateStoreWithContractEventsAsync();
}
- private _updateProviderName(injectedWeb3: Web3): void {
- const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
+ private _updateProviderName(injectedWeb3IfExists: InjectedWeb3): void {
+ const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3IfExists);
const providerName = doesInjectedWeb3Exist
- ? Blockchain._getNameGivenProvider(injectedWeb3.currentProvider)
+ ? Blockchain._getNameGivenProvider(injectedWeb3IfExists.currentProvider)
: constants.PROVIDER_NAME_PUBLIC;
this._dispatcher.updateInjectedProviderName(providerName);
}
diff --git a/packages/website/ts/containers/subproviders_documentation.ts b/packages/website/ts/containers/subproviders_documentation.ts
index 6d4230e53..567f6a37e 100644
--- a/packages/website/ts/containers/subproviders_documentation.ts
+++ b/packages/website/ts/containers/subproviders_documentation.ts
@@ -25,6 +25,7 @@ const docSections = {
emptyWalletSubprovider: 'emptyWalletSubprovider',
fakeGasEstimateSubprovider: 'fakeGasEstimateSubprovider',
injectedWeb3Subprovider: 'injectedWeb3Subprovider',
+ signerSubprovider: 'signerSubprovider',
redundantRPCSubprovider: 'redundantRPCSubprovider',
ganacheSubprovider: 'ganacheSubprovider',
nonceTrackerSubprovider: 'nonceTrackerSubprovider',
@@ -50,6 +51,7 @@ const docsInfoConfig: DocsInfoConfig = {
['emptyWallet-subprovider']: [docSections.emptyWalletSubprovider],
['fakeGasEstimate-subprovider']: [docSections.fakeGasEstimateSubprovider],
['injectedWeb3-subprovider']: [docSections.injectedWeb3Subprovider],
+ ['signer-subprovider']: [docSections.signerSubprovider],
['redundantRPC-subprovider']: [docSections.redundantRPCSubprovider],
['ganache-subprovider']: [docSections.ganacheSubprovider],
['nonceTracker-subprovider']: [docSections.nonceTrackerSubprovider],
@@ -69,6 +71,7 @@ const docsInfoConfig: DocsInfoConfig = {
[docSections.emptyWalletSubprovider]: ['"subproviders/src/subproviders/empty_wallet_subprovider"'],
[docSections.fakeGasEstimateSubprovider]: ['"subproviders/src/subproviders/fake_gas_estimate_subprovider"'],
[docSections.injectedWeb3Subprovider]: ['"subproviders/src/subproviders/injected_web3"'],
+ [docSections.signerSubprovider]: ['"subproviders/src/subproviders/signer"'],
[docSections.redundantRPCSubprovider]: ['"subproviders/src/subproviders/redundant_rpc"'],
[docSections.ganacheSubprovider]: ['"subproviders/src/subproviders/ganache"'],
[docSections.nonceTrackerSubprovider]: ['"subproviders/src/subproviders/nonce_tracker"'],
diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts
index 14e777d1a..d9b2ef618 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -1,5 +1,6 @@
import { ECSignature } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
+import { Provider } from 'ethereum-types';
import * as React from 'react';
export enum Side {
@@ -574,4 +575,16 @@ export enum AccountState {
Loading = 'Loading',
Locked = 'Locked',
}
+
+export interface InjectedProvider extends Provider {
+ publicConfigStore?: InjectedProviderObservable;
+}
+
+// Minimal expected interface for an injected web3 object
+export interface InjectedWeb3 {
+ currentProvider: InjectedProvider;
+ version: {
+ getNetwork(cd: (err: Error, networkId: string) => void): void;
+ };
+}
// tslint:disable:max-file-line-count
diff --git a/packages/website/ts/utils/analytics.ts b/packages/website/ts/utils/analytics.ts
index 928e45bc3..f4bfa083f 100644
--- a/packages/website/ts/utils/analytics.ts
+++ b/packages/website/ts/utils/analytics.ts
@@ -1,8 +1,8 @@
import * as _ from 'lodash';
import * as ReactGA from 'react-ga';
+import { InjectedWeb3 } from 'ts/types';
import { configs } from 'ts/utils/configs';
import { utils } from 'ts/utils/utils';
-import * as Web3 from 'web3';
export const analytics = {
init(): void {
@@ -16,11 +16,12 @@ export const analytics = {
value,
});
},
- async logProviderAsync(web3IfExists: Web3): Promise<void> {
+ async logProviderAsync(web3IfExists: InjectedWeb3): Promise<void> {
await utils.onPageLoadAsync();
- const providerType = !_.isUndefined(web3IfExists)
- ? utils.getProviderType(web3IfExists.currentProvider)
- : 'NONE';
+ const providerType =
+ !_.isUndefined(web3IfExists) && !_.isUndefined(web3IfExists.currentProvider)
+ ? utils.getProviderType(web3IfExists.currentProvider)
+ : 'NONE';
ReactGA.ga('set', 'dimension1', providerType);
},
};