diff options
Diffstat (limited to 'packages')
25 files changed, 1217 insertions, 368 deletions
diff --git a/packages/contracts/compiler.json b/packages/contracts/compiler.json index f66114e87..cdf49dcf6 100644 --- a/packages/contracts/compiler.json +++ b/packages/contracts/compiler.json @@ -23,6 +23,7 @@ "DummyERC20Token", "DummyERC721Receiver", "DummyERC721Token", + "DummyMultipleReturnERC20Token", "DummyNoReturnERC20Token", "ERC20Proxy", "ERC20Token", diff --git a/packages/contracts/package.json b/packages/contracts/package.json index d3351e6cf..283991cee 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -19,11 +19,14 @@ "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", "test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html", "test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha", - "run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit", + "run_mocha": + "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit", "compile": "sol-compiler --contracts-dir src", "clean": "shx rm -rf lib generated_contract_wrappers", - "generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output generated_contract_wrappers --backend ethers", - "lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/* --exclude **/lib/**/* && yarn lint-contracts", + "generate_contract_wrappers": + "abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output generated_contract_wrappers --backend ethers", + "lint": + "tslint --project . --exclude **/src/generated_contract_wrappers/**/* --exclude **/lib/**/* && yarn lint-contracts", "coverage:report:text": "istanbul report text", "coverage:report:html": "istanbul report html && open coverage/index.html", "profiler:report:html": "istanbul report html && open coverage/index.html", @@ -32,7 +35,8 @@ "lint-contracts": "solhint src/2.0.0/**/**/**/**/*.sol" }, "config": { - "abis": "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Receiver|DummyERC721Token|DummyNoReturnERC20Token|ERC20Proxy|ERC721Proxy|Forwarder|Exchange|ExchangeWrapper|IAssetData|IAssetProxy|InvalidERC721Receiver|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|OrderValidator|ReentrantERC20Token|TestAssetProxyOwner|TestAssetProxyDispatcher|TestConstants|TestExchangeInternals|TestLibBytes|TestLibs|TestSignatureValidator|TestStaticCallReceiver|Validator|Wallet|TokenRegistry|Whitelist|WETH9|ZRXToken).json" + "abis": + "../migrations/artifacts/2.0.0/@(AssetProxyOwner|DummyERC20Token|DummyERC721Receiver|DummyERC721Token|DummyMultipleReturnERC20Token|DummyNoReturnERC20Token|ERC20Proxy|ERC721Proxy|Forwarder|Exchange|ExchangeWrapper|IAssetData|IAssetProxy|InvalidERC721Receiver|MixinAuthorizable|MultiSigWallet|MultiSigWalletWithTimeLock|OrderValidator|ReentrantERC20Token|TestAssetProxyOwner|TestAssetProxyDispatcher|TestConstants|TestExchangeInternals|TestLibBytes|TestLibs|TestSignatureValidator|TestStaticCallReceiver|Validator|Wallet|TokenRegistry|Whitelist|WETH9|ZRXToken).json" }, "repository": { "type": "git", diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol index ff908917d..11bbe40fb 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol @@ -107,14 +107,7 @@ contract MixinExchangeCore is public nonReentrant { - // Fetch current order status - OrderInfo memory orderInfo = getOrderInfo(order); - - // Validate context - assertValidCancel(order, orderInfo); - - // Perform cancel - updateCancelledState(order, orderInfo.orderHash); + cancelOrderInternal(order); } /// @dev Gets information about an order: status, hash, and amount filled. @@ -236,6 +229,22 @@ contract MixinExchangeCore is return fillResults; } + /// @dev After calling, the order can not be filled anymore. + /// Throws if order is invalid or sender does not have permission to cancel. + /// @param order Order to cancel. Order must be OrderStatus.FILLABLE. + function cancelOrderInternal(Order memory order) + internal + { + // Fetch current order status + OrderInfo memory orderInfo = getOrderInfo(order); + + // Validate context + assertValidCancel(order, orderInfo); + + // Perform cancel + updateCancelledState(order, orderInfo.orderHash); + } + /// @dev Updates state with results of a fill order. /// @param order that was filled. /// @param takerAddress Address of taker who filled the order. diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol index a5459a21e..a149f95c9 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol @@ -377,10 +377,11 @@ contract MixinWrapperFunctions is /// @param orders Array of order specifications. function batchCancelOrders(LibOrder.Order[] memory orders) public + nonReentrant { uint256 ordersLength = orders.length; for (uint256 i = 0; i != ordersLength; i++) { - cancelOrder(orders[i]); + cancelOrderInternal(orders[i]); } } diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol index d85913e0f..742499568 100644 --- a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol +++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol @@ -72,6 +72,11 @@ contract MExchangeCore is internal returns (LibFillResults.FillResults memory fillResults); + /// @dev After calling, the order can not be filled anymore. + /// @param order Order struct containing order specifications. + function cancelOrderInternal(LibOrder.Order memory order) + internal; + /// @dev Updates state with results of a fill order. /// @param order that was filled. /// @param takerAddress Address of taker who filled the order. diff --git a/packages/contracts/src/2.0.0/test/DummyERC20Token/DummyMultipleReturnERC20Token.sol b/packages/contracts/src/2.0.0/test/DummyERC20Token/DummyMultipleReturnERC20Token.sol new file mode 100644 index 000000000..8a8aecae8 --- /dev/null +++ b/packages/contracts/src/2.0.0/test/DummyERC20Token/DummyMultipleReturnERC20Token.sol @@ -0,0 +1,70 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.24; + +import "./DummyERC20Token.sol"; + + +// solhint-disable no-empty-blocks +contract DummyMultipleReturnERC20Token is + DummyERC20Token +{ + + constructor ( + string _name, + string _symbol, + uint256 _decimals, + uint256 _totalSupply + ) + public + DummyERC20Token( + _name, + _symbol, + _decimals, + _totalSupply + ) + {} + + /// @dev send `value` token to `to` from `from` on the condition it is approved by `from` + /// @param _from The address of the sender + /// @param _to The address of the recipient + /// @param _value The amount of token to be transferred + function transferFrom( + address _from, + address _to, + uint256 _value + ) + external + returns (bool) + { + emit Transfer( + _from, + _to, + _value + ); + + // HACK: This contract will not compile if we remove `returns (bool)`, so we manually return 64 bytes (equiavalent to true, true) + assembly { + mstore(0, 1) + mstore(32, 1) + return(0, 64) + } + } +} + diff --git a/packages/contracts/src/2.0.0/test/ReentrantERC20Token/ReentrantERC20Token.sol b/packages/contracts/src/2.0.0/test/ReentrantERC20Token/ReentrantERC20Token.sol index 4f4e28302..e3311c703 100644 --- a/packages/contracts/src/2.0.0/test/ReentrantERC20Token/ReentrantERC20Token.sol +++ b/packages/contracts/src/2.0.0/test/ReentrantERC20Token/ReentrantERC20Token.sol @@ -51,6 +51,7 @@ contract ReentrantERC20Token is MARKET_SELL_ORDERS, MATCH_ORDERS, CANCEL_ORDER, + BATCH_CANCEL_ORDERS, CANCEL_ORDERS_UP_TO, SET_SIGNATURE_VALIDATOR_APPROVAL } @@ -150,6 +151,11 @@ contract ReentrantERC20Token is EXCHANGE.cancelOrder.selector, order ); + } else if (currentFunctionId == uint8(ExchangeFunction.BATCH_CANCEL_ORDERS)) { + calldata = abi.encodeWithSelector( + EXCHANGE.batchCancelOrders.selector, + orders + ); } else if (currentFunctionId == uint8(ExchangeFunction.CANCEL_ORDERS_UP_TO)) { calldata = abi.encodeWithSelector( EXCHANGE.cancelOrdersUpTo.selector, diff --git a/packages/contracts/test/asset_proxy/authorizable.ts b/packages/contracts/test/asset_proxy/authorizable.ts index e99c6cee3..0c0da46b3 100644 --- a/packages/contracts/test/asset_proxy/authorizable.ts +++ b/packages/contracts/test/asset_proxy/authorizable.ts @@ -2,6 +2,7 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { RevertReason } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; +import * as _ from 'lodash'; import { MixinAuthorizableContract } from '../../generated_contract_wrappers/mixin_authorizable'; import { artifacts } from '../utils/artifacts'; @@ -28,8 +29,7 @@ describe('Authorizable', () => { }); before(async () => { const accounts = await web3Wrapper.getAvailableAddressesAsync(); - owner = address = accounts[0]; - notOwner = accounts[1]; + [owner, address, notOwner] = _.slice(accounts, 0, 3); authorizable = await MixinAuthorizableContract.deployFrom0xArtifactAsync( artifacts.MixinAuthorizable, provider, diff --git a/packages/contracts/test/asset_proxy/proxies.ts b/packages/contracts/test/asset_proxy/proxies.ts index 6031e554d..4d70031d1 100644 --- a/packages/contracts/test/asset_proxy/proxies.ts +++ b/packages/contracts/test/asset_proxy/proxies.ts @@ -8,6 +8,8 @@ import * as _ from 'lodash'; import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; import { DummyERC721ReceiverContract } from '../../generated_contract_wrappers/dummy_erc721_receiver'; import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; +import { DummyMultipleReturnERC20TokenContract } from '../../generated_contract_wrappers/dummy_multiple_return_erc20_token'; +import { DummyNoReturnERC20TokenContract } from '../../generated_contract_wrappers/dummy_no_return_erc20_token'; import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_proxy'; import { IAssetProxyContract } from '../../generated_contract_wrappers/i_asset_proxy'; @@ -42,6 +44,8 @@ describe('Asset Transfer Proxies', () => { let erc721Receiver: DummyERC721ReceiverContract; let erc20Proxy: ERC20ProxyContract; let erc721Proxy: ERC721ProxyContract; + let noReturnErc20Token: DummyNoReturnERC20TokenContract; + let multipleReturnErc20Token: DummyMultipleReturnERC20TokenContract; let erc20Wrapper: ERC20Wrapper; let erc721Wrapper: ERC721Wrapper; @@ -91,6 +95,51 @@ describe('Asset Transfer Proxies', () => { provider, txDefaults, ); + noReturnErc20Token = await DummyNoReturnERC20TokenContract.deployFrom0xArtifactAsync( + artifacts.DummyNoReturnERC20Token, + provider, + txDefaults, + constants.DUMMY_TOKEN_NAME, + constants.DUMMY_TOKEN_SYMBOL, + constants.DUMMY_TOKEN_DECIMALS, + constants.DUMMY_TOKEN_TOTAL_SUPPLY, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await noReturnErc20Token.setBalance.sendTransactionAsync(makerAddress, constants.INITIAL_ERC20_BALANCE), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await noReturnErc20Token.approve.sendTransactionAsync( + erc20Proxy.address, + constants.INITIAL_ERC20_ALLOWANCE, + { from: makerAddress }, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + multipleReturnErc20Token = await DummyMultipleReturnERC20TokenContract.deployFrom0xArtifactAsync( + artifacts.DummyMultipleReturnERC20Token, + provider, + txDefaults, + constants.DUMMY_TOKEN_NAME, + constants.DUMMY_TOKEN_SYMBOL, + constants.DUMMY_TOKEN_DECIMALS, + constants.DUMMY_TOKEN_TOTAL_SUPPLY, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await multipleReturnErc20Token.setBalance.sendTransactionAsync( + makerAddress, + constants.INITIAL_ERC20_BALANCE, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await multipleReturnErc20Token.approve.sendTransactionAsync( + erc20Proxy.address, + constants.INITIAL_ERC20_ALLOWANCE, + { from: makerAddress }, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); }); beforeEach(async () => { await blockchainLifecycle.startAsync(); @@ -141,6 +190,65 @@ describe('Asset Transfer Proxies', () => { ); }); + it('should successfully transfer tokens that do not return a value', async () => { + // Construct ERC20 asset data + const encodedAssetData = assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address); + // Perform a transfer from makerAddress to takerAddress + const initialMakerBalance = await noReturnErc20Token.balanceOf.callAsync(makerAddress); + const initialTakerBalance = await noReturnErc20Token.balanceOf.callAsync(takerAddress); + const amount = new BigNumber(10); + const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( + encodedAssetData, + makerAddress, + takerAddress, + amount, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await web3Wrapper.sendTransactionAsync({ + to: erc20Proxy.address, + data, + from: exchangeAddress, + }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + // Verify transfer was successful + const newMakerBalance = await noReturnErc20Token.balanceOf.callAsync(makerAddress); + const newTakerBalance = await noReturnErc20Token.balanceOf.callAsync(takerAddress); + expect(newMakerBalance).to.be.bignumber.equal(initialMakerBalance.minus(amount)); + expect(newTakerBalance).to.be.bignumber.equal(initialTakerBalance.plus(amount)); + }); + + it('should successfully transfer tokens and ignore extra assetData', async () => { + // Construct ERC20 asset data + const extraData = '0102030405060708'; + const encodedAssetData = `${assetDataUtils.encodeERC20AssetData(zrxToken.address)}${extraData}`; + // Perform a transfer from makerAddress to takerAddress + const erc20Balances = await erc20Wrapper.getBalancesAsync(); + const amount = new BigNumber(10); + const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( + encodedAssetData, + makerAddress, + takerAddress, + amount, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await web3Wrapper.sendTransactionAsync({ + to: erc20Proxy.address, + data, + from: exchangeAddress, + }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + // Verify transfer was successful + const newBalances = await erc20Wrapper.getBalancesAsync(); + expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal( + erc20Balances[makerAddress][zrxToken.address].minus(amount), + ); + expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal( + erc20Balances[takerAddress][zrxToken.address].add(amount), + ); + }); + it('should do nothing if transferring 0 amount of a token', async () => { // Construct ERC20 asset data const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address); @@ -189,6 +297,7 @@ describe('Asset Transfer Proxies', () => { }), constants.AWAIT_TRANSACTION_MINED_MS, ); + const erc20Balances = await erc20Wrapper.getBalancesAsync(); // Perform a transfer; expect this to fail. await expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ @@ -198,6 +307,43 @@ describe('Asset Transfer Proxies', () => { }), RevertReason.TransferFailed, ); + const newBalances = await erc20Wrapper.getBalancesAsync(); + expect(newBalances).to.deep.equal(erc20Balances); + }); + + it('should throw if allowances are too low and token does not return a value', async () => { + // Construct ERC20 asset data + const encodedAssetData = assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address); + // Create allowance less than transfer amount. Set allowance on proxy. + const allowance = new BigNumber(0); + const amount = new BigNumber(10); + const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( + encodedAssetData, + makerAddress, + takerAddress, + amount, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await noReturnErc20Token.approve.sendTransactionAsync(erc20Proxy.address, allowance, { + from: makerAddress, + }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + const initialMakerBalance = await noReturnErc20Token.balanceOf.callAsync(makerAddress); + const initialTakerBalance = await noReturnErc20Token.balanceOf.callAsync(takerAddress); + // Perform a transfer; expect this to fail. + await expectTransactionFailedAsync( + web3Wrapper.sendTransactionAsync({ + to: erc20Proxy.address, + data, + from: exchangeAddress, + }), + RevertReason.TransferFailed, + ); + const newMakerBalance = await noReturnErc20Token.balanceOf.callAsync(makerAddress); + const newTakerBalance = await noReturnErc20Token.balanceOf.callAsync(takerAddress); + expect(newMakerBalance).to.be.bignumber.equal(initialMakerBalance); + expect(newTakerBalance).to.be.bignumber.equal(initialTakerBalance); }); it('should throw if requesting address is not authorized', async () => { @@ -211,6 +357,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); + const erc20Balances = await erc20Wrapper.getBalancesAsync(); await expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc20Proxy.address, @@ -219,6 +366,35 @@ describe('Asset Transfer Proxies', () => { }), RevertReason.SenderNotAuthorized, ); + const newBalances = await erc20Wrapper.getBalancesAsync(); + expect(newBalances).to.deep.equal(erc20Balances); + }); + + it('should throw if token returns more than 32 bytes', async () => { + // Construct ERC20 asset data + const encodedAssetData = assetDataUtils.encodeERC20AssetData(multipleReturnErc20Token.address); + const amount = new BigNumber(10); + const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( + encodedAssetData, + makerAddress, + takerAddress, + amount, + ); + const initialMakerBalance = await multipleReturnErc20Token.balanceOf.callAsync(makerAddress); + const initialTakerBalance = await multipleReturnErc20Token.balanceOf.callAsync(takerAddress); + // Perform a transfer; expect this to fail. + await expectTransactionFailedAsync( + web3Wrapper.sendTransactionAsync({ + to: erc20Proxy.address, + data, + from: exchangeAddress, + }), + RevertReason.TransferFailed, + ); + const newMakerBalance = await multipleReturnErc20Token.balanceOf.callAsync(makerAddress); + const newTakerBalance = await multipleReturnErc20Token.balanceOf.callAsync(takerAddress); + expect(newMakerBalance).to.be.bignumber.equal(initialMakerBalance); + expect(newTakerBalance).to.be.bignumber.equal(initialTakerBalance); }); }); @@ -247,7 +423,38 @@ describe('Asset Transfer Proxies', () => { const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); - expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); + expect(ownerMakerAsset).to.be.equal(makerAddress); + // Perform a transfer from makerAddress to takerAddress + const amount = new BigNumber(1); + const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( + encodedAssetData, + makerAddress, + takerAddress, + amount, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await web3Wrapper.sendTransactionAsync({ + to: erc721Proxy.address, + data, + from: exchangeAddress, + }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + // Verify transfer was successful + const newOwnerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(newOwnerMakerAsset).to.be.bignumber.equal(takerAddress); + }); + + it('should successfully transfer tokens and ignore extra assetData', async () => { + // Construct ERC721 asset data + const extraData = '0102030405060708'; + const encodedAssetData = `${assetDataUtils.encodeERC721AssetData( + erc721Token.address, + erc721MakerTokenId, + )}${extraData}`; + // Verify pre-condition + const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(ownerMakerAsset).to.be.equal(makerAddress); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(1); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( @@ -274,7 +481,7 @@ describe('Asset Transfer Proxies', () => { const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); - expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); + expect(ownerMakerAsset).to.be.equal(makerAddress); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(1); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( @@ -304,7 +511,7 @@ describe('Asset Transfer Proxies', () => { const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); - expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); + expect(ownerMakerAsset).to.be.equal(makerAddress); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(0); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( @@ -313,7 +520,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectTransactionFailedAsync( + await expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, @@ -321,6 +528,8 @@ describe('Asset Transfer Proxies', () => { }), RevertReason.InvalidAmount, ); + const newOwner = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(newOwner).to.be.equal(ownerMakerAsset); }); it('should throw if transferring > 1 amount of a token', async () => { @@ -328,7 +537,7 @@ describe('Asset Transfer Proxies', () => { const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); - expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); + expect(ownerMakerAsset).to.be.equal(makerAddress); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(500); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( @@ -337,7 +546,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectTransactionFailedAsync( + await expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, @@ -345,11 +554,16 @@ describe('Asset Transfer Proxies', () => { }), RevertReason.InvalidAmount, ); + const newOwner = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(newOwner).to.be.equal(ownerMakerAsset); }); it('should throw if allowances are too low', async () => { // Construct ERC721 asset data const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); + // Verify pre-condition + const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(ownerMakerAsset).to.be.equal(makerAddress); // Remove transfer approval for makerAddress. await web3Wrapper.awaitTransactionSuccessAsync( await erc721Token.approve.sendTransactionAsync(constants.NULL_ADDRESS, erc721MakerTokenId, { @@ -365,7 +579,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectTransactionFailedAsync( + await expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, @@ -373,11 +587,16 @@ describe('Asset Transfer Proxies', () => { }), RevertReason.TransferFailed, ); + const newOwner = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(newOwner).to.be.equal(ownerMakerAsset); }); it('should throw if requesting address is not authorized', async () => { // Construct ERC721 asset data const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); + // Verify pre-condition + const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(ownerMakerAsset).to.be.equal(makerAddress); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(1); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( @@ -386,7 +605,7 @@ describe('Asset Transfer Proxies', () => { takerAddress, amount, ); - return expectTransactionFailedAsync( + await expectTransactionFailedAsync( web3Wrapper.sendTransactionAsync({ to: erc721Proxy.address, data, @@ -394,6 +613,8 @@ describe('Asset Transfer Proxies', () => { }), RevertReason.SenderNotAuthorized, ); + const newOwner = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); + expect(newOwner).to.be.equal(ownerMakerAsset); }); }); diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 3bb71b58f..acb99eed1 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -8,7 +8,10 @@ import { LogWithDecodedArgs } from 'ethereum-types'; import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; -import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_erc20_token'; +import { + DummyERC20TokenContract, + DummyERC20TokenTransferEventArgs, +} from '../../generated_contract_wrappers/dummy_erc20_token'; import { DummyERC721TokenContract } from '../../generated_contract_wrappers/dummy_erc721_token'; import { DummyNoReturnERC20TokenContract } from '../../generated_contract_wrappers/dummy_no_return_erc20_token'; import { ERC20ProxyContract } from '../../generated_contract_wrappers/erc20_proxy'; @@ -243,6 +246,40 @@ describe('Exchange core', () => { RevertReason.ValidatorError, ); }); + + it('should not emit transfer events for transfers where from == to', async () => { + const txReceipt = await exchangeWrapper.fillOrderAsync(signedOrder, makerAddress); + const logs = txReceipt.logs; + const transferLogs = _.filter( + logs, + log => (log as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).event === 'Transfer', + ); + expect(transferLogs.length).to.be.equal(2); + expect((transferLogs[0] as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).address).to.be.equal( + zrxToken.address, + ); + expect((transferLogs[0] as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).args._from).to.be.equal( + makerAddress, + ); + expect((transferLogs[0] as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).args._to).to.be.equal( + feeRecipientAddress, + ); + expect( + (transferLogs[0] as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).args._value, + ).to.be.bignumber.equal(signedOrder.makerFee); + expect((transferLogs[1] as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).address).to.be.equal( + zrxToken.address, + ); + expect((transferLogs[1] as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).args._from).to.be.equal( + makerAddress, + ); + expect((transferLogs[1] as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).args._to).to.be.equal( + feeRecipientAddress, + ); + expect( + (transferLogs[1] as LogWithDecodedArgs<DummyERC20TokenTransferEventArgs>).args._value, + ).to.be.bignumber.equal(signedOrder.takerFee); + }); }); describe('Testing exchange of ERC20 tokens with no return values', () => { diff --git a/packages/contracts/test/exchange/dispatcher.ts b/packages/contracts/test/exchange/dispatcher.ts index 81871a680..a8ae897a8 100644 --- a/packages/contracts/test/exchange/dispatcher.ts +++ b/packages/contracts/test/exchange/dispatcher.ts @@ -205,6 +205,60 @@ describe('AssetProxyDispatcher', () => { ); }); + it('should not dispatch a transfer if amount == 0', async () => { + // Register ERC20 proxy + await web3Wrapper.awaitTransactionSuccessAsync( + await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: owner }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + // Construct metadata for ERC20 proxy + const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address); + + // Perform a transfer from makerAddress to takerAddress + const erc20Balances = await erc20Wrapper.getBalancesAsync(); + const amount = constants.ZERO_AMOUNT; + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( + await assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync( + encodedAssetData, + makerAddress, + takerAddress, + amount, + { from: owner }, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + expect(txReceipt.logs.length).to.be.equal(0); + const newBalances = await erc20Wrapper.getBalancesAsync(); + expect(newBalances).to.deep.equal(erc20Balances); + }); + + it('should not dispatch a transfer if from == to', async () => { + // Register ERC20 proxy + await web3Wrapper.awaitTransactionSuccessAsync( + await assetProxyDispatcher.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: owner }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + // Construct metadata for ERC20 proxy + const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address); + + // Perform a transfer from makerAddress to takerAddress + const erc20Balances = await erc20Wrapper.getBalancesAsync(); + const amount = new BigNumber(10); + const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( + await assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync( + encodedAssetData, + makerAddress, + makerAddress, + amount, + { from: owner }, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + expect(txReceipt.logs.length).to.be.equal(0); + const newBalances = await erc20Wrapper.getBalancesAsync(); + expect(newBalances).to.deep.equal(erc20Balances); + }); + it('should throw if dispatching to unregistered proxy', async () => { // Construct metadata for ERC20 proxy const encodedAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address); diff --git a/packages/contracts/test/exchange/match_orders.ts b/packages/contracts/test/exchange/match_orders.ts index 554c456cc..c6e7b494f 100644 --- a/packages/contracts/test/exchange/match_orders.ts +++ b/packages/contracts/test/exchange/match_orders.ts @@ -406,6 +406,100 @@ describe('matchOrders', () => { ); }); + it('Should give right maker and right taker a favorable fee price when rounding', async () => { + // Create orders to match + const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ + makerAddress: makerAddressLeft, + makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(16), 0), + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(22), 0), + feeRecipientAddress: feeRecipientAddressLeft, + }); + const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ + makerAddress: makerAddressRight, + makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), + takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(83), 0), + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(49), 0), + feeRecipientAddress: feeRecipientAddressRight, + makerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(10000), 0), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(10000), 0), + }); + // Note: + // The maker/taker fee percentage paid on the right order differs because + // they received different sale prices. The right maker pays a + // fee slightly lower than the right taker. + const expectedTransferAmounts = { + // Left Maker + amountSoldByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(16), 0), + amountBoughtByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(22), 0), + feePaidByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 16), // 100% + // Right Maker + amountSoldByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(22), 0), + amountBoughtByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(13), 0), + feePaidByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(2650), 0), // 2650.6 rounded down tro 2650 + // Taker + amountReceivedByTaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(3), 0), + feePaidByTakerLeft: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 16), // 100% + feePaidByTakerRight: Web3Wrapper.toBaseUnitAmount(new BigNumber(2653), 0), // 2653.1 rounded down to 2653 + }; + // Match signedOrderLeft with signedOrderRight + await matchOrderTester.matchOrdersAndAssertEffectsAsync( + signedOrderLeft, + signedOrderRight, + takerAddress, + erc20BalancesByOwner, + erc721TokenIdsByOwner, + expectedTransferAmounts, + ); + }); + + it('Should give left maker and left taker a favorable fee price when rounding', async () => { + // Create orders to match + const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ + makerAddress: makerAddressLeft, + makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(12), 0), + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(97), 0), + feeRecipientAddress: feeRecipientAddressLeft, + makerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(10000), 0), + takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(10000), 0), + }); + const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ + makerAddress: makerAddressRight, + makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), + takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(89), 0), + takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), 0), + feeRecipientAddress: feeRecipientAddressRight, + }); + // Note: + // The maker/taker fee percentage paid on the left order differs because + // they received different sale prices. The left maker pays a + // fee slightly lower than the left taker. + const expectedTransferAmounts = { + // Left Maker + amountSoldByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(11), 0), + amountBoughtByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(89), 0), + feePaidByLeftMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(9166), 0), // 9166.6 rounded down to 9166 + // Right Maker + amountSoldByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(89), 0), + amountBoughtByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), 0), + feePaidByRightMaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 16), // 100% + // Taker + amountReceivedByTaker: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 0), + feePaidByTakerLeft: Web3Wrapper.toBaseUnitAmount(new BigNumber(9175), 0), // 9175.2 rounded down to 9175 + feePaidByTakerRight: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 16), // 100% + }; + // Match signedOrderLeft with signedOrderRight + await matchOrderTester.matchOrdersAndAssertEffectsAsync( + signedOrderLeft, + signedOrderRight, + takerAddress, + erc20BalancesByOwner, + erc721TokenIdsByOwner, + expectedTransferAmounts, + ); + }); + it('Should transfer correct amounts when right order fill amount deviates from amount derived by `Exchange.fillOrder`', async () => { // Create orders to match const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ diff --git a/packages/contracts/test/utils/artifacts.ts b/packages/contracts/test/utils/artifacts.ts index 5ddb5cc7f..53f2a4e4e 100644 --- a/packages/contracts/test/utils/artifacts.ts +++ b/packages/contracts/test/utils/artifacts.ts @@ -4,6 +4,7 @@ import * as AssetProxyOwner from '../../artifacts/AssetProxyOwner.json'; import * as DummyERC20Token from '../../artifacts/DummyERC20Token.json'; import * as DummyERC721Receiver from '../../artifacts/DummyERC721Receiver.json'; import * as DummyERC721Token from '../../artifacts/DummyERC721Token.json'; +import * as DummyMultipleReturnERC20Token from '../../artifacts/DummyMultipleReturnERC20Token.json'; import * as DummyNoReturnERC20Token from '../../artifacts/DummyNoReturnERC20Token.json'; import * as ERC20Proxy from '../../artifacts/ERC20Proxy.json'; import * as ERC721Proxy from '../../artifacts/ERC721Proxy.json'; @@ -37,6 +38,7 @@ export const artifacts = { DummyERC20Token: (DummyERC20Token as any) as ContractArtifact, DummyERC721Receiver: (DummyERC721Receiver as any) as ContractArtifact, DummyERC721Token: (DummyERC721Token as any) as ContractArtifact, + DummyMultipleReturnERC20Token: (DummyMultipleReturnERC20Token as any) as ContractArtifact, DummyNoReturnERC20Token: (DummyNoReturnERC20Token as any) as ContractArtifact, ERC20Proxy: (ERC20Proxy as any) as ContractArtifact, ERC721Proxy: (ERC721Proxy as any) as ContractArtifact, diff --git a/packages/contracts/test/utils/constants.ts b/packages/contracts/test/utils/constants.ts index ee4378d2e..b9ba8ccb9 100644 --- a/packages/contracts/test/utils/constants.ts +++ b/packages/contracts/test/utils/constants.ts @@ -60,6 +60,7 @@ export const constants = { 'MARKET_SELL_ORDERS', 'MATCH_ORDERS', 'CANCEL_ORDER', + 'BATCH_CANCEL_ORDERS', 'CANCEL_ORDERS_UP_TO', 'SET_SIGNATURE_VALIDATOR_APPROVAL', ], diff --git a/packages/typescript-typings/types/react-typist/index.d.ts b/packages/typescript-typings/types/react-typist/index.d.ts new file mode 100644 index 000000000..692c596a5 --- /dev/null +++ b/packages/typescript-typings/types/react-typist/index.d.ts @@ -0,0 +1 @@ +declare module 'react-typist'; diff --git a/packages/website/package.json b/packages/website/package.json index 3b6754fb3..a7da19c9e 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -52,6 +52,7 @@ "react-router-dom": "^4.1.1", "react-scroll": "0xproject/react-scroll#similar-to-pr-330", "react-tooltip": "^3.2.7", + "react-typist": "^2.0.4", "redux": "^3.6.0", "redux-devtools-extension": "^2.13.2", "semver-sort": "0.0.4", diff --git a/packages/website/public/images/landing/0x_homepage.svg b/packages/website/public/images/landing/0x_homepage.svg new file mode 100644 index 000000000..061ac8939 --- /dev/null +++ b/packages/website/public/images/landing/0x_homepage.svg @@ -0,0 +1,386 @@ +<svg width="410" height="254" viewBox="0 0 410 254" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="410" height="254" fill="black" fill-opacity="0"/> +<rect width="410" height="254" fill="black" fill-opacity="0"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M409.979 122.524C410.195 134.531 408.758 137.636 404.251 140.251L210.864 252.464C207.334 254.512 202.985 254.512 199.455 252.464L6.06657 140.251C1.55911 137.635 -1.2295 135.189 0.536218 121.797L409.979 122.524Z" fill="#D0CAFF"/> +<rect width="98.1672" height="56.8942" fill="black" fill-opacity="0" transform="translate(87.1703 125.679)"/> +<path d="M178.097 125.679L87.1703 178.372" stroke="#C4AED9" stroke-width="1.32046" stroke-linecap="round"/> +<path d="M181.659 127.746L90.732 180.439" stroke="#C4AED9" stroke-width="1.32046" stroke-linecap="round"/> +<path d="M185.338 129.88L94.41 182.573" stroke="#C4AED9" stroke-width="1.32046" stroke-linecap="round"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M199.455 245.823L6.06657 133.61C-1.53963 129.196 -1.53963 118.163 6.06657 113.749L199.453 1.53604C202.984 -0.512014 207.333 -0.512014 210.863 1.53604L404.251 113.75C411.858 118.163 411.858 129.197 404.251 133.611L210.864 245.823C207.334 247.871 202.985 247.871 199.455 245.823Z" fill="#F0EEFF"/> +<rect width="107.203" height="36.2243" fill="black" fill-opacity="0" transform="translate(79.7358 74.3805)"/> +<path d="M79.7358 107.066L133.382 75.8612C136.304 73.965 139.326 73.974 141.767 75.4102L186.939 101.973" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<path d="M82.4662 108.801L134.79 78.5156C136.798 77.3507 139.273 77.3583 141.274 78.5356L184.001 103.681" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<path d="M85.1381 110.605L134.534 82.5144C136.541 81.3495 139.017 81.3571 141.017 82.5348L180.403 105.714" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<rect width="100.727" height="37.9813" fill="black" fill-opacity="0" transform="translate(226.643 123.734)"/> +<path d="M327.37 126.923L270.289 160.234C267.367 162.131 264.345 162.121 261.903 160.685L226.643 140.288" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<path d="M323.336 125.886L268.881 157.58C266.873 158.745 264.398 158.737 262.397 157.56L229.58 138.58" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<path d="M319.925 123.734L269.137 153.581C267.129 154.746 264.654 154.739 262.653 153.561L233.178 136.547" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M322.112 124.6C313.477 119.589 313.477 111.465 322.112 106.454C330.747 101.444 344.748 101.444 353.383 106.454C362.018 111.465 362.018 119.589 353.383 124.6C344.748 129.611 330.747 129.611 322.112 124.6Z" stroke="#DBDBFF" stroke-width="2"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M50.8048 126.749C42.1698 121.739 42.1698 113.614 50.8048 108.604C59.4403 103.593 73.4409 103.593 82.0764 108.604C90.7115 113.614 90.7115 121.739 82.0764 126.749C73.4409 131.76 59.4403 131.76 50.8048 126.749Z" stroke="#DBDBFF" stroke-width="2"/> +<g opacity="0.372566"> +<rect width="34.2587" height="23.7724" fill="black" fill-opacity="0" transform="translate(169.644 179.583)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M171.171 194.759L170.656 194.461C170.619 194.439 170.596 194.399 170.596 194.357V192.616C170.596 192.524 170.695 192.466 170.775 192.513L171.29 192.811C171.327 192.833 171.35 192.872 171.35 192.915V194.655C171.35 194.748 171.251 194.805 171.171 194.759Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M172.622 195.59L172.107 195.291C172.07 195.269 172.047 195.23 172.047 195.187V193.447C172.047 193.354 172.146 193.297 172.226 193.343L172.741 193.642C172.778 193.663 172.801 193.703 172.801 193.745V195.486C172.801 195.578 172.702 195.635 172.622 195.59Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M174.073 196.42L173.558 196.122C173.521 196.1 173.499 196.06 173.499 196.018V194.277C173.499 194.185 173.598 194.127 173.677 194.174L174.192 194.472C174.23 194.494 174.252 194.533 174.252 194.576V196.316C174.252 196.409 174.153 196.466 174.073 196.42Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M175.525 197.251L175.009 196.952C174.973 196.93 174.95 196.891 174.95 196.848V195.108C174.95 195.015 175.049 194.958 175.128 195.004L175.644 195.303C175.681 195.324 175.703 195.364 175.703 195.406V197.147C175.703 197.239 175.604 197.296 175.525 197.251Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M176.976 198.081L176.46 197.783C176.424 197.761 176.401 197.721 176.401 197.679V195.938C176.401 195.846 176.5 195.789 176.579 195.835L177.095 196.133C177.132 196.155 177.154 196.194 177.154 196.237V197.978C177.154 198.07 177.055 198.127 176.976 198.081Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M178.427 198.912L177.912 198.613C177.875 198.591 177.852 198.552 177.852 198.509V196.769C177.852 196.676 177.951 196.619 178.031 196.665L178.546 196.964C178.583 196.985 178.606 197.025 178.606 197.067V198.808C178.606 198.9 178.506 198.958 178.427 198.912Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M179.878 199.742L179.363 199.444C179.326 199.422 179.303 199.382 179.303 199.34V197.599C179.303 197.507 179.402 197.45 179.482 197.496L179.997 197.794C180.034 197.816 180.057 197.855 180.057 197.898V199.639C180.057 199.731 179.958 199.788 179.878 199.742Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M181.33 200.652L180.814 200.353C180.777 200.332 180.754 200.293 180.754 200.25V198.509C180.754 198.417 180.854 198.359 180.933 198.406L181.449 198.704C181.485 198.725 181.508 198.765 181.508 198.808V200.548C181.508 200.64 181.409 200.698 181.33 200.652Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M182.781 201.443L182.265 201.144C182.228 201.123 182.205 201.083 182.205 201.041V199.3C182.205 199.208 182.305 199.15 182.384 199.196L182.9 199.495C182.936 199.517 182.959 199.556 182.959 199.599V201.339C182.959 201.432 182.86 201.489 182.781 201.443Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M184.232 202.313L183.716 202.014C183.679 201.993 183.657 201.954 183.657 201.911V200.17C183.657 200.078 183.756 200.02 183.836 200.067L184.351 200.365C184.388 200.387 184.41 200.426 184.41 200.469V202.209C184.41 202.302 184.311 202.359 184.232 202.313Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M185.683 203.144L185.168 202.845C185.131 202.824 185.108 202.784 185.108 202.741V201.001C185.108 200.909 185.207 200.851 185.287 200.897L185.802 201.196C185.839 201.217 185.862 201.256 185.862 201.299V203.04C185.862 203.132 185.763 203.19 185.683 203.144Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M202.343 194.776L202.869 194.471C202.907 194.449 202.93 194.409 202.93 194.365V192.588C202.93 192.494 202.829 192.435 202.748 192.482L202.221 192.786C202.184 192.808 202.161 192.849 202.161 192.893V194.67C202.161 194.764 202.262 194.823 202.343 194.776Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M200.861 195.624L201.387 195.319C201.425 195.297 201.448 195.257 201.448 195.214V193.436C201.448 193.342 201.347 193.283 201.266 193.33L200.74 193.635C200.702 193.656 200.679 193.697 200.679 193.741V195.518C200.679 195.612 200.78 195.671 200.861 195.624Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M199.379 196.472L199.905 196.167C199.943 196.145 199.966 196.105 199.966 196.062V194.284C199.966 194.19 199.865 194.131 199.784 194.178L199.257 194.483C199.22 194.505 199.197 194.545 199.197 194.589V196.366C199.197 196.461 199.298 196.519 199.379 196.472Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M197.897 197.32L198.423 197.015C198.461 196.993 198.484 196.953 198.484 196.91V195.132C198.484 195.038 198.383 194.979 198.302 195.026L197.775 195.331C197.738 195.353 197.715 195.393 197.715 195.437V197.214C197.715 197.309 197.816 197.367 197.897 197.32Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M196.415 198.168L196.941 197.863C196.979 197.841 197.002 197.801 197.002 197.758V195.98C197.002 195.886 196.901 195.827 196.82 195.874L196.294 196.179C196.256 196.201 196.233 196.242 196.233 196.285V198.062C196.233 198.157 196.334 198.215 196.415 198.168Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M194.933 199.017L195.459 198.711C195.497 198.69 195.52 198.649 195.52 198.606V196.828C195.52 196.735 195.419 196.676 195.338 196.722L194.811 197.027C194.774 197.049 194.751 197.09 194.751 197.133V198.91C194.751 199.005 194.852 199.063 194.933 199.017Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M193.451 199.865L193.977 199.56C194.015 199.538 194.038 199.498 194.038 199.454V197.676C194.038 197.583 193.937 197.524 193.856 197.571L193.329 197.876C193.292 197.897 193.269 197.938 193.269 197.982V199.758C193.269 199.853 193.37 199.912 193.451 199.865Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M191.969 200.794L192.495 200.489C192.533 200.467 192.556 200.427 192.556 200.383V198.605C192.556 198.512 192.455 198.453 192.374 198.5L191.848 198.805C191.81 198.827 191.787 198.867 191.787 198.91V200.688C191.787 200.782 191.888 200.841 191.969 200.794Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M190.487 201.601L191.013 201.296C191.051 201.274 191.074 201.234 191.074 201.191V199.413C191.074 199.319 190.973 199.26 190.892 199.307L190.366 199.612C190.328 199.634 190.305 199.674 190.305 199.718V201.496C190.305 201.59 190.406 201.649 190.487 201.601Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M189.005 202.49L189.531 202.185C189.569 202.163 189.592 202.123 189.592 202.08V200.302C189.592 200.208 189.491 200.149 189.41 200.196L188.883 200.501C188.846 200.523 188.823 200.563 188.823 200.607V202.384C188.823 202.478 188.924 202.537 189.005 202.49Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M187.523 203.338L188.049 203.033C188.087 203.011 188.11 202.971 188.11 202.928V201.15C188.11 201.056 188.009 200.998 187.928 201.044L187.402 201.349C187.364 201.371 187.341 201.411 187.341 201.455V203.232C187.341 203.327 187.442 203.386 187.523 203.338Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M169.65 190.038L169.661 192.12C169.591 192.497 169.745 192.91 170.122 193.129L186.297 202.514C186.592 202.686 186.956 202.686 187.251 202.514L203.426 193.129C203.803 192.911 203.957 192.497 203.887 192.12L203.897 190.038" fill="#8B81E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M186.297 200.143L170.122 190.757C169.485 190.389 169.485 189.466 170.122 189.097L186.297 179.711C186.592 179.54 186.956 179.54 187.251 179.711L203.426 189.097C204.062 189.466 204.062 190.389 203.426 190.757L187.251 200.143C186.956 200.314 186.592 200.314 186.297 200.143Z" fill="#A59EF7"/> +</g> +<path fill-rule="evenodd" clip-rule="evenodd" d="M98.8553 102.466C96.2624 102.466 94.1604 100.354 94.1604 97.7481C94.1604 95.1427 96.2624 93.0301 98.8553 93.0301C101.448 93.0301 103.55 95.1427 103.55 97.7481C103.55 100.354 101.448 102.466 98.8553 102.466Z" fill="#92F6D2"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M117.665 88.5403C117.665 91.1457 115.563 93.2582 112.97 93.2582C110.377 93.2582 108.275 91.1457 108.275 88.5403C108.275 85.9345 110.377 83.8219 112.97 83.8219C115.563 83.8219 117.665 85.9345 117.665 88.5403Z" fill="#92F6D2"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M131.779 80.8495C131.779 83.4553 129.677 85.5679 127.085 85.5679C124.492 85.5679 122.39 83.4553 122.39 80.8495C122.39 78.2436 124.492 76.1315 127.085 76.1315C129.677 76.1315 131.779 78.2436 131.779 80.8495Z" fill="#92F6D2"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M141.021 82.3654C138.429 82.3654 136.326 80.2528 136.326 77.647C136.326 75.0416 138.429 72.9291 141.021 72.9291C143.614 72.9291 145.716 75.0416 145.716 77.647C145.716 80.2528 143.614 82.3654 141.021 82.3654Z" fill="#92F6D2"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M159.481 85.568C159.481 88.1734 157.379 90.2859 154.786 90.2859C152.194 90.2859 150.092 88.1734 150.092 85.568C150.092 82.9622 152.194 80.8496 154.786 80.8496C157.379 80.8496 159.481 82.9622 159.481 85.568Z" fill="#92F6D2"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M171.279 95.0541C171.279 97.6595 169.177 99.7721 166.585 99.7721C163.992 99.7721 161.89 97.6595 161.89 95.0541C161.89 92.4483 163.992 90.3357 166.585 90.3357C169.177 90.3357 171.279 92.4483 171.279 95.0541Z" fill="#92F6D2"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M244.927 140.363C244.927 142.969 242.825 145.082 240.232 145.082C237.639 145.082 235.537 142.969 235.537 140.363C235.537 137.758 237.639 135.645 240.232 135.645C242.825 135.645 244.927 137.758 244.927 140.363Z" fill="#8CB6FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M258.321 149.423C258.321 152.029 256.219 154.141 253.626 154.141C251.033 154.141 248.931 152.029 248.931 149.423C248.931 146.817 251.033 144.705 253.626 144.705C256.219 144.705 258.321 146.817 258.321 149.423Z" fill="#8CB6FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M267.921 161.512C265.328 161.512 263.226 159.399 263.226 156.793C263.226 154.188 265.328 152.075 267.921 152.075C270.514 152.075 272.616 154.188 272.616 156.793C272.616 159.399 270.514 161.512 267.921 161.512Z" fill="#8CB6FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M288.178 149.398C288.178 152.004 286.076 154.116 283.483 154.116C280.891 154.116 278.789 152.004 278.789 149.398C278.789 146.792 280.891 144.68 283.483 144.68C286.076 144.68 288.178 146.792 288.178 149.398Z" fill="#8CB6FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M302.505 141.805C302.505 144.411 300.403 146.523 297.811 146.523C295.218 146.523 293.116 144.411 293.116 141.805C293.116 139.199 295.218 137.087 297.811 137.087C300.403 137.087 302.505 139.199 302.505 141.805Z" fill="#8CB6FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M315.374 133.208C315.374 135.813 313.272 137.926 310.679 137.926C308.086 137.926 305.984 135.813 305.984 133.208C305.984 130.602 308.086 128.489 310.679 128.489C313.272 128.489 315.374 130.602 315.374 133.208Z" fill="#8CB6FF"/> +<rect width="94.7557" height="54.8453" fill="black" fill-opacity="0" transform="translate(89.638 130.896)"/> +<path d="M177.154 130.896L89.638 182.735" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<path d="M180.715 132.963L93.2464 184.097" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<path d="M184.394 135.097L96.4554 185.742" stroke="#DBDBFF" stroke-width="1.32046" stroke-linecap="round"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M157.606 126.233L156.096 125.357C155.988 125.295 155.922 125.178 155.922 125.053V119.944C155.922 119.674 156.212 119.505 156.445 119.64L157.956 120.516C158.064 120.579 158.13 120.695 158.13 120.821V125.929C158.13 126.2 157.839 126.368 157.606 126.233Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M161.866 128.671L160.355 127.795C160.247 127.732 160.181 127.616 160.181 127.491V122.382C160.181 122.112 160.472 121.943 160.705 122.078L162.215 122.954C162.323 123.017 162.389 123.133 162.389 123.258V128.367C162.389 128.637 162.099 128.806 161.866 128.671Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M166.125 131.109L164.615 130.232C164.507 130.17 164.44 130.054 164.44 129.929V124.819C164.44 124.549 164.731 124.38 164.964 124.516L166.474 125.392C166.582 125.455 166.649 125.57 166.649 125.696V130.805C166.649 131.075 166.358 131.244 166.125 131.109Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M170.384 133.546L168.874 132.67C168.766 132.608 168.699 132.491 168.699 132.366V127.257C168.699 126.987 168.991 126.818 169.223 126.953L170.733 127.829C170.841 127.892 170.908 128.008 170.908 128.133V133.242C170.908 133.513 170.617 133.681 170.384 133.546Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M174.644 135.984L173.133 135.107C173.025 135.045 172.959 134.929 172.959 134.804V129.695C172.959 129.425 173.249 129.255 173.483 129.391L174.993 130.267C175.101 130.33 175.167 130.445 175.167 130.571V135.68C175.167 135.95 174.876 136.119 174.644 135.984Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M178.903 138.422L177.393 137.545C177.285 137.483 177.218 137.366 177.218 137.242V132.132C177.218 131.862 177.509 131.693 177.742 131.828L179.252 132.704C179.36 132.767 179.427 132.883 179.427 133.008V138.118C179.427 138.388 179.136 138.556 178.903 138.422Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M183.162 140.859L181.652 139.983C181.544 139.92 181.477 139.804 181.477 139.679V134.57C181.477 134.3 181.768 134.13 182.001 134.266L183.511 135.142C183.619 135.205 183.686 135.321 183.686 135.446V140.555C183.686 140.826 183.395 140.994 183.162 140.859Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M187.422 143.53L185.911 142.653C185.803 142.591 185.737 142.475 185.737 142.35V137.24C185.737 136.97 186.028 136.801 186.261 136.936L187.771 137.812C187.879 137.876 187.945 137.991 187.945 138.117V143.226C187.945 143.496 187.654 143.665 187.422 143.53Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M191.681 145.851L190.171 144.974C190.063 144.912 189.996 144.796 189.996 144.671V139.562C189.996 139.292 190.287 139.122 190.52 139.258L192.03 140.134C192.138 140.197 192.205 140.312 192.205 140.438V145.547C192.205 145.817 191.913 145.986 191.681 145.851Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M195.94 148.405L194.43 147.528C194.322 147.466 194.255 147.35 194.255 147.225V142.116C194.255 141.846 194.546 141.676 194.779 141.812L196.289 142.688C196.398 142.751 196.464 142.866 196.464 142.992V148.101C196.464 148.371 196.173 148.54 195.94 148.405Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M200.199 150.843L198.689 149.966C198.581 149.904 198.515 149.788 198.515 149.663V144.553C198.515 144.283 198.805 144.114 199.038 144.249L200.549 145.125C200.657 145.188 200.723 145.304 200.723 145.43V150.539C200.723 150.809 200.432 150.978 200.199 150.843Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M249.098 126.283L250.641 125.388C250.751 125.324 250.819 125.206 250.819 125.078V119.86C250.819 119.584 250.522 119.412 250.284 119.55L248.742 120.445C248.632 120.509 248.564 120.627 248.564 120.755V125.973C248.564 126.249 248.861 126.421 249.098 126.283Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M244.749 128.773L246.291 127.877C246.401 127.813 246.469 127.695 246.469 127.567V122.349C246.469 122.073 246.172 121.901 245.934 122.039L244.392 122.934C244.282 122.998 244.214 123.116 244.214 123.244V128.462C244.214 128.738 244.511 128.91 244.749 128.773Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M240.399 131.262L241.941 130.367C242.052 130.303 242.12 130.185 242.12 130.057V124.839C242.12 124.563 241.822 124.391 241.585 124.528L240.043 125.423C239.932 125.488 239.864 125.606 239.864 125.734V130.952C239.864 131.227 240.162 131.4 240.399 131.262Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M236.049 133.751L237.592 132.856C237.702 132.792 237.77 132.674 237.77 132.546V127.328C237.77 127.052 237.473 126.88 237.235 127.018L235.693 127.913C235.583 127.977 235.515 128.095 235.515 128.223V133.441C235.515 133.717 235.812 133.889 236.049 133.751Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M231.7 136.24L233.242 135.345C233.353 135.282 233.42 135.163 233.42 135.035V129.818C233.42 129.541 233.123 129.369 232.885 129.507L231.343 130.402C231.233 130.466 231.165 130.584 231.165 130.713V135.93C231.165 136.206 231.462 136.378 231.7 136.24Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M227.35 138.73L228.892 137.835C229.003 137.771 229.071 137.653 229.071 137.525V132.307C229.071 132.031 228.773 131.858 228.536 131.996L226.994 132.891C226.883 132.956 226.815 133.074 226.815 133.202V138.42C226.815 138.695 227.113 138.868 227.35 138.73Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M223 141.219L224.543 140.324C224.653 140.26 224.721 140.142 224.721 140.014V134.796C224.721 134.52 224.424 134.348 224.186 134.486L222.644 135.381C222.534 135.445 222.466 135.563 222.466 135.691V140.909C222.466 141.185 222.763 141.357 223 141.219Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M218.651 143.946L220.193 143.051C220.304 142.988 220.371 142.869 220.371 142.741V137.523C220.371 137.247 220.074 137.075 219.836 137.213L218.294 138.107C218.184 138.172 218.116 138.29 218.116 138.419V143.636C218.116 143.912 218.413 144.084 218.651 143.946Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M214.301 146.316L215.843 145.421C215.954 145.358 216.022 145.239 216.022 145.111V139.894C216.022 139.618 215.724 139.446 215.487 139.584L213.945 140.478C213.834 140.542 213.766 140.661 213.766 140.789V146.006C213.766 146.282 214.064 146.454 214.301 146.316Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M209.951 148.925L211.494 148.03C211.604 147.966 211.672 147.847 211.672 147.719V142.502C211.672 142.226 211.375 142.054 211.137 142.192L209.595 143.086C209.485 143.15 209.417 143.269 209.417 143.397V148.614C209.417 148.89 209.714 149.063 209.951 148.925Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M205.602 151.414L207.144 150.519C207.255 150.456 207.322 150.337 207.322 150.209V144.991C207.322 144.716 207.025 144.543 206.787 144.681L205.245 145.575C205.135 145.64 205.067 145.758 205.067 145.886V151.104C205.067 151.38 205.364 151.552 205.602 151.414Z" fill="#6D6475"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M153.145 112.376L153.176 118.488C152.971 119.595 153.422 120.808 154.529 121.45L202.003 148.997C202.87 149.5 203.937 149.5 204.804 148.997L252.278 121.45C253.384 120.808 253.834 119.595 253.63 118.488L253.661 112.376" fill="#454545"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M202.003 141.196L154.529 113.649C152.661 112.566 152.661 109.857 154.529 108.774L202.003 81.2263C202.869 80.724 203.937 80.724 204.803 81.2263L252.277 108.774C254.145 109.857 254.145 112.566 252.277 113.649L204.804 141.196C203.937 141.699 202.869 141.699 202.003 141.196Z" fill="#545454"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M175.567 115.451C176.655 117.855 178.687 120.153 181.699 122.145C185.86 124.897 191.256 126.654 196.991 127.388C199.842 127.753 202.776 127.865 205.685 127.718C206.117 126.191 206.527 124.595 206.902 122.944C207.004 122.499 207.098 122.046 207.194 121.595C203.77 122.037 200.182 121.902 196.884 121.206L196.817 117.242L175.567 115.451Z" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M195.709 95.2149C191.624 95.8524 187.723 97.0234 184.334 98.748C179.587 101.165 176.557 104.299 175.295 107.631C174.67 109.279 174.479 110.975 174.729 112.656C177.361 112.907 180.112 113.146 182.96 113.364C183.724 113.423 184.504 113.478 185.281 113.534C184.522 111.549 184.756 109.47 185.953 107.559L192.84 107.513L195.709 95.2149Z" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M230.792 106.981C229.705 104.573 227.673 102.272 224.657 100.277C220.492 97.5232 215.09 95.7649 209.349 95.0321C206.508 94.6693 203.586 94.5587 200.688 94.7034C200.256 96.2311 199.844 97.8272 199.468 99.4797C199.366 99.9231 199.271 100.376 199.175 100.826C202.597 100.386 206.182 100.522 209.476 101.217L209.48 101.218L209.558 104.945L230.792 106.981Z" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M210.774 127.184C214.812 126.542 218.668 125.381 222.022 123.674C226.764 121.26 229.793 118.129 231.057 114.802C231.686 113.147 231.878 111.444 231.626 109.757C228.994 109.506 226.244 109.268 223.397 109.051C222.632 108.992 221.851 108.936 221.073 108.881C221.837 110.871 221.602 112.957 220.398 114.873L220.371 114.912L213.699 114.981L210.774 127.184Z" fill="white"/> +<g opacity="0.372566"> +<rect width="57.1535" height="39.6589" fill="black" fill-opacity="0" transform="translate(180.849 191.194)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M183.395 216.512L182.537 216.014C182.475 215.978 182.437 215.912 182.437 215.842V212.937C182.437 212.784 182.603 212.687 182.735 212.764L183.593 213.262C183.655 213.298 183.693 213.364 183.693 213.435V216.34C183.693 216.493 183.527 216.589 183.395 216.512Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M185.816 217.898L184.958 217.399C184.896 217.364 184.858 217.298 184.858 217.227V214.323C184.858 214.169 185.024 214.073 185.156 214.15L186.014 214.648C186.076 214.683 186.114 214.75 186.114 214.821V217.725C186.114 217.879 185.948 217.974 185.816 217.898Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M188.237 219.284L187.379 218.785C187.317 218.75 187.279 218.684 187.279 218.613V215.709C187.279 215.555 187.445 215.459 187.577 215.536L188.435 216.034C188.497 216.069 188.535 216.135 188.535 216.207V219.111C188.535 219.264 188.369 219.36 188.237 219.284Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M190.658 220.669L189.8 220.171C189.738 220.135 189.7 220.069 189.7 219.998V217.094C189.7 216.94 189.866 216.844 189.998 216.921L190.856 217.419C190.918 217.455 190.956 217.521 190.956 217.592V220.496C190.956 220.65 190.79 220.746 190.658 220.669Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M193.079 222.054L192.221 221.556C192.159 221.521 192.121 221.455 192.121 221.384V218.48C192.121 218.326 192.287 218.23 192.419 218.307L193.277 218.805C193.339 218.84 193.377 218.906 193.377 218.978V221.882C193.377 222.035 193.211 222.131 193.079 222.054Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M195.5 223.44L194.642 222.942C194.58 222.906 194.542 222.84 194.542 222.769V219.865C194.542 219.711 194.708 219.615 194.84 219.692L195.698 220.19C195.76 220.226 195.798 220.292 195.798 220.363V223.268C195.798 223.421 195.632 223.517 195.5 223.44Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M197.921 224.826L197.063 224.327C197.001 224.292 196.963 224.226 196.963 224.155V221.251C196.963 221.097 197.129 221.001 197.261 221.078L198.119 221.576C198.181 221.611 198.219 221.677 198.219 221.749V224.653C198.219 224.807 198.053 224.902 197.921 224.826Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M200.342 226.343L199.484 225.846C199.422 225.81 199.385 225.744 199.385 225.673V222.769C199.385 222.615 199.55 222.519 199.682 222.596L200.541 223.094C200.602 223.13 200.64 223.195 200.64 223.267V226.171C200.64 226.324 200.474 226.42 200.342 226.343Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M202.763 227.663L201.905 227.165C201.843 227.129 201.806 227.063 201.806 226.992V224.088C201.806 223.934 201.971 223.839 202.103 223.915L202.962 224.413C203.023 224.449 203.061 224.515 203.061 224.586V227.49C203.061 227.644 202.895 227.74 202.763 227.663Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M205.184 229.115L204.326 228.616C204.264 228.581 204.227 228.515 204.227 228.444V225.54C204.227 225.386 204.392 225.29 204.524 225.367L205.383 225.865C205.444 225.9 205.482 225.966 205.482 226.038V228.942C205.482 229.095 205.316 229.191 205.184 229.115Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M207.605 230.5L206.747 230.002C206.685 229.967 206.648 229.901 206.648 229.83V226.926C206.648 226.772 206.813 226.676 206.945 226.752L207.804 227.251C207.865 227.286 207.903 227.352 207.903 227.424V230.328C207.903 230.481 207.738 230.577 207.605 230.5Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M235.4 216.54L236.277 216.032C236.339 215.995 236.378 215.928 236.378 215.855V212.889C236.378 212.733 236.209 212.635 236.074 212.713L235.197 213.222C235.134 213.258 235.096 213.325 235.096 213.398V216.364C235.096 216.521 235.265 216.619 235.4 216.54Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M232.927 217.955L233.804 217.447C233.867 217.41 233.906 217.343 233.906 217.27V214.305C233.906 214.148 233.737 214.05 233.601 214.128L232.725 214.637C232.662 214.673 232.624 214.74 232.624 214.813V217.779C232.624 217.936 232.792 218.034 232.927 217.955Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M230.455 219.37L231.332 218.862C231.395 218.825 231.433 218.758 231.433 218.685V215.719C231.433 215.562 231.264 215.464 231.129 215.543L230.253 216.052C230.19 216.088 230.151 216.155 230.151 216.228V219.194C230.151 219.351 230.32 219.449 230.455 219.37Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M227.983 220.785L228.859 220.277C228.922 220.24 228.961 220.173 228.961 220.1V217.134C228.961 216.977 228.792 216.879 228.657 216.958L227.78 217.467C227.717 217.503 227.678 217.57 227.678 217.643V220.609C227.678 220.765 227.848 220.863 227.983 220.785Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M225.51 222.2L226.387 221.692C226.45 221.655 226.489 221.588 226.489 221.515V218.549C226.489 218.392 226.319 218.295 226.184 218.373L225.308 218.882C225.245 218.918 225.206 218.985 225.206 219.058V222.024C225.206 222.18 225.375 222.278 225.51 222.2Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M223.038 223.615L223.915 223.107C223.977 223.07 224.016 223.003 224.016 222.93V219.964C224.016 219.808 223.847 219.71 223.712 219.788L222.835 220.297C222.772 220.333 222.734 220.4 222.734 220.473V223.439C222.734 223.595 222.903 223.693 223.038 223.615Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M220.565 225.03L221.442 224.522C221.505 224.485 221.544 224.418 221.544 224.345V221.379C221.544 221.222 221.375 221.124 221.239 221.203L220.363 221.712C220.3 221.748 220.262 221.815 220.262 221.888V224.854C220.262 225.011 220.43 225.109 220.565 225.03Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M218.093 226.58L218.97 226.072C219.033 226.035 219.071 225.968 219.071 225.895V222.929C219.071 222.773 218.902 222.675 218.767 222.753L217.891 223.262C217.828 223.298 217.789 223.365 217.789 223.438V226.404C217.789 226.561 217.958 226.658 218.093 226.58Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M215.621 227.928L216.498 227.419C216.56 227.382 216.599 227.315 216.599 227.242V224.277C216.599 224.12 216.43 224.022 216.295 224.1L215.418 224.609C215.355 224.646 215.317 224.713 215.317 224.786V227.751C215.317 227.908 215.486 228.006 215.621 227.928Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M213.148 229.41L214.025 228.902C214.088 228.865 214.127 228.798 214.127 228.725V225.759C214.127 225.602 213.958 225.504 213.822 225.583L212.946 226.092C212.883 226.128 212.844 226.195 212.844 226.268V229.234C212.844 229.391 213.013 229.489 213.148 229.41Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M210.676 230.825L211.552 230.317C211.615 230.28 211.654 230.213 211.654 230.14V227.174C211.654 227.017 211.485 226.919 211.35 226.998L210.473 227.507C210.411 227.543 210.372 227.61 210.372 227.683V230.649C210.372 230.805 210.541 230.903 210.676 230.825Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M180.859 208.635L180.877 212.11C180.76 212.739 181.017 213.428 181.646 213.793L208.63 229.452C209.123 229.737 209.73 229.737 210.222 229.452L237.207 213.793C237.836 213.429 238.092 212.739 237.975 212.11L237.993 208.635" fill="#8B81E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M208.63 225.495L181.646 209.837C180.584 209.221 180.584 207.682 181.646 207.065L208.63 191.408C209.123 191.122 209.73 191.122 210.222 191.408L237.207 207.065C238.268 207.682 238.268 209.221 237.207 209.837L210.222 225.495C209.73 225.781 209.123 225.781 208.63 225.495Z" fill="#A59EF7"/> +</g> +<g opacity="0.327785"> +<rect width="73.5288" height="51.0612" fill="black" fill-opacity="0" transform="translate(200.318 30.1121)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M203.593 62.7101L202.489 62.0689C202.41 62.0228 202.361 61.9378 202.361 61.8468V58.1075C202.361 57.9094 202.574 57.7857 202.744 57.8848L203.848 58.5259C203.927 58.5721 203.976 58.657 203.976 58.7487V62.4879C203.976 62.6855 203.763 62.8085 203.593 62.7101Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M206.707 64.4942L205.603 63.8524C205.524 63.8069 205.475 63.722 205.475 63.6303V59.8916C205.475 59.6935 205.688 59.5698 205.858 59.6689L206.963 60.31C207.042 60.3556 207.09 60.4411 207.09 60.5328V64.2721C207.09 64.4696 206.878 64.5926 206.707 64.4942Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M209.822 66.2782L208.718 65.6365C208.638 65.5909 208.59 65.506 208.59 65.4143V61.6757C208.59 61.4775 208.803 61.3539 208.973 61.4529L210.077 62.0941C210.156 62.1396 210.205 62.2245 210.205 62.3168V66.0555C210.205 66.253 209.992 66.3767 209.822 66.2782Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M212.937 68.0617L211.833 67.4205C211.753 67.375 211.705 67.2901 211.705 67.1984V63.4591C211.705 63.261 211.918 63.1379 212.088 63.2364L213.192 63.8781C213.271 63.9237 213.32 64.0086 213.32 64.1009V67.8395C213.32 68.0371 213.107 68.1607 212.937 68.0617Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M216.052 69.8457L214.947 69.2046C214.868 69.1584 214.819 69.0735 214.819 68.9824V65.2431C214.819 65.045 215.032 64.922 215.202 65.0204L216.307 65.6616C216.386 65.7077 216.435 65.7926 216.435 65.8849V69.6236C216.435 69.8211 216.222 69.9448 216.052 69.8457Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M219.166 71.6298L218.062 70.9886C217.983 70.9425 217.934 70.8576 217.934 70.7659V67.0272C217.934 66.8291 218.147 66.7054 218.317 66.8045L219.421 67.4456C219.5 67.4918 219.549 67.5767 219.549 67.6684V71.4076C219.549 71.6052 219.336 71.7282 219.166 71.6298Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M222.281 73.4138L221.177 72.772C221.097 72.7265 221.049 72.6416 221.049 72.5499V68.8112C221.049 68.6131 221.262 68.4894 221.432 68.5885L222.536 69.2297C222.615 69.2752 222.664 69.3601 222.664 69.4524V73.1917C222.664 73.3892 222.451 73.5123 222.281 73.4138Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M225.396 75.3679L224.292 74.7268C224.212 74.6806 224.164 74.5957 224.164 74.5047V70.7654C224.164 70.5672 224.377 70.4442 224.547 70.5426L225.651 71.1838C225.73 71.2299 225.779 71.3149 225.779 71.4071V75.1458C225.779 75.3433 225.566 75.467 225.396 75.3679Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M228.51 77.0667L227.406 76.4255C227.327 76.3794 227.278 76.2945 227.278 76.2034V72.4641C227.278 72.266 227.491 72.1429 227.661 72.2414L228.766 72.8825C228.844 72.9287 228.893 73.0136 228.893 73.1053V76.8446C228.893 77.0421 228.681 77.1658 228.51 77.0667Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M231.625 78.9361L230.52 78.2943C230.441 78.2488 230.393 78.1639 230.393 78.0722V74.3335C230.393 74.1354 230.605 74.0117 230.776 74.1108L231.88 74.7519C231.959 74.7975 232.008 74.8824 232.008 74.9747V78.7134C232.008 78.9109 231.795 79.0346 231.625 78.9361Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M234.74 80.7195L233.635 80.0784C233.556 80.0328 233.508 79.9479 233.508 79.8562V76.1176C233.508 75.9195 233.72 75.7958 233.891 75.8942L234.995 76.536C235.074 76.5815 235.123 76.6664 235.123 76.7587V80.4974C235.123 80.6949 234.91 80.8186 234.74 80.7195Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M270.498 62.7461L271.626 62.0914C271.707 62.0441 271.756 61.9579 271.756 61.8638V58.0457C271.756 57.8439 271.539 57.7178 271.365 57.8187L270.237 58.474C270.157 58.5208 270.107 58.6069 270.107 58.701V62.5191C270.107 62.7209 270.324 62.847 270.498 62.7461Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M267.317 64.5681L268.445 63.9134C268.526 63.866 268.576 63.7799 268.576 63.6857V59.8677C268.576 59.6659 268.358 59.5397 268.184 59.6406L267.057 60.2959C266.976 60.3421 266.926 60.4289 266.926 60.523V64.341C266.926 64.5429 267.143 64.669 267.317 64.5681Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M264.136 66.39L265.265 65.7353C265.345 65.6879 265.395 65.6018 265.395 65.5076V61.689C265.395 61.4871 265.178 61.361 265.003 61.4619L263.876 62.1172C263.795 62.164 263.746 62.2501 263.746 62.3443V66.1629C263.746 66.3647 263.963 66.4909 264.136 66.39Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M260.956 68.2113L262.083 67.5572C262.165 67.5098 262.214 67.4231 262.214 67.3296V63.5109C262.214 63.3091 261.996 63.1829 261.823 63.2839L260.695 63.9392C260.614 63.9859 260.564 64.0721 260.564 64.1662V67.9843C260.564 68.1861 260.782 68.3122 260.956 68.2113Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M257.775 70.0332L258.902 69.3785C258.983 69.3311 259.033 69.245 259.033 69.1508V65.3328C259.033 65.131 258.816 65.0048 258.642 65.1057L257.514 65.7611C257.434 65.8078 257.383 65.894 257.383 65.9881V69.8061C257.383 70.008 257.601 70.1341 257.775 70.0332Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M254.594 71.8551L255.722 71.2004C255.803 71.153 255.852 71.0669 255.852 70.9727V67.1547C255.852 66.9529 255.635 66.8267 255.461 66.9277L254.333 67.583C254.253 67.6297 254.203 67.7159 254.203 67.81V71.6281C254.203 71.8299 254.42 71.956 254.594 71.8551Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M251.413 73.6771L252.541 73.0224C252.622 72.975 252.672 72.8888 252.672 72.7947V68.976C252.672 68.7742 252.455 68.6481 252.28 68.749L251.153 69.4043C251.072 69.4511 251.022 69.5372 251.022 69.6313V73.45C251.022 73.6518 251.24 73.778 251.413 73.6771Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M248.233 75.6726L249.361 75.0179C249.441 74.9705 249.491 74.8844 249.491 74.7902V70.9722C249.491 70.7704 249.274 70.6442 249.099 70.7451L247.972 71.4004C247.891 71.4472 247.842 71.5333 247.842 71.6275V75.4455C247.842 75.6474 248.059 75.7735 248.233 75.6726Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M245.052 77.4074L246.18 76.7527C246.261 76.7053 246.31 76.6192 246.31 76.525V72.707C246.31 72.5052 246.093 72.379 245.919 72.4799L244.791 73.1353C244.711 73.182 244.661 73.2682 244.661 73.3623V77.1803C244.661 77.3822 244.878 77.5083 245.052 77.4074Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M241.871 79.3164L242.999 78.6617C243.08 78.6144 243.129 78.5282 243.129 78.4341V74.6154C243.129 74.4136 242.912 74.2874 242.738 74.3884L241.61 75.0437C241.53 75.0904 241.48 75.1766 241.48 75.2707V79.0894C241.48 79.2912 241.697 79.4173 241.871 79.3164Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M238.69 81.1378L239.818 80.4837C239.899 80.4363 239.949 80.3495 239.949 80.256V76.4374C239.949 76.2355 239.731 76.1094 239.557 76.2103L238.43 76.8656C238.349 76.9124 238.299 76.9985 238.299 77.0927V80.9107C238.299 81.1125 238.517 81.2387 238.69 81.1378Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M200.331 52.5682L200.353 57.0421C200.203 57.8519 200.533 58.7392 201.342 59.2093L236.058 79.3695C236.692 79.7369 237.473 79.7369 238.107 79.3695L272.823 59.2093C273.632 58.7398 273.961 57.8519 273.811 57.0421L273.835 52.5682" fill="#8B81E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M236.058 74.2755L201.342 54.1153C199.977 53.3227 199.977 51.3408 201.342 50.547L236.058 30.388C236.692 30.0201 237.473 30.0201 238.107 30.388L272.823 50.547C274.188 51.3408 274.188 53.3227 272.823 54.1153L238.107 74.2755C237.473 74.6435 236.692 74.6435 236.058 74.2755Z" fill="#A59EF7"/> +</g> +<g opacity="0.120697"> +<rect width="28.3611" height="20.2117" fill="black" fill-opacity="0" transform="translate(79.9083 149.104)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M81.1767 162.008L80.746 161.754C80.7152 161.736 80.6961 161.702 80.6961 161.666V160.186C80.6961 160.107 80.7792 160.058 80.8455 160.098L81.2762 160.351C81.3072 160.37 81.3261 160.403 81.3261 160.44V161.92C81.3261 161.998 81.243 162.047 81.1767 162.008Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M82.3781 162.714L81.9474 162.46C81.9166 162.442 81.8975 162.408 81.8975 162.372V160.892C81.8975 160.814 81.9806 160.765 82.0469 160.804L82.4776 161.058C82.5084 161.076 82.5275 161.11 82.5275 161.146V162.626C82.5275 162.704 82.4444 162.753 82.3781 162.714Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M83.5795 163.42L83.1488 163.166C83.1178 163.148 83.0989 163.114 83.0989 163.078V161.598C83.0989 161.52 83.182 161.471 83.2483 161.51L83.679 161.764C83.7098 161.782 83.7288 161.815 83.7288 161.852V163.332C83.7288 163.41 83.6458 163.459 83.5795 163.42Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M84.7809 164.126L84.3502 163.872C84.3191 163.854 84.3003 163.821 84.3003 163.784V162.304C84.3003 162.226 84.3833 162.177 84.4497 162.216L84.8804 162.47C84.9111 162.488 84.9302 162.522 84.9302 162.558V164.038C84.9302 164.116 84.8472 164.165 84.7809 164.126Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M85.9823 164.832L85.5516 164.578C85.5205 164.56 85.5017 164.527 85.5017 164.49V163.01C85.5017 162.932 85.5847 162.883 85.6511 162.922L86.0817 163.176C86.1125 163.194 86.1316 163.228 86.1316 163.264V164.744C86.1316 164.822 86.0486 164.871 85.9823 164.832Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M87.1837 165.538L86.753 165.285C86.7219 165.266 86.7031 165.233 86.7031 165.196V163.717C86.7031 163.638 86.7861 163.589 86.8525 163.628L87.2832 163.882C87.3139 163.9 87.333 163.934 87.333 163.97V165.45C87.333 165.529 87.25 165.577 87.1837 165.538Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M88.385 166.245L87.9543 165.991C87.9233 165.972 87.9045 165.939 87.9045 165.903V164.423C87.9045 164.344 87.9875 164.295 88.0538 164.335L88.4845 164.588C88.5153 164.606 88.5344 164.64 88.5344 164.676V166.157C88.5344 166.235 88.4514 166.284 88.385 166.245Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M89.5864 167.018L89.1557 166.764C89.1247 166.746 89.1059 166.712 89.1059 166.676V165.196C89.1059 165.118 89.1889 165.069 89.2552 165.108L89.6859 165.362C89.7167 165.38 89.7358 165.414 89.7358 165.45V166.93C89.7358 167.008 89.6528 167.057 89.5864 167.018Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M90.7878 167.69L90.3571 167.437C90.3261 167.418 90.3073 167.385 90.3073 167.349V165.869C90.3073 165.79 90.39 165.742 90.4566 165.78L90.8873 166.034C90.9181 166.053 90.9372 166.086 90.9372 166.122V167.603C90.9372 167.681 90.8541 167.73 90.7878 167.69Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M91.9892 168.43L91.5583 168.176C91.5275 168.158 91.5086 168.125 91.5086 168.089V166.609C91.5086 166.53 91.5914 166.481 91.658 166.52L92.0887 166.774C92.1195 166.792 92.1386 166.826 92.1386 166.862V168.342C92.1386 168.42 92.0555 168.469 91.9892 168.43Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M93.1906 169.136L92.7596 168.883C92.7289 168.865 92.71 168.831 92.71 168.795V167.315C92.71 167.236 92.7928 167.187 92.8594 167.226L93.2901 167.48C93.3209 167.498 93.3399 167.532 93.3399 167.569V169.048C93.3399 169.127 93.2569 169.176 93.1906 169.136Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M106.978 162.022L107.413 161.763C107.444 161.744 107.463 161.71 107.463 161.673V160.161C107.463 160.081 107.379 160.032 107.312 160.071L106.877 160.331C106.846 160.349 106.827 160.383 106.827 160.421V161.932C106.827 162.012 106.911 162.062 106.978 162.022Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M105.751 162.743L106.186 162.484C106.217 162.465 106.236 162.431 106.236 162.394V160.883C106.236 160.803 106.152 160.753 106.085 160.793L105.65 161.052C105.619 161.07 105.6 161.105 105.6 161.142V162.653C105.6 162.733 105.684 162.783 105.751 162.743Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M104.524 163.464L104.959 163.205C104.99 163.186 105.009 163.152 105.009 163.115V161.603C105.009 161.524 104.926 161.474 104.858 161.514L104.423 161.773C104.392 161.791 104.373 161.826 104.373 161.863V163.374C104.373 163.454 104.457 163.504 104.524 163.464Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M103.297 164.185L103.732 163.926C103.763 163.908 103.782 163.873 103.782 163.836V162.325C103.782 162.245 103.698 162.195 103.631 162.235L103.197 162.494C103.165 162.513 103.146 162.547 103.146 162.584V164.095C103.146 164.175 103.23 164.225 103.297 164.185Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M102.07 164.906L102.505 164.647C102.536 164.628 102.556 164.594 102.556 164.557V163.046C102.556 162.966 102.472 162.916 102.405 162.956L101.97 163.215C101.939 163.234 101.919 163.268 101.919 163.305V164.817C101.919 164.896 102.003 164.946 102.07 164.906Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M100.843 165.628L101.278 165.368C101.31 165.35 101.329 165.316 101.329 165.278V163.767C101.329 163.687 101.245 163.637 101.178 163.677L100.743 163.937C100.712 163.955 100.693 163.989 100.693 164.026V165.538C100.693 165.618 100.776 165.668 100.843 165.628Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M99.6164 166.349L100.052 166.09C100.083 166.071 100.102 166.037 100.102 165.999V164.488C100.102 164.408 100.018 164.358 99.9508 164.398L99.5159 164.657C99.4848 164.676 99.4657 164.71 99.4657 164.747V166.259C99.4657 166.339 99.5494 166.389 99.6164 166.349Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M98.3896 167.139L98.8247 166.879C98.8559 166.861 98.875 166.827 98.875 166.789V165.278C98.875 165.198 98.7912 165.148 98.724 165.188L98.2891 165.448C98.2579 165.466 98.2388 165.5 98.2388 165.537V167.049C98.2388 167.129 98.3226 167.179 98.3896 167.139Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M97.1627 167.825L97.5979 167.566C97.629 167.547 97.6481 167.513 97.6481 167.476V165.965C97.6481 165.885 97.5644 165.835 97.4971 165.875L97.0622 166.134C97.0311 166.153 97.012 166.187 97.012 166.224V167.735C97.012 167.815 97.0957 167.865 97.1627 167.825Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M95.9359 168.581L96.371 168.322C96.4021 168.303 96.4213 168.269 96.4213 168.232V166.72C96.4213 166.64 96.3375 166.59 96.2702 166.63L95.8353 166.89C95.8042 166.908 95.7849 166.942 95.7849 166.98V168.491C95.7849 168.571 95.8689 168.621 95.9359 168.581Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M94.709 169.302L95.1439 169.043C95.1751 169.024 95.1944 168.99 95.1944 168.953V167.441C95.1944 167.361 95.1104 167.312 95.0434 167.352L94.6085 167.611C94.5774 167.629 94.558 167.664 94.558 167.701V169.212C94.558 169.292 94.642 169.342 94.709 169.302Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M79.9131 157.993L79.9218 159.764C79.864 160.085 79.9912 160.436 80.3034 160.622L93.6939 168.602C93.9383 168.747 94.2394 168.747 94.4839 168.602L107.874 160.622C108.186 160.436 108.314 160.085 108.256 159.764L108.265 157.993" fill="#8B81E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M93.6938 166.586L80.3033 158.606C79.7767 158.292 79.7767 157.507 80.3033 157.193L93.6938 149.214C93.9383 149.068 94.2394 149.068 94.4839 149.214L107.874 157.193C108.401 157.507 108.401 158.292 107.874 158.606L94.4839 166.586C94.2396 166.731 93.9383 166.731 93.6938 166.586Z" fill="#A59EF7"/> +</g> +<g opacity="0.120697"> +<rect width="28.3611" height="20.2117" fill="black" fill-opacity="0" transform="translate(99.2107 137.283)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M100.479 150.186L100.048 149.932C100.018 149.914 99.9986 149.88 99.9986 149.844V148.364C99.9986 148.286 100.082 148.237 100.148 148.276L100.579 148.53C100.61 148.548 100.629 148.582 100.629 148.618V150.098C100.629 150.176 100.545 150.225 100.479 150.186Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M101.681 150.892L101.25 150.638C101.219 150.62 101.2 150.587 101.2 150.55V149.07C101.2 148.992 101.283 148.943 101.349 148.982L101.78 149.236C101.811 149.254 101.83 149.288 101.83 149.324V150.804C101.83 150.882 101.747 150.931 101.681 150.892Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M102.882 151.598L102.451 151.344C102.42 151.326 102.401 151.293 102.401 151.256V149.777C102.401 149.698 102.484 149.649 102.551 149.688L102.981 149.942C103.012 149.96 103.031 149.994 103.031 150.03V151.51C103.031 151.588 102.948 151.637 102.882 151.598Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M104.083 152.304L103.653 152.051C103.622 152.033 103.603 151.999 103.603 151.963V150.482C103.603 150.404 103.686 150.355 103.752 150.394L104.183 150.648C104.214 150.666 104.233 150.7 104.233 150.737V152.216C104.233 152.295 104.15 152.344 104.083 152.304Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M105.285 153.011L104.854 152.757C104.823 152.738 104.804 152.705 104.804 152.669V151.189C104.804 151.11 104.887 151.062 104.954 151.101L105.384 151.354C105.415 151.373 105.434 151.406 105.434 151.443V152.923C105.434 153.001 105.351 153.05 105.285 153.011Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M106.486 153.717L106.055 153.463C106.024 153.445 106.006 153.411 106.006 153.375V151.895C106.006 151.816 106.089 151.767 106.155 151.807L106.586 152.06C106.616 152.079 106.635 152.112 106.635 152.149V153.629C106.635 153.707 106.552 153.756 106.486 153.717Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M107.687 154.423L107.257 154.169C107.226 154.151 107.207 154.117 107.207 154.081V152.601C107.207 152.523 107.29 152.474 107.356 152.513L107.787 152.767C107.818 152.785 107.837 152.818 107.837 152.855V154.335C107.837 154.413 107.754 154.462 107.687 154.423Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M108.889 155.196L108.458 154.943C108.427 154.924 108.408 154.891 108.408 154.855V153.375C108.408 153.296 108.491 153.247 108.558 153.286L108.988 153.54C109.019 153.558 109.038 153.592 109.038 153.629V155.108C109.038 155.187 108.955 155.236 108.889 155.196Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M110.09 155.869L109.66 155.615C109.629 155.597 109.61 155.563 109.61 155.527V154.047C109.61 153.969 109.693 153.92 109.759 153.959L110.19 154.213C110.221 154.231 110.24 154.264 110.24 154.301V155.781C110.24 155.859 110.157 155.908 110.09 155.869Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M111.292 156.609L110.861 156.355C110.83 156.337 110.811 156.303 110.811 156.267V154.787C110.811 154.709 110.894 154.66 110.96 154.699L111.391 154.953C111.422 154.971 111.441 155.004 111.441 155.041V156.521C111.441 156.599 111.358 156.648 111.292 156.609Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M112.493 157.315L112.062 157.061C112.031 157.043 112.012 157.009 112.012 156.973V155.493C112.012 155.415 112.095 155.366 112.162 155.405L112.593 155.659C112.623 155.677 112.642 155.71 112.642 155.747V157.227C112.642 157.305 112.559 157.354 112.493 157.315Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M126.28 150.2L126.715 149.941C126.746 149.922 126.766 149.888 126.766 149.851V148.34C126.766 148.26 126.682 148.21 126.614 148.25L126.18 148.509C126.148 148.528 126.129 148.562 126.129 148.599V150.11C126.129 150.19 126.213 150.24 126.28 150.2Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M125.053 150.921L125.488 150.662C125.52 150.644 125.539 150.609 125.539 150.572V149.061C125.539 148.981 125.455 148.931 125.388 148.971L124.953 149.23C124.922 149.249 124.902 149.283 124.902 149.32V150.832C124.902 150.911 124.986 150.961 125.053 150.921Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M123.826 151.643L124.262 151.383C124.293 151.365 124.312 151.331 124.312 151.293V149.782C124.312 149.702 124.228 149.652 124.161 149.692L123.726 149.951C123.695 149.97 123.676 150.004 123.676 150.041V151.553C123.676 151.633 123.759 151.683 123.826 151.643Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M122.6 152.364L123.034 152.105C123.066 152.086 123.085 152.052 123.085 152.015V150.503C123.085 150.423 123.001 150.373 122.934 150.413L122.499 150.673C122.468 150.691 122.449 150.725 122.449 150.762V152.274C122.449 152.354 122.533 152.404 122.6 152.364Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M121.373 153.085L121.808 152.826C121.839 152.807 121.858 152.773 121.858 152.735V151.224C121.858 151.144 121.774 151.094 121.707 151.134L121.272 151.394C121.241 151.412 121.222 151.446 121.222 151.484V152.995C121.222 153.075 121.306 153.125 121.373 153.085Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M120.146 153.806L120.581 153.547C120.612 153.528 120.631 153.494 120.631 153.457V151.945C120.631 151.865 120.547 151.816 120.48 151.855L120.045 152.115C120.014 152.133 119.995 152.167 119.995 152.205V153.716C119.995 153.796 120.079 153.846 120.146 153.806Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M118.919 154.527L119.354 154.268C119.385 154.249 119.404 154.215 119.404 154.178V152.666C119.404 152.586 119.321 152.536 119.253 152.576L118.818 152.836C118.787 152.854 118.768 152.888 118.768 152.926V154.437C118.768 154.517 118.852 154.567 118.919 154.527Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M117.692 155.317L118.127 155.058C118.158 155.039 118.177 155.005 118.177 154.968V153.456C118.177 153.377 118.094 153.327 118.026 153.367L117.592 153.626C117.56 153.644 117.541 153.679 117.541 153.716V155.227C117.541 155.307 117.625 155.357 117.692 155.317Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M116.465 156.004L116.9 155.745C116.931 155.726 116.951 155.692 116.951 155.654V154.143C116.951 154.063 116.867 154.013 116.8 154.053L116.365 154.313C116.334 154.331 116.314 154.365 116.314 154.403V155.914C116.314 155.994 116.398 156.044 116.465 156.004Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M115.238 156.759L115.673 156.5C115.705 156.481 115.724 156.447 115.724 156.41V154.899C115.724 154.819 115.64 154.769 115.573 154.809L115.138 155.068C115.107 155.087 115.087 155.121 115.087 155.158V156.669C115.087 156.749 115.171 156.799 115.238 156.759Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M114.011 157.48L114.446 157.221C114.478 157.203 114.497 157.168 114.497 157.131V155.62C114.497 155.54 114.413 155.49 114.346 155.53L113.911 155.789C113.88 155.808 113.86 155.842 113.86 155.879V157.39C113.86 157.47 113.944 157.52 114.011 157.48Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M99.2155 146.172L99.2243 147.942C99.1665 148.263 99.2936 148.614 99.6058 148.8L112.996 156.78C113.241 156.926 113.542 156.926 113.786 156.78L127.177 148.8C127.489 148.614 127.616 148.263 127.558 147.942L127.567 146.172" fill="#8B81E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M112.996 154.764L99.6058 146.784C99.0791 146.47 99.0791 145.686 99.6058 145.371L112.996 137.392C113.241 137.246 113.542 137.246 113.786 137.392L127.177 145.371C127.703 145.686 127.703 146.47 127.177 146.784L113.786 154.764C113.542 154.91 113.241 154.91 112.996 154.764Z" fill="#A59EF7"/> +</g> +<g opacity="0.120697"> +<rect width="28.3611" height="20.2117" fill="black" fill-opacity="0" transform="translate(268.643 57.7552)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M269.912 70.6586L269.481 70.4048C269.45 70.3865 269.431 70.3529 269.431 70.3169V68.8367C269.431 68.7583 269.514 68.7093 269.581 68.7486L270.011 69.0024C270.042 69.0206 270.061 69.0542 270.061 69.0905V70.5707C270.061 70.6488 269.978 70.6975 269.912 70.6586Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M271.113 71.3648L270.683 71.1108C270.652 71.0927 270.633 71.0591 270.633 71.0228V69.5429C270.633 69.4645 270.716 69.4156 270.782 69.4548L271.213 69.7086C271.243 69.7266 271.263 69.7604 271.263 69.7967V71.2769C271.263 71.355 271.18 71.4038 271.113 71.3648Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M272.315 72.071L271.884 71.8169C271.853 71.7989 271.834 71.7653 271.834 71.729V70.2491C271.834 70.1707 271.917 70.1217 271.983 70.161L272.414 70.4147C272.445 70.4328 272.464 70.4664 272.464 70.5029V71.9828C272.464 72.061 272.381 72.1099 272.315 72.071Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M273.516 72.7769L273.085 72.5231C273.054 72.5051 273.035 72.4715 273.035 72.4352V70.9551C273.035 70.8766 273.118 70.8279 273.185 70.8669L273.616 71.1209C273.646 71.1389 273.665 71.1726 273.665 71.2091V72.689C273.665 72.7672 273.582 72.8161 273.516 72.7769Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M274.717 73.4831L274.287 73.2293C274.256 73.211 274.237 73.1774 274.237 73.1414V71.6613C274.237 71.5828 274.32 71.5341 274.386 71.5731L274.817 71.8269C274.848 71.8451 274.867 71.8788 274.867 71.9153V73.3952C274.867 73.4734 274.784 73.5223 274.717 73.4831Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M275.919 74.1893L275.488 73.9355C275.457 73.9172 275.438 73.8836 275.438 73.8473V72.3674C275.438 72.289 275.521 72.2401 275.588 72.2793L276.018 72.5331C276.049 72.5513 276.068 72.5849 276.068 72.6212V74.1014C276.068 74.1795 275.985 74.2283 275.919 74.1893Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M277.12 74.8955L276.689 74.6414C276.658 74.6234 276.64 74.5898 276.64 74.5535V73.0736C276.64 72.9952 276.723 72.9462 276.789 72.9855L277.22 73.2393C277.25 73.2573 277.27 73.2909 277.27 73.3274V74.8076C277.27 74.8857 277.186 74.9344 277.12 74.8955Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M278.322 75.669L277.891 75.4152C277.86 75.3969 277.841 75.3633 277.841 75.3273V73.8471C277.841 73.7687 277.924 73.72 277.99 73.759L278.421 74.0128C278.452 74.031 278.471 74.0646 278.471 74.1012V75.5811C278.471 75.6592 278.388 75.7082 278.322 75.669Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M279.523 76.3414L279.092 76.0876C279.061 76.0693 279.042 76.0357 279.042 75.9997V74.5196C279.042 74.4411 279.125 74.3924 279.192 74.4314L279.622 74.6852C279.653 74.7034 279.672 74.7371 279.672 74.7733V76.2535C279.672 76.3317 279.589 76.3806 279.523 76.3414Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M280.724 77.0814L280.293 76.8273C280.263 76.8093 280.244 76.7757 280.244 76.7394V75.2595C280.244 75.1811 280.327 75.1322 280.393 75.1714L280.824 75.4252C280.855 75.4432 280.874 75.4768 280.874 75.5133V76.9932C280.874 77.0714 280.791 77.1204 280.724 77.0814Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M281.926 77.7873L281.495 77.5335C281.464 77.5155 281.445 77.4819 281.445 77.4456V75.9657C281.445 75.8873 281.528 75.8383 281.595 75.8773L282.025 76.1313C282.056 76.1494 282.075 76.183 282.075 76.2195V77.6994C282.075 77.7776 281.992 77.8265 281.926 77.7873Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M295.713 70.6729L296.148 70.4137C296.179 70.3949 296.198 70.3608 296.198 70.3236V68.8123C296.198 68.7324 296.114 68.6825 296.047 68.7224L295.612 68.9818C295.581 69.0003 295.562 69.0344 295.562 69.0717V70.583C295.562 70.6629 295.646 70.7128 295.713 70.6729Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M294.486 71.394L294.921 71.1349C294.952 71.1161 294.971 71.082 294.971 71.0448V69.5335C294.971 69.4536 294.888 69.4036 294.82 69.4436L294.385 69.703C294.354 69.7212 294.335 69.7556 294.335 69.7929V71.3042C294.335 71.3841 294.419 71.434 294.486 71.394Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M293.259 72.1152L293.694 71.856C293.725 71.8373 293.744 71.8032 293.744 71.7659V70.2544C293.744 70.1745 293.661 70.1246 293.593 70.1645L293.159 70.4239C293.127 70.4424 293.108 70.4765 293.108 70.5138V72.0253C293.108 72.1052 293.192 72.1551 293.259 72.1152Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M292.032 72.8362L292.467 72.5772C292.499 72.5585 292.518 72.5241 292.518 72.4871V70.9756C292.518 70.8957 292.434 70.8458 292.367 70.8857L291.932 71.1451C291.901 71.1636 291.881 71.1977 291.881 71.235V72.7463C291.881 72.8262 291.965 72.8761 292.032 72.8362Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M290.805 73.5573L291.24 73.2982C291.271 73.2794 291.291 73.2453 291.291 73.2081V71.6967C291.291 71.6169 291.207 71.5669 291.14 71.6069L290.705 71.8663C290.674 71.8848 290.654 71.9189 290.654 71.9561V73.4674C290.654 73.5473 290.738 73.5973 290.805 73.5573Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M289.578 74.2785L290.014 74.0193C290.045 74.0006 290.064 73.9665 290.064 73.9292V72.4179C290.064 72.338 289.98 72.2881 289.913 72.328L289.478 72.5874C289.447 72.6059 289.428 72.64 289.428 72.6773V74.1886C289.428 74.2685 289.511 74.3184 289.578 74.2785Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M288.352 74.9997L288.787 74.7405C288.818 74.7218 288.837 74.6877 288.837 74.6504V73.1389C288.837 73.059 288.753 73.009 288.686 73.049L288.251 73.3084C288.22 73.3269 288.201 73.361 288.201 73.3982V74.9098C288.201 74.9897 288.285 75.0396 288.352 74.9997Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M287.125 75.7896L287.56 75.5304C287.591 75.5117 287.61 75.4776 287.61 75.4403V73.929C287.61 73.8491 287.526 73.7992 287.459 73.8391L287.024 74.0985C286.993 74.117 286.974 74.1511 286.974 74.1884V75.6997C286.974 75.7796 287.058 75.8295 287.125 75.7896Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M285.898 76.4763L286.333 76.2171C286.364 76.1984 286.383 76.1643 286.383 76.127V74.6157C286.383 74.5358 286.3 74.4859 286.232 74.5258L285.797 74.7852C285.766 74.8037 285.747 74.8378 285.747 74.8751V76.3864C285.747 76.4663 285.831 76.5162 285.898 76.4763Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M284.671 77.2319L285.106 76.9728C285.137 76.954 285.156 76.9199 285.156 76.8827V75.3711C285.156 75.2912 285.073 75.2413 285.005 75.2812L284.57 75.5406C284.539 75.5591 284.52 75.5932 284.52 75.6305V77.1421C284.52 77.2219 284.604 77.2719 284.671 77.2319Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M283.444 77.9529L283.879 77.694C283.91 77.6752 283.93 77.6409 283.93 77.6038V76.0923C283.93 76.0124 283.846 75.9625 283.779 76.0024L283.344 76.2618C283.313 76.2803 283.293 76.3144 283.293 76.3517V77.863C283.293 77.9429 283.377 77.9928 283.444 77.9529Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M268.648 66.6441L268.657 68.415C268.599 68.7355 268.726 69.0868 269.039 69.2728L282.429 77.2529C282.673 77.3983 282.975 77.3983 283.219 77.2529L296.61 69.2728C296.921 69.087 297.049 68.7355 296.991 68.415L297 66.6441" fill="#8B81E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M282.429 75.2366L269.038 67.2565C268.512 66.9428 268.512 66.1582 269.038 65.844L282.429 57.8644C282.673 57.7188 282.974 57.7188 283.219 57.8644L296.609 65.844C297.136 66.1582 297.136 66.9428 296.609 67.2565L283.219 75.2366C282.975 75.3822 282.673 75.3822 282.429 75.2366Z" fill="#A59EF7"/> +</g> +<g opacity="0.327785"> +<rect width="49.9817" height="34.933" fill="black" fill-opacity="0" transform="translate(180.671 11.4867)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M182.898 33.788L182.147 33.3494C182.093 33.3176 182.06 33.2598 182.06 33.1975V30.6391C182.06 30.5041 182.205 30.4195 182.32 30.4867L183.071 30.9253C183.125 30.957 183.158 31.0149 183.158 31.0784V33.6362C183.158 33.7712 183.013 33.8552 182.898 33.788Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M185.015 35.0087L184.264 34.57C184.21 34.5383 184.177 34.4798 184.177 34.4176V31.8592C184.177 31.7248 184.322 31.6395 184.438 31.7073L185.188 32.146C185.242 32.1777 185.275 32.2356 185.275 32.2984V34.8562C185.275 34.9919 185.13 35.0759 185.015 35.0087Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M187.132 36.2287L186.381 35.7901C186.327 35.759 186.295 35.7005 186.295 35.6383V33.0798C186.295 32.9448 186.439 32.8602 186.555 32.9274L187.306 33.3667C187.359 33.3978 187.392 33.4563 187.392 33.5191V36.0769C187.392 36.2119 187.247 36.2966 187.132 36.2287Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M189.249 37.4495L188.498 37.0108C188.445 36.9791 188.411 36.9212 188.411 36.8584V34.2999C188.411 34.1656 188.557 34.0809 188.672 34.1481L189.423 34.5868C189.477 34.6185 189.509 34.6764 189.509 34.7398V37.297C189.509 37.4327 189.365 37.5167 189.249 37.4495Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M191.366 38.6695L190.616 38.2309C190.562 38.1998 190.529 38.1413 190.529 38.0791V35.5206C190.529 35.3856 190.674 35.301 190.789 35.3688L191.54 35.8075C191.594 35.8386 191.627 35.8971 191.627 35.9599V38.5177C191.627 38.6534 191.482 38.7374 191.366 38.6695Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M193.484 39.8902L192.733 39.4516C192.679 39.4198 192.646 39.362 192.646 39.2998V36.7413C192.646 36.6063 192.791 36.5217 192.906 36.5889L193.657 37.0275C193.711 37.0593 193.744 37.1171 193.744 37.1806V39.7384C193.744 39.8734 193.599 39.9574 193.484 39.8902Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M195.601 41.1109L194.85 40.6722C194.796 40.6405 194.763 40.582 194.763 40.5198V37.9614C194.763 37.827 194.908 37.7423 195.024 37.8095L195.774 38.2482C195.828 38.2799 195.861 38.3378 195.861 38.4006V40.9585C195.861 41.0941 195.717 41.1781 195.601 41.1109Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M197.718 42.4477L196.967 42.009C196.913 41.9773 196.881 41.9194 196.881 41.8572V39.2988C196.881 39.1637 197.025 39.0791 197.141 39.1463L197.892 39.585C197.945 39.6167 197.979 39.6752 197.979 39.738V42.2959C197.979 42.4309 197.834 42.5155 197.718 42.4477Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M199.835 43.61L199.084 43.1713C199.031 43.1396 198.998 43.0817 198.998 43.0189V40.4605C198.998 40.3261 199.143 40.2414 199.258 40.3086L200.009 40.7473C200.063 40.779 200.095 40.8369 200.095 40.9003V43.4576C200.095 43.5932 199.951 43.6772 199.835 43.61Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M201.953 44.8884L201.202 44.4498C201.148 44.4187 201.115 44.3602 201.115 44.2979V41.7395C201.115 41.6045 201.26 41.5199 201.375 41.5877L202.126 42.0263C202.18 42.0574 202.213 42.1159 202.213 42.1788V44.7366C202.213 44.8722 202.068 44.9562 201.953 44.8884Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M204.07 46.1091L203.319 45.6704C203.265 45.6387 203.233 45.5808 203.233 45.518V42.9602C203.233 42.8252 203.377 42.7405 203.493 42.8077L204.243 43.2464C204.297 43.2781 204.33 43.336 204.33 43.3994V45.9573C204.33 46.0923 204.185 46.1763 204.07 46.1091Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M228.377 33.8129L229.143 33.3643C229.198 33.3332 229.232 33.2735 229.232 33.2094V30.5968C229.232 30.4587 229.084 30.3728 228.966 30.4419L228.199 30.8898C228.144 30.9222 228.111 30.9807 228.111 31.0454V33.6574C228.111 33.7955 228.259 33.8813 228.377 33.8129Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M226.215 35.0591L226.981 34.6112C227.036 34.5794 227.07 34.5197 227.07 34.4556V31.8437C227.07 31.7049 226.922 31.619 226.803 31.6881L226.037 32.1361C225.982 32.1684 225.949 32.2275 225.949 32.2916V34.9036C225.949 35.0423 226.097 35.1282 226.215 35.0591Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M224.052 36.3053L224.819 35.8574C224.873 35.8256 224.908 35.7665 224.908 35.7018V33.0899C224.908 32.9511 224.76 32.8652 224.642 32.9343L223.875 33.3829C223.821 33.4146 223.786 33.4737 223.786 33.5378V36.1498C223.786 36.2885 223.934 36.3744 224.052 36.3053Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M221.89 37.5515L222.657 37.1035C222.711 37.0718 222.746 37.0127 222.746 36.948V34.336C222.746 34.1979 222.598 34.112 222.48 34.1805L221.713 34.6291C221.658 34.6608 221.624 34.7199 221.624 34.784V37.3966C221.624 37.5347 221.772 37.6206 221.89 37.5515Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M219.728 38.7983L220.495 38.3497C220.549 38.3186 220.583 38.2589 220.583 38.1948V35.5822C220.583 35.4441 220.436 35.3582 220.318 35.4273L219.551 35.8753C219.496 35.9076 219.462 35.9661 219.462 36.0308V38.6428C219.462 38.7809 219.61 38.8668 219.728 38.7983Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M217.566 40.0446L218.333 39.596C218.388 39.5649 218.421 39.5051 218.421 39.4411V36.8285C218.421 36.6903 218.273 36.6045 218.155 36.6735L217.389 37.1215C217.334 37.1539 217.3 37.2124 217.3 37.2771V39.889C217.3 40.0272 217.448 40.1136 217.566 40.0446Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M215.404 41.2908L216.171 40.8428C216.225 40.8111 216.259 40.7513 216.259 40.6873V38.0753C216.259 37.9365 216.111 37.8507 215.993 37.9197L215.226 38.3677C215.172 38.4001 215.138 38.4592 215.138 38.5233V41.1352C215.138 41.274 215.286 41.3598 215.404 41.2908Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M213.242 42.656L214.008 42.2081C214.063 42.1763 214.097 42.1172 214.097 42.0525V39.4406C214.097 39.3024 213.949 39.2159 213.831 39.285L213.064 39.7336C213.009 39.7653 212.975 39.8245 212.975 39.8885V42.5011C212.975 42.6392 213.124 42.7251 213.242 42.656Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M211.08 43.8433L211.846 43.3947C211.901 43.363 211.935 43.3039 211.935 43.2392V40.6272C211.935 40.4891 211.787 40.4032 211.668 40.4717L210.902 40.9203C210.847 40.9526 210.813 41.0111 210.813 41.0758V43.6878C210.813 43.8259 210.962 43.9118 211.08 43.8433Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M208.917 45.1491L209.684 44.7005C209.738 44.6694 209.773 44.6097 209.773 44.5456V41.933C209.773 41.7949 209.625 41.709 209.507 41.7781L208.74 42.2261C208.686 42.2584 208.651 42.3169 208.651 42.3816V44.9936C208.651 45.1317 208.799 45.2176 208.917 45.1491Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M206.755 46.3953L207.522 45.9473C207.576 45.9156 207.611 45.8559 207.611 45.7918V43.1798C207.611 43.0411 207.463 42.9552 207.345 43.0243L206.578 43.4722C206.523 43.5046 206.489 43.5631 206.489 43.6278V46.2397C206.489 46.3785 206.637 46.4644 206.755 46.3953Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M180.68 26.8497L180.695 29.9103C180.593 30.4646 180.818 31.0713 181.368 31.3936L204.966 45.1851C205.397 45.437 205.928 45.437 206.359 45.1851L229.957 31.3936C230.507 31.0719 230.731 30.4646 230.629 29.9103L230.645 26.8497" fill="#8B81E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M204.966 41.7003L181.368 27.9082C180.439 27.3656 180.439 26.0092 181.368 25.4673L204.966 11.6752C205.397 11.4238 205.927 11.4238 206.358 11.6752L229.957 25.4673C230.885 26.0099 230.885 27.3656 229.957 27.9082L206.358 41.7003C205.927 41.9517 205.397 41.9517 204.966 41.7003Z" fill="#A59EF7"/> +</g> +<g opacity="0.327785"> +<rect width="34.9717" height="24.8959" fill="black" fill-opacity="0" transform="translate(167.802 36.5651)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M169.36 52.459L168.834 52.1463C168.797 52.1237 168.774 52.0822 168.774 52.0375V50.215C168.774 50.1181 168.875 50.0584 168.956 50.1062L169.482 50.4188C169.52 50.4415 169.543 50.4824 169.543 50.5277V52.3501C169.543 52.4464 169.442 52.5068 169.36 52.459Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M170.842 53.3282L170.316 53.0156C170.278 52.9936 170.255 52.952 170.255 52.9074V51.0849C170.255 50.988 170.357 50.9283 170.437 50.9761L170.963 51.2887C171.001 51.3108 171.024 51.3523 171.024 51.3976V53.22C171.024 53.3163 170.923 53.3767 170.842 53.3282Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M172.323 54.1982L171.797 53.8855C171.76 53.8635 171.737 53.822 171.737 53.7773V51.9542C171.737 51.8573 171.838 51.7976 171.919 51.846L172.445 52.1586C172.483 52.1807 172.505 52.2222 172.505 52.2669V54.09C172.505 54.1862 172.405 54.2466 172.323 54.1982Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M173.805 55.0681L173.279 54.7554C173.241 54.7334 173.218 54.6912 173.218 54.6472V52.8241C173.218 52.7272 173.319 52.6675 173.4 52.7159L173.926 53.0286C173.964 53.0506 173.987 53.0915 173.987 53.1368V54.9599C173.987 55.0555 173.885 55.1159 173.805 55.0681Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M175.286 55.938L174.76 55.6254C174.723 55.6027 174.699 55.5612 174.699 55.5165V53.6941C174.699 53.5972 174.801 53.5374 174.882 53.5852L175.408 53.8979C175.446 53.9205 175.469 53.9614 175.469 54.0067V55.8292C175.469 55.9254 175.367 55.9858 175.286 55.938Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M176.768 56.8079L176.241 56.4953C176.204 56.4726 176.181 56.4311 176.181 56.3864V54.564C176.181 54.4671 176.282 54.4073 176.363 54.4551L176.889 54.7678C176.926 54.7904 176.95 54.8313 176.95 54.8766V56.6991C176.95 56.7953 176.848 56.8557 176.768 56.8079Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M178.249 57.6772L177.723 57.3645C177.685 57.3425 177.662 57.301 177.662 57.2563V55.4332C177.662 55.337 177.764 55.2772 177.844 55.325L178.37 55.6377C178.408 55.6597 178.432 55.7012 178.432 55.7459V57.569C178.432 57.6653 178.33 57.7256 178.249 57.6772Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M179.73 58.6301L179.204 58.3174C179.166 58.2954 179.144 58.2539 179.144 58.2092V56.3868C179.144 56.2899 179.245 56.2301 179.326 56.2779L179.852 56.5906C179.889 56.6126 179.912 56.6541 179.912 56.6994V58.5219C179.912 58.6181 179.811 58.6785 179.73 58.6301Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M181.212 59.4588L180.686 59.1461C180.648 59.1235 180.625 59.082 180.625 59.0373V57.2148C180.625 57.1179 180.726 57.0582 180.807 57.106L181.333 57.4187C181.371 57.4413 181.394 57.4822 181.394 57.5275V59.35C181.394 59.4462 181.293 59.5066 181.212 59.4588Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M182.693 60.3699L182.167 60.0573C182.129 60.0352 182.107 59.9931 182.107 59.9491V58.1259C182.107 58.0291 182.207 57.9693 182.289 58.0177L182.815 58.3304C182.852 58.3524 182.875 58.3933 182.875 58.4386V60.2617C182.875 60.3573 182.774 60.4177 182.693 60.3699Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M184.174 61.2398L183.648 60.9272C183.611 60.9045 183.588 60.863 183.588 60.8183V58.9959C183.588 58.899 183.689 58.8392 183.77 58.887L184.296 59.1997C184.334 59.2223 184.357 59.2632 184.357 59.3085V61.131C184.357 61.2272 184.256 61.2876 184.174 61.2398Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M201.181 52.4761L201.718 52.1572C201.757 52.1339 201.78 52.0924 201.78 52.0459V50.1844C201.78 50.0862 201.677 50.0252 201.594 50.0743L201.057 50.3926C201.018 50.4165 200.995 50.458 200.995 50.504V52.3654C200.995 52.4636 201.099 52.5252 201.181 52.4761Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M199.668 53.3645L200.205 53.0449C200.244 53.0223 200.268 52.9807 200.268 52.9342V51.0727C200.268 50.9746 200.164 50.9129 200.081 50.9626L199.544 51.2809C199.506 51.3042 199.482 51.3464 199.482 51.3923V53.2538C199.482 53.3519 199.586 53.4136 199.668 53.3645Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M198.155 54.2528L198.693 53.9332C198.731 53.9106 198.755 53.8684 198.755 53.8225V51.9611C198.755 51.8623 198.652 51.8013 198.569 51.8503L198.031 52.1693C197.993 52.1926 197.969 52.2347 197.969 52.28V54.1421C197.969 54.2402 198.073 54.3019 198.155 54.2528Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M196.643 55.1412L197.18 54.8217C197.218 54.799 197.242 54.7569 197.242 54.7109V52.8488C197.242 52.7507 197.139 52.6897 197.056 52.7387L196.519 53.0577C196.48 53.081 196.456 53.1231 196.456 53.1684V55.0305C196.456 55.1286 196.56 55.1903 196.643 55.1412Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M195.13 56.0296L195.667 55.71C195.705 55.6873 195.729 55.6452 195.729 55.5993V53.7372C195.729 53.639 195.626 53.578 195.543 53.6271L195.006 53.946C194.967 53.9693 194.943 54.0114 194.943 54.0567V55.9182C194.943 56.017 195.047 56.0786 195.13 56.0296Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M193.617 56.9179L194.154 56.5983C194.193 56.5757 194.216 56.5335 194.216 56.487V54.6255C194.216 54.5274 194.113 54.4663 194.03 54.5154L193.493 54.8344C193.454 54.8576 193.431 54.8998 193.431 54.9451V56.8066C193.431 56.9047 193.534 56.967 193.617 56.9179Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M192.104 57.8056L192.641 57.4867C192.68 57.4634 192.704 57.4219 192.704 57.3753V55.5138C192.704 55.4157 192.6 55.3547 192.517 55.4037L191.98 55.7221C191.942 55.746 191.918 55.7875 191.918 55.8334V57.6949C191.918 57.793 192.022 57.8547 192.104 57.8056Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M190.591 58.7787L191.128 58.4598C191.167 58.4365 191.191 58.395 191.191 58.3485V56.487C191.191 56.3888 191.087 56.3272 191.004 56.3769L190.467 56.6952C190.429 56.7191 190.405 56.7606 190.405 56.8066V58.668C190.405 58.7662 190.509 58.8278 190.591 58.7787Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M189.078 59.6247L189.616 59.3051C189.654 59.2825 189.678 59.2403 189.678 59.1944V57.3329C189.678 57.2341 189.575 57.1731 189.492 57.2222L188.954 57.5411C188.916 57.5644 188.892 57.6066 188.892 57.6519V59.514C188.892 59.6121 188.996 59.6737 189.078 59.6247Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M187.566 60.5554L188.103 60.2358C188.141 60.2132 188.165 60.171 188.165 60.1251V58.2636C188.165 58.1649 188.062 58.1039 187.979 58.1529L187.442 58.4719C187.403 58.4952 187.379 58.5373 187.379 58.5826V60.4447C187.379 60.5428 187.483 60.6045 187.566 60.5554Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M186.053 61.4438L186.59 61.1242C186.628 61.1015 186.652 61.0594 186.652 61.0135V59.1514C186.652 59.0532 186.549 58.9922 186.466 59.0413L185.929 59.3602C185.89 59.3835 185.866 59.4256 185.866 59.4709V61.333C185.866 61.4312 185.97 61.4928 186.053 61.4438Z" fill="#8C87C4"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M167.808 47.5141L167.819 49.6951C167.747 50.0902 167.904 50.5224 168.289 50.7514L184.801 60.5809C185.102 60.7608 185.474 60.7608 185.775 60.5809L202.286 50.752C202.671 50.523 202.828 50.0902 202.757 49.6951L202.768 47.5141" fill="#8B81E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M184.801 58.0974L168.289 48.2686C167.64 47.8817 167.64 46.9154 168.289 46.5285L184.801 36.6996C185.102 36.5203 185.473 36.5203 185.775 36.6996L202.287 46.5285C202.936 46.9154 202.936 47.8823 202.287 48.2686L185.775 58.0974C185.474 58.2767 185.102 58.2767 184.801 58.0974Z" fill="#A59EF7"/> +</g> +<rect width="29.9899" height="49.737" fill="black" fill-opacity="0" transform="translate(189.659 18.6826)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M189.659 43.6672L204.642 52.5638V18.6826L189.659 43.6672Z" fill="#6659FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M204.672 18.6826V52.5638L219.649 43.6672L204.672 18.6826Z" fill="#5135E6"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M189.659 46.6247L204.861 68.4196L204.642 55.5213L189.659 46.6247Z" fill="#6659FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M204.672 54.7454L204.917 67.4584L219.482 45.55L204.672 54.7454Z" fill="#4259DB"/> +<rect width="37.5326" height="24.718" fill="black" fill-opacity="0" transform="translate(318.852 99.4725)"/> +<rect width="37.5326" height="24.2005" fill="black" fill-opacity="0" transform="translate(318.852 99.4725)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M350.888 120.595C343.56 124.699 331.678 124.699 324.349 120.595C317.02 116.492 317.02 109.838 324.349 105.734C331.677 101.631 343.56 101.631 350.888 105.735C358.217 109.838 358.217 116.492 350.888 120.595Z" fill="#7F95EF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M318.852 112.846H356.385V109.662H318.852V112.846Z" fill="#838DB7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M350.888 117.411C343.56 121.515 331.678 121.515 324.349 117.411C317.02 113.307 317.02 106.654 324.349 102.55C331.677 98.4465 343.56 98.4465 350.888 102.55C358.217 106.654 358.217 113.307 350.888 117.411Z" fill="#93A8FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M326.211 115.967C319.911 112.485 319.911 106.839 326.211 103.358C332.511 99.8757 342.726 99.8757 349.026 103.358C355.326 106.84 355.326 112.485 349.026 115.967C342.726 119.449 332.511 119.449 326.211 115.967Z" fill="#9ABFFF"/> +<g opacity="0.370867"> +<rect width="19.296" height="11.091" fill="black" fill-opacity="0" transform="translate(327.431 104.017)"/> +<g opacity="0.653363"> +<rect width="14.9457" height="5.18221" fill="black" fill-opacity="0" transform="translate(327.431 109.926)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M342.161 110.157C342.497 110.398 342.355 110.571 342.298 110.734C341.315 113.539 336.078 115.549 331.129 115.025C328.909 114.79 327.621 114.016 327.452 112.816C327.266 111.493 328.324 110.596 330.572 110.173C331.906 109.922 333.285 109.901 334.667 109.943C337.204 110.021 339.711 110.353 342.161 110.157Z" fill="#4562DF"/> +</g> +<g opacity="0.653363"> +<rect width="14.909" height="5.19137" fill="black" fill-opacity="0" transform="translate(331.818 104.017)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M331.818 108.942C332.063 106.358 336.216 104.162 340.869 104.029C341.632 104.007 342.397 104.01 343.152 104.108C345.409 104.4 346.637 105.208 346.723 106.465C346.805 107.672 345.734 108.521 343.592 108.934C342.419 109.16 341.201 109.235 339.972 109.201C337.284 109.128 334.63 108.791 331.818 108.942Z" fill="#4562DF"/> +</g> +</g> +<rect width="37.5326" height="24.718" fill="black" fill-opacity="0" transform="translate(318.852 95.1737)"/> +<rect width="37.5326" height="24.2005" fill="black" fill-opacity="0" transform="translate(318.852 95.1737)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M350.888 116.296C343.56 120.4 331.678 120.4 324.349 116.296C317.02 112.193 317.02 105.539 324.349 101.436C331.677 97.332 343.56 97.332 350.888 101.436C358.217 105.539 358.217 112.193 350.888 116.296Z" fill="#7F95EF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M318.852 108.548H356.385V105.363H318.852V108.548Z" fill="#838DB7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M350.888 113.112C343.56 117.216 331.678 117.216 324.349 113.112C317.02 109.008 317.02 102.355 324.349 98.2514C331.677 94.1478 343.56 94.1478 350.888 98.2515C358.217 102.355 358.217 109.009 350.888 113.112Z" fill="#93A8FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M326.211 111.668C319.911 108.186 319.911 102.541 326.211 99.0588C332.511 95.5769 342.726 95.5769 349.026 99.0588C355.326 102.541 355.326 108.186 349.026 111.668C342.726 115.15 332.511 115.15 326.211 111.668Z" fill="#9ABFFF"/> +<g opacity="0.370867"> +<rect width="19.296" height="11.091" fill="black" fill-opacity="0" transform="translate(327.431 99.7187)"/> +<g opacity="0.653363"> +<rect width="14.9457" height="5.18221" fill="black" fill-opacity="0" transform="translate(327.431 105.627)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M342.161 105.859C342.497 106.1 342.355 106.272 342.298 106.435C341.315 109.24 336.078 111.251 331.129 110.726C328.909 110.491 327.621 109.717 327.452 108.517C327.266 107.194 328.324 106.297 330.572 105.874C331.906 105.624 333.285 105.603 334.667 105.644C337.204 105.722 339.711 106.054 342.161 105.859Z" fill="#4562DF"/> +</g> +<g opacity="0.653363"> +<rect width="14.909" height="5.19137" fill="black" fill-opacity="0" transform="translate(331.818 99.7187)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M331.818 104.643C332.063 102.059 336.216 99.8633 340.869 99.7298C341.632 99.7079 342.397 99.7109 343.152 99.8089C345.409 100.102 346.637 100.909 346.723 102.166C346.805 103.373 345.734 104.222 343.592 104.635C342.419 104.861 341.201 104.936 339.972 104.903C337.284 104.829 334.63 104.492 331.818 104.643Z" fill="#4562DF"/> +</g> +</g> +<rect width="37.5326" height="24.718" fill="black" fill-opacity="0" transform="translate(47.5456 103.771)"/> +<rect width="37.5326" height="24.2005" fill="black" fill-opacity="0" transform="translate(47.5456 103.771)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M79.5817 124.894C72.253 128.998 60.3709 128.998 53.0422 124.894C45.7135 120.79 45.7134 114.137 53.0421 110.033C60.3708 105.93 72.2529 105.93 79.5816 110.033C86.9103 114.137 86.9104 120.79 79.5817 124.894Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M47.5456 117.145H85.0782V113.961H47.5456V117.145Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M53.0422 121.71C45.7135 117.606 45.7134 110.953 53.0421 106.849C60.3708 102.745 72.2529 102.745 79.5816 106.849C86.9103 110.953 86.9104 117.606 79.5817 121.71C72.253 125.813 60.3709 125.813 53.0422 121.71Z" fill="#86F7D1"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M54.9046 120.265C48.6045 116.784 48.6044 111.138 54.9046 107.656C61.2046 104.174 71.4191 104.174 77.7192 107.656C84.0193 111.138 84.0194 116.784 77.7193 120.266C71.4192 123.747 61.2047 123.747 54.9046 120.265Z" fill="#95FFDA"/> +<rect width="26.809" height="10.7469" fill="black" fill-opacity="0" transform="translate(52.9074 109.145)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M78.1519 112.724C78.1579 112.71 78.1629 112.697 78.1681 112.684C78.1741 112.687 78.1793 112.69 78.1852 112.692L78.2281 112.712L78.1519 112.724ZM75.2505 115.293C74.8038 115.693 74.3155 116.07 73.7899 116.421C73.5585 116.576 73.3192 116.726 73.0736 116.871C71.4102 116.816 70.5534 116.576 70.1138 116.331C69.5898 116.039 69.6552 115.742 69.6552 115.742C69.6552 115.702 69.6552 115.662 69.6711 115.622C69.6711 115.622 69.6791 115.586 69.7054 115.531C69.7421 115.454 69.8139 115.34 69.9495 115.225C70.1816 115.027 70.6037 114.83 71.3568 114.828H71.3703C71.5698 114.824 71.7692 114.842 71.9367 114.886C72.7345 115.083 72.216 115.45 72.216 115.45C72.2758 115.446 72.3364 115.44 72.3978 115.433C73.3567 115.315 74.4376 114.814 74.2502 113.976C74.2079 113.785 74.0682 113.615 73.8744 113.464C73.3862 113.083 72.5533 112.83 72.0795 112.708C71.8632 112.653 71.7213 112.625 71.7213 112.625C71.7452 112.557 71.7532 112.504 71.7532 112.464C71.7532 112.456 71.7532 112.449 71.7515 112.442C71.7476 112.377 71.7213 112.352 71.7213 112.352C66.7753 110.986 62.9222 111.281 62.9222 111.281L63.8795 111.718C63.8755 111.718 63.8723 111.718 63.8684 111.718C63.7758 111.715 63.6761 111.715 63.5844 111.715C62.2306 111.737 60.9685 111.926 59.8908 112.241C57.7728 112.857 56.3649 113.954 56.3649 115.207C56.3649 115.265 56.3687 115.322 56.3752 115.376C56.3464 115.351 56.3186 115.326 56.2898 115.3C56.1422 115.169 56.0042 115.039 55.875 114.911C54.8969 113.945 54.4 113.097 54.1861 112.662C59.0388 110.884 64.9445 109.989 65.7701 109.872C66.0015 109.905 66.6285 109.999 67.5188 110.155C68.5295 110.333 69.8785 110.592 71.3719 110.935C73.2681 111.372 75.3956 111.944 77.3542 112.66C77.11 113.151 76.5037 114.17 75.2505 115.293ZM67.8363 112.25C69.1517 112.246 70.3396 112.388 71.2092 112.628C71.1812 112.624 70.7249 112.558 70.2615 112.53C70.0221 112.643 69.8147 112.691 69.7509 112.705C69.7429 112.709 69.7349 112.712 69.7349 112.712C68.3389 112.578 67.8363 112.25 67.8363 112.25ZM78.3792 112.23C73.4834 110.339 67.3313 109.373 66.1507 109.199L65.7677 109.145L65.3928 109.198C64.2081 109.373 58.0481 110.34 53.1515 112.233L52.9074 112.327L52.9672 112.482C53.0685 112.733 53.6549 114.058 55.291 115.528C56.3425 116.47 57.6284 117.296 59.1131 117.985C60.9223 118.822 63.0339 119.442 65.3929 119.83L65.7758 119.892L66.0246 119.847L66.1571 119.826C68.5016 119.441 70.6133 118.82 72.4345 117.982C73.9111 117.301 75.197 116.474 76.2572 115.524C77.903 114.049 78.5212 112.682 78.5842 112.468H78.585L78.644 112.316L78.3792 112.23Z" fill="#6CF0D1"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.9765 112.492L78.644 112.548C78.6703 112.485 78.6928 112.425 78.7153 112.369C78.7416 112.382 78.7636 112.392 78.7899 112.405L78.9765 112.492Z" fill="#000CA5"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.7893 112.405C78.7631 112.392 78.7411 112.382 78.7148 112.369C78.6923 112.425 78.6698 112.485 78.644 112.548L78.9759 112.492L78.7893 112.405Z" fill="#000CA5"/> +<rect width="37.5326" height="24.718" fill="black" fill-opacity="0" transform="translate(47.5456 99.4725)"/> +<rect width="37.5326" height="24.2005" fill="black" fill-opacity="0" transform="translate(47.5456 99.4725)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M79.5817 120.595C72.253 124.699 60.3709 124.699 53.0422 120.595C45.7135 116.492 45.7134 109.838 53.0421 105.734C60.3708 101.631 72.2529 101.631 79.5816 105.735C86.9103 109.838 86.9104 116.492 79.5817 120.595Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M47.5456 112.846H85.0782V109.662H47.5456V112.846Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M53.0422 117.411C45.7135 113.307 45.7134 106.654 53.0421 102.55C60.3708 98.4465 72.2529 98.4465 79.5816 102.55C86.9103 106.654 86.9104 113.307 79.5817 117.411C72.253 121.515 60.3709 121.515 53.0422 117.411Z" fill="#86F7D1"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M54.9046 115.967C48.6045 112.485 48.6044 106.839 54.9046 103.358C61.2046 99.8757 71.4191 99.8757 77.7192 103.358C84.0193 106.84 84.0194 112.485 77.7193 115.967C71.4192 119.449 61.2047 119.449 54.9046 115.967Z" fill="#95FFDA"/> +<rect width="26.809" height="10.7469" fill="black" fill-opacity="0" transform="translate(52.9074 104.846)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M78.1519 108.426C78.1579 108.412 78.1629 108.398 78.1681 108.386C78.1741 108.388 78.1793 108.391 78.1852 108.394L78.2281 108.413L78.1519 108.426ZM75.2505 110.994C74.8038 111.395 74.3155 111.771 73.7899 112.122C73.5585 112.277 73.3192 112.427 73.0736 112.572C71.4102 112.517 70.5534 112.277 70.1138 112.032C69.5898 111.741 69.6552 111.443 69.6552 111.443C69.6552 111.403 69.6552 111.363 69.6711 111.323C69.6711 111.323 69.6791 111.288 69.7054 111.232C69.7421 111.155 69.8139 111.041 69.9495 110.926C70.1816 110.729 70.6037 110.532 71.3568 110.529H71.3703C71.5698 110.525 71.7692 110.544 71.9367 110.587C72.7345 110.784 72.216 111.152 72.216 111.152C72.2758 111.147 72.3364 111.142 72.3978 111.134C73.3567 111.016 74.4376 110.516 74.2502 109.677C74.2079 109.487 74.0682 109.316 73.8744 109.165C73.3862 108.784 72.5533 108.531 72.0795 108.41C71.8632 108.354 71.7213 108.326 71.7213 108.326C71.7452 108.258 71.7532 108.205 71.7532 108.165C71.7532 108.157 71.7532 108.15 71.7515 108.143C71.7476 108.078 71.7213 108.053 71.7213 108.053C66.7753 106.688 62.9222 106.983 62.9222 106.983L63.8795 107.42C63.8755 107.42 63.8723 107.419 63.8684 107.419C63.7758 107.416 63.6761 107.416 63.5844 107.416C62.2306 107.438 60.9685 107.627 59.8908 107.942C57.7728 108.558 56.3649 109.656 56.3649 110.908C56.3649 110.966 56.3687 111.023 56.3752 111.077C56.3464 111.052 56.3186 111.027 56.2898 111.002C56.1422 110.87 56.0042 110.74 55.875 110.612C54.8969 109.646 54.4 108.798 54.1861 108.363C59.0388 106.586 64.9445 105.691 65.7701 105.573C66.0015 105.606 66.6285 105.7 67.5188 105.856C68.5295 106.034 69.8785 106.293 71.3719 106.637C73.2681 107.073 75.3956 107.645 77.3542 108.361C77.11 108.852 76.5037 109.871 75.2505 110.994ZM67.8363 107.951C69.1517 107.948 70.3396 108.09 71.2092 108.329C71.1812 108.325 70.7249 108.26 70.2615 108.232C70.0221 108.344 69.8147 108.392 69.7509 108.406C69.7429 108.41 69.7349 108.414 69.7349 108.414C68.3389 108.279 67.8363 107.951 67.8363 107.951ZM78.3792 107.931C73.4834 106.04 67.3313 105.074 66.1507 104.9L65.7677 104.846L65.3928 104.899C64.2081 105.074 58.0481 106.041 53.1515 107.935L52.9074 108.029L52.9672 108.183C53.0685 108.434 53.6549 109.759 55.291 111.229C56.3425 112.171 57.6284 112.997 59.1131 113.686C60.9223 114.523 63.0339 115.144 65.3929 115.531L65.7758 115.593L66.0246 115.548L66.1571 115.527C68.5016 115.142 70.6133 114.522 72.4345 113.683C73.9111 113.002 75.197 112.175 76.2572 111.225C77.903 109.75 78.5212 108.383 78.5842 108.17H78.585L78.644 108.017L78.3792 107.931Z" fill="#6CF0D1"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.9765 108.193L78.644 108.249C78.6703 108.186 78.6928 108.126 78.7153 108.07C78.7416 108.083 78.7636 108.093 78.7899 108.107L78.9765 108.193Z" fill="#000CA5"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.7893 108.107C78.7631 108.094 78.7411 108.083 78.7148 108.07C78.6923 108.126 78.6698 108.186 78.644 108.249L78.9759 108.193L78.7893 108.107Z" fill="#000CA5"/> +<rect width="37.5326" height="24.718" fill="black" fill-opacity="0" transform="translate(47.5456 95.1737)"/> +<rect width="37.5326" height="24.2005" fill="black" fill-opacity="0" transform="translate(47.5456 95.1737)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M79.5817 116.296C72.253 120.4 60.3709 120.4 53.0422 116.296C45.7135 112.193 45.7134 105.539 53.0421 101.436C60.3708 97.332 72.2529 97.332 79.5816 101.436C86.9103 105.539 86.9104 112.193 79.5817 116.296Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M47.5456 108.548H85.0782V105.363H47.5456V108.548Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M53.0422 113.112C45.7135 109.008 45.7134 102.355 53.0421 98.2514C60.3708 94.1478 72.2529 94.1478 79.5816 98.2515C86.9103 102.355 86.9104 109.009 79.5817 113.112C72.253 117.216 60.3709 117.216 53.0422 113.112Z" fill="#86F7D1"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M54.9046 111.668C48.6045 108.186 48.6044 102.541 54.9046 99.0588C61.2046 95.5769 71.4191 95.5769 77.7192 99.0588C84.0193 102.541 84.0194 108.186 77.7193 111.668C71.4192 115.15 61.2047 115.15 54.9046 111.668Z" fill="#95FFDA"/> +<rect width="26.809" height="10.7469" fill="black" fill-opacity="0" transform="translate(52.9074 100.547)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M78.1519 104.127C78.1579 104.113 78.1629 104.099 78.1681 104.087C78.1741 104.09 78.1793 104.092 78.1852 104.095L78.2281 104.114L78.1519 104.127ZM75.2505 106.696C74.8038 107.096 74.3155 107.472 73.7899 107.824C73.5585 107.978 73.3192 108.128 73.0736 108.273C71.4102 108.218 70.5534 107.978 70.1138 107.733C69.5898 107.442 69.6552 107.144 69.6552 107.144C69.6552 107.104 69.6552 107.064 69.6711 107.024C69.6711 107.024 69.6791 106.989 69.7054 106.933C69.7421 106.857 69.8139 106.742 69.9495 106.627C70.1816 106.43 70.6037 106.233 71.3568 106.23H71.3703C71.5698 106.227 71.7692 106.245 71.9367 106.289C72.7345 106.485 72.216 106.853 72.216 106.853C72.2758 106.849 72.3364 106.843 72.3978 106.835C73.3567 106.717 74.4376 106.217 74.2502 105.378C74.2079 105.188 74.0682 105.017 73.8744 104.867C73.3862 104.485 72.5533 104.232 72.0795 104.111C71.8632 104.055 71.7213 104.027 71.7213 104.027C71.7452 103.959 71.7532 103.907 71.7532 103.866C71.7532 103.858 71.7532 103.851 71.7515 103.844C71.7476 103.779 71.7213 103.754 71.7213 103.754C66.7753 102.389 62.9222 102.684 62.9222 102.684L63.8795 103.121C63.8755 103.121 63.8723 103.12 63.8684 103.12C63.7758 103.117 63.6761 103.117 63.5844 103.117C62.2306 103.139 60.9685 103.329 59.8908 103.643C57.7728 104.26 56.3649 105.357 56.3649 106.609C56.3649 106.668 56.3687 106.724 56.3752 106.779C56.3464 106.754 56.3186 106.728 56.2898 106.703C56.1422 106.572 56.0042 106.441 55.875 106.313C54.8969 105.348 54.4 104.5 54.1861 104.065C59.0388 102.287 64.9445 101.392 65.7701 101.275C66.0015 101.307 66.6285 101.401 67.5188 101.558C68.5295 101.735 69.8785 101.994 71.3719 102.338C73.2681 102.774 75.3956 103.347 77.3542 104.062C77.11 104.553 76.5037 105.573 75.2505 106.696ZM67.8363 103.652C69.1517 103.649 70.3396 103.791 71.2092 104.031C71.1812 104.027 70.7249 103.961 70.2615 103.933C70.0221 104.046 69.8147 104.093 69.7509 104.108C69.7429 104.111 69.7349 104.115 69.7349 104.115C68.3389 103.98 67.8363 103.652 67.8363 103.652ZM78.3792 103.632C73.4834 101.741 67.3313 100.775 66.1507 100.601L65.7677 100.547L65.3928 100.601C64.2081 100.775 58.0481 101.742 53.1515 103.636L52.9074 103.73L52.9672 103.884C53.0685 104.135 53.6549 105.46 55.291 106.93C56.3425 107.872 57.6284 108.699 59.1131 109.388C60.9223 110.224 63.0339 110.845 65.3929 111.232L65.7758 111.294L66.0246 111.25L66.1571 111.229C68.5016 110.843 70.6133 110.223 72.4345 109.384C73.9111 108.703 75.197 107.876 76.2572 106.927C77.903 105.451 78.5212 104.084 78.5842 103.871H78.585L78.644 103.718L78.3792 103.632Z" fill="#6CF0D1"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.9765 103.894L78.644 103.95C78.6703 103.887 78.6928 103.827 78.7153 103.771C78.7416 103.784 78.7636 103.794 78.7899 103.808L78.9765 103.894Z" fill="#000CA5"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.7893 103.808C78.7631 103.795 78.7411 103.784 78.7148 103.771C78.6923 103.827 78.6698 103.887 78.644 103.951L78.9759 103.894L78.7893 103.808Z" fill="#000CA5"/> +<rect width="37.5326" height="24.718" fill="black" fill-opacity="0" transform="translate(47.5456 90.8749)"/> +<rect width="37.5326" height="24.2005" fill="black" fill-opacity="0" transform="translate(47.5456 90.8749)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M79.5817 111.998C72.253 116.101 60.3709 116.101 53.0422 111.998C45.7135 107.894 45.7134 101.241 53.0421 97.1369C60.3708 93.0333 72.2529 93.0333 79.5816 97.137C86.9103 101.241 86.9104 107.894 79.5817 111.998Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M47.5456 104.249H85.0782V101.065H47.5456V104.249Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M53.0422 108.813C45.7135 104.71 45.7134 98.0563 53.0421 93.9526C60.3708 89.849 72.2529 89.849 79.5816 93.9527C86.9103 98.0564 86.9104 104.71 79.5817 108.813C72.253 112.917 60.3709 112.917 53.0422 108.813Z" fill="#86F7D1"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M54.9046 107.369C48.6045 103.887 48.6044 98.2419 54.9046 94.7601C61.2046 91.2781 71.4191 91.2781 77.7192 94.7601C84.0193 98.242 84.0194 103.887 77.7193 107.369C71.4192 110.851 61.2047 110.851 54.9046 107.369Z" fill="#95FFDA"/> +<rect width="26.809" height="10.7469" fill="black" fill-opacity="0" transform="translate(52.9074 96.2484)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M78.1519 99.828C78.1579 99.814 78.1629 99.8006 78.1681 99.788C78.1741 99.7909 78.1793 99.7933 78.1852 99.7962L78.2281 99.8156L78.1519 99.828ZM75.2505 102.397C74.8038 102.797 74.3155 103.174 73.7899 103.525C73.5585 103.68 73.3192 103.829 73.0736 103.974C71.4102 103.92 70.5534 103.679 70.1138 103.434C69.5898 103.143 69.6552 102.845 69.6552 102.845C69.6552 102.805 69.6552 102.765 69.6711 102.725C69.6711 102.725 69.6791 102.69 69.7054 102.634C69.7421 102.558 69.8139 102.443 69.9495 102.328C70.1816 102.131 70.6037 101.934 71.3568 101.932H71.3703C71.5698 101.928 71.7692 101.946 71.9367 101.99C72.7345 102.186 72.216 102.554 72.216 102.554C72.2758 102.55 72.3364 102.544 72.3978 102.536C73.3567 102.419 74.4376 101.918 74.2502 101.08C74.2079 100.889 74.0682 100.719 73.8744 100.568C73.3862 100.187 72.5533 99.9333 72.0795 99.812C71.8632 99.7567 71.7213 99.7287 71.7213 99.7287C71.7452 99.6605 71.7532 99.6078 71.7532 99.5673C71.7532 99.5597 71.7532 99.5524 71.7515 99.5455C71.7476 99.4806 71.7213 99.4555 71.7213 99.4555C66.7753 98.0901 62.9222 98.3851 62.9222 98.3851L63.8795 98.822C63.8755 98.822 63.8723 98.8216 63.8684 98.8216C63.7758 98.8183 63.6761 98.8183 63.5844 98.8183C62.2306 98.8405 60.9685 99.0299 59.8908 99.3442C57.7728 99.9609 56.3649 101.058 56.3649 102.31C56.3649 102.369 56.3687 102.425 56.3752 102.48C56.3464 102.455 56.3186 102.43 56.2898 102.404C56.1422 102.273 56.0042 102.142 55.875 102.015C54.8969 101.049 54.4 100.201 54.1861 99.7658C59.0388 97.9881 64.9445 97.0932 65.7701 96.9759C66.0015 97.0086 66.6285 97.1023 67.5188 97.2588C68.5295 97.4365 69.8785 97.6953 71.3719 98.0391C73.2681 98.4754 75.3956 99.0478 77.3542 99.7635C77.11 100.254 76.5037 101.274 75.2505 102.397ZM67.8363 99.3536C69.1517 99.35 70.3396 99.4919 71.2092 99.7319C71.1812 99.7279 70.7249 99.662 70.2615 99.634C70.0221 99.7469 69.8147 99.7942 69.7509 99.8087C69.7429 99.8125 69.7349 99.8161 69.7349 99.8161C68.3389 99.6813 67.8363 99.3536 67.8363 99.3536ZM78.3792 99.3332C73.4834 97.4423 67.3313 96.4767 66.1507 96.3026L65.7677 96.2484L65.3928 96.3019C64.2081 96.4767 58.0481 97.4434 53.1515 99.3371L52.9074 99.4312L52.9672 99.5855C53.0685 99.8364 53.6549 101.161 55.291 102.631C56.3425 103.573 57.6284 104.4 59.1131 105.089C60.9223 105.926 63.0339 106.546 65.3929 106.933L65.7758 106.995L66.0246 106.951L66.1571 106.93C68.5016 106.545 70.6133 105.924 72.4345 105.085C73.9111 104.404 75.197 103.577 76.2572 102.628C77.903 101.153 78.5212 99.7855 78.5842 99.572H78.585L78.644 99.4196L78.3792 99.3332Z" fill="#6CF0D1"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.9765 99.5955L78.644 99.6514C78.6703 99.5885 78.6928 99.5284 78.7153 99.4725C78.7416 99.4854 78.7636 99.4956 78.7899 99.509L78.9765 99.5955Z" fill="#000CA5"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.7893 99.509C78.7631 99.4961 78.7411 99.4854 78.7148 99.4725C78.6923 99.5284 78.6698 99.5885 78.644 99.6519L78.9759 99.5955L78.7893 99.509Z" fill="#000CA5"/> +<rect width="37.5326" height="24.718" fill="black" fill-opacity="0" transform="translate(47.5456 86.5761)"/> +<rect width="37.5326" height="24.2005" fill="black" fill-opacity="0" transform="translate(47.5456 86.5761)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M79.5817 107.699C72.253 111.803 60.3709 111.803 53.0422 107.699C45.7135 103.595 45.7134 96.9418 53.0421 92.8381C60.3708 88.7345 72.2529 88.7345 79.5816 92.8382C86.9103 96.9419 86.9104 103.595 79.5817 107.699Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M47.5456 99.9501H85.0782V96.7658H47.5456V99.9501Z" fill="#61C9A7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M53.0422 104.515C45.7135 100.411 45.7134 93.7575 53.0421 89.6539C60.3708 85.5502 72.2529 85.5502 79.5816 89.6539C86.9103 93.7576 86.9104 100.411 79.5817 104.515C72.253 108.618 60.3709 108.618 53.0422 104.515Z" fill="#86F7D1"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M54.9046 103.07C48.6045 99.5884 48.6044 93.9431 54.9046 90.4613C61.2046 86.9794 71.4191 86.9794 77.7192 90.4613C84.0193 93.9432 84.0194 99.5885 77.7193 103.07C71.4192 106.552 61.2047 106.552 54.9046 103.07Z" fill="#95FFDA"/> +<rect width="26.809" height="10.7469" fill="black" fill-opacity="0" transform="translate(52.9074 91.9496)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M78.1519 95.5293C78.1579 95.5152 78.1629 95.5018 78.1681 95.4892C78.1741 95.4921 78.1793 95.4945 78.1852 95.4974L78.2281 95.5168L78.1519 95.5293ZM75.2505 98.0981C74.8038 98.4983 74.3155 98.8747 73.7899 99.2261C73.5585 99.3809 73.3192 99.5305 73.0736 99.6755C71.4102 99.6208 70.5534 99.3805 70.1138 99.1355C69.5898 98.8442 69.6552 98.5467 69.6552 98.5467C69.6552 98.5067 69.6552 98.4665 69.6711 98.4266C69.6711 98.4266 69.6791 98.3912 69.7054 98.3355C69.7421 98.259 69.8139 98.1444 69.9495 98.0297C70.1816 97.8323 70.6037 97.6353 71.3568 97.6327H71.3703C71.5698 97.6291 71.7692 97.6473 71.9367 97.6911C72.7345 97.8876 72.216 98.2554 72.216 98.2554C72.2758 98.251 72.3364 98.2452 72.3978 98.2376C73.3567 98.1199 74.4376 97.6193 74.2502 96.7808C74.2079 96.5903 74.0682 96.4199 73.8744 96.2691C73.3862 95.8879 72.5533 95.6345 72.0795 95.5132C71.8632 95.4579 71.7213 95.4299 71.7213 95.4299C71.7452 95.3618 71.7532 95.309 71.7532 95.2685C71.7532 95.2609 71.7532 95.2536 71.7515 95.2467C71.7476 95.1818 71.7213 95.1567 71.7213 95.1567C66.7753 93.7913 62.9222 94.0863 62.9222 94.0863L63.8795 94.5232C63.8755 94.5232 63.8723 94.5228 63.8684 94.5228C63.7758 94.5195 63.6761 94.5195 63.5844 94.5195C62.2306 94.5417 60.9685 94.7311 59.8908 95.0454C57.7728 95.6622 56.3649 96.7592 56.3649 98.0115C56.3649 98.07 56.3687 98.1264 56.3752 98.1811C56.3464 98.1561 56.3186 98.1309 56.2898 98.1053C56.1422 97.974 56.0042 97.8435 55.875 97.7158C54.8969 96.7501 54.4 95.9021 54.1861 95.467C59.0388 93.6893 64.9445 92.7944 65.7701 92.6771C66.0015 92.7099 66.6285 92.8035 67.5188 92.9601C68.5295 93.1377 69.8785 93.3965 71.3719 93.7403C73.2681 94.1766 75.3956 94.749 77.3542 95.4648C77.11 95.9556 76.5037 96.9751 75.2505 98.0981ZM67.8363 95.0548C69.1517 95.0512 70.3396 95.1932 71.2092 95.4331C71.1812 95.4292 70.7249 95.3632 70.2615 95.3352C70.0221 95.4481 69.8147 95.4954 69.7509 95.51C69.7429 95.5137 69.7349 95.5173 69.7349 95.5173C68.3389 95.3825 67.8363 95.0548 67.8363 95.0548ZM78.3792 95.0344C73.4834 93.1435 67.3313 92.1779 66.1507 92.0039L65.7677 91.9496L65.3928 92.0031C64.2081 92.1779 58.0481 93.1446 53.1515 95.0383L52.9074 95.1324L52.9672 95.2867C53.0685 95.5376 53.6549 96.8626 55.291 98.3326C56.3425 99.2745 57.6284 100.101 59.1131 100.79C60.9223 101.627 63.0339 102.247 65.3929 102.635L65.7758 102.697L66.0246 102.652L66.1571 102.631C68.5016 102.246 70.6133 101.625 72.4345 100.786C73.9111 100.106 75.197 99.2786 76.2572 98.329C77.903 96.8539 78.5212 95.4867 78.5842 95.2732H78.585L78.644 95.1208L78.3792 95.0344Z" fill="#6CF0D1"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.9765 95.2967L78.644 95.3526C78.6703 95.2898 78.6928 95.2296 78.7153 95.1737C78.7416 95.1866 78.7636 95.1968 78.7899 95.2102L78.9765 95.2967Z" fill="#000CA5"/> +<path opacity="0.175894" fill-rule="evenodd" clip-rule="evenodd" d="M78.7893 95.2102C78.7631 95.1973 78.7411 95.1866 78.7148 95.1737C78.6923 95.2296 78.6698 95.2898 78.644 95.3532L78.9759 95.2967L78.7893 95.2102Z" fill="#000CA5"/> +<rect width="37.5326" height="24.718" fill="black" fill-opacity="0" transform="translate(318.852 90.8749)"/> +<rect width="37.5326" height="24.2005" fill="black" fill-opacity="0" transform="translate(318.852 90.8749)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M350.888 111.998C343.56 116.101 331.678 116.101 324.349 111.998C317.02 107.894 317.02 101.241 324.349 97.1369C331.677 93.0333 343.56 93.0333 350.888 97.137C358.217 101.241 358.217 107.894 350.888 111.998Z" fill="#7F95EF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M318.852 104.249H356.385V101.065H318.852V104.249Z" fill="#838DB7"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M350.888 108.813C343.56 112.917 331.678 112.917 324.349 108.813C317.02 104.71 317.02 98.0563 324.349 93.9526C331.677 89.849 343.56 89.849 350.888 93.9527C358.217 98.0564 358.217 104.71 350.888 108.813Z" fill="#93A8FF"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M326.211 107.369C319.911 103.887 319.911 98.2419 326.211 94.7601C332.511 91.2781 342.726 91.2781 349.026 94.7601C355.326 98.242 355.326 103.887 349.026 107.369C342.726 110.851 332.511 110.851 326.211 107.369Z" fill="#9ABFFF"/> +<g opacity="0.370867"> +<rect width="19.296" height="11.091" fill="black" fill-opacity="0" transform="translate(327.431 95.4199)"/> +<g opacity="0.653363"> +<rect width="14.9457" height="5.18222" fill="black" fill-opacity="0" transform="translate(327.431 101.329)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M342.161 101.56C342.497 101.801 342.355 101.973 342.298 102.137C341.315 104.941 336.078 106.952 331.129 106.428C328.909 106.192 327.621 105.418 327.452 104.219C327.266 102.896 328.324 101.998 330.572 101.576C331.906 101.325 333.285 101.304 334.667 101.346C337.204 101.423 339.711 101.755 342.161 101.56Z" fill="#4562DF"/> +</g> +<g opacity="0.653363"> +<rect width="14.909" height="5.19137" fill="black" fill-opacity="0" transform="translate(331.818 95.4199)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M331.818 100.345C332.063 97.7602 336.216 95.5645 340.869 95.4311C341.632 95.4091 342.397 95.4121 343.152 95.5101C345.409 95.8029 346.637 96.6105 346.723 97.8673C346.805 99.0741 345.734 99.9235 343.592 100.336C342.419 100.562 341.201 100.637 339.972 100.604C337.284 100.53 334.63 100.194 331.818 100.345Z" fill="#4562DF"/> +</g> +</g> +</svg> diff --git a/packages/website/public/images/landing/exchange_everywhere.png b/packages/website/public/images/landing/exchange_everywhere.png Binary files differnew file mode 100644 index 000000000..e63093929 --- /dev/null +++ b/packages/website/public/images/landing/exchange_everywhere.png diff --git a/packages/website/translations/english.json b/packages/website/translations/english.json index 541c29997..6864462c5 100644 --- a/packages/website/translations/english.json +++ b/packages/website/translations/english.json @@ -9,7 +9,7 @@ "FULL_LIST_LINK": "full list", "TOKENIZED_SECTION_HEADER": "the world's value is becoming tokenized", "TOKENIZED_SECTION_DESCRIPTION": - "the Ethereum blockchain is an open, borderless financial system that represents a wide variety of assets as cryptographic tokens. In the future, most digital assets and goods will be tokenized.", + "0x is the critical infrastructure layer in the emerging financial stack built on a foundation of Ethereum token standards. Developers needing exchange functionality for ERC 20 tokens, ERC 721 tokens, or any new asset type can easily integrate the 0x protocol into their application.", "CURRENCY": "currency", "TRADITIONAL_ASSETS": "traditional assets", "DIGITAL_GOODS": "digital goods", @@ -19,15 +19,16 @@ "in 0x protocol, orders are transported off-chain, massively reducing gas costs and eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time they facilitate a trade. Anyone can build a relayer.", "RELAYERS_HEADER": "relayers building on 0x", "BENEFITS_HEADER": "benefits of 0x", - "BENEFIT_ONE_TITLE": "trustless exchange", + "USE_CASES_HEADER": "uses of 0x", + "BENEFIT_ONE_TITLE": "many assets", "BENEFIT_ONE_DESCRIPTION": - "built on Ethereum's distributed network with no centralized point of failure and no down time, each trade is settled atomically and without counterparty risk.", - "BENEFIT_TWO_TITLE": "shared liquidity", + "the 0x protocol facilitates the exchange of a growing number of Ethereum-based tokens including currencies, game items, and many more digital assets.", + "BENEFIT_TWO_TITLE": "networked liquidity", "BENEFIT_TWO_DESCRIPTION": "by sharing a standard API, relayers can easily aggregate liquidity pools, creating network effects around liquidity that compound as more relayers come online.", - "BENEFIT_THREE_TITLE": "open source", + "BENEFIT_THREE_TITLE": "exchange everywhere", "BENEFIT_THREE_DESCRIPTION": - "0x is open source, permissionless and free to use. Trade directly with a known counterparty for free or pay a relayer some ZRX tokens to access their liquidity pool.", + "0x allows trade functionality to fade into the background, enabling developers to focus on building while 0x handles the exchange.", "BUILDING_BLOCK_SECTION_HEADER": "a building block for dApps", "BUILDING_BLOCK_SECTION_DESCRIPTION": "0x protocol is a pluggable building block for dApps that require exchange functionality. Join the many developers that are already using 0x in their web applications and smart contracts.", @@ -43,10 +44,10 @@ "decentralized prediction market platforms generate sets of tokens that represent a financial stake in the outcomes of real-world events. 0x allows these tokens to be instantly tradable.", "STABLE_TOKENS": "stable tokens", "STABLE_TOKENS_DESCRIPTION": - "Novel economic constructs such as stable coins require efficient, liquid markets to succeed. 0x will facilitate the underlying economic mechanisms that allow these tokens to remain stable.", + "novel economic constructs such as stable coins require efficient, liquid markets to succeed. 0x will facilitate the underlying economic mechanisms that allow these tokens to remain stable.", "DECENTRALIZED_LOANS": "decentralized loans", "DECENTRALIZED_LOANS_DESCRIPTION": - "Efficient lending requires liquid markets where investors can buy and re-sell loans. 0x enables an ecosystem of lenders to self-organize and efficiently determine market prices for all outstanding loans.", + "efficient lending requires liquid markets where investors can buy and re-sell loans. 0x enables an ecosystem of lenders to self-organize and efficiently determine market prices for all outstanding loans.", "FUND_MANAGEMENT": "fund management", "FUND_MANAGEMENT_DESCRIPTION": "Decentralized fund management limits fund managers to investing in pre-agreed upon asset classes. Embedding 0x into fund management smart contracts enables them to enforce these security constraints.", @@ -80,5 +81,12 @@ "DEVELOPERS": "developers", "HOME": "home", "ROCKETCHAT": "rocket.chat", - "TRADE_CALL_TO_ACTION": "trade on 0x" + "TRADE_CALL_TO_ACTION": "trade on 0x", + "OUR_MISSION_AND_VALUES": "our mission & values", + "GAMING_AND_COLLECTABLES": "gaming & collectables", + "GAMING_AND_COLLECTABLES_DESCRIPTION": + "artists and game makers are tokenizing digital art and in-game items known as non-fungible tokens (NFTs). 0x enables these creators to add exchange functionality to give access and the ability to build marketplaces for NFT trading.", + "ORDER_BOOKS": "order books", + "ORDER_BOOKS_DESCRIPTION": + "there are thousands of decentralized apps that have native utility tokens. 0x provides market makers and professional exchanges an ability to host order books to facilitate the exchange of these assets." } diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index fdfed961c..bb61e4fb9 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -238,7 +238,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { const fullWidthClasses = isExpandedDisplayType ? 'pr4' : ''; const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png'; const menuClasses = `col col-${ - isExpandedDisplayType ? '4' : '5' + isExpandedDisplayType ? '4' : '6' } ${fullWidthClasses} lg-pr0 md-pr2 sm-hide xs-hide`; const menuIconStyle = { fontSize: 25, @@ -302,6 +302,13 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { isExternal={false} /> <TopBarMenuItem + title={this.props.translate.get(Key.Careers, Deco.Cap)} + path={`${WebsitePaths.Careers}`} + style={styles.menuItem} + isNightVersion={isNightVersion} + isExternal={false} + /> + <TopBarMenuItem title={this.props.translate.get(Key.TradeCallToAction, Deco.Cap)} path={`${WebsitePaths.Portal}`} isPrimary={true} @@ -406,6 +413,9 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { <Link to={`${WebsitePaths.About}`} className="text-decoration-none"> <MenuItem className="py2">{this.props.translate.get(Key.About, Deco.Cap)}</MenuItem> </Link> + <Link to={`${WebsitePaths.Careers}`} className="text-decoration-none"> + <MenuItem className="py2">{this.props.translate.get(Key.Careers, Deco.Cap)}</MenuItem> + </Link> <a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}> <MenuItem className="py2">{this.props.translate.get(Key.Blog, Deco.Cap)}</MenuItem> </a> diff --git a/packages/website/ts/components/ui/button.tsx b/packages/website/ts/components/ui/button.tsx index 2952c8859..75ba7bcff 100644 --- a/packages/website/ts/components/ui/button.tsx +++ b/packages/website/ts/components/ui/button.tsx @@ -96,4 +96,5 @@ export const CallToAction: React.StatelessComponent<CallToActionProps> = ({ CallToAction.defaultProps = { type: 'dark', fontSize: '14px', + padding: '0.9em 1.6em', }; diff --git a/packages/website/ts/components/ui/text.tsx b/packages/website/ts/components/ui/text.tsx index 734483564..cd8f290e3 100644 --- a/packages/website/ts/components/ui/text.tsx +++ b/packages/website/ts/components/ui/text.tsx @@ -20,6 +20,7 @@ export interface TextProps { onClick?: (event: React.MouseEvent<HTMLElement>) => void; hoverColor?: string; noWrap?: boolean; + display?: string; } const PlainText: React.StatelessComponent<TextProps> = ({ children, className, onClick, Tag }) => ( @@ -41,6 +42,7 @@ export const Text = styled(PlainText)` ${props => (props.onClick ? 'cursor: pointer' : '')}; transition: color 0.5s ease; ${props => (props.noWrap ? 'white-space: nowrap' : '')}; + ${props => (props.display ? `display: ${props.display}` : '')}; &:hover { ${props => (props.onClick ? `color: ${props.hoverColor || darken(0.3, props.fontColor)}` : '')}; } diff --git a/packages/website/ts/components/ui/typed_text.tsx b/packages/website/ts/components/ui/typed_text.tsx new file mode 100644 index 000000000..2bb2d40b0 --- /dev/null +++ b/packages/website/ts/components/ui/typed_text.tsx @@ -0,0 +1,76 @@ +import * as _ from 'lodash'; +import { darken } from 'polished'; +import * as React from 'react'; +import Typist from 'react-typist'; + +import { Text, TextProps } from 'ts/components/ui/text'; + +import 'react-typist/dist/Typist.css'; + +export interface TypedTextProps extends TextProps { + textList: string[]; + shouldRepeat?: boolean; + wordDelayMs?: number; + avgKeystrokeDelayMs?: number; + stdKeystrokeDelay?: number; +} + +export interface TypedTextState { + cycleCount: number; +} + +export class TypedText extends React.Component<TypedTextProps, TypedTextState> { + public static defaultProps = { + shouldRepeat: false, + avgKeystrokeDelayMs: 90, + wordDelayMs: 1000, + }; + public state = { + cycleCount: 0, + }; + public render(): React.ReactNode { + const { + textList, + shouldRepeat, + wordDelayMs, + avgKeystrokeDelayMs, + stdKeystrokeDelay, + // tslint:disable-next-line + ...textProps + } = this.props; + const { cycleCount } = this.state; + if (_.isEmpty(textList)) { + return null; + } + const typistChildren: React.ReactNode[] = []; + _.forEach(textList, text => { + typistChildren.push( + <Text key={`text-${text}-${cycleCount}`} {...textProps}> + {text} + </Text>, + ); + if (wordDelayMs) { + typistChildren.push(<Typist.Delay key={`delay-${text}-${cycleCount}`} ms={wordDelayMs} />); + } + typistChildren.push(<Typist.Backspace key={`backspace-${text}-${cycleCount}`} count={text.length} />); + }); + return ( + <Typist + avgTypingDelay={avgKeystrokeDelayMs} + stdTypingDelay={stdKeystrokeDelay} + className="inline" + key={`typist-key-${cycleCount}`} + onTypingDone={this._onTypingDone.bind(this)} + > + {typistChildren} + </Typist> + ); + } + private _onTypingDone(): void { + if (this.props.shouldRepeat) { + this.setState({ + cycleCount: this.state.cycleCount + 1, + }); + } + } +} diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx index 78f5fc3c1..34f124d8c 100644 --- a/packages/website/ts/pages/landing/landing.tsx +++ b/packages/website/ts/pages/landing/landing.tsx @@ -8,6 +8,9 @@ import { SubscribeForm } from 'ts/components/forms/subscribe_form'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { CallToAction } from 'ts/components/ui/button'; import { Container } from 'ts/components/ui/container'; +import { Image } from 'ts/components/ui/image'; +import { Text } from 'ts/components/ui/text'; +import { TypedText } from 'ts/components/ui/typed_text'; import { Dispatcher } from 'ts/redux/dispatcher'; import { Deco, Key, Language, ScreenWidths, WebsitePaths } from 'ts/types'; import { constants } from 'ts/utils/constants'; @@ -31,7 +34,6 @@ interface UseCase { description: string; classNames: string; style?: React.CSSProperties; - projectIconUrls: string[]; } interface Project { logoFileName: string; @@ -41,72 +43,22 @@ interface Project { const THROTTLE_TIMEOUT = 100; const WHATS_NEW_TITLE = '18 ideas for 0x relayers in 2018'; const WHATS_NEW_URL = 'https://blog.0xproject.com/18-ideas-for-0x-relayers-in-2018-80a1498b955f'; - -const relayersAndDappProjects: Project[] = [ - { - logoFileName: 'ercdex.png', - projectUrl: constants.PROJECT_URL_ERC_DEX, - }, - { - logoFileName: 'radar_relay.png', - projectUrl: constants.PROJECT_URL_RADAR_RELAY, - }, - { - logoFileName: 'paradex.png', - projectUrl: constants.PROJECT_URL_PARADEX, - }, - { - logoFileName: 'the_ocean.png', - projectUrl: constants.PROJECT_URL_0CEAN, - }, - { - logoFileName: 'dydx.png', - projectUrl: constants.PROJECT_URL_DYDX, - }, - { - logoFileName: 'ethfinex.png', - projectUrl: constants.PROJECT_URL_ETHFINEX, - }, - { - logoFileName: 'melonport.png', - projectUrl: constants.PROJECT_URL_MELONPORT, - }, - { - logoFileName: 'maker.png', - projectUrl: constants.PROJECT_URL_MAKER, - }, - { - logoFileName: 'dharma.png', - projectUrl: constants.PROJECT_URL_DHARMA, - }, - { - logoFileName: 'lendroid.png', - projectUrl: constants.PROJECT_URL_LENDROID, - }, - { - logoFileName: 'district0x.png', - projectUrl: constants.PROJECT_URL_DISTRICT_0X, - }, - { - logoFileName: 'aragon.png', - projectUrl: constants.PROJECT_URL_ARAGON, - }, - { - logoFileName: 'blocknet.png', - projectUrl: constants.PROJECT_URL_BLOCKNET, - }, - { - logoFileName: 'imtoken.png', - projectUrl: constants.PROJECT_URL_IMTOKEN, - }, - { - logoFileName: 'augur.png', - projectUrl: constants.PROJECT_URL_AUGUR, - }, - { - logoFileName: 'anx.png', - projectUrl: constants.PROJECT_URL_OPEN_ANX, - }, +const TITLE_STYLE: React.CSSProperties = { + fontFamily: 'Roboto Mono', + color: colors.grey, + fontWeight: 300, + letterSpacing: 3, +}; +const ROTATING_LIST = [ + 'tokens', + 'game items', + 'digital art', + 'outcomes', + 'stocks', + 'derivatives', + 'loans', + 'cats', + 'everything', ]; const relayerProjects: Project[] = [ @@ -199,21 +151,13 @@ export class Landing extends React.Component<LandingProps, LandingState> { /> {this._renderHero()} {this._renderProjects( - relayersAndDappProjects, - this.props.translate.get(Key.ProjectsHeader, Deco.Upper), - colors.projectsGrey, - false, - )} - {this._renderTokenizationSection()} - {this._renderProtocolSection()} - {this._renderProjects( relayerProjects, this.props.translate.get(Key.RelayersHeader, Deco.Upper), - colors.heroGrey, + colors.projectsGrey, true, )} {this._renderInfoBoxes()} - {this._renderBuildingBlocksSection()} + {this._renderTokenizationSection()} {this._renderUseCases()} {this._renderCallToAction()} <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> @@ -222,15 +166,18 @@ export class Landing extends React.Component<LandingProps, LandingState> { } private _renderHero(): React.ReactNode { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; - const left = 'col lg-col-7 md-col-7 col-12 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center'; + const left = 'col lg-col-6 md-col-6 col-12 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center'; + const flexClassName = isSmallScreen + ? 'flex items-center flex-column justify-center' + : 'flex items-center justify-center'; return ( <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}> <div className="mx-auto max-width-4 clearfix"> {this._renderWhatsNew()} - <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-mt4 md-mt4 sm-mt2 sm-mb4 clearfix"> - <div className="col lg-col-5 md-col-5 col-12 sm-center"> - <img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} /> - </div> + <div className={`${flexClassName} lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-mt4 md-mt4 sm-mt2 sm-mb4`}> + <Container marginTop="30px" marginBottom="30px" marginLeft="15px" marginRight="15px"> + <Image src="/images/landing/0x_homepage.svg" maxWidth="100%" height="auto" /> + </Container> <div className={left} style={{ color: colors.white, height: 390, lineHeight: '390px' }}> <div className="inline-block lg-align-middle md-align-middle sm-align-top" @@ -239,37 +186,46 @@ export class Landing extends React.Component<LandingProps, LandingState> { lineHeight: '36px', }} > - <div + <Text className="sm-pb2" - style={{ - fontFamily: 'Roboto Mono', - fontSize: isSmallScreen ? 26 : 34, - }} + fontFamily="Roboto" + display="inline-block" + fontColor={colors.grey300} + fontWeight={500} + lineHeight="1.3em" + fontSize={isSmallScreen ? '28px' : '36px'} > {this.props.translate.get(Key.TopHeader, Deco.Cap)} - </div> - <div - className="pt2 h5 sm-mx-auto" - style={{ - maxWidth: 446, - fontFamily: 'Roboto Mono', - lineHeight: 1.7, - fontWeight: 300, - }} + {this.props.translate.getLanguage() === Language.English && ( + <React.Fragment> + {' '} + for{' '} + <TypedText + fontFamily="Roboto" + display="inline-block" + fontColor={colors.white} + fontWeight={700} + lineHeight="1.3em" + fontSize={isSmallScreen ? '28px' : '36px'} + textList={ROTATING_LIST} + shouldRepeat={true} + /> + </React.Fragment> + )} + </Text> + <Container + className={`pt3 flex clearfix sm-mx-auto ${isSmallScreen ? 'justify-center' : ''}`} > - {this.props.translate.get(Key.TopTagline)} - </div> - <Container className="pt3 clearfix sm-mx-auto" maxWidth="390px"> - <div className="lg-pr2 md-pr2 lg-col lg-col-6 sm-center sm-col sm-col-12 mb2"> + <Container paddingRight="20px"> <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> - <CallToAction width="175px" type="light"> + <CallToAction type="light"> {this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} </CallToAction> </Link> - </div> - <div className="lg-col lg-col-6 sm-center sm-col sm-col-12"> + </Container> + <div> <Link to={WebsitePaths.Portal} className="text-decoration-none"> - <CallToAction width="175px"> + <CallToAction> {this.props.translate.get(Key.TradeCallToAction, Deco.Cap)} </CallToAction> </Link> @@ -287,19 +243,24 @@ export class Landing extends React.Component<LandingProps, LandingState> { return ( <div className="sm-center sm-px1"> <a href={WHATS_NEW_URL} target="_blank" className="inline-block text-decoration-none"> - <div className="flex sm-pl0 md-pl2 lg-pl0" style={{ fontFamily: 'Roboto Mono', fontWeight: 600 }}> - <div - className="mr1 px1" - style={{ - backgroundColor: colors.white, - borderRadius: 3, - color: colors.heroGrey, - height: 23, - }} + <div className="flex items-center sm-pl0 md-pl2 lg-pl0"> + <Container + paddingTop="3px" + paddingLeft="8px" + paddingBottom="3px" + paddingRight="8px" + backgroundColor={colors.white} + borderRadius={6} > - New - </div> - <div style={{ color: colors.darkGrey }}>{WHATS_NEW_TITLE}</div> + <Text fontSize="14px" fontWeight={500} fontColor={colors.heroGrey}> + New + </Text> + </Container> + <Container marginLeft="12px"> + <Text fontSize="16px" fontWeight={500} fontColor={colors.grey300}> + {WHATS_NEW_TITLE} + </Text> + </Container> </div> </a> </div> @@ -344,16 +305,10 @@ export class Landing extends React.Component<LandingProps, LandingState> { </div> ); }); - const titleStyle: React.CSSProperties = { - fontFamily: 'Roboto Mono', - color: colors.grey, - fontWeight: 300, - letterSpacing: 3, - }; return ( <div className={`clearfix py4 ${isTitleCenter && 'center'}`} style={{ backgroundColor }}> <div className="mx-auto max-width-4 clearfix sm-px3"> - <div className="h4 pb3 lg-pl0 md-pl3 sm-pl2" style={titleStyle}> + <div className="h4 pb3 lg-pl0 md-pl3 sm-pl2" style={TITLE_STYLE}> {title} </div> <div className="clearfix">{projectList}</div> @@ -368,7 +323,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { > {this.props.translate.get(Key.FullListPrompt)}{' '} <Link - to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`} + to={WebsitePaths.Portal} className="text-decoration-none underline" style={{ color: colors.landingLinkGrey }} > @@ -402,7 +357,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { > {this.props.translate.get(Key.TokenizedSectionDescription, Deco.Cap)} </div> - <div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div> + <div className="flex pt1 sm-px3">{this._renderMissionAndValuesButton()}</div> </div> </div> {!isSmallScreen && this._renderTokenCloud()} @@ -410,116 +365,6 @@ export class Landing extends React.Component<LandingProps, LandingState> { </div> ); } - private _renderProtocolSection(): React.ReactNode { - const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; - return ( - <div className="clearfix pt4" style={{ backgroundColor: colors.heroGrey }}> - <div className="mx-auto max-width-4 pt4 clearfix"> - <div className="col lg-col-6 md-col-6 col-12 sm-center"> - <img src="/images/landing/relayer_diagram.png" height={isSmallScreen ? 326 : 426} /> - </div> - <div - className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto" - style={{ - color: colors.beigeWhite, - maxWidth: isSmallScreen ? 'none' : 445, - height: 430, - lineHeight: '430px', - }} - > - <div - className="inline-block lg-align-middle md-align-middle sm-align-top" - style={{ lineHeight: '43px' }} - > - <div - className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" - style={{ fontFamily: 'Roboto Mono' }} - > - <div>{this.props.translate.get(Key.OffChainOrderRelay, Deco.Cap)}</div> - <div> {this.props.translate.get(Key.OnChainSettlement, Deco.Cap)}</div> - </div> - <div - className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto" - style={{ - fontFamily: 'Roboto Mono', - lineHeight: 1.7, - fontWeight: 300, - maxWidth: 445, - }} - > - {this.props.translate.get(Key.OffChainOnChainDescription, Deco.Cap)} - </div> - </div> - </div> - </div> - </div> - ); - } - private _renderBuildingBlocksSection(): React.ReactNode { - const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; - const descriptionStyle: React.CSSProperties = { - fontFamily: 'Roboto Mono', - lineHeight: isSmallScreen ? 1.5 : 2, - fontWeight: 300, - fontSize: 15, - maxWidth: isSmallScreen ? 375 : 'none', - }; - const callToActionStyle: React.CSSProperties = { - fontFamily: 'Roboto Mono', - fontSize: 15, - fontWeight: 300, - maxWidth: isSmallScreen ? 375 : 441, - }; - return ( - <div className="clearfix lg-pt4 md-pt4" style={{ backgroundColor: colors.heroGrey }}> - <div className="mx-auto max-width-4 lg-pt4 md-pt4 lg-mb4 md-mb4 sm-mb2 clearfix"> - {isSmallScreen && this._renderBlockChipImage()} - <div - className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-px3" - style={{ color: colors.beigeWhite }} - > - <div - className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center" - style={{ fontFamily: 'Roboto Mono' }} - > - {this.props.translate.get(Key.BuildingBlockSectionHeader, Deco.Cap)} - </div> - <div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}> - {this.props.translate.get(Key.BuildingBlockSectionDescription, Deco.Cap)} - </div> - <div className="sm-mx-auto sm-center" style={callToActionStyle}> - {this.props.translate.get(Key.DevToolsPrompt, Deco.Cap)}{' '} - <Link - to={WebsitePaths.ZeroExJs} - className="text-decoration-none underline" - style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }} - > - 0x.js - </Link>{' '} - {this.props.translate.get(Key.And)}{' '} - <Link - to={WebsitePaths.SmartContracts} - className="text-decoration-none underline" - style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }} - > - {this.props.translate.get(Key.SmartContract)} - </Link>{' '} - {this.props.translate.get(Key.Docs)} - </div> - </div> - {!isSmallScreen && this._renderBlockChipImage()} - </div> - </div> - ); - } - private _renderBlockChipImage(): React.ReactNode { - const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; - return ( - <div className="col lg-col-6 md-col-6 col-12 sm-center"> - <img src="/images/landing/0x_chips.png" height={isSmallScreen ? 240 : 368} /> - </div> - ); - } private _renderTokenCloud(): React.ReactNode { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; return ( @@ -528,48 +373,16 @@ export class Landing extends React.Component<LandingProps, LandingState> { </div> ); } - private _renderAssetTypes(): React.ReactNode { - const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; - const assetTypes: AssetType[] = [ - { - title: this.props.translate.get(Key.Currency, Deco.Cap), - imageUrl: '/images/landing/currency.png', - }, - { - title: this.props.translate.get(Key.TraditionalAssets, Deco.Cap), - imageUrl: '/images/landing/stocks.png', - style: { - paddingLeft: isSmallScreen ? 41 : 56, - paddingRight: isSmallScreen ? 41 : 56, - }, - }, - { - title: this.props.translate.get(Key.DigitalGoods, Deco.Cap), - imageUrl: '/images/landing/digital_goods.png', - }, - ]; - const assets = _.map(assetTypes, (assetType: AssetType) => { - const style = _.isUndefined(assetType.style) ? {} : assetType.style; - return ( - <div key={`asset-${assetType.title}`} className="center" style={{ opacity: 0.8, ...style }}> - <div> - <img src={assetType.imageUrl} height="80" /> - </div> - <div - style={{ - fontFamily: 'Roboto Mono', - fontSize: 13.5, - fontWeight: 400, - color: colors.darkestGrey, - lineHeight: 1.4, - }} - > - {assetType.title} - </div> - </div> - ); - }); - return assets; + private _renderMissionAndValuesButton(): React.ReactNode { + return ( + <a + href={constants.URL_MISSION_AND_VALUES_BLOG_POST} + target="_blank" + className="inline-block text-decoration-none" + > + <CallToAction>{this.props.translate.get(Key.OurMissionAndValues, Deco.CapWords)}</CallToAction> + </a> + ); } private _renderInfoBoxes(): React.ReactNode { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; @@ -596,7 +409,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { { title: this.props.translate.get(Key.BenefitThreeTitle, Deco.Cap), description: this.props.translate.get(Key.BenefitThreeDescription, Deco.Cap), - imageUrl: '/images/landing/open_source.png', + imageUrl: '/images/landing/exchange_everywhere.png', classNames: 'right', }, ]; @@ -604,9 +417,13 @@ export class Landing extends React.Component<LandingProps, LandingState> { return ( <div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4"> <div className={`center sm-mx-auto ${!isSmallScreen && boxContent.classNames}`} style={boxStyle}> - <div> - <img src={boxContent.imageUrl} style={{ height: 210 }} /> - </div> + <Container className="flex items-center" height="210px"> + <img + className="mx-auto" + src={boxContent.imageUrl} + style={{ height: 'auto', maxWidth: 160 }} + /> + </Container> <div className="h3" style={{ color: 'black', fontFamily: 'Roboto Mono' }}> {boxContent.title} </div> @@ -617,15 +434,9 @@ export class Landing extends React.Component<LandingProps, LandingState> { </div> ); }); - const titleStyle: React.CSSProperties = { - fontFamily: 'Roboto Mono', - color: colors.grey, - fontWeight: 300, - letterSpacing: 3, - }; return ( <div className="clearfix" style={{ backgroundColor: colors.heroGrey }}> - <div className="center pb3 pt4" style={titleStyle}> + <div className="center pb3 pt4" style={TITLE_STYLE}> {this.props.translate.get(Key.BenefitsHeader, Deco.Upper)} </div> <div className="mx-auto pb4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}> @@ -634,53 +445,92 @@ export class Landing extends React.Component<LandingProps, LandingState> { </div> ); } - private _renderUseCases(): React.ReactNode { + private _getUseCases(): UseCase[] { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; - - const useCases: UseCase[] = [ - { - imageUrl: '/images/landing/governance_icon.png', - type: this.props.translate.get(Key.DecentralizedGovernance, Deco.Upper), - description: this.props.translate.get(Key.DecentralizedGovernanceDescription, Deco.Cap), - projectIconUrls: ['/images/landing/aragon.png'], - classNames: 'lg-px2 md-px2', - }, - { - imageUrl: '/images/landing/prediction_market_icon.png', - type: this.props.translate.get(Key.PredictionMarkets, Deco.Upper), - description: this.props.translate.get(Key.PredictionMarketsDescription, Deco.Cap), - projectIconUrls: ['/images/landing/augur.png'], - classNames: 'lg-px2 md-px2', - }, - { - imageUrl: '/images/landing/stable_tokens_icon.png', - type: this.props.translate.get(Key.StableTokens, Deco.Upper), - description: this.props.translate.get(Key.StableTokensDescription, Deco.Cap), - projectIconUrls: ['/images/landing/maker.png'], - classNames: 'lg-px2 md-px2', - }, - { - imageUrl: '/images/landing/loans_icon.png', - type: this.props.translate.get(Key.DecentralizedLoans, Deco.Upper), - description: this.props.translate.get(Key.DecentralizedLoansDescription, Deco.Cap), - projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'], - classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6', - style: { - width: 291, - float: 'right', - marginTop: !isSmallScreen ? 38 : 0, + const isEnglish = this.props.translate.getLanguage() === Language.English; + if (isEnglish) { + return [ + { + imageUrl: '/images/landing/governance_icon.png', + type: this.props.translate.get(Key.GamingAndCollectables, Deco.Upper), + description: this.props.translate.get(Key.GamingAndCollectablesDescription, Deco.Cap), + classNames: 'lg-px2 md-px2', }, - }, - { - imageUrl: '/images/landing/fund_management_icon.png', - type: this.props.translate.get(Key.FundManagement, Deco.Upper), - description: this.props.translate.get(Key.FundManagementDescription, Deco.Cap), - projectIconUrls: ['/images/landing/melonport.png'], - classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6', - style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 }, - }, - ]; - + { + imageUrl: '/images/landing/prediction_market_icon.png', + type: this.props.translate.get(Key.PredictionMarkets, Deco.Upper), + description: this.props.translate.get(Key.PredictionMarketsDescription, Deco.Cap), + classNames: 'lg-px2 md-px2', + }, + { + imageUrl: '/images/landing/fund_management_icon.png', + type: this.props.translate.get(Key.OrderBooks, Deco.Upper), + description: this.props.translate.get(Key.OrderBooksDescription, Deco.Cap), + classNames: 'lg-px2 md-px2', + }, + { + imageUrl: '/images/landing/loans_icon.png', + type: this.props.translate.get(Key.DecentralizedLoans, Deco.Upper), + description: this.props.translate.get(Key.DecentralizedLoansDescription, Deco.Cap), + classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6', + style: { + width: 291, + float: 'right', + marginTop: !isSmallScreen ? 38 : 0, + }, + }, + { + imageUrl: '/images/landing/stable_tokens_icon.png', + type: this.props.translate.get(Key.StableTokens, Deco.Upper), + description: this.props.translate.get(Key.StableTokensDescription, Deco.Cap), + classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6', + style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 }, + }, + ]; + } else { + return [ + { + imageUrl: '/images/landing/governance_icon.png', + type: this.props.translate.get(Key.DecentralizedGovernance, Deco.Upper), + description: this.props.translate.get(Key.DecentralizedGovernanceDescription, Deco.Cap), + classNames: 'lg-px2 md-px2', + }, + { + imageUrl: '/images/landing/prediction_market_icon.png', + type: this.props.translate.get(Key.PredictionMarkets, Deco.Upper), + description: this.props.translate.get(Key.PredictionMarketsDescription, Deco.Cap), + classNames: 'lg-px2 md-px2', + }, + { + imageUrl: '/images/landing/stable_tokens_icon.png', + type: this.props.translate.get(Key.StableTokens, Deco.Upper), + description: this.props.translate.get(Key.StableTokensDescription, Deco.Cap), + classNames: 'lg-px2 md-px2', + }, + { + imageUrl: '/images/landing/loans_icon.png', + type: this.props.translate.get(Key.DecentralizedLoans, Deco.Upper), + description: this.props.translate.get(Key.DecentralizedLoansDescription, Deco.Cap), + classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6', + style: { + width: 291, + float: 'right', + marginTop: !isSmallScreen ? 38 : 0, + }, + }, + { + imageUrl: '/images/landing/fund_management_icon.png', + type: this.props.translate.get(Key.FundManagement, Deco.Upper), + description: this.props.translate.get(Key.FundManagementDescription, Deco.Cap), + classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6', + style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 }, + }, + ]; + } + } + private _renderUseCases(): React.ReactNode { + const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; + const useCases = this._getUseCases(); const cases = _.map(useCases, (useCase: UseCase) => { const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style; const useCaseBoxStyle = { @@ -725,7 +575,10 @@ export class Landing extends React.Component<LandingProps, LandingState> { ); }); return ( - <div className="clearfix pb4 lg-pt2 md-pt2 sm-pt4" style={{ backgroundColor: colors.heroGrey }}> + <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}> + <div className="center h4 pb3 lg-pl0 md-pl3 sm-pl2" style={TITLE_STYLE}> + {this.props.translate.get(Key.UseCasesHeader, Deco.Upper)} + </div> <div className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix" style={{ maxWidth: '67em' }}> {cases} </div> diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index c637171dd..6ab17e261 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -415,6 +415,7 @@ export enum Key { OffChainOnChainDescription = 'OFFCHAIN_ONCHAIN_DESCRIPTION', RelayersHeader = 'RELAYERS_HEADER', BenefitsHeader = 'BENEFITS_HEADER', + UseCasesHeader = 'USE_CASES_HEADER', BenefitOneTitle = 'BENEFIT_ONE_TITLE', BenefitOneDescription = 'BENEFIT_ONE_DESCRIPTION', BenefitTwoTitle = 'BENEFIT_TWO_TITLE', @@ -436,6 +437,10 @@ export enum Key { DecentralizedLoansDescription = 'DECENTRALIZED_LOANS_DESCRIPTION', FundManagement = 'FUND_MANAGEMENT', FundManagementDescription = 'FUND_MANAGEMENT_DESCRIPTION', + GamingAndCollectables = 'GAMING_AND_COLLECTABLES', + GamingAndCollectablesDescription = 'GAMING_AND_COLLECTABLES_DESCRIPTION', + OrderBooks = 'ORDER_BOOKS', + OrderBooksDescription = 'ORDER_BOOKS_DESCRIPTION', FinalCallToAction = 'FINAL_CALL_TO_ACTION', Documentation = 'DOCUMENTATION', Community = 'COMMUNITY', @@ -468,6 +473,7 @@ export enum Key { Home = 'HOME', RocketChat = 'ROCKETCHAT', TradeCallToAction = 'TRADE_CALL_TO_ACTION', + OurMissionAndValues = 'OUR_MISSION_AND_VALUES', } export enum SmartContractDocSections { |