ERC-20
Overview
Max Total Supply
1,000,000 DSOUTH
Holders
49
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
0.36560491861097362 DSOUTHValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
DeepSouthAI
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-01-06 */ /** * @dev This smart contract was developed based on the general * OpenZeppelin Contracts guidelines where functions revert instead of * returning `false` on failure. */ // SPDX-License-Identifier: MIT pragma solidity 0.8.18; /******************************************************************************************** LIBRARY ********************************************************************************************/ /** * @title Address Library * * @notice Collection of functions providing utility for interacting with addresses. */ library Address { // ERROR /** * @notice Error indicating insufficient balance while performing an operation. * * @param account Address where the balance is insufficient. */ error AddressInsufficientBalance(address account); /** * @notice Error indicating an attempt to interact with a contract having empty code. * * @param target Address of the contract with empty code. */ error AddressEmptyCode(address target); /** * @notice Error indicating a failed internal call. */ error FailedInnerCall(); // FUNCTION /** * @notice Calls a function on a specified address without transferring value. * * @param target Address on which the function will be called. * @param data Encoded data of the function call. * * @return returndata Result of the function call. * * @dev The `target` must be a contract address and this function must be calling * `target` with `data` not reverting. */ function functionCall( address target, bytes memory data ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @notice Calls a function on a specified address with a specified value. * * @param target Address on which the function will be called. * @param data Encoded data of the function call. * @param value Value to be sent in the call. * * @return returndata Result of the function call. * * @dev This function ensure that the calling contract actually have Ether balance * of at least `value` and that the called Solidity function is a `payable`. Should * throw if caller does have insufficient balance. */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResultFromTarget(target, success, returndata); } /** * @notice Verifies the result of a function call and handles errors if any. * * @param target Address on which the function was called. * @param success Boolean indicating the success of the function call. * @param returndata Result data of the function call. * * @return Result of the function call or reverts with an appropriate error. * * @dev This help to verify that a low level call to smart-contract was successful * and will reverts if the target was not a contract. For unsuccessful call, this * will bubble up the revert reason (falling back to {FailedInnerCall}). Should * throw if both the returndata and target.code length are 0 when `success` is true. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @notice Reverts with decoded revert data or FailedInnerCall if no revert * data is available. * * @param returndata Result data of a failed function call. * * @dev Should throw if returndata length is 0. */ function _revert(bytes memory returndata) private pure { if (returndata.length > 0) { assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } } /** * @title SafeERC20 Library * * @notice Collection of functions providing utility for safe operations with * ERC20 tokens. * * @dev This is mainly for the usage of token that throw on failure (when the * token contract returns false). Tokens that return no value (and instead revert * or throw on failure) are also supported where non-reverting calls are assumed * to be a successful transaction. */ library SafeERC20 { // LIBRARY using Address for address; // ERROR /** * @notice Error indicating a failed operation during an ERC-20 token transfer. * * @param token Address of the token contract. */ error SafeERC20FailedOperation(address token); // FUNCTION /** * @notice Safely transfers tokens. * * @param token ERC20 token interface. * @param to Address to which the tokens will be transferred. * @param value Amount of tokens to be transferred. * * @dev Transfer `value` amount of `token` from the calling contract to `to` where * non-reverting calls are assumed to be successful if `token` returns no value. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @notice Calls a function on a token contract and reverts if the operation fails. * * @param token ERC20 token interface. * @param data Encoded data of the function call. * * @dev This imitates a Solidity high-level call such as a regular function call to * a contract while relaxing the requirement on the return value. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } } /******************************************************************************************** INTERFACE ********************************************************************************************/ /** * @title Router Interface * * @notice Interface of the Router contract, providing functions to interact with * Router contract that is derived from Uniswap V2 Router. * * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02 */ interface IRouter { // FUNCTION /** * @notice Get the address of the Wrapped Ether (WETH) token. * * @return The address of the WETH token. */ function WETH() external pure returns (address); /** * @notice Get the address of the linked Factory contract. * * @return The address of the Factory contract. */ function factory() external pure returns (address); /** * @notice Swaps an exact amount of tokens for ETH, supporting * tokens that implement fee-on-transfer mechanisms. * * @param amountIn The exact amount of input tokens for the swap. * @param amountOutMin The minimum acceptable amount of ETH to receive in the swap. * @param path An array of token addresses representing the token swap path. * @param to The recipient address that will receive the swapped ETH. * @param deadline The timestamp by which the transaction must be executed to be * considered valid. * * @dev This function swaps a specific amount of tokens for ETH on a specified path, * ensuring a minimum amount of output ETH. */ function swapExactTokensForETHSupportingFeeOnTransferTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external; /** * @notice Swaps a precise amount of ETH for tokens, supporting tokens with fee-on-transfer mechanisms. * * @param amountOutMin The minimum acceptable amount of output tokens expected from the swap. * @param path An array of token addresses representing the token swap path. * @param to The recipient address that will receive the swapped tokens. * @param deadline The timestamp by which the transaction must be executed to be considered valid. * * @dev This function performs a direct swap of a specified amount of ETH for tokens based on the provided * path and minimum acceptable output token amount. */ function swapExactETHForTokensSupportingFeeOnTransferTokens(uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external payable; } /** * @title Factory Interface * * @notice Interface of the Factory contract, providing functions to interact with * Factory contract that is derived from Uniswap V2 Factory. * * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory */ interface IFactory { // FUNCTION /** * @notice Create a new token pair for two given tokens on Uniswap V2-based factory. * * @param tokenA The address of the first token. * @param tokenB The address of the second token. * * @return pair The address of the created pair for the given tokens. */ function createPair(address tokenA, address tokenB) external returns (address pair); /** * @notice Get the address of the pair for two tokens on the decentralized exchange. * * @param tokenA The address of the first token. * @param tokenB The address of the second token. * * @return pair The address of the pair corresponding to the provided tokens. */ function getPair(address tokenA, address tokenB) external view returns (address pair); } /** * @title Pair Interface * * @notice Interface of the Pair contract in a decentralized exchange based on the * Pair contract that is derived from Uniswap V2 Pair. * * @dev See https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair */ interface IPair { // FUNCTION /** * @notice Get the address of the first token in the pair. * * @return The address of the first token. */ function token0() external view returns (address); /** * @notice Get the address of the second token in the pair. * * @return The address of the second token. */ function token1() external view returns (address); } /** * @title ERC20 Token Standard Interface * * @notice Interface of the ERC-20 standard token as defined in the ERC. * * @dev See https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20 { // EVENT /** * @notice Emitted when `value` tokens are transferred from * one account (`from`) to another (`to`). * * @param from The address tokens are transferred from. * @param to The address tokens are transferred to. * @param value The amount of tokens transferred. * * @dev The `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @notice Emitted when the allowance of a `spender` for an `owner` * is set by a call to {approve}. * * @param owner The address allowing `spender` to spend on their behalf. * @param spender The address allowed to spend tokens on behalf of `owner`. * @param value The allowance amount set for `spender`. * * @dev The `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); // FUNCTION /** * @notice Returns the value of tokens in existence. * * @return The value of the total supply of tokens. * * @dev This should get the total token supply. */ function totalSupply() external view returns (uint256); /** * @notice Returns the value of tokens owned by `account`. * * @param account The address to query the balance for. * * @return The token balance of `account`. * * @dev This should get the token balance of a specific account. */ function balanceOf(address account) external view returns (uint256); /** * @notice Moves a `value` amount of tokens from the caller's account to `to`. * * @param to The address to transfer tokens to. * @param value The amount of tokens to be transferred. * * @return A boolean indicating whether the transfer was successful or not. * * @dev This should transfer tokens to a specified address and emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @notice Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. * * @param owner The address allowing `spender` to spend on their behalf. * @param spender The address allowed to spend tokens on behalf of `owner`. * * @return The allowance amount for `spender`. * * @dev The return value should be zero by default and * changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @notice Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * @param spender The address allowed to spend tokens on behalf of the sender. * @param value The allowance amount for `spender`. * * @return A boolean indicating whether the approval was successful or not. * * @dev This should approve `spender` to spend a specified amount of tokens * on behalf of the sender and emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @notice Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's allowance. * * @param from The address to transfer tokens from. * @param to The address to transfer tokens to. * @param value The amount of tokens to be transferred. * * @return A boolean indicating whether the transfer was successful or not. * * @dev This should transfer tokens from one address to another after * spending caller's allowance and emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } /** * @title ERC20 Token Metadata Interface * * @notice Interface for the optional metadata functions of the ERC-20 standard as defined in the ERC. * * @dev It extends the IERC20 interface. See https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20Metadata is IERC20 { // FUNCTION /** * @notice Returns the name of the token. * * @return The name of the token as a string. */ function name() external view returns (string memory); /** * @notice Returns the symbol of the token. * * @return The symbol of the token as a string. */ function symbol() external view returns (string memory); /** * @notice Returns the number of decimals used to display the token. * * @return The number of decimals as a uint8. */ function decimals() external view returns (uint8); } /** * @title ERC20 Token Standard Error Interface * * @notice Interface of the ERC-6093 custom errors that defined common errors * related to the ERC-20 standard token functionalities. * * @dev See https://eips.ethereum.org/EIPS/eip-6093 */ interface IERC20Errors { // ERROR /** * @notice Error indicating that the `sender` has inssufficient `balance` for the operation. * * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * * @dev The `needed` value is required to inform user on the needed amount. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @notice Error indicating that the `sender` is invalid for the operation. * * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @notice Error indicating that the `receiver` is invalid for the operation. * * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @notice Error indicating that the `spender` does not have enough `allowance` for the operation. * * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. * * @dev The `needed` value is required to inform user on the needed amount. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @notice Error indicating that the `approver` is invalid for the approval operation. * * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @notice Error indicating that the `spender` is invalid for the allowance operation. * * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @title Common Error Interface * * @notice Interface of the common errors not specific to ERC-20 functionalities. */ interface ICommonError { // ERROR /** * @notice Error indicating that the `current` address cannot be used in this context. * * @param current Address used in the context. */ error CannotUseCurrentAddress(address current); /** * @notice Error indicating that the `current` value cannot be used in this context. * * @param current Value used in the context. */ error CannotUseCurrentValue(uint256 current); /** * @notice Error indicating that the `current` state cannot be used in this context. * * @param current Boolean state used in the context. */ error CannotUseCurrentState(bool current); /** * @notice Error indicating that the `invalid` address provided is not a valid address for this context. * * @param invalid Address used in the context. */ error InvalidAddress(address invalid); /** * @notice Error indicating that the `invalid` value provided is not a valid value for this context. * * @param invalid Value used in the context. */ error InvalidValue(uint256 invalid); } /******************************************************************************************** ACCESS ********************************************************************************************/ /** * @title Ownable Contract * * @notice Abstract contract module implementing ownership functionality through * inheritance as a basic access control mechanism, where there is an owner account * that can be granted exclusive access to specific functions. * * @dev The initial owner is set to the address provided by the deployer and can * later be changed with {transferOwnership}. */ abstract contract Ownable { // DATA address private _owner; // MODIFIER /** * @notice Modifier that allows access only to the contract owner. * * @dev Should throw if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } // ERROR /** * @notice Error indicating that the `account` is not authorized to perform an operation. * * @param account Address used to perform the operation. */ error OwnableUnauthorizedAccount(address account); /** * @notice Error indicating that the provided `owner` address is invalid. * * @param owner Address used to perform the operation. * * @dev Should throw if called by an invalid owner account such as address(0) as an example. */ error OwnableInvalidOwner(address owner); // CONSTRUCTOR /** * @notice Initializes the contract setting the `initialOwner` address provided by * the deployer as the initial owner. * * @param initialOwner The address to set as the initial owner. * * @dev Should throw an error if called with address(0) as the `initialOwner`. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } // EVENT /** * @notice Emitted when ownership of the contract is transferred. * * @param previousOwner The address of the previous owner. * @param newOwner The address of the new owner. */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // FUNCTION /** * @notice Get the address of the smart contract owner. * * @return The address of the current owner. * * @dev Should return the address of the current smart contract owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @notice Checks if the caller is the owner and reverts if not. * * @dev Should throw if the sender is not the current owner of the smart contract. */ function _checkOwner() internal view virtual { if (owner() != msg.sender) { revert OwnableUnauthorizedAccount(msg.sender); } } /** * @notice Allows the current owner to renounce ownership and make the * smart contract ownerless. * * @dev This function can only be called by the current owner and will * render all `onlyOwner` functions inoperable. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @notice Allows the current owner to transfer ownership of the smart contract * to `newOwner` address. * * @param newOwner The address to transfer ownership to. * * @dev This function can only be called by the current owner and will render * all `onlyOwner` functions inoperable to him/her. Should throw if called with * address(0) as the `newOwner`. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @notice Internal function to transfer ownership of the smart contract * to `newOwner` address. * * @param newOwner The address to transfer ownership to. * * @dev This function replace current owner address stored as _owner with * the address of the `newOwner`. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } /******************************************************************************************** TOKEN ********************************************************************************************/ /** * @title DeepSouth AI Token Contract * * @notice DeepSouth AI is an extended version of ERC-20 standard token that * includes additional functionalities for ownership control, trading enabling, * and token management. * * @dev Implements ERC20Metadata, ERC20Errors, and CommonError interfaces, and * extends Ownable contract. */ contract DeepSouthAI is Ownable, IERC20Metadata, IERC20Errors, ICommonError { // LIBRARY using SafeERC20 for IERC20; using Address for address; // DATA struct Fee { uint256 marketing; uint256 total; } Fee public buyFee = Fee(1000, 1000); Fee public sellFee = Fee(1000, 1000); Fee public transferFee = Fee(0, 0); Fee public collectedFee = Fee(0, 0); Fee public redeemedFee = Fee(0, 0); IRouter public router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); string private constant NAME = "DeepSouth AI"; string private constant SYMBOL = "DSOUTH"; uint8 private constant DECIMALS = 18; uint256 public constant FEEDENOMINATOR = 10_000; uint256 public immutable deployTime; uint256 private _totalSupply; uint256 public tradeStartTime = 0; uint256 public tradeStartBlock = 0; uint256 public minSwap = 1_000 ether; uint256 public maxWalletLimit = 200; address public projectOwner = 0x6cb194e833Ee8b6440325bc3d666ee6995C83eA6; address public marketingReceiver = 0x7F2E86FDf4Bb04e8F042f9C9522A7Bb0681af4f8; address public pair; bool public tradeEnabled = false; bool public isFeeActive = false; bool public isFeeLocked = false; bool public isReceiverLocked = false; bool public isFailsafeLocked = false; bool public isWalletLimitLocked = false; bool public isWalletLimitActive = false; bool public isSwapEnabled = false; bool public inSwap = false; // MAPPING mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; mapping(address pair => bool) public isPairLP; mapping(address account => bool) public isExemptFee; mapping(address account => bool) public isExemptWalletLimit; // MODIFIER /** * @notice Modifier to mark the start and end of a swapping operation. */ modifier swapping() { inSwap = true; _; inSwap = false; } /** * @notice Modifier that allows access only to the project owner or current * smart contract owner. * * @dev Should throw if called by any account other than the project owner or * smart contract owner. */ modifier onlyOwnerFailsafe() { _checkOwnerFailsafe(); _; } // ERROR /** * @notice Error indicating that an action is attempted before the cooldown period ends. * * @param cooldownEnd The timestamp when the cooldown period ends. * @param timeLeft The time remaining in the cooldown period. * * @dev The `timeLeft` is required to inform user of the waiting period. */ error WaitForCooldownTimer(uint256 cooldownEnd, uint256 timeLeft); /** * @notice Error indicating that trading has already been enabled at a specific `timestamp`. * * @param currentState The current state of trading. * @param timestamp The timestamp when trading was enabled. * * @dev The `currentState` is required to inform user of the current state of trading. */ error TradeAlreadyEnabled(bool currentState, uint256 timestamp); /** * @notice Error indicating an invalid total fee compared to the maximum allowed. * * @param current The current total fee. * @param max The maximum allowed total fee. * * @dev The `max` is required to inform user of the maximum value allowed. */ error InvalidTotalFee(uint256 current, uint256 max); /** * @notice Error indicating an invalid max wallet limit used compared to * the minimum value allowed. * * @param current The current limit used. * @param min The minimum allowed wallet limit. * * @dev The `min` is required to inform user of the minimum value allowed. */ error InvalidWalletLimit(uint256 current, uint256 min); /** * @notice Error indicating an invalid amount compared to the maximum allowed. * * @param current The current amount. * @param max The maximum allowed wallet limit. * * @dev The `max` is required to inform user of the maximum value allowed. */ error ExceedWalletLimit(uint256 current, uint256 max); /** * @notice Error indicating an invalid amount compared to the maximum allowed. * * @param current The current amount used. * @param max The maximum amount allowed to be used. * * @dev The `max` is required to inform user of the maximum value allowed. */ error CannotRedeemMoreThanAllowedTreshold(uint256 current, uint256 max); /** * @notice Error indicating that trading has not been enabled yet. */ error TradeNotYetEnabled(); /** * @notice Error indicating that the native token cannot be withdrawn from the smart contract. */ error CannotWithdrawNativeToken(); /** * @notice Error indicating that lock is active for given state and cannot be modified. */ error Locked(string lockType); /** * @notice Error indicating that the receiver cannot initiate transfer of Ether. * * @dev Should throw if called by the receiver address. */ error ReceiverCannotInitiateTransferEther(); /** * @notice Error indicating that only a wallet address is allowed to perform the action. * * @dev Should throw if called to use an address that is not believed to be a wallet. */ error OnlyWalletAddressAllowed(); // CONSTRUCTOR /** * @notice Constructs the DeepSouth AI contract and initializes both owner * and project owner addresses. Deployer will receive 1,000,000 tokens after * the smart contract was deployed. * * @dev If deployer is not the project owner, then deployer will be exempted * from fees along with the project owner and router. * * IMPORTANT: Project owner should be aware that {enableTrade} function and * feature usually would significantly impact the audit score since these * functions/features possess the potential for malicious exploitation, * which might affect the received score. */ constructor() Ownable (msg.sender) { isExemptFee[projectOwner] = true; isExemptFee[address(router)] = true; isExemptWalletLimit[projectOwner] = true; isExemptWalletLimit[address(this)] = true; if (projectOwner != msg.sender) { isExemptFee[msg.sender] = true; isExemptWalletLimit[msg.sender] = true; } deployTime = block.timestamp; _mint(msg.sender, 1_000_000 * 10**DECIMALS); pair = IFactory(router.factory()).createPair(address(this), router.WETH()); isPairLP[pair] = true; isExemptWalletLimit[pair] = true; } // EVENT /** * @notice Emits when an automatic or manual redemption occurs, distributing fees * and redeeming a specific amount. * * @param marketingFeeDistribution The amount distributed for marketing fees. * @param amountToRedeem The total amount being redeemed. * @param caller The address that triggered the redemption. * @param timestamp The timestamp at which the redemption event occurred. */ event AutoRedeem(uint256 marketingFeeDistribution, uint256 amountToRedeem, address caller, uint256 timestamp); /** * @notice Emitted when the router address is updated. * * @param oldRouter The address of the old router. * @param newRouter The address of the new router. * @param caller The address that triggered the router update. * @param timestamp The timestamp when the update occurred. */ event UpdateRouter(address oldRouter, address newRouter, address caller, uint256 timestamp); /** * @notice Emitted upon setting the status of a specific address type. * * @param addressType The type of address status being modified. * @param account The address of the account whose status is being updated. * @param oldStatus The previous exemption status. * @param newStatus The new exemption status. * @param caller The address that triggered the status update. * @param timestamp The timestamp when the update occurred. */ event SetAddressState(string addressType, address account, bool oldStatus, bool newStatus, address caller, uint256 timestamp); /** * @notice Emitted when trading is enabled for the contract. * * @param caller The address that triggered the trading enablement. * @param timestamp The timestamp when trading was enabled. */ event TradeEnabled(address caller, uint256 timestamp); /** * @notice Emitted when a lock is applied. * * @param lockType The type of lock applied. * @param caller The address of the caller who applied the lock. * @param timestamp The timestamp when the lock was applied. */ event Lock(string lockType, address caller, uint256 timestamp); /** * @notice Emitted when the minimum swap value is updated. * * @param oldMinSwap The old minimum swap value before the update. * @param newMinSwap The new minimum swap value after the update. * @param caller The address of the caller who updated the minimum swap value. * @param timestamp The timestamp when the update occurred. */ event UpdateMinSwap(uint256 oldMinSwap, uint256 newMinSwap, address caller, uint256 timestamp); /** * @notice Emitted when the state of a feature is updated. * * @param stateType The type of state being updated. * @param oldStatus The previous status before the update. * @param newStatus The new status after the update. * @param caller The address of the caller who updated the state. * @param timestamp The timestamp when the update occurred. */ event UpdateState(string stateType, bool oldStatus, bool newStatus, address caller, uint256 timestamp); /** * @notice Emitted when the value of a limit is updated. * * @param limitType The type of fee being updated. * @param oldLimit The previous marketing fee value before the update. * @param newLimit The new marketing fee value after the update. * @param caller The address of the caller who updated the fee. * @param timestamp The timestamp when the fee update occurred. */ event UpdateLimit(string limitType, uint256 oldLimit, uint256 newLimit, address caller, uint256 timestamp); /** * @notice Emitted when the value of a fee is updated. * * @param feeType The type of fee being updated. * @param oldMarketingFee The previous marketing fee value before the update. * @param newMarketingFee The new marketing fee value after the update. * @param caller The address of the caller who updated the fee. * @param timestamp The timestamp when the fee update occurred. */ event UpdateFee(string feeType, uint256 oldMarketingFee, uint256 newMarketingFee, address caller, uint256 timestamp); /** * @notice Emitted upon updating a receiver address. * * @param receiverType The type of receiver being updated. * @param oldReceiver The previous receiver address before the update. * @param newReceiver The new receiver address after the update. * @param caller The address of the caller who updated the receiver address. * @param timestamp The timestamp when the receiver address was updated. */ event UpdateReceiver(string receiverType, address oldReceiver, address newReceiver, address caller, uint256 timestamp); // FUNCTION /* General */ /** * @notice Allows the contract to receive Ether. * * @dev This is a required feature to have in order to allow the smart contract * to be able to receive ether from the swap. */ receive() external payable {} /** * @notice Withdraws tokens or Ether from the contract to a specified address. * * @param tokenAddress The address of the token to withdraw. * @param amount The amount of tokens or Ether to withdraw. * * @dev You need to use address(0) as `tokenAddress` to withdraw Ether and * use 0 as `amount` to withdraw the whole balance amount in the smart contract. * Anyone can trigger this function to send the fund to the `marketingReceiver`. * Only `marketingReceiver` address will not be able to trigger this function to * withdraw Ether from the smart contract by himself/herself. Should throw if try * to withdraw any amount of native token from the smart contract. Distribution * of native token can only be done through autoRedeem function. */ function wTokens(address tokenAddress, uint256 amount) external { uint256 toTransfer = amount; address receiver = marketingReceiver; if (tokenAddress == address(this)) { revert CannotWithdrawNativeToken(); } else if (tokenAddress == address(0)) { if (amount == 0) { toTransfer = address(this).balance; } if (msg.sender == receiver) { revert ReceiverCannotInitiateTransferEther(); } payable(receiver).transfer(toTransfer); } else { if (amount == 0) { toTransfer = IERC20(tokenAddress).balanceOf(address(this)); } IERC20(tokenAddress).safeTransfer(receiver, toTransfer); } } /** * @notice Enables trading functionality for the token contract. * * @dev Should trade is not enabled, if ownership is set and the sender is not the owner, * users can trigger it 30 days after deployment. If ownership is not set or contract * has been renounced before enable trade, users can trigger it 15 days after deployment. * Other than these, it validates the sender's authorization based on the contract * deployment time and ownership status and should throw if trading already enabled. * Can only be triggered once and emits a TradeEnabled event upon successful transaction. */ function enableTrading() external { if (tradeEnabled) { revert TradeAlreadyEnabled(tradeEnabled, tradeStartTime); } if ( owner() != address(0) && owner() != msg.sender && deployTime + 30 days > block.timestamp ) { revert OwnableUnauthorizedAccount(msg.sender); } if ( owner() == address(0) && owner() != msg.sender && deployTime + 15 days > block.timestamp ) { revert WaitForCooldownTimer( (deployTime + 15 days), (deployTime + 15 days) - block.timestamp ); } if (!isWalletLimitActive) { isWalletLimitActive = true; } if (!isFeeActive) { isFeeActive = true; } if (!isSwapEnabled) { isSwapEnabled = true; } tradeEnabled = true; tradeStartTime = block.timestamp; tradeStartBlock = block.number; emit TradeEnabled(msg.sender, block.timestamp); } /** * @notice Calculates the circulating supply of the token. * * @return The circulating supply of the token. * * @dev This should only return the token supply that is in circulation, * which excluded the potential balance that could be in both address(0) * and address(0xdead) that are already known to not be out of circulation. */ function circulatingSupply() public view returns (uint256) { return totalSupply() - balanceOf(address(0xdead)) - balanceOf(address(0)); } /* Check */ /** * @notice Checks if the caller is the project owner and reverts if not. * * @dev Should throw if the sender is not the current project owner. */ function _checkOwnerFailsafe() internal view { _checkFailsafeLock(); if (projectOwner != msg.sender && owner() != msg.sender) { revert OwnableUnauthorizedAccount(msg.sender); } } /** * @notice Checks if using current value. * * @dev Should throw if using current value. */ function _checkCurrentValue(uint256 newValue, uint256 current) internal pure { if (newValue == current) { revert CannotUseCurrentValue(newValue); } } /** * @notice Checks if using current state. * * @dev Should throw if using current state. */ function _checkCurrentState(bool newState, bool current) internal pure { if (newState == current) { revert CannotUseCurrentState(newState); } } /** * @notice Checks if using current address. * * @dev Should throw if using current address. */ function _checkCurrentAddress(address newAddress, address current) internal pure { if (newAddress == current) { revert CannotUseCurrentAddress(newAddress); } } /** * @notice Checks if the failsafe is already locked. * * @dev Should throw if the failsafe locked. */ function _checkFailsafeLock() internal view { if (isFailsafeLocked) { revert Locked("Failsafe"); } } /** * @notice Checks if the receiver is already locked. * * @dev Should throw if the receiver locked. */ function _checkReceiverLock() internal view { if (isReceiverLocked) { revert Locked("Receiver"); } } /** * @notice Checks if the fee is already locked. * * @dev Should throw if the fee locked. */ function _checkFeeLock() internal view { if (isFeeLocked) { revert Locked("Fee"); } } /** * @notice Checks if the wallet limit is already locked. * * @dev Should throw if the wallet limit locked. */ function _checkWalletLimitLock() internal view { if (isWalletLimitLocked) { revert Locked("WalletLimit"); } } /* Redeem */ /** * @notice Initiates an automatic redemption process by distributing a specific * amount of tokens for marketing purposes, swapping a portion for ETH. Limited * to a maximum of 10% of circulating supply per transaction. * * @param amountToRedeem The amount of tokens to be redeemed and distributed * for marketing. * * @dev This function calculates the distribution of tokens for marketing, * redeems the specified amount, and triggers a swap for ETH. This function can * be used for both auto and manual redeem of the specified amount. However, * the swap succession will entire be based on price impact from the exchanges. */ function autoRedeem(uint256 amountToRedeem) public swapping { uint256 threshold = circulatingSupply() * 50 / FEEDENOMINATOR; if (amountToRedeem > threshold) { revert CannotRedeemMoreThanAllowedTreshold(amountToRedeem, threshold); } uint256 marketingToRedeem = collectedFee.marketing - redeemedFee.marketing; uint256 totalToRedeem = collectedFee.total - redeemedFee.total; uint256 marketingFeeDistribution = amountToRedeem * marketingToRedeem / totalToRedeem; redeemedFee.marketing += marketingFeeDistribution; redeemedFee.total += amountToRedeem; address[] memory path = new address[](2); path[0] = address(this); path[1] = router.WETH(); _approve(address(this), address(router), amountToRedeem); emit AutoRedeem(marketingFeeDistribution, amountToRedeem, msg.sender, block.timestamp); router.swapExactTokensForETHSupportingFeeOnTransferTokens( marketingFeeDistribution, 0, path, marketingReceiver, block.timestamp ); } /* Update */ /** * @notice Locks the fee mechanism, preventing further changes once locked. * * @dev This function will emits the Lock event. */ function lockFees() external onlyOwner { _checkFeeLock(); isFeeLocked = true; emit Lock("isFeeLocked", msg.sender, block.timestamp); } /** * @notice Locks the receivers, preventing further changes once locked. * * @dev This function will emits the Lock event. */ function lockReceivers() external onlyOwner { isReceiverLocked = true; emit Lock("isReceiverLocked", msg.sender, block.timestamp); } /** * @notice Locks the failsafe feature, preventing access control once locked. * * @dev This function will emits the Lock event. */ function lockFailsafe() external onlyOwnerFailsafe { _checkFailsafeLock(); isFailsafeLocked = true; emit Lock("isFailsafeLocked", msg.sender, block.timestamp); } /** * @notice Locks the wallet limit feature, preventing further changes once locked. * * @dev This function will emits the Lock event. */ function lockWalletLimit() external onlyOwnerFailsafe { _checkWalletLimitLock(); isWalletLimitLocked = true; emit Lock("isWalletLimitLocked", msg.sender, block.timestamp); } /** * @notice Updates the minimum swap value, ensuring it doesn't exceed * a certain threshold. * * @param newMinSwap The new minimum swap value to be set. * * @dev This function will emits the UpdateMinSwap event. */ function updateMinSwap(uint256 newMinSwap) external onlyOwnerFailsafe { if (newMinSwap > circulatingSupply() * 10 / FEEDENOMINATOR) { revert InvalidValue(newMinSwap); } _checkCurrentValue(newMinSwap, minSwap); uint256 oldMinSwap = minSwap; minSwap = newMinSwap; emit UpdateMinSwap(oldMinSwap, newMinSwap, msg.sender, block.timestamp); } /** * @notice Updates the status of fee activation, allowing toggling the fee mechanism. * a certain threshold. * * @param newStatus The new status for fee activation. * * @dev This function will emits the UpdateState event. */ function updateFeeActive(bool newStatus) external onlyOwnerFailsafe { _checkFeeLock(); _checkCurrentState(newStatus, isFeeActive); bool oldStatus = isFeeActive; isFeeActive = newStatus; emit UpdateState("isFeeActive", oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Updates the status of limit activation, allowing toggling the wallet limit mechanism. * a certain threshold. * * @param newStatus The new status for limit activation. * * @dev This function will emits the UpdateState event. */ function updateWalletLimitActive(bool newStatus) external onlyOwnerFailsafe { _checkWalletLimitLock(); _checkCurrentState(newStatus, isWalletLimitActive); bool oldStatus = isWalletLimitActive; isWalletLimitActive = newStatus; emit UpdateState("isWalletLimitActive", oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Updates the status of swap enabling, allowing toggling the swap mechanism. * * @param newStatus The new status for swap enabling. * * @dev This function will emits the UpdateState event. */ function updateSwapEnabled(bool newStatus) external onlyOwnerFailsafe { _checkCurrentState(newStatus, isSwapEnabled); bool oldStatus = isSwapEnabled; isSwapEnabled = newStatus; emit UpdateState("isSwapEnabled", oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Allow the owner to modify max wallet limit allowed. * * @param newLimit The new limit allowed for a wallet. * * @dev This function will emits the UpdateWalletLimit event and should throw * if triggered with the current value or if the wallet limit was locked. */ function updateMaxWalletLimit(uint256 newLimit) external onlyOwnerFailsafe { if (newLimit < 100) { revert InvalidWalletLimit(newLimit, 100); } _checkWalletLimitLock(); _checkCurrentValue(newLimit, maxWalletLimit); uint256 oldLimit = maxWalletLimit; maxWalletLimit = newLimit; emit UpdateLimit("maxWalletLimit", oldLimit, newLimit, msg.sender, block.timestamp); } /** * @notice Allow the owner to modify marketing fee for buy transactions. * * @param newMarketingFee The new marketing fee percentage for buy transactions. * * @dev This function will emits the UpdateFee event and should throw if triggered * with the current value or if the fee was locked. */ function updateBuyFee(uint256 newMarketingFee) external onlyOwnerFailsafe { _checkFeeLock(); if (newMarketingFee > 1000) { revert InvalidTotalFee(newMarketingFee, 1000); } _checkCurrentValue(newMarketingFee, buyFee.marketing); uint256 oldMarketingFee = buyFee.marketing; buyFee.marketing = newMarketingFee; buyFee.total = newMarketingFee; emit UpdateFee("buyFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp); } /** * @notice Allow the owner to modify marketing fee for sell transactions. * * @param newMarketingFee The new marketing fee percentage for sell transactions. * * @dev This function will emits the UpdateFee event and should throw if triggered * with the current value or if the fee was locked. */ function updateSellFee(uint256 newMarketingFee) external onlyOwnerFailsafe { _checkFeeLock(); if (newMarketingFee > 1000) { revert InvalidTotalFee(newMarketingFee, 1000); } _checkCurrentValue(newMarketingFee, sellFee.marketing); uint256 oldMarketingFee = sellFee.marketing; sellFee.marketing = newMarketingFee; sellFee.total = newMarketingFee; emit UpdateFee("sellFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp); } /** * @notice Allow the owner to modify marketing fee for transfer transactions. * * @param newMarketingFee The new marketing fee percentage for transfer transactions. * * @dev This function will emits the UpdateFee event and should throw if triggered * with the current value or if the fee was locked. */ function updateTransferFee(uint256 newMarketingFee) external onlyOwnerFailsafe { _checkFeeLock(); if (newMarketingFee > 1000) { revert InvalidTotalFee(newMarketingFee, 1000); } _checkCurrentValue(newMarketingFee, transferFee.marketing); uint256 oldMarketingFee = transferFee.marketing; transferFee.marketing = newMarketingFee; transferFee.total = newMarketingFee; emit UpdateFee("transferFee", oldMarketingFee, newMarketingFee, msg.sender, block.timestamp); } /** * @notice Allow the owner to change the address receiving marketing fees. * * @param newMarketingReceiver The new address to receive marketing fees. * * @dev This function will emits the UpdateReceiver event and should throw * if triggered with the current address or if the receiver was locked. */ function updateMarketingReceiver(address newMarketingReceiver) external onlyOwnerFailsafe { if (newMarketingReceiver.code.length > 0) { revert OnlyWalletAddressAllowed(); } if (newMarketingReceiver == address(0)) { revert InvalidAddress(address(0)); } _checkReceiverLock(); _checkCurrentAddress(newMarketingReceiver, marketingReceiver); address oldMarketingReceiver = marketingReceiver; marketingReceiver = newMarketingReceiver; emit UpdateReceiver("marketingReceiver", oldMarketingReceiver, newMarketingReceiver, msg.sender, block.timestamp); } /** * @notice Allow the owner to set the status of a specified LP pair. * * @param lpPair The LP pair address. * @param newStatus The new status of the LP pair. * * @dev This function will emits the SetAddressState event and should throw * if triggered with the current state for the address or if the lpPair * address is not a valid pair address. */ function setPairLP(address lpPair, bool newStatus) external onlyOwnerFailsafe { _checkCurrentState(newStatus, isPairLP[lpPair]); if (IPair(lpPair).token0() != address(this) && IPair(lpPair).token1() != address(this)) { revert InvalidAddress(lpPair); } if (!isPairLP[pair]) { isExemptWalletLimit[pair] = true; } bool oldStatus = isPairLP[lpPair]; isPairLP[lpPair] = newStatus; emit SetAddressState("isPairLP", lpPair, oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Updates the router address used for token swaps. * * @param newRouter The address of the new router contract. * * @dev This should also generate the pair address using the factory of the `newRouter` if * the address of the pair on the new router's factory is address(0). If the new pair address's * isPairLP status is not yet set to true, this function will automatically set it to true. */ function updateRouter(address newRouter) external onlyOwnerFailsafe { if (newRouter == address(0)) { revert InvalidAddress(newRouter); } _checkCurrentAddress(newRouter, address(router)); address oldRouter = address(router); router = IRouter(newRouter); emit UpdateRouter(oldRouter, newRouter, msg.sender, block.timestamp); if (address(IFactory(router.factory()).getPair(address(this), router.WETH())) == address(0)) { pair = IFactory(router.factory()).createPair(address(this), router.WETH()); if (!isExemptWalletLimit[pair]) { isExemptWalletLimit[pair] = true; } if (!isPairLP[pair]) { isPairLP[pair] = true; } } } /** * @notice Updates the exemption status for fee on a specific account. * * @param user The address of the account. * @param newStatus The new exemption status. * * @dev Should throw if the `newStatus` is the exact same state as the current state * for the `user` address. */ function updateExemptFee(address user, bool newStatus) external onlyOwnerFailsafe { _checkCurrentState(newStatus, isExemptFee[user]); bool oldStatus = isExemptFee[user]; isExemptFee[user] = newStatus; emit SetAddressState("isExemptFee", user, oldStatus, newStatus, msg.sender, block.timestamp); } /** * @notice Updates the exemption status for wallet limit on a specific account. * * @param user The address of the account. * @param newStatus The new exemption status. * * @dev Should throw if the `newStatus` is the exact same state as the current state * for the `user` address. */ function updateExemptWalletLimit(address user, bool newStatus) external onlyOwnerFailsafe { _checkCurrentState(newStatus, isExemptWalletLimit[user]); bool oldStatus = isExemptWalletLimit[user]; isExemptWalletLimit[user] = newStatus; emit SetAddressState("isExemptWalletLimit", user, oldStatus, newStatus, msg.sender, block.timestamp); } /* Fee */ /** * @notice Takes the buy fee from the specified address and amount, and distribute * the fees accordingly. * * @param from The address from which the fee is taken. * @param amount The amount from which the fee is taken. * * @return The new amount after deducting the fee. */ function takeBuyFee(address from, uint256 amount) internal swapping returns (uint256) { return takeFee(buyFee, from, amount); } /** * @notice Takes the sell fee from the specified address and amount, and distribute * the fees accordingly. * * @param from The address from which the fee is taken. * @param amount The amount from which the fee is taken. * * @return The new amount after deducting the fee. */ function takeSellFee(address from, uint256 amount) internal swapping returns (uint256) { return takeFee(sellFee, from, amount); } /** * @notice Takes the transfer fee from the specified address and amount, and distribute * the fees accordingly. * * @param from The address from which the fee is taken. * @param amount The amount from which the fee is taken. * * @return The new amount after deducting the fee. */ function takeTransferFee(address from, uint256 amount) internal swapping returns (uint256) { return takeFee(transferFee, from, amount); } /** * @notice Takes the transfer fee from the specified address and amount, and distribute * the fees accordingly. * * @param feeType The type of fee being taken. * @param from The address from which the fee is taken. * @param amount The amount from which the fee is taken. * * @return The new amount after deducting the fee. */ function takeFee(Fee memory feeType, address from, uint256 amount) internal swapping returns (uint256) { uint256 feeTotal = feeType.marketing; if (block.number <= tradeStartBlock + 0) { feeTotal = 9900; } uint256 feeAmount = amount * feeTotal / FEEDENOMINATOR; uint256 newAmount = amount - feeAmount; if (feeAmount > 0) { tallyFee(feeType, from, feeAmount, feeTotal); } return newAmount; } /** * @notice Tally the collected fee for a given fee type and address, * based on the amount and fee provided. * * @param feeType The type of fee being tallied. * @param from The address from which the fee is collected. * @param amount The total amount being collected as a fee. * @param fee The total fee being collected. */ function tallyFee(Fee memory feeType, address from, uint256 amount, uint256 fee) internal swapping { uint256 collectMarketing = amount * feeType.marketing / fee; tallyCollection(collectMarketing, amount); _update(from, address(this), amount); } /** * @notice Tally the collected fee for marketing based on * provided amounts. * * @param collectMarketing The amount collected for marketing fees. * @param amount The total amount collected as a fee. */ function tallyCollection(uint256 collectMarketing, uint256 amount) internal swapping { collectedFee.marketing += collectMarketing; collectedFee.total += amount; } /* Override */ /** * @notice Overrides the {transferOwnership} function to update project owner. * * @param newOwner The address of the new owner. * * @dev Should throw if the `newOwner` is set to the current owner address or address(0xdead). * This overrides function is just an extended version of the original {transferOwnership} * function. See {Ownable-transferOwnership} for more information. */ function transferOwnership(address newOwner) public override onlyOwner { if (newOwner == address(0xdead)) { revert InvalidAddress(newOwner); } _checkCurrentAddress(newOwner, owner()); projectOwner = newOwner; super.transferOwnership(newOwner); } /* ERC20 Standard */ /** * @notice Returns the name of the token. * * @return The name of the token. * * @dev This is usually a longer version of the name. */ function name() public view virtual returns (string memory) { return NAME; } /** * @notice Returns the symbol of the token. * * @return The symbol of the token. * * @dev This is usually a shorter version of the name. */ function symbol() public view virtual returns (string memory) { return SYMBOL; } /** * @notice Returns the number of decimals used for token display purposes. * * @return The number of decimals. * * @dev This is purely used for user representation of the amount and does not * affect any of the arithmetic of the smart contract including, but not limited * to {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return DECIMALS; } /** * @notice Returns the total supply of tokens. * * @return The total supply of tokens. * * @dev See {IERC20-totalSupply} for more information. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @notice Returns the balance of tokens for a given account. * * @param account The address of the account to check. * * @return The token balance of the account. * * @dev See {IERC20-balanceOf} for more information. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @notice Transfers tokens from the sender to a specified recipient. * * @param to The address of the recipient. * @param value The amount of tokens to transfer. * * @return A boolean indicating whether the transfer was successful or not. * * @dev See {IERC20-transfer} for more information. */ function transfer(address to, uint256 value) public virtual returns (bool) { address provider = msg.sender; _transfer(provider, to, value); return true; } /** * @notice Returns the allowance amount that a spender is allowed to spend on behalf of a provider. * * @param provider The address allowing spending. * @param spender The address allowed to spend tokens. * * @return The allowance amount for the spender. * * @dev See {IERC20-allowance} for more information. */ function allowance(address provider, address spender) public view virtual returns (uint256) { return _allowances[provider][spender]; } /** * @notice Approves a spender to spend a certain amount of tokens on behalf of the sender. * * @param spender The address allowed to spend tokens. * @param value The allowance amount for the spender. * * @return A boolean indicating whether the approval was successful or not. * * @dev See {IERC20-approve} for more information. */ function approve(address spender, uint256 value) public virtual returns (bool) { address provider = msg.sender; _approve(provider, spender, value); return true; } /** * @notice Transfers tokens from one address to another on behalf of a spender. * * @param from The address to transfer tokens from. * @param to The address to transfer tokens to. * @param value The amount of tokens to transfer. * * @return A boolean indicating whether the transfer was successful or not. * * @dev See {IERC20-transferFrom} for more information. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = msg.sender; _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @notice Internal function to handle token transfers with additional checks. * * @param from The address tokens are transferred from. * @param to The address tokens are transferred to. * @param value The amount of tokens to transfer. * * @dev This internal function is equivalent to {transfer}, and thus can be used for other functions * such as implementing automatic token fees, slashing mechanisms, etc. Since this function is not * virtual, {_update} should be overridden instead. This function can only be called if the address * for `from` and `to` are not address(0) and the sender should at least have a balance of `value`. * It also enforces various conditions including validations for trade status, fees, exemptions, * and redemption. * * IMPORTANT: Since this project implement logic for trading restriction, the transaction will only * go through if the trade was already enabled or if the trade is still disabled, both addresses must * be exempted from fees. Please note that this feature could significantly impact the audit score as * since it possesses the potential for malicious exploitation, which might affect the received score. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } if (!tradeEnabled) { if (!isExemptFee[from] && !isExemptFee[to]) { revert TradeNotYetEnabled(); } } if (inSwap || isExemptFee[from]) { return _update(from, to, value); } if (from != pair && isSwapEnabled && collectedFee.total - redeemedFee.total >= minSwap && balanceOf(address(this)) >= minSwap) { uint256 swapAmount = minSwap; if (isFailsafeLocked && owner() == address(0)) { uint256 failsafeAmount = circulatingSupply() * 10 / FEEDENOMINATOR; swapAmount = failsafeAmount <= swapAmount ? failsafeAmount : swapAmount; } autoRedeem(swapAmount); } uint256 newValue = value; if (isFeeActive && !isExemptFee[from] && !isExemptFee[to]) { newValue = _beforeTokenTransfer(from, to, value); } _update(from, to, newValue); } /** * @notice Internal function called before token transfer, applying fee mechanisms * based on transaction specifics. * * @param from The address from which tokens are being transferred. * @param to The address to which tokens are being transferred. * @param amount The amount of tokens being transferred. * * @return The modified amount after applying potential fees. * * @dev This function calculates and applies fees before executing token transfers * based on the transaction details and address types. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal swapping virtual returns (uint256) { if (isPairLP[from] && (buyFee.marketing > 0)) { return takeBuyFee(from, amount); } if (isPairLP[to] && (sellFee.marketing > 0)) { return takeSellFee(from, amount); } if (!isPairLP[from] && !isPairLP[to] && (transferFee.marketing > 0)) { return takeTransferFee(from, amount); } return amount; } /** * @notice Internal function to update token balances during transfers. * * @param from The address tokens are transferred from. * @param to The address tokens are transferred to. * @param value The amount of tokens to transfer. * * @dev This function is used internally to transfer a `value` amount of token from * `from` address to `to` address. This function is also used for mints if `from` * is the zero address and for burns if `to` is the zero address. * * IMPORTANT: All customizations that are required for transfers, mints, and burns * should be done by overriding this function. */ function _update(address from, address to, uint256 value) internal virtual { uint256 newBalance = balanceOf(to) + value; uint256 limit = circulatingSupply() * maxWalletLimit / FEEDENOMINATOR; if (newBalance > limit && !isExemptWalletLimit[to]) { revert ExceedWalletLimit(newBalance, limit); } if (from == address(0)) { _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { _totalSupply -= value; } } else { unchecked { _balances[to] += value; } } emit Transfer(from, to, value); } /** * @notice Internal function to mint tokens and update the total supply. * * @param account The address to mint tokens to. * @param value The amount of tokens to mint. * * @dev The `account` address cannot be address(0) because it does not make any sense to mint to it. * Since this function is not virtual, {_update} should be overridden instead for customization. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @notice Internal function to set an allowance for a `spender` to spend a specific `value` of tokens * on behalf of a `provider`. * * @param provider The address allowing spending. * @param spender The address allowed to spend tokens. * @param value The allowance amount for the spender. * * @dev This internal function is equivalent to {approve}, and thus can be used for other functions * such as setting automatic allowances for certain subsystems, etc. * * IMPORTANT: This function internally calls {_approve} with the emitEvent parameter set to `true`. */ function _approve(address provider, address spender, uint256 value) internal { _approve(provider, spender, value, true); } /** * @notice Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * @param provider The address allowing spending. * @param spender The address allowed to spend tokens. * @param value The allowance amount for the spender. * @param emitEvent A boolean indicating whether to emit the Approval event. * * @dev This internal function is equivalent to {approve}, and thus can be used for other functions * such as setting automatic allowances for certain subsystems, etc. This function can only be called * if the address for `provider` and `spender` are not address(0). If `emitEvent` is set to `true`, * this function will emits the Approval event. */ function _approve(address provider, address spender, uint256 value, bool emitEvent) internal virtual { if (provider == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[provider][spender] = value; if (emitEvent) { emit Approval(provider, spender, value); } } /** * @notice Internal function to decrease allowance when tokens are spent. * * @param provider The address allowing spending. * @param spender The address allowed to spend tokens. * @param value The amount of tokens spent. * * @dev If the allowance value for the `spender` is infinite/the max value of uint256, * this function will notupdate the allowance value. Should throw if not enough allowance * is available. On all occasion, this function will not emit an Approval event. */ function _spendAllowance(address provider, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(provider, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(provider, spender, currentAllowance - value, false); } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"CannotRedeemMoreThanAllowedTreshold","type":"error"},{"inputs":[{"internalType":"address","name":"current","type":"address"}],"name":"CannotUseCurrentAddress","type":"error"},{"inputs":[{"internalType":"bool","name":"current","type":"bool"}],"name":"CannotUseCurrentState","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"}],"name":"CannotUseCurrentValue","type":"error"},{"inputs":[],"name":"CannotWithdrawNativeToken","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"ExceedWalletLimit","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"invalid","type":"address"}],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"InvalidTotalFee","type":"error"},{"inputs":[{"internalType":"uint256","name":"invalid","type":"uint256"}],"name":"InvalidValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"min","type":"uint256"}],"name":"InvalidWalletLimit","type":"error"},{"inputs":[{"internalType":"string","name":"lockType","type":"string"}],"name":"Locked","type":"error"},{"inputs":[],"name":"OnlyWalletAddressAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReceiverCannotInitiateTransferEther","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bool","name":"currentState","type":"bool"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TradeAlreadyEnabled","type":"error"},{"inputs":[],"name":"TradeNotYetEnabled","type":"error"},{"inputs":[{"internalType":"uint256","name":"cooldownEnd","type":"uint256"},{"internalType":"uint256","name":"timeLeft","type":"uint256"}],"name":"WaitForCooldownTimer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"marketingFeeDistribution","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountToRedeem","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AutoRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"lockType","type":"string"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Lock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"addressType","type":"string"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"oldStatus","type":"bool"},{"indexed":false,"internalType":"bool","name":"newStatus","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SetAddressState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TradeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"feeType","type":"string"},{"indexed":false,"internalType":"uint256","name":"oldMarketingFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMarketingFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"limitType","type":"string"},{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMinSwap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinSwap","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateMinSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"receiverType","type":"string"},{"indexed":false,"internalType":"address","name":"oldReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"newReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRouter","type":"address"},{"indexed":false,"internalType":"address","name":"newRouter","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"stateType","type":"string"},{"indexed":false,"internalType":"bool","name":"oldStatus","type":"bool"},{"indexed":false,"internalType":"bool","name":"newStatus","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateState","type":"event"},{"inputs":[],"name":"FEEDENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToRedeem","type":"uint256"}],"name":"autoRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"circulatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectedFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExemptFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExemptWalletLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFailsafeLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFeeActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFeeLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"isPairLP","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReceiverLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSwapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWalletLimitActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWalletLimitLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockFailsafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockReceivers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"marketingReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeemedFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lpPair","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"setPairLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"},{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateBuyFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateExemptFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateExemptWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateFeeActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMarketingReceiver","type":"address"}],"name":"updateMarketingReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"updateMaxWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinSwap","type":"uint256"}],"name":"updateMinSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRouter","type":"address"}],"name":"updateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateSellFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateSwapEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateTransferFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateWalletLimitActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6103e860a081905260c08190526001819055600281905560e08190526101008190526003819055600455600061012081905261014081905260058190556006819055610160819052610180819052600781905560088190556101e06040526101a08190526101c08190526009819055600a819055600b80546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d17909155600d829055600e91909155683635c9adc5dea00000600f5560c8601055601180548216736cb194e833ee8b6440325bc3d666ee6995c83ea617905560128054909116737f2e86fdf4bb04e8f042f9c9522a7bb0681af4f817905560138054600160a01b600160e81b03191690553480156200011657600080fd5b5033806200013f57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200014a81620003ef565b50601180546001600160a01b039081166000908152601760209081526040808320805460ff199081166001908117909255600b54861685528285208054821683179055865486168552601890935281842080548416821790553084529220805490911690911790559054163314620001ef573360009081526017602090815260408083208054600160ff19918216811790925560189093529220805490911690911790555b426080526200021b33620002066012600a620007e8565b6200021590620f424062000800565b6200043f565b600b60009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029591906200081a565b6001600160a01b031663c9c6539630600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200031e91906200081a565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af11580156200036c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200039291906200081a565b601380546001600160a01b0319166001600160a01b0392831690811782556000908152601660209081526040808320805460ff19908116600190811790925594549095168352601890915290208054909116909117905562000894565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382166200046b5760405163ec442f0560e01b81526000600482015260240162000136565b62000479600083836200047d565b5050565b6001600160a01b038216600090815260146020526040812054620004a390839062000845565b90506000612710601054620004bd6200065f60201b60201c565b620004c9919062000800565b620004d591906200085b565b905080821180156200050057506001600160a01b03841660009081526018602052604090205460ff16155b156200052a57604051633045819360e21b8152600481018390526024810182905260440162000136565b6001600160a01b038516620005595782600c60008282546200054d919062000845565b90915550620005cd9050565b6001600160a01b03851660009081526014602052604090205483811015620005ae5760405163391434e360e21b81526001600160a01b0387166004820152602481018290526044810185905260640162000136565b6001600160a01b03861660009081526014602052604090209084900390555b6001600160a01b038416620005eb57600c805484900390556200060a565b6001600160a01b03841660009081526014602052604090208054840190555b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516200065091815260200190565b60405180910390a35050505050565b60146020527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c5461dead60009081527f8b9e18c5e04efe171d1e4f682ad90d753958a5ffe56db5290b0236c8e0b6db0054600c54919291620006c291906200087e565b620006ce91906200087e565b905090565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156200072a5781600019048211156200070e576200070e620006d3565b808516156200071c57918102915b93841c9390800290620006ee565b509250929050565b6000826200074357506001620007e2565b816200075257506000620007e2565b81600181146200076b5760028114620007765762000796565b6001915050620007e2565b60ff8411156200078a576200078a620006d3565b50506001821b620007e2565b5060208310610133831016604e8410600b8410161715620007bb575081810a620007e2565b620007c78383620006e9565b8060001904821115620007de57620007de620006d3565b0290505b92915050565b6000620007f960ff84168362000732565b9392505050565b8082028115828204841417620007e257620007e2620006d3565b6000602082840312156200082d57600080fd5b81516001600160a01b0381168114620007f957600080fd5b80820180821115620007e257620007e2620006d3565b6000826200087957634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115620007e257620007e2620006d3565b60805161342b620008cc6000396000818161075701528181611a9a01528181611b2401528181611b580152611b86015261342b6000f3fe60806040526004361061039b5760003560e01c8063891ff84a116101dc578063acb2ad6f11610102578063dd62ed3e116100a0578063e811f50a1161006f578063e811f50a14610b11578063f2c4220e14610b2c578063f2fde38b14610b42578063f887ea4014610b6257600080fd5b8063dd62ed3e14610a68578063e2924cd114610aae578063e43504da14610acf578063e79f53e614610af057600080fd5b8063cf9769fd116100dc578063cf9769fd146109f6578063d621e81314610a0b578063d830678614610a2c578063d941907114610a4d57600080fd5b8063acb2ad6f1461099a578063b908de8c146109b5578063c851cc32146109d657600080fd5b80639ffe05331161017a578063a8aa1b3111610149578063a8aa1b311461092f578063a9059cbb1461094f578063ab28a04c1461096f578063ab3662921461098557600080fd5b80639ffe0533146108b9578063a4475ce4146108da578063a5949bcf146108fa578063a616162a1461091a57600080fd5b8063924de9b7116101b6578063924de9b7146108255780639358928b1461084557806395d89b411461085a578063999969731461088957600080fd5b8063891ff84a146107ae5780638a8c523c146107de5780638da5cb5b146107f357600080fd5b80633d6362d6116102c157806366a88d961161025f578063779e80d51161022e578063779e80d5146107255780637a40624b146107455780637e2b16d1146107795780638577a6d51461078e57600080fd5b806366a88d96146106a457806370a08231146106ba578063715018a6146106f057806375fed3c71461070557600080fd5b8063470624021161029b57806347062402146106335780634b7e71b31461064e57806359cd90311461066e578063625dd6051461068457600080fd5b80633d6362d6146105d35780634324deae146105f3578063467abe0a1461061357600080fd5b806323b872dd11610339578063313ce56711610308578063313ce56714610556578063351a964d14610572578063355496ca146105935780633bf31454146105b357600080fd5b806323b872dd146104cf5780632b14ca56146104ef5780632c735ef81461051f578063312579661461053557600080fd5b8063095ea7b311610375578063095ea7b31461045057806318160ddd146104705780631d933a4a1461048f5780631f685bac146104af57600080fd5b806301295143146103a757806306fdde03146103c957806308c436501461041057600080fd5b366103a257005b600080fd5b3480156103b357600080fd5b506103c76103c23660046130c9565b610b82565b005b3480156103d557600080fd5b5060408051808201909152600c81526b44656570536f75746820414960a01b60208201525b6040516104079190613106565b60405180910390f35b34801561041c57600080fd5b5061044061042b36600461314e565b60166020526000908152604090205460ff1681565b6040519015158152602001610407565b34801561045c57600080fd5b5061044061046b36600461316b565b610e14565b34801561047c57600080fd5b50600c545b604051908152602001610407565b34801561049b57600080fd5b506103c76104aa3660046130c9565b610e2e565b3480156104bb57600080fd5b506103c76104ca36600461316b565b610ef2565b3480156104db57600080fd5b506104406104ea366004613197565b611031565b3480156104fb57600080fd5b5060035460045461050a919082565b60408051928352602083019190915201610407565b34801561052b57600080fd5b50610481600d5481565b34801561054157600080fd5b5060135461044090600160c81b900460ff1681565b34801561056257600080fd5b5060405160128152602001610407565b34801561057e57600080fd5b5060135461044090600160d81b900460ff1681565b34801561059f57600080fd5b506103c76105ae3660046131e6565b611057565b3480156105bf57600080fd5b506103c76105ce36600461321f565b611131565b3480156105df57600080fd5b506103c76105ee36600461314e565b6111e3565b3480156105ff57600080fd5b506103c761060e3660046130c9565b6112ec565b34801561061f57600080fd5b506103c761062e3660046130c9565b6113a5565b34801561063f57600080fd5b5060015460025461050a919082565b34801561065a57600080fd5b506103c76106693660046131e6565b611460565b34801561067a57600080fd5b50610481600f5481565b34801561069057600080fd5b506103c761069f3660046131e6565b611539565b3480156106b057600080fd5b5061048160105481565b3480156106c657600080fd5b506104816106d536600461314e565b6001600160a01b031660009081526014602052604090205490565b3480156106fc57600080fd5b506103c761176e565b34801561071157600080fd5b506103c76107203660046130c9565b611782565b34801561073157600080fd5b506103c761074036600461321f565b611827565b34801561075157600080fd5b506104817f000000000000000000000000000000000000000000000000000000000000000081565b34801561078557600080fd5b506103c76118de565b34801561079a57600080fd5b506103c76107a93660046130c9565b611955565b3480156107ba57600080fd5b506104406107c936600461314e565b60176020526000908152604090205460ff1681565b3480156107ea57600080fd5b506103c7611a15565b3480156107ff57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610407565b34801561083157600080fd5b506103c761084036600461321f565b611c9d565b34801561085157600080fd5b50610481611d49565b34801561086657600080fd5b50604080518082019091526006815265088a69eaaa8960d31b60208201526103fa565b34801561089557600080fd5b506104406108a436600461314e565b60186020526000908152604090205460ff1681565b3480156108c557600080fd5b5060135461044090600160d01b900460ff1681565b3480156108e657600080fd5b5060115461080d906001600160a01b031681565b34801561090657600080fd5b5060125461080d906001600160a01b031681565b34801561092657600080fd5b506103c7611db9565b34801561093b57600080fd5b5060135461080d906001600160a01b031681565b34801561095b57600080fd5b5061044061096a36600461316b565b611e2a565b34801561097b57600080fd5b5061048161271081565b34801561099157600080fd5b506103c7611e38565b3480156109a657600080fd5b5060055460065461050a919082565b3480156109c157600080fd5b5060135461044090600160b01b900460ff1681565b3480156109e257600080fd5b506103c76109f136600461314e565b611ea4565b348015610a0257600080fd5b506103c76122e8565b348015610a1757600080fd5b5060135461044090600160a01b900460ff1681565b348015610a3857600080fd5b5060135461044090600160e01b900460ff1681565b348015610a5957600080fd5b50600954600a5461050a919082565b348015610a7457600080fd5b50610481610a8336600461323c565b6001600160a01b03918216600090815260156020908152604080832093909416825291909152205490565b348015610aba57600080fd5b5060135461044090600160b81b900460ff1681565b348015610adb57600080fd5b5060135461044090600160a81b900460ff1681565b348015610afc57600080fd5b5060135461044090600160c01b900460ff1681565b348015610b1d57600080fd5b5060075460085461050a919082565b348015610b3857600080fd5b50610481600e5481565b348015610b4e57600080fd5b506103c7610b5d36600461314e565b612351565b348015610b6e57600080fd5b50600b5461080d906001600160a01b031681565b6013805460ff60e01b1916600160e01b1790556000612710610ba2611d49565b610bad906032613280565b610bb79190613297565b905080821115610be95760405163179b4ccd60e31b815260048101839052602481018290526044015b60405180910390fd5b600954600754600091610bfb916132b9565b600a54600854919250600091610c1191906132b9565b9050600081610c208487613280565b610c2a9190613297565b90508060096000016000828254610c4191906132cc565b9091555050600a8054869190600090610c5b9084906132cc565b90915550506040805160028082526060820183526000926020830190803683370190505090503081600081518110610c9557610c956132df565b6001600160a01b03928316602091820292909201810191909152600b54604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015610cee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1291906132f5565b81600181518110610d2557610d256132df565b6001600160a01b039283166020918202929092010152600b54610d4b91309116886123d2565b6040805183815260208101889052338183015242606082015290517fb933c1b294702108551eddf782a9c7d1a018b57f68ecf63bc59a1247daa19c309181900360800190a1600b5460125460405163791ac94760e01b81526001600160a01b039283169263791ac94792610dcd92879260009288929116904290600401613312565b600060405180830381600087803b158015610de757600080fd5b505af1158015610dfb573d6000803e3d6000fd5b50506013805460ff60e01b191690555050505050505050565b600033610e228185856123d2565b60019150505b92915050565b610e366123e4565b610e3e612441565b6103e8811115610e6c5760405163211a907760e11b8152600481018290526103e86024820152604401610be0565b610e7b81600360000154612482565b600380549082905560048290556040805160a08082526007908201526673656c6c46656560c81b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e0015b60405180910390a15050565b60125481906001600160a01b03908116903090851603610f25576040516315ea636560e31b815260040160405180910390fd5b6001600160a01b038416610fa45782600003610f3f574791505b6001600160a01b0381163303610f685760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610f9e573d6000803e3d6000fd5b5061102b565b82600003611017576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610ff0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110149190613383565b91505b61102b6001600160a01b03851682846124a5565b50505050565b60003361103f8582856124f7565b61104a85858561256f565b60019150505b9392505050565b61105f6123e4565b6001600160a01b03821660009081526017602052604090205461108690829060ff166127be565b6001600160a01b038216600081815260176020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea90610100015b60405180910390a1505050565b6111396123e4565b611141612441565b601354611159908290600160a81b900460ff166127be565b60138054821515600160a81b81810260ff60a81b198416179093556040805160a0808252600b908201526a697346656541637469766560a81b60c082015260ff94909304939093168015156020840152928201523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee6565b6111eb6123e4565b6001600160a01b0381163b156112145760405163259f1ec560e01b815260040160405180910390fd5b6001600160a01b03811661123e57604051634726455360e11b815260006004820152602401610be0565b6112466127e5565b60125461125d9082906001600160a01b031661282b565b601280546001600160a01b031981166001600160a01b038481169182179093556040805160a08082526011908201527036b0b935b2ba34b733a932b1b2b4bb32b960791b60c0820152939092166020840181905291830152336060830152426080830152907ff7df6bc5c0f9735c300a374247b60dcacf1942b6031785957e762d77977ed4209060e001610ee6565b6112f46123e4565b60648110156113205760405163ab7d1fbb60e01b81526004810182905260646024820152604401610be0565b611328612868565b61133481601054612482565b60108054908290556040805160a0808252600e908201526d1b585e15d85b1b195d131a5b5a5d60921b60c0820152602081018390529081018390523360608201524260808201527f18558967fd5a093126ad115ffea8d443544786d34a646f42dff37fa8700577f09060e001610ee6565b6113ad6123e4565b6113b5612441565b6103e88111156113e35760405163211a907760e11b8152600481018290526103e86024820152604401610be0565b6113f281600160000154612482565b600180549082905560028290556040805160a08082526006908201526562757946656560d01b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610ee6565b6114686123e4565b6001600160a01b03821660009081526018602052604090205461148f90829060ff166127be565b6001600160a01b038216600081815260186020908152604091829020805485151560ff1982168117909255835160c0808252601390820152721a5cd15e195b5c1d15d85b1b195d131a5b5a5d606a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611124565b6115416123e4565b6001600160a01b03821660009081526016602052604090205461156890829060ff166127be565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d491906132f5565b6001600160a01b03161415801561165e5750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165291906132f5565b6001600160a01b031614155b1561168757604051634726455360e11b81526001600160a01b0383166004820152602401610be0565b6013546001600160a01b031660009081526016602052604090205460ff166116cf576013546001600160a01b03166000908152601860205260409020805460ff191660011790555b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611124565b6117766128b1565b61178060006128ed565b565b61178a6123e4565b612710611795611d49565b6117a090600a613280565b6117aa9190613297565b8111156117cd5760405163181c9d0b60e21b815260048101829052602401610be0565b6117d981600f54612482565b600f805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610ee6565b61182f6123e4565b611837612868565b60135461184f908290600160d01b900460ff166127be565b60138054821515600160d01b81810260ff60d01b1984161784556040805160a080825281019590955272697357616c6c65744c696d697441637469766560681b60c086015260ff9190930416801515602085015291830152336060830152426080830152907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee6565b6118e66123e4565b6118ee61293d565b6013805460ff60c01b1916600160c01b1790556040805160608082526010908201526f1a5cd1985a5b1cd85999531bd8dad95960821b608082015233602082015242918101919091526000805160206133d68339815191529060a0015b60405180910390a1565b61195d6123e4565b611965612441565b6103e88111156119935760405163211a907760e11b8152600481018290526103e86024820152604401610be0565b6119a281600560000154612482565b600580549082905560068290556040805160a0808252600b908201526a7472616e7366657246656560a81b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610ee6565b601354600160a01b900460ff1615611a5957601354600d5460405163e39c1e8760e01b8152600160a01b90920460ff16151560048301526024820152604401610be0565b6000546001600160a01b031615801590611a8d575033611a816000546001600160a01b031690565b6001600160a01b031614155b8015611ac4575042611ac27f000000000000000000000000000000000000000000000000000000000000000062278d006132cc565b115b15611ae45760405163118cdaa760e01b8152336004820152602401610be0565b6000546001600160a01b0316158015611b17575033611b0b6000546001600160a01b031690565b6001600160a01b031614155b8015611b4e575042611b4c7f00000000000000000000000000000000000000000000000000000000000000006213c6806132cc565b115b15611bda57611b807f00000000000000000000000000000000000000000000000000000000000000006213c6806132cc565b42611bae7f00000000000000000000000000000000000000000000000000000000000000006213c6806132cc565b611bb891906132b9565b604051636ddcad9f60e01b815260048101929092526024820152604401610be0565b601354600160d01b900460ff16611bff576013805460ff60d01b1916600160d01b1790555b601354600160a81b900460ff16611c24576013805460ff60a81b1916600160a81b1790555b601354600160d81b900460ff16611c49576013805460ff60d81b1916600160d81b1790555b6013805460ff60a01b1916600160a01b17905542600d81905543600e556040805133815260208101929092527f8b70aa279b24da71d8a874fa0b0ee8f1a587c4fb32b80d87e95cdbdae01b7b4f910161194b565b611ca56123e4565b601354611cbd908290600160d81b900460ff166127be565b60138054821515600160d81b81810260ff60d81b198416179093556040805160a0808252600d908201526c1a5cd4ddd85c115b98589b1959609a1b60c082015260ff94909304939093168015156020840152928201523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee6565b60146020527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c5461dead60009081527f8b9e18c5e04efe171d1e4f682ad90d753958a5ffe56db5290b0236c8e0b6db0054600c54919291611daa91906132b9565b611db491906132b9565b905090565b611dc16123e4565b611dc9612868565b6013805460ff60c81b1916600160c81b178155604080516060808252810192909252721a5cd5d85b1b195d131a5b5a5d131bd8dad959606a1b608083015233602083015242908201526000805160206133d68339815191529060a00161194b565b600033610e2281858561256f565b611e406128b1565b611e48612441565b6013805460ff60b01b1916600160b01b179055604080516060808252600b908201526a1a5cd19959531bd8dad95960aa1b608082015233602082015242918101919091526000805160206133d68339815191529060a00161194b565b611eac6123e4565b6001600160a01b038116611ede57604051634726455360e11b81526001600160a01b0382166004820152602401610be0565b600b54611ef59082906001600160a01b031661282b565b600b80546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a1600b546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015611fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd091906132f5565b6001600160a01b031663e6a4390530600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612032573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205691906132f5565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa1580156120a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c591906132f5565b6001600160a01b0316036122e457600b60009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214a91906132f5565b6001600160a01b031663c9c6539630600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d091906132f5565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af115801561221d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224191906132f5565b601380546001600160a01b0319166001600160a01b0392909216918217905560009081526018602052604090205460ff1661229c576013546001600160a01b03166000908152601860205260409020805460ff191660011790555b6013546001600160a01b031660009081526016602052604090205460ff166122e4576013546001600160a01b03166000908152601660205260409020805460ff191660011790555b5050565b6122f06128b1565b6013805460ff60b81b1916600160b81b1790556040805160608082526010908201526f1a5cd49958d95a5d995c931bd8dad95960821b608082015233602082015242918101919091526000805160206133d68339815191529060a00161194b565b6123596128b1565b61deac196001600160a01b0382160161239057604051634726455360e11b81526001600160a01b0382166004820152602401610be0565b6123ab816123a66000546001600160a01b031690565b61282b565b601180546001600160a01b0319166001600160a01b0383161790556123cf81612983565b50565b6123df83838360016129be565b505050565b6123ec61293d565b6011546001600160a01b031633148015906124215750336124156000546001600160a01b031690565b6001600160a01b031614155b156117805760405163118cdaa760e01b8152336004820152602401610be0565b601354600160b01b900460ff1615611780576040516354f3dc5160e11b815260206004820152600360248201526246656560e81b6044820152606401610be0565b8082036122e45760405163657e16cf60e01b815260048101839052602401610be0565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526123df908490612a93565b6001600160a01b03838116600090815260156020908152604080832093861683529290522054600019811461102b578181101561256057604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610be0565b61102b848484840360006129be565b6001600160a01b03831661259957604051634b637e8f60e11b815260006004820152602401610be0565b6001600160a01b0382166125c35760405163ec442f0560e01b815260006004820152602401610be0565b601354600160a01b900460ff16612634576001600160a01b03831660009081526017602052604090205460ff1615801561261657506001600160a01b03821660009081526017602052604090205460ff16155b156126345760405163ab9827ff60e01b815260040160405180910390fd5b601354600160e01b900460ff168061266457506001600160a01b03831660009081526017602052604090205460ff165b15612674576123df838383612af6565b6013546001600160a01b0384811691161480159061269b5750601354600160d81b900460ff165b80156126b85750600f54600a546008546126b591906132b9565b10155b80156126d55750600f543060009081526014602052604090205410155b1561274757600f54601354600160c01b900460ff1680156126ff57506000546001600160a01b0316155b1561273c576000612710612711611d49565b61271c90600a613280565b6127269190613297565b9050818111156127365781612738565b805b9150505b61274581610b82565b505b6013548190600160a81b900460ff16801561277b57506001600160a01b03841660009081526017602052604090205460ff16155b80156127a057506001600160a01b03831660009081526017602052604090205460ff16155b156127b3576127b0848484612cbe565b90505b61102b848483612af6565b801515821515036122e45760405162a7e72d60e41b81528215156004820152602401610be0565b601354600160b81b900460ff1615611780576040516354f3dc5160e11b81526020600482015260086024820152672932b1b2b4bb32b960c11b6044820152606401610be0565b806001600160a01b0316826001600160a01b0316036122e45760405163a936636960e01b81526001600160a01b0383166004820152602401610be0565b601354600160c81b900460ff1615611780576040516354f3dc5160e11b815260206004820152600b60248201526a15d85b1b195d131a5b5a5d60aa1b6044820152606401610be0565b336128c46000546001600160a01b031690565b6001600160a01b0316146117805760405163118cdaa760e01b8152336004820152602401610be0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b601354600160c01b900460ff1615611780576040516354f3dc5160e11b81526020600482015260086024820152674661696c7361666560c01b6044820152606401610be0565b61298b6128b1565b6001600160a01b0381166129b557604051631e4fbdf760e01b815260006004820152602401610be0565b6123cf816128ed565b6001600160a01b0384166129e85760405163e602df0560e01b815260006004820152602401610be0565b6001600160a01b038316612a1257604051634a1406b160e11b815260006004820152602401610be0565b6001600160a01b038085166000908152601560209081526040808320938716835292905220829055801561102b57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051612a8591815260200190565b60405180910390a350505050565b6000612aa86001600160a01b03841683612dbd565b90508051600014158015612acd575080806020019051810190612acb919061339c565b155b156123df57604051635274afe760e01b81526001600160a01b0384166004820152602401610be0565b6001600160a01b038216600090815260146020526040812054612b1a9083906132cc565b90506000612710601054612b2c611d49565b612b369190613280565b612b409190613297565b90508082118015612b6a57506001600160a01b03841660009081526018602052604090205460ff16155b15612b9257604051633045819360e21b81526004810183905260248101829052604401610be0565b6001600160a01b038516612bbd5782600c6000828254612bb291906132cc565b90915550612c2f9050565b6001600160a01b03851660009081526014602052604090205483811015612c105760405163391434e360e21b81526001600160a01b03871660048201526024810182905260448101859052606401610be0565b6001600160a01b03861660009081526014602052604090209084900390555b6001600160a01b038416612c4b57600c80548490039055612c6a565b6001600160a01b03841660009081526014602052604090208054840190555b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051612caf91815260200190565b60405180910390a35050505050565b6013805460ff60e01b1916600160e01b1790556001600160a01b03831660009081526016602052604081205460ff168015612cfa575060015415155b15612d1057612d098483612dcb565b9050612da9565b6001600160a01b03831660009081526016602052604090205460ff168015612d39575060035415155b15612d4857612d098483612e03565b6001600160a01b03841660009081526016602052604090205460ff16158015612d8a57506001600160a01b03831660009081526016602052604090205460ff16155b8015612d97575060055415155b15612da657612d098483612e3b565b50805b6013805460ff60e01b191690559392505050565b606061105083836000612e73565b6013805460ff60e01b1916600160e01b1790556040805180820190915260015481526002546020820152600090612da9908484612f10565b6013805460ff60e01b1916600160e01b1790556040805180820190915260035481526004546020820152600090612da9908484612f10565b6013805460ff60e01b1916600160e01b1790556040805180820190915260055481526006546020820152600090612da9908484612f10565b606081471015612e985760405163cd78605960e01b8152306004820152602401610be0565b600080856001600160a01b03168486604051612eb491906133b9565b60006040518083038185875af1925050503d8060008114612ef1576040519150601f19603f3d011682016040523d82523d6000602084013e612ef6565b606091505b5091509150612f06868383612f93565b9695505050505050565b6013805460ff60e01b1916600160e01b1790558251600e5460009190612f3690836132cc565b4311612f4157506126ac5b6000612710612f508386613280565b612f5a9190613297565b90506000612f6882866132b9565b90508115612f7c57612f7c87878486612fef565b6013805460ff60e01b191690559695505050505050565b606082612fa857612fa382613048565b611050565b8151158015612fbf57506001600160a01b0384163b155b15612fe857604051639996b31560e01b81526001600160a01b0385166004820152602401610be0565b5080611050565b6013805460ff60e01b1916600160e01b179055835160009082906130139085613280565b61301d9190613297565b90506130298184613071565b613034843085612af6565b50506013805460ff60e01b19169055505050565b8051156130585780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6013805460ff60e01b1916600160e01b179055600780548391906000906130999084906132cc565b9091555050600880548291906000906130b39084906132cc565b90915550506013805460ff60e01b191690555050565b6000602082840312156130db57600080fd5b5035919050565b60005b838110156130fd5781810151838201526020016130e5565b50506000910152565b60208152600082518060208401526131258160408501602087016130e2565b601f01601f19169190910160400192915050565b6001600160a01b03811681146123cf57600080fd5b60006020828403121561316057600080fd5b813561105081613139565b6000806040838503121561317e57600080fd5b823561318981613139565b946020939093013593505050565b6000806000606084860312156131ac57600080fd5b83356131b781613139565b925060208401356131c781613139565b929592945050506040919091013590565b80151581146123cf57600080fd5b600080604083850312156131f957600080fd5b823561320481613139565b91506020830135613214816131d8565b809150509250929050565b60006020828403121561323157600080fd5b8135611050816131d8565b6000806040838503121561324f57600080fd5b823561325a81613139565b9150602083013561321481613139565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e2857610e2861326a565b6000826132b457634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610e2857610e2861326a565b80820180821115610e2857610e2861326a565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561330757600080fd5b815161105081613139565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156133625784516001600160a01b03168352938301939183019160010161333d565b50506001600160a01b03969096166060850152505050608001529392505050565b60006020828403121561339557600080fd5b5051919050565b6000602082840312156133ae57600080fd5b8151611050816131d8565b600082516133cb8184602087016130e2565b919091019291505056fe611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b4a2646970667358221220bad7885b9185658913a0acf06678eca7cce0f2caef63a8c6ebc72fd39092315764736f6c63430008120033
Deployed Bytecode
0x60806040526004361061039b5760003560e01c8063891ff84a116101dc578063acb2ad6f11610102578063dd62ed3e116100a0578063e811f50a1161006f578063e811f50a14610b11578063f2c4220e14610b2c578063f2fde38b14610b42578063f887ea4014610b6257600080fd5b8063dd62ed3e14610a68578063e2924cd114610aae578063e43504da14610acf578063e79f53e614610af057600080fd5b8063cf9769fd116100dc578063cf9769fd146109f6578063d621e81314610a0b578063d830678614610a2c578063d941907114610a4d57600080fd5b8063acb2ad6f1461099a578063b908de8c146109b5578063c851cc32146109d657600080fd5b80639ffe05331161017a578063a8aa1b3111610149578063a8aa1b311461092f578063a9059cbb1461094f578063ab28a04c1461096f578063ab3662921461098557600080fd5b80639ffe0533146108b9578063a4475ce4146108da578063a5949bcf146108fa578063a616162a1461091a57600080fd5b8063924de9b7116101b6578063924de9b7146108255780639358928b1461084557806395d89b411461085a578063999969731461088957600080fd5b8063891ff84a146107ae5780638a8c523c146107de5780638da5cb5b146107f357600080fd5b80633d6362d6116102c157806366a88d961161025f578063779e80d51161022e578063779e80d5146107255780637a40624b146107455780637e2b16d1146107795780638577a6d51461078e57600080fd5b806366a88d96146106a457806370a08231146106ba578063715018a6146106f057806375fed3c71461070557600080fd5b8063470624021161029b57806347062402146106335780634b7e71b31461064e57806359cd90311461066e578063625dd6051461068457600080fd5b80633d6362d6146105d35780634324deae146105f3578063467abe0a1461061357600080fd5b806323b872dd11610339578063313ce56711610308578063313ce56714610556578063351a964d14610572578063355496ca146105935780633bf31454146105b357600080fd5b806323b872dd146104cf5780632b14ca56146104ef5780632c735ef81461051f578063312579661461053557600080fd5b8063095ea7b311610375578063095ea7b31461045057806318160ddd146104705780631d933a4a1461048f5780631f685bac146104af57600080fd5b806301295143146103a757806306fdde03146103c957806308c436501461041057600080fd5b366103a257005b600080fd5b3480156103b357600080fd5b506103c76103c23660046130c9565b610b82565b005b3480156103d557600080fd5b5060408051808201909152600c81526b44656570536f75746820414960a01b60208201525b6040516104079190613106565b60405180910390f35b34801561041c57600080fd5b5061044061042b36600461314e565b60166020526000908152604090205460ff1681565b6040519015158152602001610407565b34801561045c57600080fd5b5061044061046b36600461316b565b610e14565b34801561047c57600080fd5b50600c545b604051908152602001610407565b34801561049b57600080fd5b506103c76104aa3660046130c9565b610e2e565b3480156104bb57600080fd5b506103c76104ca36600461316b565b610ef2565b3480156104db57600080fd5b506104406104ea366004613197565b611031565b3480156104fb57600080fd5b5060035460045461050a919082565b60408051928352602083019190915201610407565b34801561052b57600080fd5b50610481600d5481565b34801561054157600080fd5b5060135461044090600160c81b900460ff1681565b34801561056257600080fd5b5060405160128152602001610407565b34801561057e57600080fd5b5060135461044090600160d81b900460ff1681565b34801561059f57600080fd5b506103c76105ae3660046131e6565b611057565b3480156105bf57600080fd5b506103c76105ce36600461321f565b611131565b3480156105df57600080fd5b506103c76105ee36600461314e565b6111e3565b3480156105ff57600080fd5b506103c761060e3660046130c9565b6112ec565b34801561061f57600080fd5b506103c761062e3660046130c9565b6113a5565b34801561063f57600080fd5b5060015460025461050a919082565b34801561065a57600080fd5b506103c76106693660046131e6565b611460565b34801561067a57600080fd5b50610481600f5481565b34801561069057600080fd5b506103c761069f3660046131e6565b611539565b3480156106b057600080fd5b5061048160105481565b3480156106c657600080fd5b506104816106d536600461314e565b6001600160a01b031660009081526014602052604090205490565b3480156106fc57600080fd5b506103c761176e565b34801561071157600080fd5b506103c76107203660046130c9565b611782565b34801561073157600080fd5b506103c761074036600461321f565b611827565b34801561075157600080fd5b506104817f000000000000000000000000000000000000000000000000000000006598904f81565b34801561078557600080fd5b506103c76118de565b34801561079a57600080fd5b506103c76107a93660046130c9565b611955565b3480156107ba57600080fd5b506104406107c936600461314e565b60176020526000908152604090205460ff1681565b3480156107ea57600080fd5b506103c7611a15565b3480156107ff57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610407565b34801561083157600080fd5b506103c761084036600461321f565b611c9d565b34801561085157600080fd5b50610481611d49565b34801561086657600080fd5b50604080518082019091526006815265088a69eaaa8960d31b60208201526103fa565b34801561089557600080fd5b506104406108a436600461314e565b60186020526000908152604090205460ff1681565b3480156108c557600080fd5b5060135461044090600160d01b900460ff1681565b3480156108e657600080fd5b5060115461080d906001600160a01b031681565b34801561090657600080fd5b5060125461080d906001600160a01b031681565b34801561092657600080fd5b506103c7611db9565b34801561093b57600080fd5b5060135461080d906001600160a01b031681565b34801561095b57600080fd5b5061044061096a36600461316b565b611e2a565b34801561097b57600080fd5b5061048161271081565b34801561099157600080fd5b506103c7611e38565b3480156109a657600080fd5b5060055460065461050a919082565b3480156109c157600080fd5b5060135461044090600160b01b900460ff1681565b3480156109e257600080fd5b506103c76109f136600461314e565b611ea4565b348015610a0257600080fd5b506103c76122e8565b348015610a1757600080fd5b5060135461044090600160a01b900460ff1681565b348015610a3857600080fd5b5060135461044090600160e01b900460ff1681565b348015610a5957600080fd5b50600954600a5461050a919082565b348015610a7457600080fd5b50610481610a8336600461323c565b6001600160a01b03918216600090815260156020908152604080832093909416825291909152205490565b348015610aba57600080fd5b5060135461044090600160b81b900460ff1681565b348015610adb57600080fd5b5060135461044090600160a81b900460ff1681565b348015610afc57600080fd5b5060135461044090600160c01b900460ff1681565b348015610b1d57600080fd5b5060075460085461050a919082565b348015610b3857600080fd5b50610481600e5481565b348015610b4e57600080fd5b506103c7610b5d36600461314e565b612351565b348015610b6e57600080fd5b50600b5461080d906001600160a01b031681565b6013805460ff60e01b1916600160e01b1790556000612710610ba2611d49565b610bad906032613280565b610bb79190613297565b905080821115610be95760405163179b4ccd60e31b815260048101839052602481018290526044015b60405180910390fd5b600954600754600091610bfb916132b9565b600a54600854919250600091610c1191906132b9565b9050600081610c208487613280565b610c2a9190613297565b90508060096000016000828254610c4191906132cc565b9091555050600a8054869190600090610c5b9084906132cc565b90915550506040805160028082526060820183526000926020830190803683370190505090503081600081518110610c9557610c956132df565b6001600160a01b03928316602091820292909201810191909152600b54604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015610cee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1291906132f5565b81600181518110610d2557610d256132df565b6001600160a01b039283166020918202929092010152600b54610d4b91309116886123d2565b6040805183815260208101889052338183015242606082015290517fb933c1b294702108551eddf782a9c7d1a018b57f68ecf63bc59a1247daa19c309181900360800190a1600b5460125460405163791ac94760e01b81526001600160a01b039283169263791ac94792610dcd92879260009288929116904290600401613312565b600060405180830381600087803b158015610de757600080fd5b505af1158015610dfb573d6000803e3d6000fd5b50506013805460ff60e01b191690555050505050505050565b600033610e228185856123d2565b60019150505b92915050565b610e366123e4565b610e3e612441565b6103e8811115610e6c5760405163211a907760e11b8152600481018290526103e86024820152604401610be0565b610e7b81600360000154612482565b600380549082905560048290556040805160a08082526007908201526673656c6c46656560c81b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e0015b60405180910390a15050565b60125481906001600160a01b03908116903090851603610f25576040516315ea636560e31b815260040160405180910390fd5b6001600160a01b038416610fa45782600003610f3f574791505b6001600160a01b0381163303610f685760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610f9e573d6000803e3d6000fd5b5061102b565b82600003611017576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610ff0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110149190613383565b91505b61102b6001600160a01b03851682846124a5565b50505050565b60003361103f8582856124f7565b61104a85858561256f565b60019150505b9392505050565b61105f6123e4565b6001600160a01b03821660009081526017602052604090205461108690829060ff166127be565b6001600160a01b038216600081815260176020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea90610100015b60405180910390a1505050565b6111396123e4565b611141612441565b601354611159908290600160a81b900460ff166127be565b60138054821515600160a81b81810260ff60a81b198416179093556040805160a0808252600b908201526a697346656541637469766560a81b60c082015260ff94909304939093168015156020840152928201523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee6565b6111eb6123e4565b6001600160a01b0381163b156112145760405163259f1ec560e01b815260040160405180910390fd5b6001600160a01b03811661123e57604051634726455360e11b815260006004820152602401610be0565b6112466127e5565b60125461125d9082906001600160a01b031661282b565b601280546001600160a01b031981166001600160a01b038481169182179093556040805160a08082526011908201527036b0b935b2ba34b733a932b1b2b4bb32b960791b60c0820152939092166020840181905291830152336060830152426080830152907ff7df6bc5c0f9735c300a374247b60dcacf1942b6031785957e762d77977ed4209060e001610ee6565b6112f46123e4565b60648110156113205760405163ab7d1fbb60e01b81526004810182905260646024820152604401610be0565b611328612868565b61133481601054612482565b60108054908290556040805160a0808252600e908201526d1b585e15d85b1b195d131a5b5a5d60921b60c0820152602081018390529081018390523360608201524260808201527f18558967fd5a093126ad115ffea8d443544786d34a646f42dff37fa8700577f09060e001610ee6565b6113ad6123e4565b6113b5612441565b6103e88111156113e35760405163211a907760e11b8152600481018290526103e86024820152604401610be0565b6113f281600160000154612482565b600180549082905560028290556040805160a08082526006908201526562757946656560d01b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610ee6565b6114686123e4565b6001600160a01b03821660009081526018602052604090205461148f90829060ff166127be565b6001600160a01b038216600081815260186020908152604091829020805485151560ff1982168117909255835160c0808252601390820152721a5cd15e195b5c1d15d85b1b195d131a5b5a5d606a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611124565b6115416123e4565b6001600160a01b03821660009081526016602052604090205461156890829060ff166127be565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d491906132f5565b6001600160a01b03161415801561165e5750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165291906132f5565b6001600160a01b031614155b1561168757604051634726455360e11b81526001600160a01b0383166004820152602401610be0565b6013546001600160a01b031660009081526016602052604090205460ff166116cf576013546001600160a01b03166000908152601860205260409020805460ff191660011790555b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611124565b6117766128b1565b61178060006128ed565b565b61178a6123e4565b612710611795611d49565b6117a090600a613280565b6117aa9190613297565b8111156117cd5760405163181c9d0b60e21b815260048101829052602401610be0565b6117d981600f54612482565b600f805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610ee6565b61182f6123e4565b611837612868565b60135461184f908290600160d01b900460ff166127be565b60138054821515600160d01b81810260ff60d01b1984161784556040805160a080825281019590955272697357616c6c65744c696d697441637469766560681b60c086015260ff9190930416801515602085015291830152336060830152426080830152907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee6565b6118e66123e4565b6118ee61293d565b6013805460ff60c01b1916600160c01b1790556040805160608082526010908201526f1a5cd1985a5b1cd85999531bd8dad95960821b608082015233602082015242918101919091526000805160206133d68339815191529060a0015b60405180910390a1565b61195d6123e4565b611965612441565b6103e88111156119935760405163211a907760e11b8152600481018290526103e86024820152604401610be0565b6119a281600560000154612482565b600580549082905560068290556040805160a0808252600b908201526a7472616e7366657246656560a81b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610ee6565b601354600160a01b900460ff1615611a5957601354600d5460405163e39c1e8760e01b8152600160a01b90920460ff16151560048301526024820152604401610be0565b6000546001600160a01b031615801590611a8d575033611a816000546001600160a01b031690565b6001600160a01b031614155b8015611ac4575042611ac27f000000000000000000000000000000000000000000000000000000006598904f62278d006132cc565b115b15611ae45760405163118cdaa760e01b8152336004820152602401610be0565b6000546001600160a01b0316158015611b17575033611b0b6000546001600160a01b031690565b6001600160a01b031614155b8015611b4e575042611b4c7f000000000000000000000000000000000000000000000000000000006598904f6213c6806132cc565b115b15611bda57611b807f000000000000000000000000000000000000000000000000000000006598904f6213c6806132cc565b42611bae7f000000000000000000000000000000000000000000000000000000006598904f6213c6806132cc565b611bb891906132b9565b604051636ddcad9f60e01b815260048101929092526024820152604401610be0565b601354600160d01b900460ff16611bff576013805460ff60d01b1916600160d01b1790555b601354600160a81b900460ff16611c24576013805460ff60a81b1916600160a81b1790555b601354600160d81b900460ff16611c49576013805460ff60d81b1916600160d81b1790555b6013805460ff60a01b1916600160a01b17905542600d81905543600e556040805133815260208101929092527f8b70aa279b24da71d8a874fa0b0ee8f1a587c4fb32b80d87e95cdbdae01b7b4f910161194b565b611ca56123e4565b601354611cbd908290600160d81b900460ff166127be565b60138054821515600160d81b81810260ff60d81b198416179093556040805160a0808252600d908201526c1a5cd4ddd85c115b98589b1959609a1b60c082015260ff94909304939093168015156020840152928201523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610ee6565b60146020527f4f26c3876aa9f4b92579780beea1161a61f87ebf1ec6ee865b299e447ecba99c5461dead60009081527f8b9e18c5e04efe171d1e4f682ad90d753958a5ffe56db5290b0236c8e0b6db0054600c54919291611daa91906132b9565b611db491906132b9565b905090565b611dc16123e4565b611dc9612868565b6013805460ff60c81b1916600160c81b178155604080516060808252810192909252721a5cd5d85b1b195d131a5b5a5d131bd8dad959606a1b608083015233602083015242908201526000805160206133d68339815191529060a00161194b565b600033610e2281858561256f565b611e406128b1565b611e48612441565b6013805460ff60b01b1916600160b01b179055604080516060808252600b908201526a1a5cd19959531bd8dad95960aa1b608082015233602082015242918101919091526000805160206133d68339815191529060a00161194b565b611eac6123e4565b6001600160a01b038116611ede57604051634726455360e11b81526001600160a01b0382166004820152602401610be0565b600b54611ef59082906001600160a01b031661282b565b600b80546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a1600b546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015611fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd091906132f5565b6001600160a01b031663e6a4390530600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612032573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205691906132f5565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa1580156120a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c591906132f5565b6001600160a01b0316036122e457600b60009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214a91906132f5565b6001600160a01b031663c9c6539630600b60009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d091906132f5565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af115801561221d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224191906132f5565b601380546001600160a01b0319166001600160a01b0392909216918217905560009081526018602052604090205460ff1661229c576013546001600160a01b03166000908152601860205260409020805460ff191660011790555b6013546001600160a01b031660009081526016602052604090205460ff166122e4576013546001600160a01b03166000908152601660205260409020805460ff191660011790555b5050565b6122f06128b1565b6013805460ff60b81b1916600160b81b1790556040805160608082526010908201526f1a5cd49958d95a5d995c931bd8dad95960821b608082015233602082015242918101919091526000805160206133d68339815191529060a00161194b565b6123596128b1565b61deac196001600160a01b0382160161239057604051634726455360e11b81526001600160a01b0382166004820152602401610be0565b6123ab816123a66000546001600160a01b031690565b61282b565b601180546001600160a01b0319166001600160a01b0383161790556123cf81612983565b50565b6123df83838360016129be565b505050565b6123ec61293d565b6011546001600160a01b031633148015906124215750336124156000546001600160a01b031690565b6001600160a01b031614155b156117805760405163118cdaa760e01b8152336004820152602401610be0565b601354600160b01b900460ff1615611780576040516354f3dc5160e11b815260206004820152600360248201526246656560e81b6044820152606401610be0565b8082036122e45760405163657e16cf60e01b815260048101839052602401610be0565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526123df908490612a93565b6001600160a01b03838116600090815260156020908152604080832093861683529290522054600019811461102b578181101561256057604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610be0565b61102b848484840360006129be565b6001600160a01b03831661259957604051634b637e8f60e11b815260006004820152602401610be0565b6001600160a01b0382166125c35760405163ec442f0560e01b815260006004820152602401610be0565b601354600160a01b900460ff16612634576001600160a01b03831660009081526017602052604090205460ff1615801561261657506001600160a01b03821660009081526017602052604090205460ff16155b156126345760405163ab9827ff60e01b815260040160405180910390fd5b601354600160e01b900460ff168061266457506001600160a01b03831660009081526017602052604090205460ff165b15612674576123df838383612af6565b6013546001600160a01b0384811691161480159061269b5750601354600160d81b900460ff165b80156126b85750600f54600a546008546126b591906132b9565b10155b80156126d55750600f543060009081526014602052604090205410155b1561274757600f54601354600160c01b900460ff1680156126ff57506000546001600160a01b0316155b1561273c576000612710612711611d49565b61271c90600a613280565b6127269190613297565b9050818111156127365781612738565b805b9150505b61274581610b82565b505b6013548190600160a81b900460ff16801561277b57506001600160a01b03841660009081526017602052604090205460ff16155b80156127a057506001600160a01b03831660009081526017602052604090205460ff16155b156127b3576127b0848484612cbe565b90505b61102b848483612af6565b801515821515036122e45760405162a7e72d60e41b81528215156004820152602401610be0565b601354600160b81b900460ff1615611780576040516354f3dc5160e11b81526020600482015260086024820152672932b1b2b4bb32b960c11b6044820152606401610be0565b806001600160a01b0316826001600160a01b0316036122e45760405163a936636960e01b81526001600160a01b0383166004820152602401610be0565b601354600160c81b900460ff1615611780576040516354f3dc5160e11b815260206004820152600b60248201526a15d85b1b195d131a5b5a5d60aa1b6044820152606401610be0565b336128c46000546001600160a01b031690565b6001600160a01b0316146117805760405163118cdaa760e01b8152336004820152602401610be0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b601354600160c01b900460ff1615611780576040516354f3dc5160e11b81526020600482015260086024820152674661696c7361666560c01b6044820152606401610be0565b61298b6128b1565b6001600160a01b0381166129b557604051631e4fbdf760e01b815260006004820152602401610be0565b6123cf816128ed565b6001600160a01b0384166129e85760405163e602df0560e01b815260006004820152602401610be0565b6001600160a01b038316612a1257604051634a1406b160e11b815260006004820152602401610be0565b6001600160a01b038085166000908152601560209081526040808320938716835292905220829055801561102b57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051612a8591815260200190565b60405180910390a350505050565b6000612aa86001600160a01b03841683612dbd565b90508051600014158015612acd575080806020019051810190612acb919061339c565b155b156123df57604051635274afe760e01b81526001600160a01b0384166004820152602401610be0565b6001600160a01b038216600090815260146020526040812054612b1a9083906132cc565b90506000612710601054612b2c611d49565b612b369190613280565b612b409190613297565b90508082118015612b6a57506001600160a01b03841660009081526018602052604090205460ff16155b15612b9257604051633045819360e21b81526004810183905260248101829052604401610be0565b6001600160a01b038516612bbd5782600c6000828254612bb291906132cc565b90915550612c2f9050565b6001600160a01b03851660009081526014602052604090205483811015612c105760405163391434e360e21b81526001600160a01b03871660048201526024810182905260448101859052606401610be0565b6001600160a01b03861660009081526014602052604090209084900390555b6001600160a01b038416612c4b57600c80548490039055612c6a565b6001600160a01b03841660009081526014602052604090208054840190555b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051612caf91815260200190565b60405180910390a35050505050565b6013805460ff60e01b1916600160e01b1790556001600160a01b03831660009081526016602052604081205460ff168015612cfa575060015415155b15612d1057612d098483612dcb565b9050612da9565b6001600160a01b03831660009081526016602052604090205460ff168015612d39575060035415155b15612d4857612d098483612e03565b6001600160a01b03841660009081526016602052604090205460ff16158015612d8a57506001600160a01b03831660009081526016602052604090205460ff16155b8015612d97575060055415155b15612da657612d098483612e3b565b50805b6013805460ff60e01b191690559392505050565b606061105083836000612e73565b6013805460ff60e01b1916600160e01b1790556040805180820190915260015481526002546020820152600090612da9908484612f10565b6013805460ff60e01b1916600160e01b1790556040805180820190915260035481526004546020820152600090612da9908484612f10565b6013805460ff60e01b1916600160e01b1790556040805180820190915260055481526006546020820152600090612da9908484612f10565b606081471015612e985760405163cd78605960e01b8152306004820152602401610be0565b600080856001600160a01b03168486604051612eb491906133b9565b60006040518083038185875af1925050503d8060008114612ef1576040519150601f19603f3d011682016040523d82523d6000602084013e612ef6565b606091505b5091509150612f06868383612f93565b9695505050505050565b6013805460ff60e01b1916600160e01b1790558251600e5460009190612f3690836132cc565b4311612f4157506126ac5b6000612710612f508386613280565b612f5a9190613297565b90506000612f6882866132b9565b90508115612f7c57612f7c87878486612fef565b6013805460ff60e01b191690559695505050505050565b606082612fa857612fa382613048565b611050565b8151158015612fbf57506001600160a01b0384163b155b15612fe857604051639996b31560e01b81526001600160a01b0385166004820152602401610be0565b5080611050565b6013805460ff60e01b1916600160e01b179055835160009082906130139085613280565b61301d9190613297565b90506130298184613071565b613034843085612af6565b50506013805460ff60e01b19169055505050565b8051156130585780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6013805460ff60e01b1916600160e01b179055600780548391906000906130999084906132cc565b9091555050600880548291906000906130b39084906132cc565b90915550506013805460ff60e01b191690555050565b6000602082840312156130db57600080fd5b5035919050565b60005b838110156130fd5781810151838201526020016130e5565b50506000910152565b60208152600082518060208401526131258160408501602087016130e2565b601f01601f19169190910160400192915050565b6001600160a01b03811681146123cf57600080fd5b60006020828403121561316057600080fd5b813561105081613139565b6000806040838503121561317e57600080fd5b823561318981613139565b946020939093013593505050565b6000806000606084860312156131ac57600080fd5b83356131b781613139565b925060208401356131c781613139565b929592945050506040919091013590565b80151581146123cf57600080fd5b600080604083850312156131f957600080fd5b823561320481613139565b91506020830135613214816131d8565b809150509250929050565b60006020828403121561323157600080fd5b8135611050816131d8565b6000806040838503121561324f57600080fd5b823561325a81613139565b9150602083013561321481613139565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e2857610e2861326a565b6000826132b457634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610e2857610e2861326a565b80820180821115610e2857610e2861326a565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561330757600080fd5b815161105081613139565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156133625784516001600160a01b03168352938301939183019160010161333d565b50506001600160a01b03969096166060850152505050608001529392505050565b60006020828403121561339557600080fd5b5051919050565b6000602082840312156133ae57600080fd5b8151611050816131d8565b600082516133cb8184602087016130e2565b919091019291505056fe611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b4a2646970667358221220bad7885b9185658913a0acf06678eca7cce0f2caef63a8c6ebc72fd39092315764736f6c63430008120033
Deployed Bytecode Sourcemap
25091:50095:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44568:1148;;;;;;;;;;-1:-1:-1;44568:1148:0;;;;;:::i;:::-;;:::i;:::-;;62224:90;;;;;;;;;;-1:-1:-1;62302:4:0;;;;;;;;;;;;-1:-1:-1;;;62302:4:0;;;;62224:90;;;;;;;:::i;:::-;;;;;;;;26833:45;;;;;;;;;;-1:-1:-1;26833:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1408:14:1;;1401:22;1383:41;;1371:2;1356:18;26833:45:0;1243:187:1;65259:194:0;;;;;;;;;;-1:-1:-1;65259:194:0;;;;;:::i;:::-;;:::i;63273:99::-;;;;;;;;;;-1:-1:-1;63352:12:0;;63273:99;;;1901:25:1;;;1889:2;1874:18;63273:99:0;1755:177:1;51642:525:0;;;;;;;;;;-1:-1:-1;51642:525:0;;;;;:::i;:::-;;:::i;38220:801::-;;;;;;;;;;-1:-1:-1;38220:801:0;;;;;:::i;:::-;;:::i;65895:247::-;;;;;;;;;;-1:-1:-1;65895:247:0;;;;;:::i;:::-;;:::i;25397:36::-;;;;;;;;;;-1:-1:-1;25397:36:0;;;;;;;;;;;;;2572:25:1;;;2628:2;2613:18;;2606:34;;;;2545:18;25397:36:0;2398:248:1;25934:33:0;;;;;;;;;;;;;;;;26496:39;;;;;;;;;;-1:-1:-1;26496:39:0;;;;-1:-1:-1;;;26496:39:0;;;;;;62985:90;;;;;;;;;;-1:-1:-1;62985:90:0;;25786:2;2793:36:1;;2781:2;2766:18;62985:90:0;2651:184:1;26588:33:0;;;;;;;;;;-1:-1:-1;26588:33:0;;;;-1:-1:-1;;;26588:33:0;;;;;;56700:337;;;;;;;;;;-1:-1:-1;56700:337:0;;;;;:::i;:::-;;:::i;48100:321::-;;;;;;;;;;-1:-1:-1;48100:321:0;;;;;:::i;:::-;;:::i;53435:657::-;;;;;;;;;;-1:-1:-1;53435:657:0;;;;;:::i;:::-;;:::i;49976:443::-;;;;;;;;;;-1:-1:-1;49976:443:0;;;;;:::i;:::-;;:::i;50770:519::-;;;;;;;;;;-1:-1:-1;50770:519:0;;;;;:::i;:::-;;:::i;25355:35::-;;;;;;;;;;-1:-1:-1;25355:35:0;;;;;;;;;57385:377;;;;;;;;;;-1:-1:-1;57385:377:0;;;;;:::i;:::-;;:::i;26015:36::-;;;;;;;;;;;;;;;;54510:573;;;;;;;;;;-1:-1:-1;54510:573:0;;;;;:::i;:::-;;:::i;26058:35::-;;;;;;;;;;;;;;;;63657:118;;;;;;;;;;-1:-1:-1;63657:118:0;;;;;:::i;:::-;-1:-1:-1;;;;;63749:18:0;63722:7;63749:18;;;:9;:18;;;;;;;63657:118;23260:103;;;;;;;;;;;;;:::i;47409:408::-;;;;;;;;;;-1:-1:-1;47409:408:0;;;;;:::i;:::-;;:::i;48717:369::-;;;;;;;;;;-1:-1:-1;48717:369:0;;;;;:::i;:::-;;:::i;25853:35::-;;;;;;;;;;;;;;;46562:193;;;;;;;;;;;;;:::i;52528:549::-;;;;;;;;;;-1:-1:-1;52528:549:0;;;;;:::i;:::-;;:::i;26885:51::-;;;;;;;;;;-1:-1:-1;26885:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;39679:1118;;;;;;;;;;;;;:::i;22546:87::-;;;;;;;;;;-1:-1:-1;22592:7:0;22619:6;-1:-1:-1;;;;;22619:6:0;22546:87;;;-1:-1:-1;;;;;3760:32:1;;;3742:51;;3730:2;3715:18;22546:87:0;3596:203:1;49339:305:0;;;;;;;;;;-1:-1:-1;49339:305:0;;;;;:::i;:::-;;:::i;41193:151::-;;;;;;;;;;;;;:::i;62506:94::-;;;;;;;;;;-1:-1:-1;62586:6:0;;;;;;;;;;;;-1:-1:-1;;;62586:6:0;;;;62506:94;;26943:59;;;;;;;;;;-1:-1:-1;26943:59:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;26542:39;;;;;;;;;;-1:-1:-1;26542:39:0;;;;-1:-1:-1;;;26542:39:0;;;;;;26102:72;;;;;;;;;;-1:-1:-1;26102:72:0;;;;-1:-1:-1;;;;;26102:72:0;;;26181:77;;;;;;;;;;-1:-1:-1;26181:77:0;;;;-1:-1:-1;;;;;26181:77:0;;;46931:205;;;;;;;;;;;;;:::i;26267:19::-;;;;;;;;;;-1:-1:-1;26267:19:0;;;;-1:-1:-1;;;;;26267:19:0;;;64141:186;;;;;;;;;;-1:-1:-1;64141:186:0;;;;;:::i;:::-;;:::i;25797:47::-;;;;;;;;;;;;25838:6;25797:47;;45905:166;;;;;;;;;;;;;:::i;25440:34::-;;;;;;;;;;-1:-1:-1;25440:34:0;;;;;;;;;26372:31;;;;;;;;;;-1:-1:-1;26372:31:0;;;;-1:-1:-1;;;26372:31:0;;;;;;55549:812;;;;;;;;;;-1:-1:-1;55549:812:0;;;;;:::i;:::-;;:::i;46236:155::-;;;;;;;;;;;;;:::i;26295:32::-;;;;;;;;;;-1:-1:-1;26295:32:0;;;;-1:-1:-1;;;26295:32:0;;;;;;26628:26;;;;;;;;;;-1:-1:-1;26628:26:0;;;;-1:-1:-1;;;26628:26:0;;;;;;25523:34;;;;;;;;;;-1:-1:-1;25523:34:0;;;;;;;;;64709:148;;;;;;;;;;-1:-1:-1;64709:148:0;;;;;:::i;:::-;-1:-1:-1;;;;;64819:21:0;;;64792:7;64819:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;;;;64709:148;26410:36;;;;;;;;;;-1:-1:-1;26410:36:0;;;;-1:-1:-1;;;26410:36:0;;;;;;26334:31;;;;;;;;;;-1:-1:-1;26334:31:0;;;;-1:-1:-1;;;26334:31:0;;;;;;26453:36;;;;;;;;;;-1:-1:-1;26453:36:0;;;;-1:-1:-1;;;26453:36:0;;;;;;25481:35;;;;;;;;;;-1:-1:-1;25481:35:0;;;;;;;;;25974:34;;;;;;;;;;;;;;;;61701:308;;;;;;;;;;-1:-1:-1;61701:308:0;;;;;:::i;:::-;;:::i;25566:75::-;;;;;;;;;;-1:-1:-1;25566:75:0;;;;-1:-1:-1;;;;;25566:75:0;;;44568:1148;27155:6;:13;;-1:-1:-1;;;;27155:13:0;-1:-1:-1;;;27155:13:0;;;;25838:6:::1;44659:19;:17;:19::i;:::-;:24;::::0;44681:2:::1;44659:24;:::i;:::-;:41;;;;:::i;:::-;44639:61;;44732:9;44715:14;:26;44711:128;;;44765:62;::::0;-1:-1:-1;;;44765:62:0;;::::1;::::0;::::1;2572:25:1::0;;;2613:18;;;2606:34;;;2545:18;;44765:62:0::1;;;;;;;;44711:128;44902:11;:21:::0;44877:12:::1;:22:::0;44849:25:::1;::::0;44877:46:::1;::::0;::::1;:::i;:::-;44979:17:::0;;44958:18;;44849:74;;-1:-1:-1;44934:21:0::1;::::0;44958:38:::1;::::0;44979:17;44958:38:::1;:::i;:::-;44934:62:::0;-1:-1:-1;45009:32:0::1;44934:62:::0;45044:34:::1;45061:17:::0;45044:14;:34:::1;:::i;:::-;:50;;;;:::i;:::-;45009:85;;45132:24;45107:11;:21;;;:49;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;45167:17:0;:35;;45188:14;;45167:17;::::1;::::0;:35:::1;::::0;45188:14;;45167:35:::1;:::i;:::-;::::0;;;-1:-1:-1;;45239:16:0::1;::::0;;45253:1:::1;45239:16:::0;;;;;::::1;::::0;;45215:21:::1;::::0;45239:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;45239:16:0::1;45215:40;;45284:4;45266;45271:1;45266:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;45266:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;;:23;;;;45310:6:::1;::::0;:13:::1;::::0;;-1:-1:-1;;;45310:13:0;;;;:6;;;::::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;45266:7;;45310:13;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45300:4;45305:1;45300:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;45300:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;45368:6:::1;::::0;45336:56:::1;::::0;45353:4:::1;::::0;45368:6:::1;45377:14:::0;45336:8:::1;:56::i;:::-;45410:81;::::0;;5961:25:1;;;6017:2;6002:18;;5995:34;;;45463:10:0::1;6045:18:1::0;;;6038:60;45475:15:0::1;6129:2:1::0;6114:18;;6107:34;45410:81:0;;::::1;::::0;;;;5948:3:1;45410:81:0;;::::1;45504:6;::::0;45650:17:::1;::::0;45504:204:::1;::::0;-1:-1:-1;;;45504:204:0;;-1:-1:-1;;;;;45504:6:0;;::::1;::::0;:57:::1;::::0;:204:::1;::::0;45576:24;;45504:6:::1;::::0;45631:4;;45650:17;::::1;::::0;45682:15:::1;::::0;45504:204:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;27191:6:0;:14;;-1:-1:-1;;;;27191:14:0;;;-1:-1:-1;;;;;;;;44568:1148:0:o;65259:194::-;65332:4;65368:10;65389:34;65368:10;65408:7;65417:5;65389:8;:34::i;:::-;65441:4;65434:11;;;65259:194;;;;;:::o;51642:525::-;27511:21;:19;:21::i;:::-;51728:15:::1;:13;:15::i;:::-;51776:4;51758:15;:22;51754:100;;;51804:38;::::0;-1:-1:-1;;;51804:38:0;;::::1;::::0;::::1;2572:25:1::0;;;51837:4:0::1;2613:18:1::0;;;2606:34;2545:18;;51804:38:0::1;2398:248:1::0;51754:100:0::1;51864:54;51883:15;51900:7;:17;;;51864:18;:54::i;:::-;51955:7;:17:::0;;51983:35;;;;52029:13;:31;;;52076:83:::1;::::0;;7715:3:1;7697:22;;;7756:1;7735:19;;;7728:30;-1:-1:-1;;;7789:3:1;7774:19;;7767:38;7872:4;7857:20;;7850:36;;;7902:18;;;7895:34;;;52131:10:0::1;-1:-1:-1::0;7945:18:1;;7938:60;52143:15:0::1;-1:-1:-1::0;8014:19:1;;8007:35;52076:83:0::1;::::0;7837:3:1;7822:19;52076:83:0::1;;;;;;;;51717:450;51642:525:::0;:::o;38220:801::-;38352:17;;38316:6;;-1:-1:-1;;;;;38352:17:0;;;;38410:4;38386:29;;;;38382:632;;38439:27;;-1:-1:-1;;;38439:27:0;;;;;;;;;;;38382:632;-1:-1:-1;;;;;38488:26:0;;38484:530;;38535:6;38545:1;38535:11;38531:86;;38580:21;38567:34;;38531:86;-1:-1:-1;;;;;38635:22:0;;:10;:22;38631:107;;38685:37;;-1:-1:-1;;;38685:37:0;;;;;;;;;;;38631:107;38752:38;;-1:-1:-1;;;;;38752:26:0;;;:38;;;;;38779:10;;38752:38;;;;38779:10;38752:26;:38;;;;;;;;;;;;;;;;;;;;;38484:530;;;38827:6;38837:1;38827:11;38823:110;;38872:45;;-1:-1:-1;;;38872:45:0;;38911:4;38872:45;;;3742:51:1;-1:-1:-1;;;;;38872:30:0;;;;;3715:18:1;;38872:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38859:58;;38823:110;38947:55;-1:-1:-1;;;;;38947:33:0;;38981:8;38991:10;38947:33;:55::i;:::-;38284:737;;38220:801;;:::o;65895:247::-;65982:4;66017:10;66038:37;66054:4;66017:10;66069:5;66038:15;:37::i;:::-;66086:26;66096:4;66102:2;66106:5;66086:9;:26::i;:::-;66130:4;66123:11;;;65895:247;;;;;;:::o;56700:337::-;27511:21;:19;:21::i;:::-;-1:-1:-1;;;;;56823:17:0;::::1;;::::0;;;:11:::1;:17;::::0;;;;;56793:48:::1;::::0;56812:9;;56823:17:::1;;56793:18;:48::i;:::-;-1:-1:-1::0;;;;;56869:17:0;::::1;56852:14;56869:17:::0;;;:11:::1;:17;::::0;;;;;;;;;;56897:29;::::1;;-1:-1:-1::0;;56897:29:0;::::1;::::0;::::1;::::0;;;56942:87;;8572:3:1;8554:22;;;8613:2;8592:19;;;8585:31;-1:-1:-1;;;8647:3:1;8632:19;;8625:42;8757:20;;;8750:45;;;;56869:17:0::1;::::0;;::::1;8838:14:1::0;;8831:22;8811:18;;;8804:50;;;;8885:2;8870:18;;8863:50;;;;57001:10:0::1;-1:-1:-1::0;8929:19:1;;8922:44;57013:15:0::1;-1:-1:-1::0;8982:19:1;;8975:35;56869:17:0;56942:87:::1;::::0;8699:3:1;8684:19;56942:87:0::1;;;;;;;;56782:255;56700:337:::0;;:::o;48100:321::-;27511:21;:19;:21::i;:::-;48179:15:::1;:13;:15::i;:::-;48235:11;::::0;48205:42:::1;::::0;48224:9;;-1:-1:-1;;;48235:11:0;::::1;;;48205:18;:42::i;:::-;48275:11;::::0;;48297:23;::::1;;-1:-1:-1::0;;;48297:23:0;;::::1;-1:-1:-1::0;;;;48297:23:0;::::1;;::::0;;;48336:77:::1;::::0;;9323:3:1;9305:22;;;9364:2;9343:19;;;9336:31;-1:-1:-1;;;9398:3:1;9383:19;;9376:42;48275:11:0::1;::::0;;;::::1;::::0;;;::::1;9499:14:1::0;;9492:22;9485:4;9470:20;;9463:52;9531:18;;;9524:50;48385:10:0::1;-1:-1:-1::0;9590:18:1;;9583:60;48397:15:0::1;-1:-1:-1::0;9659:19:1;;9652:35;48336:77:0::1;::::0;9450:3:1;9435:19;48336:77:0::1;9021:672:1::0;53435:657:0;27511:21;:19;:21::i;:::-;-1:-1:-1;;;;;53540:32:0;::::1;;:36:::0;53536:102:::1;;53600:26;;-1:-1:-1::0;;;53600:26:0::1;;;;;;;;;;;53536:102;-1:-1:-1::0;;;;;53652:34:0;::::1;53648:100;;53710:26;::::0;-1:-1:-1;;;53710:26:0;;53733:1:::1;53710:26;::::0;::::1;3742:51:1::0;3715:18;;53710:26:0::1;3596:203:1::0;53648:100:0::1;53758:20;:18;:20::i;:::-;53832:17;::::0;53789:61:::1;::::0;53810:20;;-1:-1:-1;;;;;53832:17:0::1;53789:20;:61::i;:::-;53892:17;::::0;;-1:-1:-1;;;;;;53920:40:0;::::1;-1:-1:-1::0;;;;;53920:40:0;;::::1;::::0;;::::1;::::0;;;53976:108:::1;::::0;;10012:3:1;9994:22;;;10053:2;10032:19;;;10025:31;-1:-1:-1;;;10087:3:1;10072:19;;10065:48;53892:17:0;;;::::1;10218:4:1::0;10203:20;;10196:45;;;10257:18;;;10250:43;54056:10:0::1;-1:-1:-1::0;10309:18:1;;10302:43;54068:15:0::1;-1:-1:-1::0;10361:19:1;;10354:35;53892:17:0;53976:108:::1;::::0;10145:3:1;10130:19;53976:108:0::1;9698:697:1::0;49976:443:0;27511:21;:19;:21::i;:::-;50077:3:::1;50066:8;:14;50062:87;;;50104:33;::::0;-1:-1:-1;;;50104:33:0;;::::1;::::0;::::1;2572:25:1::0;;;50133:3:0::1;2613:18:1::0;;;2606:34;2545:18;;50104:33:0::1;2398:248:1::0;50062:87:0::1;50159:23;:21;:23::i;:::-;50193:44;50212:8;50222:14;;50193:18;:44::i;:::-;50267:14;::::0;;50292:25;;;;50333:78:::1;::::0;;10977:3:1;10959:22;;;11018:2;10997:19;;;10990:31;-1:-1:-1;;;11052:3:1;11037:19;;11030:45;11142:4;11127:20;;11120:36;;;11172:18;;;11165:34;;;50383:10:0::1;-1:-1:-1::0;11215:18:1;;11208:60;50395:15:0::1;-1:-1:-1::0;11284:19:1;;11277:35;50333:78:0::1;::::0;11107:3:1;11092:19;50333:78:0::1;10663:655:1::0;50770:519:0;27511:21;:19;:21::i;:::-;50855:15:::1;:13;:15::i;:::-;50903:4;50885:15;:22;50881:100;;;50931:38;::::0;-1:-1:-1;;;50931:38:0;;::::1;::::0;::::1;2572:25:1::0;;;50964:4:0::1;2613:18:1::0;;;2606:34;2545:18;;50931:38:0::1;2398:248:1::0;50881:100:0::1;50991:53;51010:15;51027:6;:16;;;50991:18;:53::i;:::-;51081:6;:16:::0;;51108:34;;;;51153:12;:30;;;51199:82:::1;::::0;;11637:3:1;11619:22;;;11678:1;11657:19;;;11650:30;-1:-1:-1;;;11711:3:1;11696:19;;11689:37;11793:4;11778:20;;11771:36;;;11823:18;;;11816:34;;;51253:10:0::1;-1:-1:-1::0;11866:18:1;;11859:60;51265:15:0::1;-1:-1:-1::0;11935:19:1;;11928:35;51199:82:0::1;::::0;11758:3:1;11743:19;51199:82:0::1;11323:646:1::0;57385:377:0;27511:21;:19;:21::i;:::-;-1:-1:-1;;;;;57516:25:0;::::1;;::::0;;;:19:::1;:25;::::0;;;;;57486:56:::1;::::0;57505:9;;57516:25:::1;;57486:18;:56::i;:::-;-1:-1:-1::0;;;;;57570:25:0;::::1;57553:14;57570:25:::0;;;:19:::1;:25;::::0;;;;;;;;;;57606:37;::::1;;-1:-1:-1::0;;57606:37:0;::::1;::::0;::::1;::::0;;;57659:95;;12304:3:1;12286:22;;;12345:2;12324:19;;;12317:31;-1:-1:-1;;;12379:3:1;12364:19;;12357:50;12497:20;;;12490:45;;;;57570:25:0::1;::::0;;::::1;12578:14:1::0;;12571:22;12551:18;;;12544:50;;;;12625:2;12610:18;;12603:50;;;;57726:10:0::1;-1:-1:-1::0;12669:19:1;;12662:44;57738:15:0::1;-1:-1:-1::0;12722:19:1;;12715:35;57570:25:0;57659:95:::1;::::0;12439:3:1;12424:19;57659:95:0::1;11974:782:1::0;54510:573:0;27511:21;:19;:21::i;:::-;-1:-1:-1;;;;;54629:16:0;::::1;;::::0;;;:8:::1;:16;::::0;;;;;54599:47:::1;::::0;54618:9;;54629:16:::1;;54599:18;:47::i;:::-;54695:4;-1:-1:-1::0;;;;;54661:39:0::1;54667:6;-1:-1:-1::0;;;;;54661:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;54661:39:0::1;;;:82;;;;;54738:4;-1:-1:-1::0;;;;;54704:39:0::1;54710:6;-1:-1:-1::0;;;;;54704:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;54704:39:0::1;;;54661:82;54657:144;;;54767:22;::::0;-1:-1:-1;;;54767:22:0;;-1:-1:-1;;;;;3760:32:1;;54767:22:0::1;::::0;::::1;3742:51:1::0;3715:18;;54767:22:0::1;3596:203:1::0;54657:144:0::1;54825:4;::::0;-1:-1:-1;;;;;54825:4:0::1;54816:14;::::0;;;:8:::1;:14;::::0;;;;;::::1;;54811:80;;54867:4;::::0;-1:-1:-1;;;;;54867:4:0::1;54847:25;::::0;;;:19:::1;:25;::::0;;;;:32;;-1:-1:-1;;54847:32:0::1;54875:4;54847:32;::::0;;54811:80:::1;-1:-1:-1::0;;;;;54918:16:0;::::1;54901:14;54918:16:::0;;;:8:::1;:16;::::0;;;;;;;;;;54945:28;::::1;;-1:-1:-1::0;;54945:28:0;::::1;::::0;::::1;::::0;;;54989:86;;13091:3:1;13073:22;;;13132:1;13111:19;;;13104:30;-1:-1:-1;;;13165:3:1;13150:19;;13143:39;13272:20;;;13265:45;;;;54918:16:0::1;::::0;;::::1;13353:14:1::0;;13346:22;13326:18;;;13319:50;;;;13400:2;13385:18;;13378:50;;;;55047:10:0::1;-1:-1:-1::0;13444:19:1;;13437:44;55059:15:0::1;-1:-1:-1::0;13497:19:1;;13490:35;54918:16:0;54989:86:::1;::::0;13214:3:1;13199:19;54989:86:0::1;12761:770:1::0;23260:103:0;20825:13;:11;:13::i;:::-;23325:30:::1;23352:1;23325:18;:30::i;:::-;23260:103::o:0;47409:408::-;27511:21;:19;:21::i;:::-;25838:6:::1;47507:19;:17;:19::i;:::-;:24;::::0;47529:2:::1;47507:24;:::i;:::-;:41;;;;:::i;:::-;47494:10;:54;47490:118;;;47572:24;::::0;-1:-1:-1;;;47572:24:0;;::::1;::::0;::::1;1901:25:1::0;;;1874:18;;47572:24:0::1;1755:177:1::0;47490:118:0::1;47618:39;47637:10;47649:7;;47618:18;:39::i;:::-;47689:7;::::0;;47707:20;;;;47743:66:::1;::::0;;5961:25:1;;;6017:2;6002:18;;5995:34;;;47781:10:0::1;6045:18:1::0;;;6038:60;;;;47793:15:0::1;6129:2:1::0;6114:18;;6107:34;47743:66:0::1;::::0;5948:3:1;5933:19;47743:66:0::1;5730:417:1::0;48717:369:0;27511:21;:19;:21::i;:::-;48804:23:::1;:21;:23::i;:::-;48868:19;::::0;48838:50:::1;::::0;48857:9;;-1:-1:-1;;;48868:19:0;::::1;;;48838:18;:50::i;:::-;48916:19;::::0;;48946:31;::::1;;-1:-1:-1::0;;;48946:31:0;;::::1;-1:-1:-1::0;;;;48946:31:0;::::1;;::::0;;48993:85:::1;::::0;;13838:3:1;13820:22;;;13858:19;;13851:31;;;;-1:-1:-1;;;13913:3:1;13898:19;;13891:50;48916:19:0::1;::::0;;;::::1;;14022:14:1::0;;14015:22;14008:4;13993:20;;13986:52;14054:18;;;14047:50;49050:10:0::1;-1:-1:-1::0;14113:18:1;;14106:60;49062:15:0::1;-1:-1:-1::0;14182:19:1;;14175:35;48916:19:0;48993:85:::1;::::0;13973:3:1;13958:19;48993:85:0::1;13536:680:1::0;46562:193:0;27511:21;:19;:21::i;:::-;46624:20:::1;:18;:20::i;:::-;46655:16;:23:::0;;-1:-1:-1;;;;46655:23:0::1;-1:-1:-1::0;;;46655:23:0::1;::::0;;46694:53:::1;::::0;;14479:2:1;14461:21;;;14518:2;14498:18;;;14491:30;-1:-1:-1;;;14552:3:1;14537:19;;14530:47;46719:10:0::1;14644:4:1::0;14629:20;;14622:62;46731:15:0::1;14700:18:1::0;;;14693:34;;;;-1:-1:-1;;;;;;;;;;;46694:53:0;14609:3:1;14594:19;46694:53:0::1;;;;;;;;46562:193::o:0;52528:549::-;27511:21;:19;:21::i;:::-;52618:15:::1;:13;:15::i;:::-;52666:4;52648:15;:22;52644:100;;;52694:38;::::0;-1:-1:-1;;;52694:38:0;;::::1;::::0;::::1;2572:25:1::0;;;52727:4:0::1;2613:18:1::0;;;2606:34;2545:18;;52694:38:0::1;2398:248:1::0;52644:100:0::1;52754:58;52773:15;52790:11;:21;;;52754:18;:58::i;:::-;52849:11;:21:::0;;52881:39;;;;52931:17;:35;;;52982:87:::1;::::0;;15052:3:1;15034:22;;;15093:2;15072:19;;;15065:31;-1:-1:-1;;;15127:3:1;15112:19;;15105:42;15214:4;15199:20;;15192:36;;;15244:18;;;15237:34;;;53041:10:0::1;-1:-1:-1::0;15287:18:1;;15280:60;53053:15:0::1;-1:-1:-1::0;15356:19:1;;15349:35;52982:87:0::1;::::0;15179:3:1;15164:19;52982:87:0::1;14738:652:1::0;39679:1118:0;39728:12;;-1:-1:-1;;;39728:12:0;;;;39724:101;;;39784:12;;39798:14;;39764:49;;-1:-1:-1;;;39764:49:0;;-1:-1:-1;;;39784:12:0;;;;;15588:14:1;15581:22;39764:49:0;;;15563:41:1;15620:18;;;15613:34;15536:18;;39764:49:0;15395:258:1;39724:101:0;39872:1;22619:6;-1:-1:-1;;;;;22619:6:0;39853:21;;;;:59;;-1:-1:-1;39902:10:0;39891:7;22592;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;39891:7;-1:-1:-1;;;;;39891:21:0;;;39853:59;:114;;;;-1:-1:-1;39952:15:0;39929:20;:10;39942:7;39929:20;:::i;:::-;:38;39853:114;39835:216;;;40001:38;;-1:-1:-1;;;40001:38:0;;40028:10;40001:38;;;3742:51:1;3715:18;;40001:38:0;3596:203:1;39835:216:0;40098:1;22619:6;-1:-1:-1;;;;;22619:6:0;40079:21;:59;;;;-1:-1:-1;40128:10:0;40117:7;22592;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;40117:7;-1:-1:-1;;;;;40117:21:0;;;40079:59;:114;;;;-1:-1:-1;40178:15:0;40155:20;:10;40168:7;40155:20;:::i;:::-;:38;40079:114;40061:313;;;40267:20;:10;40280:7;40267:20;:::i;:::-;40332:15;40308:20;:10;40321:7;40308:20;:::i;:::-;40307:40;;;;:::i;:::-;40227:135;;-1:-1:-1;;;40227:135:0;;;;;2572:25:1;;;;2613:18;;;2606:34;2545:18;;40227:135:0;2398:248:1;40061:313:0;40391:19;;-1:-1:-1;;;40391:19:0;;;;40386:79;;40427:19;:26;;-1:-1:-1;;;;40427:26:0;-1:-1:-1;;;40427:26:0;;;40386:79;40480:11;;-1:-1:-1;;;40480:11:0;;;;40475:63;;40508:11;:18;;-1:-1:-1;;;;40508:18:0;-1:-1:-1;;;40508:18:0;;;40475:63;40553:13;;-1:-1:-1;;;40553:13:0;;;;40548:67;;40583:13;:20;;-1:-1:-1;;;;40583:20:0;-1:-1:-1;;;40583:20:0;;;40548:67;40627:12;:19;;-1:-1:-1;;;;40627:19:0;-1:-1:-1;;;40627:19:0;;;40674:15;40657:14;:32;;;40718:12;40700:15;:30;40748:41;;;40761:10;15832:51:1;;15914:2;15899:18;;15892:34;;;;40748:41:0;;15805:18:1;40748:41:0;15658:274:1;49339:305:0;27511:21;:19;:21::i;:::-;49450:13:::1;::::0;49420:44:::1;::::0;49439:9;;-1:-1:-1;;;49450:13:0;::::1;;;49420:18;:44::i;:::-;49492:13;::::0;;49516:25;::::1;;-1:-1:-1::0;;;49516:25:0;;::::1;-1:-1:-1::0;;;;49516:25:0;::::1;;::::0;;;49557:79:::1;::::0;;16239:3:1;16221:22;;;16280:2;16259:19;;;16252:31;-1:-1:-1;;;16314:3:1;16299:19;;16292:44;49492:13:0::1;::::0;;;::::1;::::0;;;::::1;16417:14:1::0;;16410:22;16403:4;16388:20;;16381:52;16449:18;;;16442:50;49608:10:0::1;-1:-1:-1::0;16508:18:1;;16501:60;49620:15:0::1;-1:-1:-1::0;16577:19:1;;16570:35;49557:79:0::1;::::0;16368:3:1;16353:19;49557:79:0::1;15937:674:1::0;41193:151:0;63749:9;:18;;;;41304:6;41243:7;63749:18;;;;;63352:12;;41243:7;;63749:18;41270:42;;63749:18;41270:42;:::i;:::-;:66;;;;:::i;:::-;41263:73;;41193:151;:::o;46931:205::-;27511:21;:19;:21::i;:::-;46996:23:::1;:21;:23::i;:::-;47030:19;:26:::0;;-1:-1:-1;;;;47030:26:0::1;-1:-1:-1::0;;;47030:26:0::1;::::0;;47072:56:::1;::::0;;16874:2:1;16856:21;;;16893:18;;16886:30;;;;-1:-1:-1;;;16947:3:1;16932:19;;16925:50;47100:10:0::1;17042:4:1::0;17027:20;;17020:62;47112:15:0::1;17098:18:1::0;;;17091:34;-1:-1:-1;;;;;;;;;;;47072:56:0;17007:3:1;16992:19;47072:56:0::1;16616:515:1::0;64141:186:0;64210:4;64246:10;64267:30;64246:10;64287:2;64291:5;64267:9;:30::i;45905:166::-;20825:13;:11;:13::i;:::-;45955:15:::1;:13;:15::i;:::-;45981:11;:18:::0;;-1:-1:-1;;;;45981:18:0::1;-1:-1:-1::0;;;45981:18:0::1;::::0;;46015:48:::1;::::0;;17394:2:1;17376:21;;;17433:2;17413:18;;;17406:30;-1:-1:-1;;;17467:3:1;17452:19;;17445:42;46035:10:0::1;17554:4:1::0;17539:20;;17532:62;46047:15:0::1;17610:18:1::0;;;17603:34;;;;-1:-1:-1;;;;;;;;;;;46015:48:0;17519:3:1;17504:19;46015:48:0::1;17136:507:1::0;55549:812:0;27511:21;:19;:21::i;:::-;-1:-1:-1;;;;;55632:23:0;::::1;55628:88;;55679:25;::::0;-1:-1:-1;;;55679:25:0;;-1:-1:-1;;;;;3760:32:1;;55679:25:0::1;::::0;::::1;3742:51:1::0;3715:18;;55679:25:0::1;3596:203:1::0;55628:88:0::1;55766:6;::::0;55726:48:::1;::::0;55747:9;;-1:-1:-1;;;;;55766:6:0::1;55726:20;:48::i;:::-;55815:6;::::0;;-1:-1:-1;;;;;55833:27:0;;::::1;-1:-1:-1::0;;;;;;55833:27:0;::::1;::::0;::::1;::::0;;;55878:63:::1;::::0;;55815:6;;;::::1;17917:34:1::0;;;17982:2;17967:18;;17960:43;;;;55913:10:0::1;18019:18:1::0;;;18012:43;;;;55925:15:0::1;18086:2:1::0;18071:18;;18064:34;55878:63:0::1;::::0;17866:3:1;17851:19;55878:63:0::1;;;;;;;55975:6;::::0;:16:::1;::::0;;-1:-1:-1;;;55975:16:0;;;;56043:1:::1;::::0;-1:-1:-1;;;;;55975:6:0::1;::::0;:14:::1;::::0;:16:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:6;:16:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;55966:34:0::1;;56009:4;56016:6;;;;;;;;;-1:-1:-1::0;;;;;56016:6:0::1;-1:-1:-1::0;;;;;56016:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55966:64;::::0;-1:-1:-1;;;;;;55966:64:0::1;::::0;;;;;;-1:-1:-1;;;;;18339:15:1;;;55966:64:0::1;::::0;::::1;18321:34:1::0;18391:15;;18371:18;;;18364:43;18256:18;;55966:64:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;55958:87:0::1;::::0;55954:400:::1;;56078:6;;;;;;;;;-1:-1:-1::0;;;;;56078:6:0::1;-1:-1:-1::0;;;;;56078:14:0::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;56069:37:0::1;;56115:4;56122:6;;;;;;;;;-1:-1:-1::0;;;;;56122:6:0::1;-1:-1:-1::0;;;;;56122:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56069:67;::::0;-1:-1:-1;;;;;;56069:67:0::1;::::0;;;;;;-1:-1:-1;;;;;18339:15:1;;;56069:67:0::1;::::0;::::1;18321:34:1::0;18391:15;;18371:18;;;18364:43;18256:18;;56069:67:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56062:4;:74:::0;;-1:-1:-1;;;;;;56062:74:0::1;-1:-1:-1::0;;;;;56062:74:0;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;56158:25:0;;;:19:::1;:25;::::0;;;;;::::1;;56153:99;;56224:4;::::0;-1:-1:-1;;;;;56224:4:0::1;56204:25;::::0;;;:19:::1;:25;::::0;;;;:32;;-1:-1:-1;;56204:32:0::1;56232:4;56204:32;::::0;;56153:99:::1;56280:4;::::0;-1:-1:-1;;;;;56280:4:0::1;56271:14;::::0;;;:8:::1;:14;::::0;;;;;::::1;;56266:77;;56315:4;::::0;-1:-1:-1;;;;;56315:4:0::1;56306:14;::::0;;;:8:::1;:14;::::0;;;;:21;;-1:-1:-1;;56306:21:0::1;56323:4;56306:21;::::0;;56266:77:::1;55617:744;55549:812:::0;:::o;46236:155::-;20825:13;:11;:13::i;:::-;46291:16:::1;:23:::0;;-1:-1:-1;;;;46291:23:0::1;-1:-1:-1::0;;;46291:23:0::1;::::0;;46330:53:::1;::::0;;18676:2:1;18658:21;;;18715:2;18695:18;;;18688:30;-1:-1:-1;;;18749:3:1;18734:19;;18727:47;46355:10:0::1;18841:4:1::0;18826:20;;18819:62;46367:15:0::1;18897:18:1::0;;;18890:34;;;;-1:-1:-1;;;;;;;;;;;46330:53:0;18806:3:1;18791:19;46330:53:0::1;18418:512:1::0;61701:308:0;20825:13;:11;:13::i;:::-;-1:-1:-1;;;;;;;61787:27:0;::::1;::::0;61783:91:::1;;61838:24;::::0;-1:-1:-1;;;61838:24:0;;-1:-1:-1;;;;;3760:32:1;;61838:24:0::1;::::0;::::1;3742:51:1::0;3715:18;;61838:24:0::1;3596:203:1::0;61783:91:0::1;61884:39;61905:8;61915:7;22592::::0;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;61915:7:::1;61884:20;:39::i;:::-;61934:12;:23:::0;;-1:-1:-1;;;;;;61934:23:0::1;-1:-1:-1::0;;;;;61934:23:0;::::1;;::::0;;61968:33:::1;61934:23:::0;61968::::1;:33::i;:::-;61701:308:::0;:::o;72767:136::-;72855:40;72864:8;72874:7;72883:5;72890:4;72855:8;:40::i;:::-;72767:136;;;:::o;41549:223::-;41605:20;:18;:20::i;:::-;41640:12;;-1:-1:-1;;;;;41640:12:0;41656:10;41640:26;;;;:51;;-1:-1:-1;41681:10:0;41670:7;22592;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;41670:7;-1:-1:-1;;;;;41670:21:0;;;41640:51;41636:129;;;41715:38;;-1:-1:-1;;;41715:38:0;;41742:10;41715:38;;;3742:51:1;3715:18;;41715:38:0;3596:203:1;43416:121:0;43470:11;;-1:-1:-1;;;43470:11:0;;;;43466:64;;;43505:13;;-1:-1:-1;;;43505:13:0;;19137:2:1;43505:13:0;;;19119:21:1;19176:1;19156:18;;;19149:29;-1:-1:-1;;;19194:18:1;;;19187:33;19237:18;;43505:13:0;18935:326:1;41903:185:0;42007:7;41995:8;:19;41991:90;;42038:31;;-1:-1:-1;;;42038:31:0;;;;;1901:25:1;;;1874:18;;42038:31:0;1755:177:1;5824:162:0;5934:43;;;-1:-1:-1;;;;;15850:32:1;;5934:43:0;;;15832:51:1;15899:18;;;;15892:34;;;5934:43:0;;;;;;;;;;15805:18:1;;;;5934:43:0;;;;;;;;-1:-1:-1;;;;;5934:43:0;-1:-1:-1;;;5934:43:0;;;5907:71;;5927:5;;5907:19;:71::i;74687:496::-;-1:-1:-1;;;;;64819:21:0;;;74790:24;64819:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;-1:-1:-1;;74860:37:0;;74856:320;;74937:5;74918:16;:24;74914:132;;;74970:60;;-1:-1:-1;;;74970:60:0;;-1:-1:-1;;;;;19486:32:1;;74970:60:0;;;19468:51:1;19535:18;;;19528:34;;;19578:18;;;19571:34;;;19441:18;;74970:60:0;19266:345:1;74914:132:0;75089:60;75098:8;75108:7;75136:5;75117:16;:24;75143:5;75089:8;:60::i;67422:1245::-;-1:-1:-1;;;;;67506:18:0;;67502:88;;67548:30;;-1:-1:-1;;;67548:30:0;;67575:1;67548:30;;;3742:51:1;3715:18;;67548:30:0;3596:203:1;67502:88:0;-1:-1:-1;;;;;67604:16:0;;67600:88;;67644:32;;-1:-1:-1;;;67644:32:0;;67673:1;67644:32;;;3742:51:1;3715:18;;67644:32:0;3596:203:1;67600:88:0;67703:12;;-1:-1:-1;;;67703:12:0;;;;67698:151;;-1:-1:-1;;;;;67737:17:0;;;;;;:11;:17;;;;;;;;67736:18;:38;;;;-1:-1:-1;;;;;;67759:15:0;;;;;;:11;:15;;;;;;;;67758:16;67736:38;67732:106;;;67802:20;;-1:-1:-1;;;67802:20:0;;;;;;;;;;;67732:106;67865:6;;-1:-1:-1;;;67865:6:0;;;;;:27;;-1:-1:-1;;;;;;67875:17:0;;;;;;:11;:17;;;;;;;;67865:27;67861:91;;;67916:24;67924:4;67930:2;67934:5;67916:7;:24::i;67861:91::-;67974:4;;-1:-1:-1;;;;;67966:12:0;;;67974:4;;67966:12;;;;:29;;-1:-1:-1;67982:13:0;;-1:-1:-1;;;67982:13:0;;;;67966:29;:82;;;;-1:-1:-1;68041:7:0;;68020:17;;67999:18;;:38;;68020:17;67999:38;:::i;:::-;:49;;67966:82;:121;;;;-1:-1:-1;68080:7:0;;68070:4;63722:7;63749:18;;;:9;:18;;;;;;68052:35;;67966:121;67962:475;;;68125:7;;68153:16;;-1:-1:-1;;;68153:16:0;;;;:41;;;;-1:-1:-1;68192:1:0;22619:6;-1:-1:-1;;;;;22619:6:0;68173:21;68153:41;68149:238;;;68215:22;25838:6;68240:19;:17;:19::i;:::-;:24;;68262:2;68240:24;:::i;:::-;:41;;;;:::i;:::-;68215:66;;68331:10;68313:14;:28;;:58;;68361:10;68313:58;;;68344:14;68313:58;68300:71;;68196:191;68149:238;68403:22;68414:10;68403;:22::i;:::-;68089:348;67962:475;68490:11;;68468:5;;-1:-1:-1;;;68490:11:0;;;;:33;;;;-1:-1:-1;;;;;;68506:17:0;;;;;;:11;:17;;;;;;;;68505:18;68490:33;:53;;;;-1:-1:-1;;;;;;68528:15:0;;;;;;:11;:15;;;;;;;;68527:16;68490:53;68486:134;;;68571:37;68592:4;68598:2;68602:5;68571:20;:37::i;:::-;68560:48;;68486:134;68632:27;68640:4;68646:2;68650:8;68632:7;:27::i;42219:179::-;42317:7;42305:19;;:8;:19;;;42301:90;;42348:31;;-1:-1:-1;;;42348:31:0;;1408:14:1;;1401:22;42348:31:0;;;1383:41:1;1356:18;;42348:31:0;1243:187:1;43148:136:0;43207:16;;-1:-1:-1;;;43207:16:0;;;;43203:74;;;43247:18;;-1:-1:-1;;;43247:18:0;;19818:2:1;43247:18:0;;;19800:21:1;19857:1;19837:18;;;19830:29;-1:-1:-1;;;19875:18:1;;;19868:38;19923:18;;43247::0;19616:331:1;42533:195:0;42643:7;-1:-1:-1;;;;;42629:21:0;:10;-1:-1:-1;;;;;42629:21:0;;42625:96;;42674:35;;-1:-1:-1;;;42674:35:0;;-1:-1:-1;;;;;3760:32:1;;42674:35:0;;;3742:51:1;3715:18;;42674:35:0;3596:203:1;43687:145:0;43749:19;;-1:-1:-1;;;43749:19:0;;;;43745:80;;;43792:21;;-1:-1:-1;;;43792:21:0;;20154:2:1;43792:21:0;;;20136::1;20193:2;20173:18;;;20166:30;-1:-1:-1;;;20212:18:1;;;20205:41;20263:18;;43792:21:0;19952:335:1;22825:162:0;22896:10;22885:7;22592;22619:6;-1:-1:-1;;;;;22619:6:0;;22546:87;22885:7;-1:-1:-1;;;;;22885:21:0;;22881:99;;22930:38;;-1:-1:-1;;;22930:38:0;;22957:10;22930:38;;;3742:51:1;3715:18;;22930:38:0;3596:203:1;24340:191:0;24414:16;24433:6;;-1:-1:-1;;;;;24450:17:0;;;-1:-1:-1;;;;;;24450:17:0;;;;;;24483:40;;24433:6;;;;;;;24483:40;;24414:16;24483:40;24403:128;24340:191;:::o;42870:136::-;42929:16;;-1:-1:-1;;;42929:16:0;;;;42925:74;;;42969:18;;-1:-1:-1;;;42969:18:0;;20494:2:1;42969:18:0;;;20476:21:1;20533:1;20513:18;;;20506:29;-1:-1:-1;;;20551:18:1;;;20544:38;20599:18;;42969::0;20292:331:1;23789:220:0;20825:13;:11;:13::i;:::-;-1:-1:-1;;;;;23874:22:0;::::1;23870:93;;23920:31;::::0;-1:-1:-1;;;23920:31:0;;23948:1:::1;23920:31;::::0;::::1;3742:51:1::0;3715:18;;23920:31:0::1;3596:203:1::0;23870:93:0::1;23973:28;23992:8;23973:18;:28::i;73674:455::-:0;-1:-1:-1;;;;;73790:22:0;;73786:94;;73836:32;;-1:-1:-1;;;73836:32:0;;73865:1;73836:32;;;3742:51:1;3715:18;;73836:32:0;3596:203:1;73786:94:0;-1:-1:-1;;;;;73894:21:0;;73890:92;;73939:31;;-1:-1:-1;;;73939:31:0;;73967:1;73939:31;;;3742:51:1;3715:18;;73939:31:0;3596:203:1;73890:92:0;-1:-1:-1;;;;;73992:21:0;;;;;;;:11;:21;;;;;;;;:30;;;;;;;;;:38;;;74041:81;;;;74095:7;-1:-1:-1;;;;;74076:34:0;74085:8;-1:-1:-1;;;;;74076:34:0;;74104:5;74076:34;;;;1901:25:1;;1889:2;1874:18;;1755:177;74076:34:0;;;;;;;;73674:455;;;;:::o;6376:295::-;6457:23;6483:33;-1:-1:-1;;;;;6483:27:0;;6511:4;6483:27;:33::i;:::-;6457:59;;6531:10;:17;6552:1;6531:22;;:57;;;;;6569:10;6558:30;;;;;;;;;;;;:::i;:::-;6557:31;6531:57;6527:137;;;6612:40;;-1:-1:-1;;;6612:40:0;;-1:-1:-1;;;;;3760:32:1;;6612:40:0;;;3742:51:1;3715:18;;6612:40:0;3596:203:1;70471:999:0;-1:-1:-1;;;;;63749:18:0;;70557;63749;;;:9;:18;;;;;;70578:21;;70594:5;;70578:21;:::i;:::-;70557:42;;70610:13;25838:6;70648:14;;70626:19;:17;:19::i;:::-;:36;;;;:::i;:::-;:53;;;;:::i;:::-;70610:69;;70709:5;70696:10;:18;:46;;;;-1:-1:-1;;;;;;70719:23:0;;;;;;:19;:23;;;;;;;;70718:24;70696:46;70692:122;;;70766:36;;-1:-1:-1;;;70766:36:0;;;;;2572:25:1;;;2613:18;;;2606:34;;;2545:18;;70766:36:0;2398:248:1;70692:122:0;-1:-1:-1;;;;;70830:18:0;;70826:369;;70881:5;70865:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;70826:369:0;;-1:-1:-1;70826:369:0;;-1:-1:-1;;;;;70941:15:0;;70919:19;70941:15;;;:9;:15;;;;;;70975:19;;;70971:117;;;71022:50;;-1:-1:-1;;;71022:50:0;;-1:-1:-1;;;;;19486:32:1;;71022:50:0;;;19468:51:1;19535:18;;;19528:34;;;19578:18;;;19571:34;;;19441:18;;71022:50:0;19266:345:1;70971:117:0;-1:-1:-1;;;;;71131:15:0;;;;;;:9;:15;;;;;71149:19;;;;71131:37;;70826:369;-1:-1:-1;;;;;71211:16:0;;71207:213;;71273:12;:21;;;;;;;71207:213;;;-1:-1:-1;;;;;71371:13:0;;;;;;:9;:13;;;;;:22;;;;;;71207:213;71452:2;-1:-1:-1;;;;;71437:25:0;71446:4;-1:-1:-1;;;;;71437:25:0;;71456:5;71437:25;;;;1901::1;;1889:2;1874:18;;1755:177;71437:25:0;;;;;;;;70546:924;;70471:999;;;:::o;69264:518::-;27155:6;:13;;-1:-1:-1;;;;27155:13:0;-1:-1:-1;;;27155:13:0;;;-1:-1:-1;;;;;69395:14:0;::::1;69371:7:::0;69395:14;;;:8:::1;:14;::::0;;;;;27155:13;69395:14:::1;:40:::0;::::1;;;-1:-1:-1::0;69414:6:0::1;:16:::0;:20;;69395:40:::1;69391:104;;;69459:24;69470:4;69476:6;69459:10;:24::i;:::-;69452:31;;;;69391:104;-1:-1:-1::0;;;;;69509:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;:39:::0;::::1;;;-1:-1:-1::0;69526:7:0::1;:17:::0;:21;;69509:39:::1;69505:104;;;69572:25;69584:4;69590:6;69572:11;:25::i;69505:104::-;-1:-1:-1::0;;;;;69624:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;;::::1;;69623:15;:32:::0;::::1;;;-1:-1:-1::0;;;;;;69643:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;69642:13;69623:32;:63;;;;-1:-1:-1::0;69660:11:0::1;:21:::0;:25;;69623:63:::1;69619:132;;;69710:29;69726:4;69732:6;69710:15;:29::i;69619:132::-;-1:-1:-1::0;69768:6:0;27179:1:::1;27191:6:::0;:14;;-1:-1:-1;;;;27191:14:0;;;69264:518;;-1:-1:-1;;;69264:518:0:o;1635:178::-;1735:12;1767:38;1789:6;1797:4;1803:1;1767:21;:38::i;58118:141::-;27155:6;:13;;-1:-1:-1;;;;27155:13:0;-1:-1:-1;;;27155:13:0;;;58222:29:::1;::::0;;;;::::1;::::0;;;27164:4;58222:29;;;;;::::1;::::0;::::1;::::0;58195:7;;58222:29:::1;::::0;58238:4;58244:6;58222:7:::1;:29::i;58599:143::-:0;27155:6;:13;;-1:-1:-1;;;;27155:13:0;-1:-1:-1;;;27155:13:0;;;58704:30:::1;::::0;;;;::::1;::::0;;;58712:7:::1;58704:30:::0;;;;;::::1;::::0;::::1;::::0;58677:7;;58704:30:::1;::::0;58721:4;58727:6;58704:7:::1;:30::i;59086:151::-:0;27155:6;:13;;-1:-1:-1;;;;27155:13:0;-1:-1:-1;;;27155:13:0;;;59195:34:::1;::::0;;;;::::1;::::0;;;59203:11:::1;59195:34:::0;;;;;::::1;::::0;::::1;::::0;59168:7;;59195:34:::1;::::0;59216:4;59222:6;59195:7:::1;:34::i;2406:456::-:0;2539:12;2592:5;2568:21;:29;2564:110;;;2621:41;;-1:-1:-1;;;2621:41:0;;2656:4;2621:41;;;3742:51:1;3715:18;;2621:41:0;3596:203:1;2564:110:0;2685:12;2699:23;2726:6;-1:-1:-1;;;;;2726:11:0;2745:5;2766:4;2726:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2684:97;;;;2799:55;2826:6;2834:7;2843:10;2799:26;:55::i;:::-;2792:62;2406:456;-1:-1:-1;;;;;;2406:456:0:o;59633:492::-;27155:6;:13;;-1:-1:-1;;;;27155:13:0;-1:-1:-1;;;27155:13:0;;;59766:17;;59814:15:::1;::::0;59727:7;;59766:17;59814:19:::1;::::0;59727:7;59814:19:::1;:::i;:::-;59798:12;:35;59794:83;;-1:-1:-1::0;59861:4:0::1;59794:83;59887:17;25838:6;59907:17;59916:8:::0;59907:6;:17:::1;:::i;:::-;:34;;;;:::i;:::-;59887:54:::0;-1:-1:-1;59952:17:0::1;59972:18;59887:54:::0;59972:6;:18:::1;:::i;:::-;59952:38:::0;-1:-1:-1;60005:13:0;;60001:90:::1;;60035:44;60044:7;60053:4;60059:9;60070:8;60035;:44::i;:::-;27191:6:::0;:14;;-1:-1:-1;;;;27191:14:0;;;60108:9;59633:492;-1:-1:-1;;;;;;59633:492:0:o;3626:425::-;3774:12;3804:7;3799:245;;3828:19;3836:10;3828:7;:19::i;:::-;3799:245;;;3884:17;;:22;:49;;;;-1:-1:-1;;;;;;3910:18:0;;;:23;3884:49;3880:121;;;3961:24;;-1:-1:-1;;;3961:24:0;;-1:-1:-1;;;;;3760:32:1;;3961:24:0;;;3742:51:1;3715:18;;3961:24:0;3596:203:1;3880:121:0;-1:-1:-1;4022:10:0;4015:17;;60513:278;27155:6;:13;;-1:-1:-1;;;;27155:13:0;-1:-1:-1;;;27155:13:0;;;60659:17;;27155:13;;60679:3;;60650:26:::1;::::0;:6;:26:::1;:::i;:::-;:32;;;;:::i;:::-;60623:59;;60693:41;60709:16;60727:6;60693:15;:41::i;:::-;60747:36;60755:4;60769;60776:6;60747:7;:36::i;:::-;-1:-1:-1::0;;27191:6:0;:14;;-1:-1:-1;;;;27191:14:0;;;-1:-1:-1;;;60513:278:0:o;4319:328::-;4389:17;;:21;4385:255;;4484:10;4478:17;4541:15;4528:10;4524:2;4520:19;4513:44;4385:255;4611:17;;-1:-1:-1;;;4611:17:0;;;;;;;;;;;61046:185;27155:6;:13;;-1:-1:-1;;;;27155:13:0;-1:-1:-1;;;27155:13:0;;;61142:12:::1;:42:::0;;61168:16;;61142:12;27155:13;;61142:42:::1;::::0;61168:16;;61142:42:::1;:::i;:::-;::::0;;;-1:-1:-1;;61195:18:0;:28;;61217:6;;61195:18;::::1;::::0;:28:::1;::::0;61217:6;;61195:28:::1;:::i;:::-;::::0;;;-1:-1:-1;;27191:6:0;:14;;-1:-1:-1;;;;27191:14:0;;;-1:-1:-1;;61046:185:0:o;14:180:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;199:250::-;284:1;294:113;308:6;305:1;302:13;294:113;;;384:11;;;378:18;365:11;;;358:39;330:2;323:10;294:113;;;-1:-1:-1;;441:1:1;423:16;;416:27;199:250::o;454:396::-;603:2;592:9;585:21;566:4;635:6;629:13;678:6;673:2;662:9;658:18;651:34;694:79;766:6;761:2;750:9;746:18;741:2;733:6;729:15;694:79;:::i;:::-;834:2;813:15;-1:-1:-1;;809:29:1;794:45;;;;841:2;790:54;;454:396;-1:-1:-1;;454:396:1:o;855:131::-;-1:-1:-1;;;;;930:31:1;;920:42;;910:70;;976:1;973;966:12;991:247;1050:6;1103:2;1091:9;1082:7;1078:23;1074:32;1071:52;;;1119:1;1116;1109:12;1071:52;1158:9;1145:23;1177:31;1202:5;1177:31;:::i;1435:315::-;1503:6;1511;1564:2;1552:9;1543:7;1539:23;1535:32;1532:52;;;1580:1;1577;1570:12;1532:52;1619:9;1606:23;1638:31;1663:5;1638:31;:::i;:::-;1688:5;1740:2;1725:18;;;;1712:32;;-1:-1:-1;;;1435:315:1:o;1937:456::-;2014:6;2022;2030;2083:2;2071:9;2062:7;2058:23;2054:32;2051:52;;;2099:1;2096;2089:12;2051:52;2138:9;2125:23;2157:31;2182:5;2157:31;:::i;:::-;2207:5;-1:-1:-1;2264:2:1;2249:18;;2236:32;2277:33;2236:32;2277:33;:::i;:::-;1937:456;;2329:7;;-1:-1:-1;;;2383:2:1;2368:18;;;;2355:32;;1937:456::o;2840:118::-;2926:5;2919:13;2912:21;2905:5;2902:32;2892:60;;2948:1;2945;2938:12;2963:382;3028:6;3036;3089:2;3077:9;3068:7;3064:23;3060:32;3057:52;;;3105:1;3102;3095:12;3057:52;3144:9;3131:23;3163:31;3188:5;3163:31;:::i;:::-;3213:5;-1:-1:-1;3270:2:1;3255:18;;3242:32;3283:30;3242:32;3283:30;:::i;:::-;3332:7;3322:17;;;2963:382;;;;;:::o;3350:241::-;3406:6;3459:2;3447:9;3438:7;3434:23;3430:32;3427:52;;;3475:1;3472;3465:12;3427:52;3514:9;3501:23;3533:28;3555:5;3533:28;:::i;3804:388::-;3872:6;3880;3933:2;3921:9;3912:7;3908:23;3904:32;3901:52;;;3949:1;3946;3939:12;3901:52;3988:9;3975:23;4007:31;4032:5;4007:31;:::i;:::-;4057:5;-1:-1:-1;4114:2:1;4099:18;;4086:32;4127:33;4086:32;4127:33;:::i;4420:127::-;4481:10;4476:3;4472:20;4469:1;4462:31;4512:4;4509:1;4502:15;4536:4;4533:1;4526:15;4552:168;4625:9;;;4656;;4673:15;;;4667:22;;4653:37;4643:71;;4694:18;;:::i;4725:217::-;4765:1;4791;4781:132;;4835:10;4830:3;4826:20;4823:1;4816:31;4870:4;4867:1;4860:15;4898:4;4895:1;4888:15;4781:132;-1:-1:-1;4927:9:1;;4725:217::o;4947:128::-;5014:9;;;5035:11;;;5032:37;;;5049:18;;:::i;5080:125::-;5145:9;;;5166:10;;;5163:36;;;5179:18;;:::i;5342:127::-;5403:10;5398:3;5394:20;5391:1;5384:31;5434:4;5431:1;5424:15;5458:4;5455:1;5448:15;5474:251;5544:6;5597:2;5585:9;5576:7;5572:23;5568:32;5565:52;;;5613:1;5610;5603:12;5565:52;5645:9;5639:16;5664:31;5689:5;5664:31;:::i;6152:980::-;6414:4;6462:3;6451:9;6447:19;6493:6;6482:9;6475:25;6519:2;6557:6;6552:2;6541:9;6537:18;6530:34;6600:3;6595:2;6584:9;6580:18;6573:31;6624:6;6659;6653:13;6690:6;6682;6675:22;6728:3;6717:9;6713:19;6706:26;;6767:2;6759:6;6755:15;6741:29;;6788:1;6798:195;6812:6;6809:1;6806:13;6798:195;;;6877:13;;-1:-1:-1;;;;;6873:39:1;6861:52;;6968:15;;;;6933:12;;;;6909:1;6827:9;6798:195;;;-1:-1:-1;;;;;;;7049:32:1;;;;7044:2;7029:18;;7022:60;-1:-1:-1;;;7113:3:1;7098:19;7091:35;7010:3;6152:980;-1:-1:-1;;;6152:980:1:o;8053:184::-;8123:6;8176:2;8164:9;8155:7;8151:23;8147:32;8144:52;;;8192:1;8189;8182:12;8144:52;-1:-1:-1;8215:16:1;;8053:184;-1:-1:-1;8053:184:1:o;20628:245::-;20695:6;20748:2;20736:9;20727:7;20723:23;20719:32;20716:52;;;20764:1;20761;20754:12;20716:52;20796:9;20790:16;20815:28;20837:5;20815:28;:::i;20878:287::-;21007:3;21045:6;21039:13;21061:66;21120:6;21115:3;21108:4;21100:6;21096:17;21061:66;:::i;:::-;21143:16;;;;;20878:287;-1:-1:-1;;20878:287:1:o
Swarm Source
ipfs://bad7885b9185658913a0acf06678eca7cce0f2caef63a8c6ebc72fd390923157
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.