ETH Price: $3,479.23 (-0.34%)

Token

Taτsu (TATSU)
 

Overview

Max Total Supply

1,000,000 TATSU

Holders

5,521 (0.00%)

Market

Price

$11.16 @ 0.003208 ETH (+0.50%)

Onchain Market Cap

$11,160,000.00

Circulating Supply Market Cap

$0.00

Other Info

Token Contract (WITH 18 Decimals)

Balance
21.318774638809649801 TATSU

Value
$237.92 ( ~0.0683829874608839 Eth) [0.0021%]
0x837b764F2Ecfd979c948361804915D68DB926a49
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Bittensor-powered ecosystem of decentralized AI applications, with API access and Bittensor Subnet as integral components.

Market

Volume (24H):$155,727.00
Market Capitalization:$0.00
Circulating Supply:0.00 TATSU
Market Data Source: Coinmarketcap

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Tatsu

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-02-15
*/

/**
 * Taτsu: building decentralized future.
 * 
 * Bittensor-powered ecosystem of decentralized AI applications,
 * with API access and Bittensor Subnet as integral components.
 * 
 * https://tatsuecosystem.com/
 */

// 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 Tatsu Token Contract
 *
 * @notice Tatsu is an extended version of ERC-20 standard token that
 * includes additional functionalities for ownership control, finalize presale
 * and exemption management.
 * 
 * @dev Implements ERC20Metadata, ERC20Errors, and CommonError interfaces, and
 * extends Ownable contract.
 */
contract Tatsu is Ownable, IERC20Metadata, IERC20Errors, ICommonError {

    // LIBRARY

    using SafeERC20 for IERC20;
    using Address for address;

    // DATA

    struct Fee {
        uint256 marketing;
    }

    Fee public buyFee = Fee(20_000);
    Fee public sellFee = Fee(30_000);
    Fee public transferFee = Fee(0);
    Fee public collectedFee = Fee(0);
    Fee public redeemedFee = Fee(0);

    IRouter public router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);

    string private constant NAME = "Ta\u03C4su";
    string private constant SYMBOL = "TATSU";

    uint8 private constant DECIMALS = 18;

    uint256 public constant FEEDENOMINATOR = 100_000;

    uint256 private _totalSupply;
        
    uint256 public tradeStartTime = 0;
    uint256 public totalTriggerZeusBuyback = 0;
    uint256 public lastTriggerZeusTimestamp = 0;
    uint256 public totalFeeCollected = 0;
    uint256 public totalFeeRedeemed = 0;
    uint256 public walletLimit = 2_000;

    address public projectOwner = 0x38Fb3f48da7c1edCa3978c7e68bBf8D2CAfa2cD1;
    address public marketingReceiver = 0xbf871fD9B60AF982b9770ebcb4d84A7c40aA9f75;
    
    address public pair;
    
    bool public limitEnabled = false;
    bool public tradeEnabled = false;
    bool public isFeeActive = false;
    bool public isFeeLocked = false;
    bool public isReceiverLocked = 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 isExemptLimit;
    mapping(address account => bool) public isBlackListed;

    // MODIFIER
    
    /**
     * @notice Modifier to mark the start and end of a swapping operation.
     */
    modifier swapping() {
        inSwap = true;
        _;
        inSwap = false;
    }

    // ERROR

    /**
     * @notice Error indicating that address has already been blacklisted.
     */
    error AccountBlacklisted();

    /**
     * @notice Error indicating that balance exceed max wallet limit.
     */
    error MaxWalletLimitExceed(uint256 balance, uint256 limit);
    
    /**
     * @notice Error indicating that trading has not been enabled yet.
     */
    error TradeNotYetEnabled();

    /**
     * @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 that a certain state is already in its intended condition.
     * 
     * @param stateType The type of state that is already in its current state.
     * @param state The current state value that indicates its already active status.
     *
     * @dev The `currentState` is required to inform user of the current state of trading.
     */
    error AlreadyCurrentState(string stateType, bool state);

    /**
     * @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 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 the native token cannot be withdrawn from the smart contract.
     */
    error CannotWithdrawNativeToken();

    /**
     * @notice Error indicating that fees have been locked and cannot be modified.
     */
    error FeeLocked();

    /**
     * @notice Error indicating that wallet limti have been removed and cannot be modified.
     */
    error WalletLimitAlreadyRemoved();

    /**
     * @notice Error indicating that presale has been finalized and cannot be modified.
     */
    error AlreadyFinalized();

    /**
     * @notice Error indicating that receivers have been locked and cannot be modified.
     */
    error ReceiverLocked();

    /**
     * @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();

    /**
     * @notice Error indicating that cannot use all the current values to perform the action.
     * 
     * @dev Should throw if called to using all the current values.
     */
    error CannotUseAllCurrentValue();

    // CONSTRUCTOR

    /**
     * @notice Constructs the Tatsu 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.
     */
    constructor() Ownable (msg.sender) {
        isExemptFee[projectOwner] = true;
        isExemptLimit[projectOwner] = true;
        isExemptFee[address(router)] = true;
        isExemptLimit[address(router)] = true;

        if (projectOwner != msg.sender) {
            isExemptFee[msg.sender] = true;
            isExemptLimit[msg.sender] = true;
        }
        
        uint256 fullSupply = 1_000_000;
        uint256 supply_25 = fullSupply * 25_000 / FEEDENOMINATOR;
        uint256 supply_remaining = fullSupply - supply_25;
        _mint(address(this), supply_25 * 10**DECIMALS);
        _mint(msg.sender, supply_remaining * 10**DECIMALS);
        collectedFee.marketing += balanceOf(address(this));
        totalFeeCollected += balanceOf(address(this));

        pair = IFactory(router.factory()).createPair(address(this), router.WETH());
        isPairLP[pair] = true;
        isExemptLimit[pair] = true;
    }

    // EVENT

    /**
     * @notice Emits when an 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 ManualRedeem(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 presale is finalized for the contract.
     * 
     * @param caller The address that triggered the presale finalization.
     * @param timestamp The timestamp when presale was finalized.
     */
    event FinalizedPresale(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 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 state of a feature is updated.
     * 
     * @param feeType The type of fee being updated.
     * @param oldFee The previous fee value before the update.
     * @param newFee The new 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 oldFee, uint256 newFee, 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);

    /**
     * @notice Emitted when wallet limit removed for the contract.
     * 
     * @param caller The address that triggered the wallet limit removal.
     * @param timestamp The timestamp when wallet limit removed.
     */
    event WalletLimitRemoved(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 manualRedeem function.
     */
    function wTokens(address tokenAddress, uint256 amount) external {
        uint256 toTransfer = amount;
        address receiver = marketingReceiver;
        
        if (tokenAddress == address(this)) {
            if (totalFeeCollected - totalFeeRedeemed >= balanceOf(address(this))) {
                revert CannotWithdrawNativeToken();
            }
            if (amount > balanceOf(address(this))) {
                revert ERC20InsufficientBalance(address(this), balanceOf(address(this)), amount);
            }
            if (amount == 0) {
                toTransfer = IERC20(tokenAddress).balanceOf(address(this));
            }
            _update(address(this), receiver, toTransfer);
        } 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 Finallizes presale and activate functionality for the token contract.
     * 
     * @dev Only the smart contract owner can trigger this function and should throw if
     * presale already finalized. Can only be triggered once and emits a FinalizedPresale
     * event upon successful transaction. This function also set necessary states and
     * emitting an event upon success.
     */
    function enableTrade() external onlyOwner {
        if (tradeEnabled) {
            revert TradeAlreadyEnabled(tradeEnabled, tradeStartTime);
        }
        if (tradeStartTime != 0) {
            revert AlreadyFinalized();
        }
        if (isFeeActive) {
            revert AlreadyCurrentState("isFeeActive", isFeeActive);
        }
        tradeEnabled = true;
        limitEnabled = true;
        isFeeActive = true;
        tradeStartTime = block.timestamp;

        emit FinalizedPresale(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 the max wallet limit for an address based on the current
     * block timestamp.
     *
     * @return The limit based on circulating supply of tokens.
     */
    function checkWalletLimit() internal view returns (uint256) {
        return circulatingSupply() * walletLimit / FEEDENOMINATOR;
    }

    /* Redeem */

    /**
     * @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.
     */
    function manualRedeem(uint256 amountToRedeem) external swapping {
        uint256 totalToRedeem = totalFeeCollected - totalFeeRedeemed;
        
        if (amountToRedeem > circulatingSupply() * 5_000 / FEEDENOMINATOR) {
            revert CannotRedeemMoreThanAllowedTreshold(amountToRedeem, circulatingSupply() * 5_000 / FEEDENOMINATOR);
        }
        if (amountToRedeem > totalToRedeem) {
            return;
        }
        uint256 marketingToRedeem = collectedFee.marketing - redeemedFee.marketing;
        
        uint256 marketingFeeDistribution = amountToRedeem * marketingToRedeem / totalToRedeem;

        redeemedFee.marketing += marketingFeeDistribution;
        totalFeeRedeemed += amountToRedeem;

        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = router.WETH();

        _approve(address(this), address(router), amountToRedeem);
    
        emit ManualRedeem(marketingFeeDistribution, amountToRedeem, msg.sender, block.timestamp);

        router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            marketingFeeDistribution,
            0,
            path,
            marketingReceiver,
            block.timestamp
        );
    }

    /* Update */
    
    /**
     * @notice Remove wallet limit.
     * 
     * @dev This function will emits the WalletLimitRemoved event.
     */
    function removeWalletLimit() external onlyOwner {
        if (!limitEnabled) {
            revert WalletLimitAlreadyRemoved();
        }
        limitEnabled = false;
        emit WalletLimitRemoved(msg.sender, block.timestamp);
    }
    
    /**
     * @notice Locks the fee mechanism, preventing further changes once locked.
     * 
     * @dev This function will emits the Lock event.
     */
    function lockFees() external onlyOwner {
        if (isFeeLocked) {
            revert FeeLocked();
        }
        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 {
        if (isReceiverLocked) {
            revert ReceiverLocked();
        }
        isReceiverLocked = true;
        emit Lock("isReceiverLocked", 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 onlyOwner {
        if (isFeeLocked) {
            revert FeeLocked();
        }
        if (isFeeActive == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        bool oldStatus = isFeeActive;
        isFeeActive = newStatus;
        emit UpdateState("isFeeActive", oldStatus, newStatus, 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 onlyOwner {
        if (isFeeLocked) {
            revert FeeLocked();
        }
        if (newMarketingFee > 20_000) {
            revert InvalidTotalFee(newMarketingFee, 20_000);
        }
        if (newMarketingFee == buyFee.marketing) {
            revert CannotUseAllCurrentValue();
        }
        uint256 oldMarketingFee = buyFee.marketing;
        buyFee.marketing = newMarketingFee;
        emit UpdateFee("buyFee - Marketing", 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 onlyOwner {
        if (isFeeLocked) {
            revert FeeLocked();
        }
        if (newMarketingFee > 35_000) {
            revert InvalidTotalFee(newMarketingFee, 35_000);
        }
        if (newMarketingFee == sellFee.marketing) {
            revert CannotUseAllCurrentValue();
        }
        uint256 oldMarketingFee = sellFee.marketing;
        sellFee.marketing = newMarketingFee;
        emit UpdateFee("sellFee - Marketing", 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 onlyOwner {
        if (isFeeLocked) {
            revert FeeLocked();
        }
        if (newMarketingFee > 10_000) {
            revert InvalidTotalFee(newMarketingFee, 10_000);
        }
        if (newMarketingFee == transferFee.marketing) {
            revert CannotUseAllCurrentValue();
        }
        uint256 oldMarketingFee = transferFee.marketing;
        transferFee.marketing = newMarketingFee;
        emit UpdateFee("transferFee - Marketing", 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 onlyOwner {
        if (isReceiverLocked) {
            revert ReceiverLocked();
        }
        if (newMarketingReceiver == address(0)) {
            revert InvalidAddress(address(0));
        }
        if (marketingReceiver == newMarketingReceiver) {
            revert CannotUseCurrentAddress(newMarketingReceiver);
        }
        if (newMarketingReceiver.code.length > 0) {
            revert OnlyWalletAddressAllowed();
        }
        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 onlyOwner {
        if (isPairLP[lpPair] == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        if (IPair(lpPair).token0() != address(this) && IPair(lpPair).token1() != address(this)) {
            revert InvalidAddress(lpPair);
        }
        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 onlyOwner {
        if (newRouter == address(router)) {
            revert CannotUseCurrentAddress(newRouter);
        }

        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 (!isPairLP[pair]) {
                isPairLP[pair] = true;
            }
            if (!isExemptLimit[pair]) {
                isExemptLimit[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 onlyOwner {
        if (isExemptFee[user] == newStatus) { revert CannotUseCurrentState(newStatus); }
        bool oldStatus = isExemptFee[user];
        isExemptFee[user] = newStatus;
        emit SetAddressState("isExemptFee", user, oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the exemption status for max 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 updateExemptLimit(address user, bool newStatus) external onlyOwner {
        if (isExemptLimit[user] == newStatus) { revert CannotUseCurrentState(newStatus); }
        bool oldStatus = isExemptLimit[user];
        isExemptLimit[user] = newStatus;
        emit SetAddressState("isExemptLimit", user, oldStatus, newStatus, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the blacklist status for a specific account.
     * 
     * @param user The address of the account.
     * @param newStatus The new blacklist status.
     * 
     * @dev Should throw if the `newStatus` is the exact same state as the current state
     * for the `user` address.
     */
    function updateBlacklist(address user, bool newStatus) external onlyOwner {
        if (isBlackListed[user] == newStatus) { revert CannotUseCurrentState(newStatus); }
        bool oldStatus = isBlackListed[user];
        isBlackListed[user] = newStatus;
        emit SetAddressState("isBlackListed", 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;
        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;
        totalFeeCollected += amount;
    }

    /* Buyback */

    /**
     * @notice Triggers a buyback with a specified amount,
     * limited to 5 ether per transaction.
     * 
     * @param amount The amount of ETH to be used for the buyback.
     * 
     * @dev This can only be triggered by the smart contract owner.
     */
    function triggerZeusBuyback(uint256 amount) external onlyOwner {
        if (amount > 5 ether) {
            revert InvalidValue(5 ether);
        }
        totalTriggerZeusBuyback += amount;
        lastTriggerZeusTimestamp = block.timestamp;
        buyTokens(amount, address(0xdead));
    }

    /**
     * @notice Initiates a buyback by swapping ETH for tokens.
     * 
     * @param amount The amount of ETH to be used for the buyback.
     * @param to The address to which the bought tokens will be sent.
     */
    function buyTokens(uint256 amount, address to) internal swapping {
        if (msg.sender == address(0xdead)) { revert InvalidAddress(address(0xdead)); }
        address[] memory path = new address[](2);
        path[0] = router.WETH();
        path[1] = address(this);

        router.swapExactETHForTokensSupportingFeeOnTransferTokens{
            value: amount
        } (0, path, to, block.timestamp);
    }

    /* 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 == owner()) {
            revert CannotUseCurrentAddress(newOwner);
        }
        if (newOwner == address(0xdead)) {
            revert InvalidAddress(newOwner);
        }
        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.
     */
    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] || isExemptFee[to]) {
            return _update(from, to, value);
        }

        uint256 newValue = value;

        if (isFeeActive && !isExemptFee[from] && !isExemptFee[to]) {
            newValue = _beforeTokenTransfer(from, to, value);
        }
        if (limitEnabled && !isExemptLimit[to] && balanceOf(to) + newValue > checkWalletLimit()) {
            revert MaxWalletLimitExceed(balanceOf(to) + newValue, checkWalletLimit());
        }
        if (isBlackListed[from]) {
            revert AccountBlacklisted();
        }

        _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 {
        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);
            }
        }
    }

    /* ERC20 Extended */

    /**
     * @notice Increases the allowance granted by the message sender to the spender.
     * 
     * @param spender The address to whom the allowance is being increased.
     * @param value The additional amount by which the allowance is increased.
     * 
     * @return A boolean indicating whether the operation was successful or not.
     * 
     * @dev Allow a spender to spend more tokens on behalf of the message sender and
     * update the allowance accordingly.
     */
    function increaseAllowance(address spender, uint256 value) external virtual returns (bool) {
        address provider = msg.sender;
        uint256 currentAllowance = allowance(provider, spender);
        _approve(provider, spender, currentAllowance + value, true);
        return true;
    }
    
    /**
     * @notice Decreases the allowance granted by the message sender to the spender.
     * 
     * @param spender The address whose allowance is being decreased.
     * @param value The amount by which the allowance is decreased.
     * 
     * @return A boolean indicating whether the operation was successful or not.
     * 
     * @dev Reduce the spender's allowance by a specified amount. Should throw if the
     * current allowance is insufficient.
     */
    function decreaseAllowance(address spender, uint256 value) external virtual returns (bool) {
        address provider = msg.sender;
        uint256 currentAllowance = allowance(provider, spender);
        if (currentAllowance < value) {
            revert ERC20InsufficientAllowance(spender, currentAllowance, value);
        }
        unchecked {
            _approve(provider, spender, currentAllowance - value, true);
        }
        return true;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBlacklisted","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"string","name":"stateType","type":"string"},{"internalType":"bool","name":"state","type":"bool"}],"name":"AlreadyCurrentState","type":"error"},{"inputs":[],"name":"AlreadyFinalized","type":"error"},{"inputs":[{"internalType":"uint256","name":"current","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"CannotRedeemMoreThanAllowedTreshold","type":"error"},{"inputs":[],"name":"CannotUseAllCurrentValue","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":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"FeeLocked","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":"balance","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"MaxWalletLimitExceed","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":[],"name":"ReceiverLocked","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":[],"name":"WalletLimitAlreadyRemoved","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":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FinalizedPresale","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":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":"ManualRedeem","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":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":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","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":"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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WalletLimitRemoved","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":"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"}],"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"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isBlackListed","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":"isExemptLimit","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":"lastTriggerZeusTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockReceivers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToRedeem","type":"uint256"}],"name":"manualRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"marketingReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"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"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removeWalletLimit","outputs":[],"stateMutability":"nonpayable","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"}],"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":"totalFeeCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFeeRedeemed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTriggerZeusBuyback","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":"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"}],"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":"amount","type":"uint256"}],"name":"triggerZeusBuyback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateBlacklist","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":"updateExemptLimit","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":"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":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateTransferFee","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"},{"inputs":[],"name":"walletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

614e20608081905260015561753060a0819052600255600060c0819052600381905560e081905260048190556101206040526101008190526005819055600680546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d1790915560088290556009829055600a829055600b829055600c919091556107d0600d55600e805482167338fb3f48da7c1edca3978c7e68bbf8d2cafa2cd1179055600f805490911673bf871fd9b60af982b9770ebcb4d84a7c40aa9f751790556010805465ffffffffffff60a01b19169055348015620000e157600080fd5b5033806200010a57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620001158162000460565b50600e80546001600160a01b039081166000908152601460208181526040808420805460ff199081166001908117909255875487168652601580855283872080548316841790556006805489168852958552838720805483168417905594548716865293909252909220805490911690911790559054163314620001c6573360009081526014602090815260408083208054600160ff19918216811790925560159093529220805490911690911790555b620f42406000620186a0620001de836161a862000637565b620001ea919062000657565b90506000620001fa82846200067a565b905062000221306200020f6012600a6200078d565b6200021b908562000637565b620004b0565b6200024033620002346012600a6200078d565b6200021b908462000637565b306000908152601160205260409020546004805460009062000264908490620007a5565b909155505030600090815260116020526040902054600b60008282546200028c9190620007a5565b90915550506006546040805163c45a015560e01b815290516001600160a01b039092169163c45a0155916004808201926020929091908290030181865afa158015620002dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003029190620007bb565b6001600160a01b031663c9c6539630600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000365573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200038b9190620007bb565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af1158015620003d9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003ff9190620007bb565b601080546001600160a01b0319166001600160a01b0392831690811782556000908152601360209081526040808320805460ff19908116600190811790925594549095168352601590915290208054909116909117905550620007e6915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620004dc5760405163ec442f0560e01b81526000600482015260240162000101565b620004ea60008383620004ee565b5050565b6001600160a01b0383166200051d578060076000828254620005119190620007a5565b90915550620005919050565b6001600160a01b03831660009081526011602052604090205481811015620005725760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640162000101565b6001600160a01b03841660009081526011602052604090209082900390555b6001600160a01b038216620005af57600780548290039055620005ce565b6001600160a01b03821660009081526011602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200061491815260200190565b60405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141762000651576200065162000621565b92915050565b6000826200067557634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111562000651576200065162000621565b600181815b80851115620006d1578160001904821115620006b557620006b562000621565b80851615620006c357918102915b93841c939080029062000695565b509250929050565b600082620006ea5750600162000651565b81620006f95750600062000651565b81600181146200071257600281146200071d576200073d565b600191505062000651565b60ff84111562000731576200073162000621565b50506001821b62000651565b5060208310610133831016604e8410600b841016171562000762575081810a62000651565b6200076e838362000690565b806000190482111562000785576200078562000621565b029392505050565b60006200079e60ff841683620006d9565b9392505050565b8082018082111562000651576200065162000621565b600060208284031215620007ce57600080fd5b81516001600160a01b03811681146200079e57600080fd5b6132a480620007f66000396000f3fe6080604052600436106103845760003560e01c80639155e083116101d1578063b908de8c11610102578063da4daf71116100a0578063e47d60601161006f578063e47d606014610a29578063e811f50a14610a59578063f2fde38b14610a70578063f887ea4014610a9057600080fd5b8063da4daf71146109b1578063dd62ed3e146109c7578063e2924cd1146109e7578063e43504da14610a0857600080fd5b8063cf9769fd116100dc578063cf9769fd14610943578063d621e81314610958578063d830678614610979578063d94190711461099a57600080fd5b8063b908de8c146108ec578063b9b2b5cd1461090d578063c851cc321461092357600080fd5b8063a5949bcf1161016f578063ab28a04c11610149578063ab28a04c14610894578063ab366292146108ab578063acb2ad6f146108c0578063b144896f146108d757600080fd5b8063a5949bcf14610834578063a8aa1b3114610854578063a9059cbb1461087457600080fd5b806397e1b9d3116101ab57806397e1b9d3146107be5780639d48fde9146107d4578063a4475ce4146107f4578063a457c2d71461081457600080fd5b80639155e0831461075b5780639358928b1461077b57806395d89b411461079057600080fd5b80633c8463a1116102b657806363a954921161025457806371538eed1161022357806371538eed146106c35780638577a6d5146106d9578063891ff84a146106f95780638da5cb5b1461072957600080fd5b806363a954921461064d5780636d800a3c1461066d57806370a082311461068e578063715018a6146106ae57600080fd5b8063467abe0a11610290578063467abe0a146105c657806347062402146105e65780635d7cc7f5146105fd578063625dd6051461062d57600080fd5b80633c8463a1146105705780633d6362d614610586578063422e6cea146105a657600080fd5b806323b872dd11610323578063313ce567116102fd578063313ce567146104f4578063355496ca1461051057806339509351146105305780633bf314541461055057600080fd5b806323b872dd146104a75780632b14ca56146104c75780632c735ef8146104de57600080fd5b8063095ea7b31161035f578063095ea7b31461042857806318160ddd146104485780631d933a4a146104675780631f685bac1461048757600080fd5b806299d3861461039057806306fdde03146103a757806308c43650146103e857600080fd5b3661038b57005b600080fd5b34801561039c57600080fd5b506103a5610ab0565b005b3480156103b357600080fd5b506040805180820190915260068152655461cf84737560d01b60208201525b6040516103df9190612e70565b60405180910390f35b3480156103f457600080fd5b50610418610403366004612eb8565b60136020526000908152604090205460ff1681565b60405190151581526020016103df565b34801561043457600080fd5b50610418610443366004612ed5565b610bb5565b34801561045457600080fd5b506007545b6040519081526020016103df565b34801561047357600080fd5b506103a5610482366004612f01565b610bcf565b34801561049357600080fd5b506103a56104a2366004612ed5565b610cd0565b3480156104b357600080fd5b506104186104c2366004612f1a565b610ee7565b3480156104d357600080fd5b506002546104599081565b3480156104ea57600080fd5b5061045960085481565b34801561050057600080fd5b50604051601281526020016103df565b34801561051c57600080fd5b506103a561052b366004612f69565b610f0d565b34801561053c57600080fd5b5061041861054b366004612ed5565b610ff2565b34801561055c57600080fd5b506103a561056b366004612fa2565b611023565b34801561057c57600080fd5b50610459600d5481565b34801561059257600080fd5b506103a56105a1366004612eb8565b6110e6565b3480156105b257600080fd5b506103a56105c1366004612f69565b611234565b3480156105d257600080fd5b506103a56105e1366004612f01565b611312565b3480156105f257600080fd5b506001546104599081565b34801561060957600080fd5b50610418610618366004612eb8565b60156020526000908152604090205460ff1681565b34801561063957600080fd5b506103a5610648366004612f69565b61140a565b34801561065957600080fd5b506103a5610668366004612f01565b611602565b34801561067957600080fd5b5060105461041890600160a01b900460ff1681565b34801561069a57600080fd5b506104596106a9366004612eb8565b611667565b3480156106ba57600080fd5b506103a5611682565b3480156106cf57600080fd5b50610459600c5481565b3480156106e557600080fd5b506103a56106f4366004612f01565b611696565b34801561070557600080fd5b50610418610714366004612eb8565b60146020526000908152604090205460ff1681565b34801561073557600080fd5b506000546001600160a01b03165b6040516001600160a01b0390911681526020016103df565b34801561076757600080fd5b506103a5610776366004612f69565b611799565b34801561078757600080fd5b50610459611877565b34801561079c57600080fd5b50604080518082019091526005815264544154535560d81b60208201526103d2565b3480156107ca57600080fd5b50610459600a5481565b3480156107e057600080fd5b506103a56107ef366004612f01565b6118aa565b34801561080057600080fd5b50600e54610743906001600160a01b031681565b34801561082057600080fd5b5061041861082f366004612ed5565b611b61565b34801561084057600080fd5b50600f54610743906001600160a01b031681565b34801561086057600080fd5b50601054610743906001600160a01b031681565b34801561088057600080fd5b5061041861088f366004612ed5565b611ba7565b3480156108a057600080fd5b50610459620186a081565b3480156108b757600080fd5b506103a5611bb5565b3480156108cc57600080fd5b506003546104599081565b3480156108e357600080fd5b506103a5611c56565b3480156108f857600080fd5b5060105461041890600160b81b900460ff1681565b34801561091957600080fd5b50610459600b5481565b34801561092f57600080fd5b506103a561093e366004612eb8565b611cca565b34801561094f57600080fd5b506103a56120ff565b34801561096457600080fd5b5060105461041890600160a81b900460ff1681565b34801561098557600080fd5b5060105461041890600160c81b900460ff1681565b3480156109a657600080fd5b506005546104599081565b3480156109bd57600080fd5b5061045960095481565b3480156109d357600080fd5b506104596109e2366004612fbf565b6121a2565b3480156109f357600080fd5b5060105461041890600160c01b900460ff1681565b348015610a1457600080fd5b5060105461041890600160b01b900460ff1681565b348015610a3557600080fd5b50610418610a44366004612eb8565b60166020526000908152604090205460ff1681565b348015610a6557600080fd5b506004546104599081565b348015610a7c57600080fd5b506103a5610a8b366004612eb8565b6121cd565b348015610a9c57600080fd5b50600654610743906001600160a01b031681565b610ab8612278565b601054600160a81b900460ff1615610b015760105460085460405163e39c1e8760e01b8152600160a81b90920460ff161515600483015260248201526044015b60405180910390fd5b60085415610b225760405163475a253560e01b815260040160405180910390fd5b601054600160b01b900460ff1615610b5b57601054604051633f3e417d60e21b8152610af891600160b01b900460ff1690600401612fed565b6010805462ffffff60a01b19166201010160a01b1790554260088190556040805133815260208101929092527f7111af66182bdf8afd5e1cfa53fdb90ebba682d2cc11a7dfead27fcbf50bea8291015b60405180910390a1565b600033610bc38185856122b4565b60019150505b92915050565b610bd7612278565b601054600160b81b900460ff1615610c025760405163882d29d360e01b815260040160405180910390fd5b6188b8811115610c305760405163211a907760e11b8152600481018290526188b86024820152604401610af8565b6002548103610c525760405163f6f35fcf60e01b815260040160405180910390fd5b60028054908290556040805160a08082526013908201527273656c6c466565202d204d61726b6574696e6760681b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e0015b60405180910390a15050565b600f5481906001600160a01b03908116903090851603610ddb57610cf330611667565b600c54600b54610d03919061303e565b10610d21576040516315ea636560e31b815260040160405180910390fd5b610d2a30611667565b831115610d585730610d3b30611667565b8460405163391434e360e21b8152600401610af893929190613051565b82600003610dcb576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610da4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc89190613072565b91505b610dd63082846122c6565b610ee1565b6001600160a01b038416610e5a5782600003610df5574791505b6001600160a01b0381163303610e1e5760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610e54573d6000803e3d6000fd5b50610ee1565b82600003610ecd576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610ea6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eca9190613072565b91505b610ee16001600160a01b03851682846123dd565b50505050565b600033610ef585828561242f565b610f0085858561247c565b60019150505b9392505050565b610f15612278565b6001600160a01b03821660009081526014602052604090205481151560ff909116151503610f595760405162a7e72d60e41b81528115156004820152602401610af8565b6001600160a01b038216600081815260146020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061324f83398151915290610100015b60405180910390a1505050565b6000338161100082866121a2565b90506110188286611011878561308b565b60016126ef565b506001949350505050565b61102b612278565b601054600160b81b900460ff16156110565760405163882d29d360e01b815260040160405180910390fd5b801515601060169054906101000a900460ff1615150361108c5760405162a7e72d60e41b81528115156004820152602401610af8565b6010805460ff60b01b198116600160b01b84151581029190911790925560405191900460ff16907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf390610cc490839085903390429061309e565b6110ee612278565b601054600160c01b900460ff16156111195760405163341e380d60e11b815260040160405180910390fd5b6001600160a01b03811661114357604051634726455360e11b815260006004820152602401610af8565b600f546001600160a01b0380831691160361117c5760405163a936636960e01b81526001600160a01b0382166004820152602401610af8565b6001600160a01b0381163b156111a55760405163259f1ec560e01b815260040160405180910390fd5b600f80546001600160a01b031981166001600160a01b038481169182179093556040805160a08082526011908201527036b0b935b2ba34b733a932b1b2b4bb32b960791b60c0820152939092166020840181905291830152336060830152426080830152907ff7df6bc5c0f9735c300a374247b60dcacf1942b6031785957e762d77977ed4209060e001610cc4565b61123c612278565b6001600160a01b03821660009081526015602052604090205481151560ff9091161515036112805760405162a7e72d60e41b81528115156004820152602401610af8565b6001600160a01b038216600081815260156020908152604091829020805485151560ff1982168117909255835160c0808252600d908201526c1a5cd15e195b5c1d131a5b5a5d609a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061324f8339815191529061010001610fe5565b61131a612278565b601054600160b81b900460ff16156113455760405163882d29d360e01b815260040160405180910390fd5b614e208111156113735760405163211a907760e11b815260048101829052614e206024820152604401610af8565b60015481036113955760405163f6f35fcf60e01b815260040160405180910390fd5b60018054908290556040805160a080825260129082015271627579466565202d204d61726b6574696e6760701b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610cc4565b611412612278565b6001600160a01b03821660009081526013602052604090205481151560ff9091161515036114565760405162a7e72d60e41b81528115156004820152602401610af8565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561149e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c291906130f4565b6001600160a01b03161415801561154c5750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561151c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154091906130f4565b6001600160a01b031614155b1561157557604051634726455360e11b81526001600160a01b0383166004820152602401610af8565b6001600160a01b038216600081815260136020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061324f8339815191529061010001610fe5565b61160a612278565b674563918244f4000081111561163d5760405163181c9d0b60e21b8152674563918244f400006004820152602401610af8565b806009600082825461164f919061308b565b909155505042600a556116648161dead6127c4565b50565b6001600160a01b031660009081526011602052604090205490565b61168a612278565b611694600061295d565b565b61169e612278565b601054600160b81b900460ff16156116c95760405163882d29d360e01b815260040160405180910390fd5b6127108111156116f75760405163211a907760e11b8152600481018290526127106024820152604401610af8565b60035481036117195760405163f6f35fcf60e01b815260040160405180910390fd5b60038054908290556040805160a08082526017908201527f7472616e73666572466565202d204d61726b6574696e6700000000000000000060c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610cc4565b6117a1612278565b6001600160a01b03821660009081526016602052604090205481151560ff9091161515036117e55760405162a7e72d60e41b81528115156004820152602401610af8565b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c0808252600d908201526c1a5cd09b1858dad31a5cdd1959609a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061324f8339815191529061010001610fe5565b60006118836000611667565b61188e61dead611667565b60075461189b919061303e565b6118a5919061303e565b905090565b6010805460ff60c81b1916600160c81b179055600c54600b546000916118cf9161303e565b9050620186a06118dd611877565b6118e990611388613111565b6118f39190613128565b82111561193f5781620186a0611907611877565b61191390611388613111565b61191d9190613128565b60405163179b4ccd60e31b815260048101929092526024820152604401610af8565b8082111561194d5750611b51565b60055460045460009161195f9161303e565b905060008261196e8386613111565b6119789190613128565b9050806005600001600082825461198f919061308b565b9250508190555083600c60008282546119a8919061308b565b909155505060408051600280825260608201835260009260208301908036833701905050905030816000815181106119e2576119e261314a565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015611a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5f91906130f4565b81600181518110611a7257611a7261314a565b6001600160a01b039283166020918202929092010152600654611a9891309116876122b4565b6040805183815260208101879052338183015242606082015290517f62d5bfe0b49513c77ceefd1b93b95e3b41178dd115bc4113b2c67ed1e54aa8199181900360800190a1600654600f5460405163791ac94760e01b81526001600160a01b039283169263791ac94792611b1a928792600092889291169042906004016131a4565b600060405180830381600087803b158015611b3457600080fd5b505af1158015611b48573d6000803e3d6000fd5b50505050505050505b506010805460ff60c81b19169055565b60003381611b6f82866121a2565b905083811015611b9857848185604051637dc7a0d960e11b8152600401610af893929190613051565b611018828686840360016126ef565b600033610bc381858561247c565b611bbd612278565b601054600160b81b900460ff1615611be85760405163882d29d360e01b815260040160405180910390fd5b6010805460ff60b81b1916600160b81b179055604080516060808252600b908201526a1a5cd19959531bd8dad95960aa1b608082015233602082015242918101919091527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610bab565b611c5e612278565b601054600160a01b900460ff16611c88576040516314a718bb60e01b815260040160405180910390fd5b6010805460ff60a01b19169055604080513381524260208201527f94a26be55f53cfa27037e7421d95604590923e5ac016ce527ff1acd99786e6d29101610bab565b611cd2612278565b6006546001600160a01b0390811690821603611d0c5760405163a936636960e01b81526001600160a01b0382166004820152602401610af8565b600680546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a16006546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015611dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de791906130f4565b6001600160a01b031663e6a4390530600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6d91906130f4565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611eb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611edc91906130f4565b6001600160a01b0316036120fb57600660009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6191906130f4565b6001600160a01b031663c9c6539630600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe791906130f4565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af1158015612034573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205891906130f4565b601080546001600160a01b0319166001600160a01b0392909216918217905560009081526013602052604090205460ff166120b3576010546001600160a01b03166000908152601360205260409020805460ff191660011790555b6010546001600160a01b031660009081526015602052604090205460ff166120fb576010546001600160a01b03166000908152601560205260409020805460ff191660011790555b5050565b612107612278565b601054600160c01b900460ff16156121325760405163341e380d60e11b815260040160405180910390fd5b6010805460ff60c01b1916600160c01b1781556040805160608082528101929092526f1a5cd49958d95a5d995c931bd8dad95960821b608083015233602083015242908201527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610bab565b6001600160a01b03918216600090815260126020908152604080832093909416825291909152205490565b6121d5612278565b6000546001600160a01b03166001600160a01b0316816001600160a01b03160361221d5760405163a936636960e01b81526001600160a01b0382166004820152602401610af8565b61deac196001600160a01b0382160161225457604051634726455360e11b81526001600160a01b0382166004820152602401610af8565b600e80546001600160a01b0319166001600160a01b038316179055611664816129ad565b3361228b6000546001600160a01b031690565b6001600160a01b0316146116945760405163118cdaa760e01b8152336004820152602401610af8565b6122c183838360016126ef565b505050565b6001600160a01b0383166122f15780600760008282546122e6919061308b565b909155506123509050565b6001600160a01b038316600090815260116020526040902054818110156123315783818360405163391434e360e21b8152600401610af893929190613051565b6001600160a01b03841660009081526011602052604090209082900390555b6001600160a01b03821661236c5760078054829003905561238b565b6001600160a01b03821660009081526011602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516123d091815260200190565b60405180910390a3505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526122c19084906129e8565b600061243b84846121a2565b90506000198114610ee1578181101561246d57828183604051637dc7a0d960e11b8152600401610af893929190613051565b610ee1848484840360006126ef565b6001600160a01b0383166124a657604051634b637e8f60e11b815260006004820152602401610af8565b6001600160a01b0382166124d05760405163ec442f0560e01b815260006004820152602401610af8565b601054600160a81b900460ff16612541576001600160a01b03831660009081526014602052604090205460ff1615801561252357506001600160a01b03821660009081526014602052604090205460ff16155b156125415760405163ab9827ff60e01b815260040160405180910390fd5b601054600160c81b900460ff168061257157506001600160a01b03831660009081526014602052604090205460ff165b8061259457506001600160a01b03821660009081526014602052604090205460ff165b156125a4576122c18383836122c6565b6010548190600160b01b900460ff1680156125d857506001600160a01b03841660009081526014602052604090205460ff16155b80156125fd57506001600160a01b03831660009081526014602052604090205460ff16155b156126105761260d848484612a4b565b90505b601054600160a01b900460ff16801561264257506001600160a01b03831660009081526015602052604090205460ff16155b80156126675750612651612b4a565b8161265b85611667565b612665919061308b565b115b156126aa578061267684611667565b612680919061308b565b612688612b4a565b6040516335bd477b60e11b815260048101929092526024820152604401610af8565b6001600160a01b03841660009081526016602052604090205460ff16156126e457604051637d28af3f60e01b815260040160405180910390fd5b610ee18484836122c6565b6001600160a01b0384166127195760405163e602df0560e01b815260006004820152602401610af8565b6001600160a01b03831661274357604051634a1406b160e11b815260006004820152602401610af8565b6001600160a01b0380851660009081526012602090815260408083209387168352929052208290558015610ee157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516127b691815260200190565b60405180910390a350505050565b6010805460ff60c81b1916600160c81b17905561deac1933016127fe57604051634726455360e11b815261dead6004820152602401610af8565b6040805160028082526060820183526000926020830190803683375050600654604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa158015612868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061288c91906130f4565b8160008151811061289f5761289f61314a565b60200260200101906001600160a01b031690816001600160a01b03168152505030816001815181106128d3576128d361314a565b6001600160a01b03928316602091820292909201015260065460405163b6f9de9560e01b815291169063b6f9de95908590612919906000908690889042906004016131e0565b6000604051808303818588803b15801561293257600080fd5b505af1158015612946573d6000803e3d6000fd5b50506010805460ff60c81b19169055505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6129b5612278565b6001600160a01b0381166129df57604051631e4fbdf760e01b815260006004820152602401610af8565b6116648161295d565b60006129fd6001600160a01b03841683612b6f565b90508051600014158015612a22575080806020019051810190612a209190613215565b155b156122c157604051635274afe760e01b81526001600160a01b0384166004820152602401610af8565b6010805460ff60c81b1916600160c81b1790556001600160a01b03831660009081526013602052604081205460ff168015612a87575060015415155b15612a9d57612a968483612b7d565b9050612b36565b6001600160a01b03831660009081526013602052604090205460ff168015612ac6575060025415155b15612ad557612a968483612bae565b6001600160a01b03841660009081526013602052604090205460ff16158015612b1757506001600160a01b03831660009081526013602052604090205460ff16155b8015612b24575060035415155b15612b3357612a968483612bdf565b50805b6010805460ff60c81b191690559392505050565b6000620186a0600d54612b5b611877565b612b659190613111565b6118a59190613128565b6060610f0683836000612c10565b6010805460ff60c81b1916600160c81b17905560408051602081019091526001548152600090612b36908484612cad565b6010805460ff60c81b1916600160c81b17905560408051602081019091526002548152600090612b36908484612cad565b6010805460ff60c81b1916600160c81b17905560408051602081019091526003548152600090612b36908484612cad565b606081471015612c355760405163cd78605960e01b8152306004820152602401610af8565b600080856001600160a01b03168486604051612c519190613232565b60006040518083038185875af1925050503d8060008114612c8e576040519150601f19603f3d011682016040523d82523d6000602084013e612c93565b606091505b5091509150612ca3868383612d17565b9695505050505050565b6010805460ff60c81b1916600160c81b179055825160009081620186a0612cd48386613111565b612cde9190613128565b90506000612cec828661303e565b90508115612d0057612d0087878486612d73565b6010805460ff60c81b191690559695505050505050565b606082612d2c57612d2782612dcc565b610f06565b8151158015612d4357506001600160a01b0384163b155b15612d6c57604051639996b31560e01b81526001600160a01b0385166004820152602401610af8565b5080610f06565b6010805460ff60c81b1916600160c81b17905583516000908290612d979085613111565b612da19190613128565b9050612dad8184612df5565b612db88430856122c6565b50506010805460ff60c81b19169055505050565b805115612ddc5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6010805460ff60c81b1916600160c81b17905560048054839190600090612e1d90849061308b565b9250508190555080600b6000828254612e36919061308b565b90915550506010805460ff60c81b191690555050565b60005b83811015612e67578181015183820152602001612e4f565b50506000910152565b6020815260008251806020840152612e8f816040850160208701612e4c565b601f01601f19169190910160400192915050565b6001600160a01b038116811461166457600080fd5b600060208284031215612eca57600080fd5b8135610f0681612ea3565b60008060408385031215612ee857600080fd5b8235612ef381612ea3565b946020939093013593505050565b600060208284031215612f1357600080fd5b5035919050565b600080600060608486031215612f2f57600080fd5b8335612f3a81612ea3565b92506020840135612f4a81612ea3565b929592945050506040919091013590565b801515811461166457600080fd5b60008060408385031215612f7c57600080fd5b8235612f8781612ea3565b91506020830135612f9781612f5b565b809150509250929050565b600060208284031215612fb457600080fd5b8135610f0681612f5b565b60008060408385031215612fd257600080fd5b8235612fdd81612ea3565b91506020830135612f9781612ea3565b60408152600061301860408301600b81526a697346656541637469766560a81b602082015260400190565b9050821515602083015292915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610bc957610bc9613028565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020828403121561308457600080fd5b5051919050565b80820180821115610bc957610bc9613028565b60a0815260006130c960a08301600b81526a697346656541637469766560a81b602082015260400190565b95151560208301525092151560408401526001600160a01b0391909116606083015260809091015290565b60006020828403121561310657600080fd5b8151610f0681612ea3565b8082028115828204841417610bc957610bc9613028565b60008261314557634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156131995781516001600160a01b031687529582019590820190600101613174565b509495945050505050565b85815284602082015260a0604082015260006131c360a0830186613160565b6001600160a01b0394909416606083015250608001529392505050565b8481526080602082015260006131f96080830186613160565b6001600160a01b03949094166040830152506060015292915050565b60006020828403121561322757600080fd5b8151610f0681612f5b565b60008251613244818460208701612e4c565b919091019291505056fe59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aeaa26469706673582212200722c751dbdd45ceea94b2a7c299c73f6397f7ae0a67e96eaa0c64748ca431e264736f6c63430008120033

Deployed Bytecode

0x6080604052600436106103845760003560e01c80639155e083116101d1578063b908de8c11610102578063da4daf71116100a0578063e47d60601161006f578063e47d606014610a29578063e811f50a14610a59578063f2fde38b14610a70578063f887ea4014610a9057600080fd5b8063da4daf71146109b1578063dd62ed3e146109c7578063e2924cd1146109e7578063e43504da14610a0857600080fd5b8063cf9769fd116100dc578063cf9769fd14610943578063d621e81314610958578063d830678614610979578063d94190711461099a57600080fd5b8063b908de8c146108ec578063b9b2b5cd1461090d578063c851cc321461092357600080fd5b8063a5949bcf1161016f578063ab28a04c11610149578063ab28a04c14610894578063ab366292146108ab578063acb2ad6f146108c0578063b144896f146108d757600080fd5b8063a5949bcf14610834578063a8aa1b3114610854578063a9059cbb1461087457600080fd5b806397e1b9d3116101ab57806397e1b9d3146107be5780639d48fde9146107d4578063a4475ce4146107f4578063a457c2d71461081457600080fd5b80639155e0831461075b5780639358928b1461077b57806395d89b411461079057600080fd5b80633c8463a1116102b657806363a954921161025457806371538eed1161022357806371538eed146106c35780638577a6d5146106d9578063891ff84a146106f95780638da5cb5b1461072957600080fd5b806363a954921461064d5780636d800a3c1461066d57806370a082311461068e578063715018a6146106ae57600080fd5b8063467abe0a11610290578063467abe0a146105c657806347062402146105e65780635d7cc7f5146105fd578063625dd6051461062d57600080fd5b80633c8463a1146105705780633d6362d614610586578063422e6cea146105a657600080fd5b806323b872dd11610323578063313ce567116102fd578063313ce567146104f4578063355496ca1461051057806339509351146105305780633bf314541461055057600080fd5b806323b872dd146104a75780632b14ca56146104c75780632c735ef8146104de57600080fd5b8063095ea7b31161035f578063095ea7b31461042857806318160ddd146104485780631d933a4a146104675780631f685bac1461048757600080fd5b806299d3861461039057806306fdde03146103a757806308c43650146103e857600080fd5b3661038b57005b600080fd5b34801561039c57600080fd5b506103a5610ab0565b005b3480156103b357600080fd5b506040805180820190915260068152655461cf84737560d01b60208201525b6040516103df9190612e70565b60405180910390f35b3480156103f457600080fd5b50610418610403366004612eb8565b60136020526000908152604090205460ff1681565b60405190151581526020016103df565b34801561043457600080fd5b50610418610443366004612ed5565b610bb5565b34801561045457600080fd5b506007545b6040519081526020016103df565b34801561047357600080fd5b506103a5610482366004612f01565b610bcf565b34801561049357600080fd5b506103a56104a2366004612ed5565b610cd0565b3480156104b357600080fd5b506104186104c2366004612f1a565b610ee7565b3480156104d357600080fd5b506002546104599081565b3480156104ea57600080fd5b5061045960085481565b34801561050057600080fd5b50604051601281526020016103df565b34801561051c57600080fd5b506103a561052b366004612f69565b610f0d565b34801561053c57600080fd5b5061041861054b366004612ed5565b610ff2565b34801561055c57600080fd5b506103a561056b366004612fa2565b611023565b34801561057c57600080fd5b50610459600d5481565b34801561059257600080fd5b506103a56105a1366004612eb8565b6110e6565b3480156105b257600080fd5b506103a56105c1366004612f69565b611234565b3480156105d257600080fd5b506103a56105e1366004612f01565b611312565b3480156105f257600080fd5b506001546104599081565b34801561060957600080fd5b50610418610618366004612eb8565b60156020526000908152604090205460ff1681565b34801561063957600080fd5b506103a5610648366004612f69565b61140a565b34801561065957600080fd5b506103a5610668366004612f01565b611602565b34801561067957600080fd5b5060105461041890600160a01b900460ff1681565b34801561069a57600080fd5b506104596106a9366004612eb8565b611667565b3480156106ba57600080fd5b506103a5611682565b3480156106cf57600080fd5b50610459600c5481565b3480156106e557600080fd5b506103a56106f4366004612f01565b611696565b34801561070557600080fd5b50610418610714366004612eb8565b60146020526000908152604090205460ff1681565b34801561073557600080fd5b506000546001600160a01b03165b6040516001600160a01b0390911681526020016103df565b34801561076757600080fd5b506103a5610776366004612f69565b611799565b34801561078757600080fd5b50610459611877565b34801561079c57600080fd5b50604080518082019091526005815264544154535560d81b60208201526103d2565b3480156107ca57600080fd5b50610459600a5481565b3480156107e057600080fd5b506103a56107ef366004612f01565b6118aa565b34801561080057600080fd5b50600e54610743906001600160a01b031681565b34801561082057600080fd5b5061041861082f366004612ed5565b611b61565b34801561084057600080fd5b50600f54610743906001600160a01b031681565b34801561086057600080fd5b50601054610743906001600160a01b031681565b34801561088057600080fd5b5061041861088f366004612ed5565b611ba7565b3480156108a057600080fd5b50610459620186a081565b3480156108b757600080fd5b506103a5611bb5565b3480156108cc57600080fd5b506003546104599081565b3480156108e357600080fd5b506103a5611c56565b3480156108f857600080fd5b5060105461041890600160b81b900460ff1681565b34801561091957600080fd5b50610459600b5481565b34801561092f57600080fd5b506103a561093e366004612eb8565b611cca565b34801561094f57600080fd5b506103a56120ff565b34801561096457600080fd5b5060105461041890600160a81b900460ff1681565b34801561098557600080fd5b5060105461041890600160c81b900460ff1681565b3480156109a657600080fd5b506005546104599081565b3480156109bd57600080fd5b5061045960095481565b3480156109d357600080fd5b506104596109e2366004612fbf565b6121a2565b3480156109f357600080fd5b5060105461041890600160c01b900460ff1681565b348015610a1457600080fd5b5060105461041890600160b01b900460ff1681565b348015610a3557600080fd5b50610418610a44366004612eb8565b60166020526000908152604090205460ff1681565b348015610a6557600080fd5b506004546104599081565b348015610a7c57600080fd5b506103a5610a8b366004612eb8565b6121cd565b348015610a9c57600080fd5b50600654610743906001600160a01b031681565b610ab8612278565b601054600160a81b900460ff1615610b015760105460085460405163e39c1e8760e01b8152600160a81b90920460ff161515600483015260248201526044015b60405180910390fd5b60085415610b225760405163475a253560e01b815260040160405180910390fd5b601054600160b01b900460ff1615610b5b57601054604051633f3e417d60e21b8152610af891600160b01b900460ff1690600401612fed565b6010805462ffffff60a01b19166201010160a01b1790554260088190556040805133815260208101929092527f7111af66182bdf8afd5e1cfa53fdb90ebba682d2cc11a7dfead27fcbf50bea8291015b60405180910390a1565b600033610bc38185856122b4565b60019150505b92915050565b610bd7612278565b601054600160b81b900460ff1615610c025760405163882d29d360e01b815260040160405180910390fd5b6188b8811115610c305760405163211a907760e11b8152600481018290526188b86024820152604401610af8565b6002548103610c525760405163f6f35fcf60e01b815260040160405180910390fd5b60028054908290556040805160a08082526013908201527273656c6c466565202d204d61726b6574696e6760681b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e0015b60405180910390a15050565b600f5481906001600160a01b03908116903090851603610ddb57610cf330611667565b600c54600b54610d03919061303e565b10610d21576040516315ea636560e31b815260040160405180910390fd5b610d2a30611667565b831115610d585730610d3b30611667565b8460405163391434e360e21b8152600401610af893929190613051565b82600003610dcb576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610da4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc89190613072565b91505b610dd63082846122c6565b610ee1565b6001600160a01b038416610e5a5782600003610df5574791505b6001600160a01b0381163303610e1e5760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610e54573d6000803e3d6000fd5b50610ee1565b82600003610ecd576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015610ea6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eca9190613072565b91505b610ee16001600160a01b03851682846123dd565b50505050565b600033610ef585828561242f565b610f0085858561247c565b60019150505b9392505050565b610f15612278565b6001600160a01b03821660009081526014602052604090205481151560ff909116151503610f595760405162a7e72d60e41b81528115156004820152602401610af8565b6001600160a01b038216600081815260146020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061324f83398151915290610100015b60405180910390a1505050565b6000338161100082866121a2565b90506110188286611011878561308b565b60016126ef565b506001949350505050565b61102b612278565b601054600160b81b900460ff16156110565760405163882d29d360e01b815260040160405180910390fd5b801515601060169054906101000a900460ff1615150361108c5760405162a7e72d60e41b81528115156004820152602401610af8565b6010805460ff60b01b198116600160b01b84151581029190911790925560405191900460ff16907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf390610cc490839085903390429061309e565b6110ee612278565b601054600160c01b900460ff16156111195760405163341e380d60e11b815260040160405180910390fd5b6001600160a01b03811661114357604051634726455360e11b815260006004820152602401610af8565b600f546001600160a01b0380831691160361117c5760405163a936636960e01b81526001600160a01b0382166004820152602401610af8565b6001600160a01b0381163b156111a55760405163259f1ec560e01b815260040160405180910390fd5b600f80546001600160a01b031981166001600160a01b038481169182179093556040805160a08082526011908201527036b0b935b2ba34b733a932b1b2b4bb32b960791b60c0820152939092166020840181905291830152336060830152426080830152907ff7df6bc5c0f9735c300a374247b60dcacf1942b6031785957e762d77977ed4209060e001610cc4565b61123c612278565b6001600160a01b03821660009081526015602052604090205481151560ff9091161515036112805760405162a7e72d60e41b81528115156004820152602401610af8565b6001600160a01b038216600081815260156020908152604091829020805485151560ff1982168117909255835160c0808252600d908201526c1a5cd15e195b5c1d131a5b5a5d609a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061324f8339815191529061010001610fe5565b61131a612278565b601054600160b81b900460ff16156113455760405163882d29d360e01b815260040160405180910390fd5b614e208111156113735760405163211a907760e11b815260048101829052614e206024820152604401610af8565b60015481036113955760405163f6f35fcf60e01b815260040160405180910390fd5b60018054908290556040805160a080825260129082015271627579466565202d204d61726b6574696e6760701b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610cc4565b611412612278565b6001600160a01b03821660009081526013602052604090205481151560ff9091161515036114565760405162a7e72d60e41b81528115156004820152602401610af8565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561149e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c291906130f4565b6001600160a01b03161415801561154c5750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561151c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154091906130f4565b6001600160a01b031614155b1561157557604051634726455360e11b81526001600160a01b0383166004820152602401610af8565b6001600160a01b038216600081815260136020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061324f8339815191529061010001610fe5565b61160a612278565b674563918244f4000081111561163d5760405163181c9d0b60e21b8152674563918244f400006004820152602401610af8565b806009600082825461164f919061308b565b909155505042600a556116648161dead6127c4565b50565b6001600160a01b031660009081526011602052604090205490565b61168a612278565b611694600061295d565b565b61169e612278565b601054600160b81b900460ff16156116c95760405163882d29d360e01b815260040160405180910390fd5b6127108111156116f75760405163211a907760e11b8152600481018290526127106024820152604401610af8565b60035481036117195760405163f6f35fcf60e01b815260040160405180910390fd5b60038054908290556040805160a08082526017908201527f7472616e73666572466565202d204d61726b6574696e6700000000000000000060c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610cc4565b6117a1612278565b6001600160a01b03821660009081526016602052604090205481151560ff9091161515036117e55760405162a7e72d60e41b81528115156004820152602401610af8565b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c0808252600d908201526c1a5cd09b1858dad31a5cdd1959609a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a08301529060008051602061324f8339815191529061010001610fe5565b60006118836000611667565b61188e61dead611667565b60075461189b919061303e565b6118a5919061303e565b905090565b6010805460ff60c81b1916600160c81b179055600c54600b546000916118cf9161303e565b9050620186a06118dd611877565b6118e990611388613111565b6118f39190613128565b82111561193f5781620186a0611907611877565b61191390611388613111565b61191d9190613128565b60405163179b4ccd60e31b815260048101929092526024820152604401610af8565b8082111561194d5750611b51565b60055460045460009161195f9161303e565b905060008261196e8386613111565b6119789190613128565b9050806005600001600082825461198f919061308b565b9250508190555083600c60008282546119a8919061308b565b909155505060408051600280825260608201835260009260208301908036833701905050905030816000815181106119e2576119e261314a565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015611a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5f91906130f4565b81600181518110611a7257611a7261314a565b6001600160a01b039283166020918202929092010152600654611a9891309116876122b4565b6040805183815260208101879052338183015242606082015290517f62d5bfe0b49513c77ceefd1b93b95e3b41178dd115bc4113b2c67ed1e54aa8199181900360800190a1600654600f5460405163791ac94760e01b81526001600160a01b039283169263791ac94792611b1a928792600092889291169042906004016131a4565b600060405180830381600087803b158015611b3457600080fd5b505af1158015611b48573d6000803e3d6000fd5b50505050505050505b506010805460ff60c81b19169055565b60003381611b6f82866121a2565b905083811015611b9857848185604051637dc7a0d960e11b8152600401610af893929190613051565b611018828686840360016126ef565b600033610bc381858561247c565b611bbd612278565b601054600160b81b900460ff1615611be85760405163882d29d360e01b815260040160405180910390fd5b6010805460ff60b81b1916600160b81b179055604080516060808252600b908201526a1a5cd19959531bd8dad95960aa1b608082015233602082015242918101919091527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610bab565b611c5e612278565b601054600160a01b900460ff16611c88576040516314a718bb60e01b815260040160405180910390fd5b6010805460ff60a01b19169055604080513381524260208201527f94a26be55f53cfa27037e7421d95604590923e5ac016ce527ff1acd99786e6d29101610bab565b611cd2612278565b6006546001600160a01b0390811690821603611d0c5760405163a936636960e01b81526001600160a01b0382166004820152602401610af8565b600680546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a16006546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015611dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de791906130f4565b6001600160a01b031663e6a4390530600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6d91906130f4565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611eb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611edc91906130f4565b6001600160a01b0316036120fb57600660009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6191906130f4565b6001600160a01b031663c9c6539630600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe791906130f4565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af1158015612034573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205891906130f4565b601080546001600160a01b0319166001600160a01b0392909216918217905560009081526013602052604090205460ff166120b3576010546001600160a01b03166000908152601360205260409020805460ff191660011790555b6010546001600160a01b031660009081526015602052604090205460ff166120fb576010546001600160a01b03166000908152601560205260409020805460ff191660011790555b5050565b612107612278565b601054600160c01b900460ff16156121325760405163341e380d60e11b815260040160405180910390fd5b6010805460ff60c01b1916600160c01b1781556040805160608082528101929092526f1a5cd49958d95a5d995c931bd8dad95960821b608083015233602083015242908201527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610bab565b6001600160a01b03918216600090815260126020908152604080832093909416825291909152205490565b6121d5612278565b6000546001600160a01b03166001600160a01b0316816001600160a01b03160361221d5760405163a936636960e01b81526001600160a01b0382166004820152602401610af8565b61deac196001600160a01b0382160161225457604051634726455360e11b81526001600160a01b0382166004820152602401610af8565b600e80546001600160a01b0319166001600160a01b038316179055611664816129ad565b3361228b6000546001600160a01b031690565b6001600160a01b0316146116945760405163118cdaa760e01b8152336004820152602401610af8565b6122c183838360016126ef565b505050565b6001600160a01b0383166122f15780600760008282546122e6919061308b565b909155506123509050565b6001600160a01b038316600090815260116020526040902054818110156123315783818360405163391434e360e21b8152600401610af893929190613051565b6001600160a01b03841660009081526011602052604090209082900390555b6001600160a01b03821661236c5760078054829003905561238b565b6001600160a01b03821660009081526011602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516123d091815260200190565b60405180910390a3505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526122c19084906129e8565b600061243b84846121a2565b90506000198114610ee1578181101561246d57828183604051637dc7a0d960e11b8152600401610af893929190613051565b610ee1848484840360006126ef565b6001600160a01b0383166124a657604051634b637e8f60e11b815260006004820152602401610af8565b6001600160a01b0382166124d05760405163ec442f0560e01b815260006004820152602401610af8565b601054600160a81b900460ff16612541576001600160a01b03831660009081526014602052604090205460ff1615801561252357506001600160a01b03821660009081526014602052604090205460ff16155b156125415760405163ab9827ff60e01b815260040160405180910390fd5b601054600160c81b900460ff168061257157506001600160a01b03831660009081526014602052604090205460ff165b8061259457506001600160a01b03821660009081526014602052604090205460ff165b156125a4576122c18383836122c6565b6010548190600160b01b900460ff1680156125d857506001600160a01b03841660009081526014602052604090205460ff16155b80156125fd57506001600160a01b03831660009081526014602052604090205460ff16155b156126105761260d848484612a4b565b90505b601054600160a01b900460ff16801561264257506001600160a01b03831660009081526015602052604090205460ff16155b80156126675750612651612b4a565b8161265b85611667565b612665919061308b565b115b156126aa578061267684611667565b612680919061308b565b612688612b4a565b6040516335bd477b60e11b815260048101929092526024820152604401610af8565b6001600160a01b03841660009081526016602052604090205460ff16156126e457604051637d28af3f60e01b815260040160405180910390fd5b610ee18484836122c6565b6001600160a01b0384166127195760405163e602df0560e01b815260006004820152602401610af8565b6001600160a01b03831661274357604051634a1406b160e11b815260006004820152602401610af8565b6001600160a01b0380851660009081526012602090815260408083209387168352929052208290558015610ee157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516127b691815260200190565b60405180910390a350505050565b6010805460ff60c81b1916600160c81b17905561deac1933016127fe57604051634726455360e11b815261dead6004820152602401610af8565b6040805160028082526060820183526000926020830190803683375050600654604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa158015612868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061288c91906130f4565b8160008151811061289f5761289f61314a565b60200260200101906001600160a01b031690816001600160a01b03168152505030816001815181106128d3576128d361314a565b6001600160a01b03928316602091820292909201015260065460405163b6f9de9560e01b815291169063b6f9de95908590612919906000908690889042906004016131e0565b6000604051808303818588803b15801561293257600080fd5b505af1158015612946573d6000803e3d6000fd5b50506010805460ff60c81b19169055505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6129b5612278565b6001600160a01b0381166129df57604051631e4fbdf760e01b815260006004820152602401610af8565b6116648161295d565b60006129fd6001600160a01b03841683612b6f565b90508051600014158015612a22575080806020019051810190612a209190613215565b155b156122c157604051635274afe760e01b81526001600160a01b0384166004820152602401610af8565b6010805460ff60c81b1916600160c81b1790556001600160a01b03831660009081526013602052604081205460ff168015612a87575060015415155b15612a9d57612a968483612b7d565b9050612b36565b6001600160a01b03831660009081526013602052604090205460ff168015612ac6575060025415155b15612ad557612a968483612bae565b6001600160a01b03841660009081526013602052604090205460ff16158015612b1757506001600160a01b03831660009081526013602052604090205460ff16155b8015612b24575060035415155b15612b3357612a968483612bdf565b50805b6010805460ff60c81b191690559392505050565b6000620186a0600d54612b5b611877565b612b659190613111565b6118a59190613128565b6060610f0683836000612c10565b6010805460ff60c81b1916600160c81b17905560408051602081019091526001548152600090612b36908484612cad565b6010805460ff60c81b1916600160c81b17905560408051602081019091526002548152600090612b36908484612cad565b6010805460ff60c81b1916600160c81b17905560408051602081019091526003548152600090612b36908484612cad565b606081471015612c355760405163cd78605960e01b8152306004820152602401610af8565b600080856001600160a01b03168486604051612c519190613232565b60006040518083038185875af1925050503d8060008114612c8e576040519150601f19603f3d011682016040523d82523d6000602084013e612c93565b606091505b5091509150612ca3868383612d17565b9695505050505050565b6010805460ff60c81b1916600160c81b179055825160009081620186a0612cd48386613111565b612cde9190613128565b90506000612cec828661303e565b90508115612d0057612d0087878486612d73565b6010805460ff60c81b191690559695505050505050565b606082612d2c57612d2782612dcc565b610f06565b8151158015612d4357506001600160a01b0384163b155b15612d6c57604051639996b31560e01b81526001600160a01b0385166004820152602401610af8565b5080610f06565b6010805460ff60c81b1916600160c81b17905583516000908290612d979085613111565b612da19190613128565b9050612dad8184612df5565b612db88430856122c6565b50506010805460ff60c81b19169055505050565b805115612ddc5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6010805460ff60c81b1916600160c81b17905560048054839190600090612e1d90849061308b565b9250508190555080600b6000828254612e36919061308b565b90915550506010805460ff60c81b191690555050565b60005b83811015612e67578181015183820152602001612e4f565b50506000910152565b6020815260008251806020840152612e8f816040850160208701612e4c565b601f01601f19169190910160400192915050565b6001600160a01b038116811461166457600080fd5b600060208284031215612eca57600080fd5b8135610f0681612ea3565b60008060408385031215612ee857600080fd5b8235612ef381612ea3565b946020939093013593505050565b600060208284031215612f1357600080fd5b5035919050565b600080600060608486031215612f2f57600080fd5b8335612f3a81612ea3565b92506020840135612f4a81612ea3565b929592945050506040919091013590565b801515811461166457600080fd5b60008060408385031215612f7c57600080fd5b8235612f8781612ea3565b91506020830135612f9781612f5b565b809150509250929050565b600060208284031215612fb457600080fd5b8135610f0681612f5b565b60008060408385031215612fd257600080fd5b8235612fdd81612ea3565b91506020830135612f9781612ea3565b60408152600061301860408301600b81526a697346656541637469766560a81b602082015260400190565b9050821515602083015292915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610bc957610bc9613028565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020828403121561308457600080fd5b5051919050565b80820180821115610bc957610bc9613028565b60a0815260006130c960a08301600b81526a697346656541637469766560a81b602082015260400190565b95151560208301525092151560408401526001600160a01b0391909116606083015260809091015290565b60006020828403121561310657600080fd5b8151610f0681612ea3565b8082028115828204841417610bc957610bc9613028565b60008261314557634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156131995781516001600160a01b031687529582019590820190600101613174565b509495945050505050565b85815284602082015260a0604082015260006131c360a0830186613160565b6001600160a01b0394909416606083015250608001529392505050565b8481526080602082015260006131f96080830186613160565b6001600160a01b03949094166040830152506060015292915050565b60006020828403121561322757600080fd5b8151610f0681612f5b565b60008251613244818460208701612e4c565b919091019291505056fe59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aeaa26469706673582212200722c751dbdd45ceea94b2a7c299c73f6397f7ae0a67e96eaa0c64748ca431e264736f6c63430008120033

Deployed Bytecode Sourcemap

25158:46801:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39061:551;;;;;;;;;;;;;:::i;:::-;;58033:90;;;;;;;;;;-1:-1:-1;58111:4:0;;;;;;;;;;;;-1:-1:-1;;;58111:4:0;;;;58033:90;;;;;;;:::i;:::-;;;;;;;;26790:45;;;;;;;;;;-1:-1:-1;26790:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1223:14:1;;1216:22;1198:41;;1186:2;1171:18;26790:45:0;1058:187:1;61090:194:0;;;;;;;;;;-1:-1:-1;61090:194:0;;;;;:::i;:::-;;:::i;59088:99::-;;;;;;;;;;-1:-1:-1;59167:12:0;;59088:99;;;1716:25:1;;;1704:2;1689:18;59088:99:0;1570:177:1;45353:584:0;;;;;;;;;;-1:-1:-1;45353:584:0;;;;;:::i;:::-;;:::i;37369:1264::-;;;;;;;;;;-1:-1:-1;37369:1264:0;;;;;:::i;:::-;;:::i;61729:247::-;;;;;;;;;;-1:-1:-1;61729:247:0;;;;;:::i;:::-;;:::i;25430:32::-;;;;;;;;;;-1:-1:-1;25430:32:0;;;;;;25916:33;;;;;;;;;;;;;;;;58798:90;;;;;;;;;;-1:-1:-1;58798:90:0;;25803:2;2540:36:1;;2528:2;2513:18;58798:90:0;2398:184:1;50533:360:0;;;;;;;;;;-1:-1:-1;50533:360:0;;;;;:::i;:::-;;:::i;70697:297::-;;;;;;;;;;-1:-1:-1;70697:297:0;;;;;:::i;:::-;;:::i;43646:412::-;;;;;;;;;;-1:-1:-1;43646:412:0;;;;;:::i;:::-;;:::i;26140:34::-;;;;;;;;;;;;;;;;47268:764;;;;;;;;;;-1:-1:-1;47268:764:0;;;;;:::i;:::-;;:::i;51247:370::-;;;;;;;;;;-1:-1:-1;51247:370:0;;;;;:::i;:::-;;:::i;44415:579::-;;;;;;;;;;-1:-1:-1;44415:579:0;;;;;:::i;:::-;;:::i;25392:31::-;;;;;;;;;;-1:-1:-1;25392:31:0;;;;;;26900:53;;;;;;;;;;-1:-1:-1;26900:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;48452:528;;;;;;;;;;-1:-1:-1;48452:528:0;;;;;:::i;:::-;;:::i;56022:300::-;;;;;;;;;;-1:-1:-1;56022:300:0;;;;;:::i;:::-;;:::i;26384:32::-;;;;;;;;;;-1:-1:-1;26384:32:0;;;;-1:-1:-1;;;26384:32:0;;;;;;59475:118;;;;;;;;;;-1:-1:-1;59475:118:0;;;;;:::i;:::-;;:::i;23326:103::-;;;;;;;;;;;;;:::i;26098:35::-;;;;;;;;;;;;;;;;46304:604;;;;;;;;;;-1:-1:-1;46304:604:0;;;;;:::i;:::-;;:::i;26842:51::-;;;;;;;;;;-1:-1:-1;26842:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;22602:87;;;;;;;;;;-1:-1:-1;22648:7:0;22675:6;-1:-1:-1;;;;;22675:6:0;22602:87;;;-1:-1:-1;;;;;3507:32:1;;;3489:51;;3477:2;3462:18;22602:87:0;3343:203:1;51951:368:0;;;;;;;;;;-1:-1:-1;51951:368:0;;;;;:::i;:::-;;:::i;40010:151::-;;;;;;;;;;;;;:::i;58317:94::-;;;;;;;;;;-1:-1:-1;58397:6:0;;;;;;;;;;;;-1:-1:-1;;;58397:6:0;;;;58317:94;;26005:43;;;;;;;;;;;;;;;;40918:1250;;;;;;;;;;-1:-1:-1;40918:1250:0;;;;;:::i;:::-;;:::i;26183:72::-;;;;;;;;;;-1:-1:-1;26183:72:0;;;;-1:-1:-1;;;;;26183:72:0;;;71489:467;;;;;;;;;;-1:-1:-1;71489:467:0;;;;;:::i;:::-;;:::i;26262:77::-;;;;;;;;;;-1:-1:-1;26262:77:0;;;;-1:-1:-1;;;;;26262:77:0;;;26352:19;;;;;;;;;;-1:-1:-1;26352:19:0;;;;-1:-1:-1;;;;;26352:19:0;;;59962:186;;;;;;;;;;-1:-1:-1;59962:186:0;;;;;:::i;:::-;;:::i;25814:48::-;;;;;;;;;;;;25855:7;25814:48;;42746:212;;;;;;;;;;;;;:::i;25469:31::-;;;;;;;;;;-1:-1:-1;25469:31:0;;;;;;42332:240;;;;;;;;;;;;;:::i;26500:31::-;;;;;;;;;;-1:-1:-1;26500:31:0;;;;-1:-1:-1;;;26500:31:0;;;;;;26055:36;;;;;;;;;;;;;;;;49447:745;;;;;;;;;;-1:-1:-1;49447:745:0;;;;;:::i;:::-;;:::i;43124:237::-;;;;;;;;;;;;;:::i;26423:32::-;;;;;;;;;;-1:-1:-1;26423:32:0;;;;-1:-1:-1;;;26423:32:0;;;;;;26581:26;;;;;;;;;;-1:-1:-1;26581:26:0;;;;-1:-1:-1;;;26581:26:0;;;;;;25546:31;;;;;;;;;;-1:-1:-1;25546:31:0;;;;;;25956:42;;;;;;;;;;;;;;;;60533:148;;;;;;;;;;-1:-1:-1;60533:148:0;;;;;:::i;:::-;;:::i;26538:36::-;;;;;;;;;;-1:-1:-1;26538:36:0;;;;-1:-1:-1;;;26538:36:0;;;;;;26462:31;;;;;;;;;;-1:-1:-1;26462:31:0;;;;-1:-1:-1;;;26462:31:0;;;;;;26960:53;;;;;;;;;;-1:-1:-1;26960:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;25507:32;;;;;;;;;;-1:-1:-1;25507:32:0;;;;;;57456:360;;;;;;;;;;-1:-1:-1;57456:360:0;;;;;:::i;:::-;;:::i;25586:75::-;;;;;;;;;;-1:-1:-1;25586:75:0;;;;-1:-1:-1;;;;;25586:75:0;;;39061:551;20867:13;:11;:13::i;:::-;39118:12:::1;::::0;-1:-1:-1;;;39118:12:0;::::1;;;39114:101;;;39174:12;::::0;39188:14:::1;::::0;39154:49:::1;::::0;-1:-1:-1;;;39154:49:0;;-1:-1:-1;;;39174:12:0;;::::1;;;4360:14:1::0;4353:22;39154:49:0::1;::::0;::::1;4335:41:1::0;4392:18;;;4385:34;4308:18;;39154:49:0::1;;;;;;;;39114:101;39229:14;::::0;:19;39225:77:::1;;39272:18;;-1:-1:-1::0;;;39272:18:0::1;;;;;;;;;;;39225:77;39316:11;::::0;-1:-1:-1;;;39316:11:0;::::1;;;39312:98;;;39386:11;::::0;39351:47:::1;::::0;-1:-1:-1;;;39351:47:0;;::::1;::::0;-1:-1:-1;;;39386:11:0;::::1;;;::::0;39351:47:::1;;;:::i;39312:98::-;39420:12;:19:::0;;-1:-1:-1;;;;39480:18:0;-1:-1:-1;;;39480:18:0;;;39526:15:::1;39509:14;:32:::0;;;39559:45:::1;::::0;;39576:10:::1;5132:51:1::0;;5214:2;5199:18;;5192:34;;;;39559:45:0::1;::::0;5105:18:1;39559:45:0::1;;;;;;;;39061:551::o:0;61090:194::-;61163:4;61199:10;61220:34;61199:10;61239:7;61248:5;61220:8;:34::i;:::-;61272:4;61265:11;;;61090:194;;;;;:::o;45353:584::-;20867:13;:11;:13::i;:::-;45435:11:::1;::::0;-1:-1:-1;;;45435:11:0;::::1;;;45431:62;;;45470:11;;-1:-1:-1::0;;;45470:11:0::1;;;;;;;;;;;45431:62;45525:6;45507:15;:24;45503:104;;;45555:40;::::0;-1:-1:-1;;;45555:40:0;;::::1;::::0;::::1;5423:25:1::0;;;45588:6:0::1;5464:18:1::0;;;5457:34;5396:18;;45555:40:0::1;5237:260:1::0;45503:104:0::1;45640:7;:17:::0;45621:36;;45617:102:::1;;45681:26;;-1:-1:-1::0;;;45681:26:0::1;;;;;;;;;;;45617:102;45755:7;:17:::0;;45783:35;;;;45834:95:::1;::::0;;5816:3:1;5798:22;;;5857:2;5836:19;;;5829:31;-1:-1:-1;;;5891:3:1;5876:19;;5869:50;5986:4;5971:20;;5964:36;;;6016:18;;;6009:34;;;45901:10:0::1;-1:-1:-1::0;6059:18:1;;6052:60;45913:15:0::1;-1:-1:-1::0;6128:19:1;;6121:35;45834:95:0::1;::::0;5951:3:1;5936:19;45834:95:0::1;;;;;;;;45420:517;45353:584:::0;:::o;37369:1264::-;37501:17;;37465:6;;-1:-1:-1;;;;;37501:17:0;;;;37567:4;37543:29;;;;37539:1087;;37633:24;37651:4;37633:9;:24::i;:::-;37613:16;;37593:17;;:36;;;;:::i;:::-;:64;37589:139;;37685:27;;-1:-1:-1;;;37685:27:0;;;;;;;;;;;37589:139;37755:24;37773:4;37755:9;:24::i;:::-;37746:6;:33;37742:154;;;37840:4;37847:24;37865:4;37847:9;:24::i;:::-;37873:6;37807:73;;-1:-1:-1;;;37807:73:0;;;;;;;;;;:::i;37742:154::-;37914:6;37924:1;37914:11;37910:110;;37959:45;;-1:-1:-1;;;37959:45:0;;37998:4;37959:45;;;3489:51:1;-1:-1:-1;;;;;37959:30:0;;;;;3462:18:1;;37959:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37946:58;;37910:110;38034:44;38050:4;38057:8;38067:10;38034:7;:44::i;:::-;37539:1087;;;-1:-1:-1;;;;;38100:26:0;;38096:530;;38147:6;38157:1;38147:11;38143:86;;38192:21;38179:34;;38143:86;-1:-1:-1;;;;;38247:22:0;;:10;:22;38243:107;;38297:37;;-1:-1:-1;;;38297:37:0;;;;;;;;;;;38243:107;38364:38;;-1:-1:-1;;;;;38364:26:0;;;:38;;;;;38391:10;;38364:38;;;;38391:10;38364:26;:38;;;;;;;;;;;;;;;;;;;;;38096:530;;;38439:6;38449:1;38439:11;38435:110;;38484:45;;-1:-1:-1;;;38484:45:0;;38523:4;38484:45;;;3489:51:1;-1:-1:-1;;;;;38484:30:0;;;;;3462:18:1;;38484:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38471:58;;38435:110;38559:55;-1:-1:-1;;;;;38559:33:0;;38593:8;38603:10;38559:33;:55::i;:::-;37433:1200;;37369:1264;;:::o;61729:247::-;61816:4;61851:10;61872:37;61888:4;61851:10;61903:5;61872:15;:37::i;:::-;61920:26;61930:4;61936:2;61940:5;61920:9;:26::i;:::-;61964:4;61957:11;;;61729:247;;;;;;:::o;50533:360::-;20867:13;:11;:13::i;:::-;-1:-1:-1;;;;;50622:17:0;::::1;;::::0;;;:11:::1;:17;::::0;;;;;:30;::::1;;:17;::::0;;::::1;:30;;::::0;50618:80:::1;;50663:32;::::0;-1:-1:-1;;;50663:32:0;;1223:14:1;;1216:22;50663:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;50663:32:0::1;1058:187:1::0;50618:80:0::1;-1:-1:-1::0;;;;;50725:17:0;::::1;50708:14;50725:17:::0;;;:11:::1;:17;::::0;;;;;;;;;;50753:29;::::1;;-1:-1:-1::0;;50753:29:0;::::1;::::0;::::1;::::0;;;50798:87;;7301:3:1;7283:22;;;7342:2;7321:19;;;7314:31;-1:-1:-1;;;7376:3:1;7361:19;;7354:42;7486:20;;;7479:45;;;;50725:17:0::1;::::0;;::::1;7567:14:1::0;;7560:22;7540:18;;;7533:50;;;;7614:2;7599:18;;7592:50;;;;50857:10:0::1;-1:-1:-1::0;7658:19:1;;7651:44;50869:15:0::1;-1:-1:-1::0;7711:19:1;;7704:35;50725:17:0;-1:-1:-1;;;;;;;;;;;50798:87:0;7428:3:1;7413:19;50798:87:0::1;;;;;;;;50607:286;50533:360:::0;;:::o;70697:297::-;70782:4;70818:10;70782:4;70866:28;70818:10;70886:7;70866:9;:28::i;:::-;70839:55;-1:-1:-1;70905:59:0;70914:8;70924:7;70933:24;70952:5;70839:55;70933:24;:::i;:::-;70959:4;70905:8;:59::i;:::-;-1:-1:-1;70982:4:0;;70697:297;-1:-1:-1;;;;70697:297:0:o;43646:412::-;20867:13;:11;:13::i;:::-;43721:11:::1;::::0;-1:-1:-1;;;43721:11:0;::::1;;;43717:62;;;43756:11;;-1:-1:-1::0;;;43756:11:0::1;;;;;;;;;;;43717:62;43808:9;43793:24;;:11;;;;;;;;;;;:24;;::::0;43789:96:::1;;43841:32;::::0;-1:-1:-1;;;43841:32:0;;1223:14:1;;1216:22;43841:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;43841:32:0::1;1058:187:1::0;43789:96:0::1;43912:11;::::0;;-1:-1:-1;;;;43934:23:0;::::1;-1:-1:-1::0;;;43934:23:0;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;43973:77:::1;::::0;43912:11;;::::1;;;::::0;43973:77:::1;::::0;::::1;::::0;43912:11;;43934:23;;44022:10:::1;::::0;44034:15:::1;::::0;43973:77:::1;:::i;47268:764::-:0;20867:13;:11;:13::i;:::-;47365:16:::1;::::0;-1:-1:-1;;;47365:16:0;::::1;;;47361:72;;;47405:16;;-1:-1:-1::0;;;47405:16:0::1;;;;;;;;;;;47361:72;-1:-1:-1::0;;;;;47447:34:0;::::1;47443:100;;47505:26;::::0;-1:-1:-1;;;47505:26:0;;47528:1:::1;47505:26;::::0;::::1;3489:51:1::0;3462:18;;47505:26:0::1;3343:203:1::0;47443:100:0::1;47557:17;::::0;-1:-1:-1;;;;;47557:41:0;;::::1;:17:::0;::::1;:41:::0;47553:126:::1;;47622:45;::::0;-1:-1:-1;;;47622:45:0;;-1:-1:-1;;;;;3507:32:1;;47622:45:0::1;::::0;::::1;3489:51:1::0;3462:18;;47622:45:0::1;3343:203:1::0;47553:126:0::1;-1:-1:-1::0;;;;;47693:32:0;::::1;;:36:::0;47689:102:::1;;47753:26;;-1:-1:-1::0;;;47753:26:0::1;;;;;;;;;;;47689:102;47832:17;::::0;;-1:-1:-1;;;;;;47860:40:0;::::1;-1:-1:-1::0;;;;;47860:40:0;;::::1;::::0;;::::1;::::0;;;47916:108:::1;::::0;;8809:3:1;8791:22;;;8850:2;8829:19;;;8822:31;-1:-1:-1;;;8884:3:1;8869:19;;8862:48;47832:17:0;;;::::1;9015:4:1::0;9000:20;;8993:45;;;9054:18;;;9047:43;47996:10:0::1;-1:-1:-1::0;9106:18:1;;9099:43;48008:15:0::1;-1:-1:-1::0;9158:19:1;;9151:35;47832:17:0;47916:108:::1;::::0;8942:3:1;8927:19;47916:108:0::1;8495:697:1::0;51247:370:0;20867:13;:11;:13::i;:::-;-1:-1:-1;;;;;51338:19:0;::::1;;::::0;;;:13:::1;:19;::::0;;;;;:32;::::1;;:19;::::0;;::::1;:32;;::::0;51334:82:::1;;51381:32;::::0;-1:-1:-1;;;51381:32:0;;1223:14:1;;1216:22;51381:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;51381:32:0::1;1058:187:1::0;51334:82:0::1;-1:-1:-1::0;;;;;51443:19:0;::::1;51426:14;51443:19:::0;;;:13:::1;:19;::::0;;;;;;;;;;51473:31;::::1;;-1:-1:-1::0;;51473:31:0;::::1;::::0;::::1;::::0;;;51520:89;;9527:3:1;9509:22;;;9568:2;9547:19;;;9540:31;-1:-1:-1;;;9602:3:1;9587:19;;9580:44;9714:20;;;9707:45;;;;51443:19:0::1;::::0;;::::1;9795:14:1::0;;9788:22;9768:18;;;9761:50;;;;9842:2;9827:18;;9820:50;;;;51581:10:0::1;-1:-1:-1::0;9886:19:1;;9879:44;51593:15:0::1;-1:-1:-1::0;9939:19:1;;9932:35;51443:19:0;-1:-1:-1;;;;;;;;;;;51520:89:0;9656:3:1;9641:19;51520:89:0::1;9197:776:1::0;44415:579:0;20867:13;:11;:13::i;:::-;44496:11:::1;::::0;-1:-1:-1;;;44496:11:0;::::1;;;44492:62;;;44531:11;;-1:-1:-1::0;;;44531:11:0::1;;;;;;;;;;;44492:62;44586:6;44568:15;:24;44564:104;;;44616:40;::::0;-1:-1:-1;;;44616:40:0;;::::1;::::0;::::1;5423:25:1::0;;;44649:6:0::1;5464:18:1::0;;;5457:34;5396:18;;44616:40:0::1;5237:260:1::0;44564:104:0::1;44701:6;:16:::0;44682:35;;44678:101:::1;;44741:26;;-1:-1:-1::0;;;44741:26:0::1;;;;;;;;;;;44678:101;44815:6;:16:::0;;44842:34;;;;44892:94:::1;::::0;;10557:3:1;10539:22;;;10598:2;10577:19;;;10570:31;-1:-1:-1;;;10632:3:1;10617:19;;10610:49;10726:4;10711:20;;10704:36;;;10756:18;;;10749:34;;;44958:10:0::1;-1:-1:-1::0;10799:18:1;;10792:60;44970:15:0::1;-1:-1:-1::0;10868:19:1;;10861:35;44892:94:0::1;::::0;10691:3:1;10676:19;44892:94:0::1;10243:659:1::0;48452:528:0;20867:13;:11;:13::i;:::-;-1:-1:-1;;;;;48537:16:0;::::1;;::::0;;;:8:::1;:16;::::0;;;;;:29;::::1;;:16;::::0;;::::1;:29;;::::0;48533:101:::1;;48590:32;::::0;-1:-1:-1;;;48590:32:0;;1223:14:1;;1216:22;48590:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;48590:32:0::1;1058:187:1::0;48533:101:0::1;48682:4;-1:-1:-1::0;;;;;48648:39:0::1;48654:6;-1:-1:-1::0;;;;;48648:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;48648:39:0::1;;;:82;;;;;48725:4;-1:-1:-1::0;;;;;48691:39:0::1;48697:6;-1:-1:-1::0;;;;;48691:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;48691:39:0::1;;;48648:82;48644:144;;;48754:22;::::0;-1:-1:-1;;;48754:22:0;;-1:-1:-1;;;;;3507:32:1;;48754:22:0::1;::::0;::::1;3489:51:1::0;3462:18;;48754:22:0::1;3343:203:1::0;48644:144:0::1;-1:-1:-1::0;;;;;48815:16:0;::::1;48798:14;48815:16:::0;;;:8:::1;:16;::::0;;;;;;;;;;48842:28;::::1;;-1:-1:-1::0;;48842:28:0;::::1;::::0;::::1;::::0;;;48886:86;;11493:3:1;11475:22;;;11534:1;11513:19;;;11506:30;-1:-1:-1;;;11567:3:1;11552:19;;11545:39;11674:20;;;11667:45;;;;48815:16:0::1;::::0;;::::1;11755:14:1::0;;11748:22;11728:18;;;11721:50;;;;11802:2;11787:18;;11780:50;;;;48944:10:0::1;-1:-1:-1::0;11846:19:1;;11839:44;48956:15:0::1;-1:-1:-1::0;11899:19:1;;11892:35;48815:16:0;-1:-1:-1;;;;;;;;;;;48886:86:0;11616:3:1;11601:19;48886:86:0::1;11163:770:1::0;56022:300:0;20867:13;:11;:13::i;:::-;56109:7:::1;56100:6;:16;56096:77;;;56140:21;::::0;-1:-1:-1;;;56140:21:0;;56153:7:::1;56140:21;::::0;::::1;1716:25:1::0;1689:18;;56140:21:0::1;1570:177:1::0;56096:77:0::1;56210:6;56183:23;;:33;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;56254:15:0::1;56227:24;:42:::0;56280:34:::1;56290:6:::0;56306::::1;56280:9;:34::i;:::-;56022:300:::0;:::o;59475:118::-;-1:-1:-1;;;;;59567:18:0;59540:7;59567:18;;;:9;:18;;;;;;;59475:118::o;23326:103::-;20867:13;:11;:13::i;:::-;23391:30:::1;23418:1;23391:18;:30::i;:::-;23326:103::o:0;46304:604::-;20867:13;:11;:13::i;:::-;46390:11:::1;::::0;-1:-1:-1;;;46390:11:0;::::1;;;46386:62;;;46425:11;;-1:-1:-1::0;;;46425:11:0::1;;;;;;;;;;;46386:62;46480:6;46462:15;:24;46458:104;;;46510:40;::::0;-1:-1:-1;;;46510:40:0;;::::1;::::0;::::1;5423:25:1::0;;;46543:6:0::1;5464:18:1::0;;;5457:34;5396:18;;46510:40:0::1;5237:260:1::0;46458:104:0::1;46595:11;:21:::0;46576:40;;46572:106:::1;;46640:26;;-1:-1:-1::0;;;46640:26:0::1;;;;;;;;;;;46572:106;46714:11;:21:::0;;46746:39;;;;46801:99:::1;::::0;;12725:3:1;12707:22;;;12766:2;12745:19;;;12738:31;12806:25;12800:3;12785:19;;12778:54;12899:4;12884:20;;12877:36;;;12929:18;;;12922:34;;;46872:10:0::1;-1:-1:-1::0;12972:18:1;;12965:60;46884:15:0::1;-1:-1:-1::0;13041:19:1;;13034:35;46801:99:0::1;::::0;12864:3:1;12849:19;46801:99:0::1;12411:664:1::0;51951:368:0;20867:13;:11;:13::i;:::-;-1:-1:-1;;;;;52040:19:0;::::1;;::::0;;;:13:::1;:19;::::0;;;;;:32;::::1;;:19;::::0;;::::1;:32;;::::0;52036:82:::1;;52083:32;::::0;-1:-1:-1;;;52083:32:0;;1223:14:1;;1216:22;52083:32:0::1;::::0;::::1;1198:41:1::0;1171:18;;52083:32:0::1;1058:187:1::0;52036:82:0::1;-1:-1:-1::0;;;;;52145:19:0;::::1;52128:14;52145:19:::0;;;:13:::1;:19;::::0;;;;;;;;;;52175:31;::::1;;-1:-1:-1::0;;52175:31:0;::::1;::::0;::::1;::::0;;;52222:89;;13410:3:1;13392:22;;;13451:2;13430:19;;;13423:31;-1:-1:-1;;;13485:3:1;13470:19;;13463:44;13597:20;;;13590:45;;;;52145:19:0::1;::::0;;::::1;13678:14:1::0;;13671:22;13651:18;;;13644:50;;;;13725:2;13710:18;;13703:50;;;;52283:10:0::1;-1:-1:-1::0;13769:19:1;;13762:44;52295:15:0::1;-1:-1:-1::0;13822:19:1;;13815:35;52145:19:0;-1:-1:-1;;;;;;;;;;;52222:89:0;13539:3:1;13524:19;52222:89:0::1;13080:776:1::0;40010:151:0;40060:7;40132:21;40150:1;40132:9;:21::i;:::-;40103:26;40121:6;40103:9;:26::i;:::-;59167:12;;40087:42;;;;:::i;:::-;:66;;;;:::i;:::-;40080:73;;40010:151;:::o;40918:1250::-;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;41037:16:::1;::::0;41017:17:::1;::::0;27170:13;;41017:36:::1;::::0;::::1;:::i;:::-;40993:60;;25855:7;41095:19;:17;:19::i;:::-;:27;::::0;41117:5:::1;41095:27;:::i;:::-;:44;;;;:::i;:::-;41078:14;:61;41074:198;;;41199:14;25855:7;41215:19;:17;:19::i;:::-;:27;::::0;41237:5:::1;41215:27;:::i;:::-;:44;;;;:::i;:::-;41163:97;::::0;-1:-1:-1;;;41163:97:0;;::::1;::::0;::::1;5423:25:1::0;;;;5464:18;;;5457:34;5396:18;;41163:97:0::1;5237:260:1::0;41074:198:0::1;41303:13;41286:14;:30;41282:69;;;41333:7;;;41282:69;41414:11;:21:::0;41389:12:::1;:22:::0;41361:25:::1;::::0;41389:46:::1;::::0;::::1;:::i;:::-;41361:74:::0;-1:-1:-1;41456:32:0::1;41528:13:::0;41491:34:::1;41361:74:::0;41491:14;:34:::1;:::i;:::-;:50;;;;:::i;:::-;41456:85;;41579:24;41554:11;:21;;;:49;;;;;;;:::i;:::-;;;;;;;;41634:14;41614:16;;:34;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;41685:16:0::1;::::0;;41699:1:::1;41685:16:::0;;;;;::::1;::::0;;41661:21:::1;::::0;41685:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;41685:16:0::1;41661:40;;41730:4;41712;41717:1;41712:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;41712:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;;:23;;;;41756:6:::1;::::0;:13:::1;::::0;;-1:-1:-1;;;41756:13:0;;;;:6;;;::::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;41712:7;;41756:13;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41746:4;41751:1;41746:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;41746:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;41814:6:::1;::::0;41782:56:::1;::::0;41799:4:::1;::::0;41814:6:::1;41823:14:::0;41782:8:::1;:56::i;:::-;41860:83;::::0;;15004:25:1;;;15060:2;15045:18;;15038:34;;;41915:10:0::1;15088:18:1::0;;;15081:60;41927:15:0::1;15172:2:1::0;15157:18;;15150:34;41860:83:0;;::::1;::::0;;;;14991:3:1;41860:83:0;;::::1;41956:6;::::0;42102:17:::1;::::0;41956:204:::1;::::0;-1:-1:-1;;;41956:204:0;;-1:-1:-1;;;;;41956:6:0;;::::1;::::0;:57:::1;::::0;:204:::1;::::0;42028:24;;41956:6:::1;::::0;42083:4;;42102:17;::::1;::::0;42134:15:::1;::::0;41956:204:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;40982:1186;;;;27194:1;-1:-1:-1::0;27206:6:0;:14;;-1:-1:-1;;;;27206:14:0;;;40918:1250::o;71489:467::-;71574:4;71610:10;71574:4;71658:28;71610:10;71678:7;71658:9;:28::i;:::-;71631:55;;71720:5;71701:16;:24;71697:124;;;71776:7;71785:16;71803:5;71749:60;;-1:-1:-1;;;71749:60:0;;;;;;;;;;:::i;71697:124::-;71856:59;71865:8;71875:7;71903:5;71884:16;:24;71910:4;71856:8;:59::i;59962:186::-;60031:4;60067:10;60088:30;60067:10;60108:2;60112:5;60088:9;:30::i;42746:212::-;20867:13;:11;:13::i;:::-;42800:11:::1;::::0;-1:-1:-1;;;42800:11:0;::::1;;;42796:62;;;42835:11;;-1:-1:-1::0;;;42835:11:0::1;;;;;;;;;;;42796:62;42868:11;:18:::0;;-1:-1:-1;;;;42868:18:0::1;-1:-1:-1::0;;;42868:18:0::1;::::0;;42902:48:::1;::::0;;16506:2:1;16488:21;;;16545:2;16525:18;;;16518:30;-1:-1:-1;;;16579:3:1;16564:19;;16557:42;42922:10:0::1;16666:4:1::0;16651:20;;16644:62;42934:15:0::1;16722:18:1::0;;;16715:34;;;;42902:48:0::1;::::0;16631:3:1;16616:19;42902:48:0::1;16248:507:1::0;42332:240:0;20867:13;:11;:13::i;:::-;42396:12:::1;::::0;-1:-1:-1;;;42396:12:0;::::1;;;42391:80;;42432:27;;-1:-1:-1::0;;;42432:27:0::1;;;;;;;;;;;42391:80;42481:12;:20:::0;;-1:-1:-1;;;;42481:20:0::1;::::0;;42517:47:::1;::::0;;42536:10:::1;5132:51:1::0;;42548:15:0::1;5214:2:1::0;5199:18;;5192:34;42517:47:0::1;::::0;5105:18:1;42517:47:0::1;4958:274:1::0;49447:745:0;20867:13;:11;:13::i;:::-;49543:6:::1;::::0;-1:-1:-1;;;;;49543:6:0;;::::1;49522:28:::0;;::::1;::::0;49518:102:::1;;49574:34;::::0;-1:-1:-1;;;49574:34:0;;-1:-1:-1;;;;;3507:32:1;;49574:34:0::1;::::0;::::1;3489:51:1::0;3462:18;;49574:34:0::1;3343:203:1::0;49518:102:0::1;49660:6;::::0;;-1:-1:-1;;;;;49678:27:0;;::::1;-1:-1:-1::0;;;;;;49678:27:0;::::1;::::0;::::1;::::0;;;49723:63:::1;::::0;;49660:6;;;::::1;17029:34:1::0;;;17094:2;17079:18;;17072:43;;;;49758:10:0::1;17131:18:1::0;;;17124:43;;;;49770:15:0::1;17198:2:1::0;17183:18;;17176:34;49723:63:0::1;::::0;16978:3:1;16963:19;49723:63:0::1;;;;;;;49820:6;::::0;:16:::1;::::0;;-1:-1:-1;;;49820:16:0;;;;49888:1:::1;::::0;-1:-1:-1;;;;;49820:6:0::1;::::0;:14:::1;::::0;:16:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:6;:16:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;49811:34:0::1;;49854:4;49861:6;;;;;;;;;-1:-1:-1::0;;;;;49861:6:0::1;-1:-1:-1::0;;;;;49861:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49811:64;::::0;-1:-1:-1;;;;;;49811:64:0::1;::::0;;;;;;-1:-1:-1;;;;;17451:15:1;;;49811:64:0::1;::::0;::::1;17433:34:1::0;17503:15;;17483:18;;;17476:43;17368:18;;49811:64:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;49803:87:0::1;::::0;49799:386:::1;;49923:6;;;;;;;;;-1:-1:-1::0;;;;;49923:6:0::1;-1:-1:-1::0;;;;;49923:14:0::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;49914:37:0::1;;49960:4;49967:6;;;;;;;;;-1:-1:-1::0;;;;;49967:6:0::1;-1:-1:-1::0;;;;;49967:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49914:67;::::0;-1:-1:-1;;;;;;49914:67:0::1;::::0;;;;;;-1:-1:-1;;;;;17451:15:1;;;49914:67:0::1;::::0;::::1;17433:34:1::0;17503:15;;17483:18;;;17476:43;17368:18;;49914:67:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49907:4;:74:::0;;-1:-1:-1;;;;;;49907:74:0::1;-1:-1:-1::0;;;;;49907:74:0;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;50001:14:0;;;:8:::1;:14;::::0;;;;;::::1;;49996:77;;50045:4;::::0;-1:-1:-1;;;;;50045:4:0::1;50036:14;::::0;;;:8:::1;:14;::::0;;;;:21;;-1:-1:-1;;50036:21:0::1;50053:4;50036:21;::::0;;49996:77:::1;50106:4;::::0;-1:-1:-1;;;;;50106:4:0::1;50092:19;::::0;;;:13:::1;:19;::::0;;;;;::::1;;50087:87;;50146:4;::::0;-1:-1:-1;;;;;50146:4:0::1;50132:19;::::0;;;:13:::1;:19;::::0;;;;:26;;-1:-1:-1;;50132:26:0::1;50154:4;50132:26;::::0;;50087:87:::1;49507:685;49447:745:::0;:::o;43124:237::-;20867:13;:11;:13::i;:::-;43183:16:::1;::::0;-1:-1:-1;;;43183:16:0;::::1;;;43179:72;;;43223:16;;-1:-1:-1::0;;;43223:16:0::1;;;;;;;;;;;43179:72;43261:16;:23:::0;;-1:-1:-1;;;;43261:23:0::1;-1:-1:-1::0;;;43261:23:0::1;::::0;;43300:53:::1;::::0;;17788:2:1;17770:21;;;17807:18;;17800:30;;;;-1:-1:-1;;;17861:3:1;17846:19;;17839:47;43325:10:0::1;17953:4:1::0;17938:20;;17931:62;43337:15:0::1;18009:18:1::0;;;18002:34;43300:53:0::1;::::0;17918:3:1;17903:19;43300:53:0::1;17530:512:1::0;60533:148:0;-1:-1:-1;;;;;60643:21:0;;;60616:7;60643:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;;;;60533:148::o;57456:360::-;20867:13;:11;:13::i;:::-;22648:7;22675:6;-1:-1:-1;;;;;22675:6:0;-1:-1:-1;;;;;57542:19:0::1;:8;-1:-1:-1::0;;;;;57542:19:0::1;::::0;57538:92:::1;;57585:33;::::0;-1:-1:-1;;;57585:33:0;;-1:-1:-1;;;;;3507:32:1;;57585:33:0::1;::::0;::::1;3489:51:1::0;3462:18;;57585:33:0::1;3343:203:1::0;57538:92:0::1;-1:-1:-1::0;;;;;;;57644:27:0;::::1;::::0;57640:91:::1;;57695:24;::::0;-1:-1:-1;;;57695:24:0;;-1:-1:-1;;;;;3507:32:1;;57695:24:0::1;::::0;::::1;3489:51:1::0;3462:18;;57695:24:0::1;3343:203:1::0;57640:91:0::1;57741:12;:23:::0;;-1:-1:-1;;;;;;57741:23:0::1;-1:-1:-1::0;;;;;57741:23:0;::::1;;::::0;;57775:33:::1;57741:23:::0;57775::::1;:33::i;22886:162::-:0;22957:10;22946:7;22648;22675:6;-1:-1:-1;;;;;22675:6:0;;22602:87;22946:7;-1:-1:-1;;;;;22946:21:0;;22942:99;;22991:38;;-1:-1:-1;;;22991:38:0;;23018:10;22991:38;;;3489:51:1;3462:18;;22991:38:0;3343:203:1;67743:136:0;67831:40;67840:8;67850:7;67859:5;67866:4;67831:8;:40::i;:::-;67743:136;;;:::o;65708:730::-;-1:-1:-1;;;;;65798:18:0;;65794:369;;65849:5;65833:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;65794:369:0;;-1:-1:-1;65794:369:0;;-1:-1:-1;;;;;65909:15:0;;65887:19;65909:15;;;:9;:15;;;;;;65943:19;;;65939:117;;;66015:4;66021:11;66034:5;65990:50;;-1:-1:-1;;;65990:50:0;;;;;;;;;;:::i;65939:117::-;-1:-1:-1;;;;;66099:15:0;;;;;;:9;:15;;;;;66117:19;;;;66099:37;;65794:369;-1:-1:-1;;;;;66179:16:0;;66175:213;;66241:12;:21;;;;;;;66175:213;;;-1:-1:-1;;;;;66339:13:0;;;;;;:9;:13;;;;;:22;;;;;;66175:213;66420:2;-1:-1:-1;;;;;66405:25:0;66414:4;-1:-1:-1;;;;;66405:25:0;;66424:5;66405:25;;;;1716::1;;1704:2;1689:18;;1570:177;66405:25:0;;;;;;;;65708:730;;;:::o;5762:162::-;5872:43;;;-1:-1:-1;;;;;5150:32:1;;5872:43:0;;;5132:51:1;5199:18;;;;5192:34;;;5872:43:0;;;;;;;;;;5105:18:1;;;;5872:43:0;;;;;;;;-1:-1:-1;;;;;5872:43:0;-1:-1:-1;;;5872:43:0;;;5845:71;;5865:5;;5845:19;:71::i;69667:496::-;69770:24;69797:28;69807:8;69817:7;69797:9;:28::i;:::-;69770:55;;-1:-1:-1;;69840:16:0;:37;69836:320;;69917:5;69898:16;:24;69894:132;;;69977:7;69986:16;70004:5;69950:60;;-1:-1:-1;;;69950:60:0;;;;;;;;;;:::i;69894:132::-;70069:60;70078:8;70088:7;70116:5;70097:16;:24;70123:5;70069:8;:60::i;62823:1075::-;-1:-1:-1;;;;;62907:18:0;;62903:88;;62949:30;;-1:-1:-1;;;62949:30:0;;62976:1;62949:30;;;3489:51:1;3462:18;;62949:30:0;3343:203:1;62903:88:0;-1:-1:-1;;;;;63005:16:0;;63001:88;;63045:32;;-1:-1:-1;;;63045:32:0;;63074:1;63045:32;;;3489:51:1;3462:18;;63045:32:0;3343:203:1;63001:88:0;63104:12;;-1:-1:-1;;;63104:12:0;;;;63099:151;;-1:-1:-1;;;;;63138:17:0;;;;;;:11;:17;;;;;;;;63137:18;:38;;;;-1:-1:-1;;;;;;63160:15:0;;;;;;:11;:15;;;;;;;;63159:16;63137:38;63133:106;;;63203:20;;-1:-1:-1;;;63203:20:0;;;;;;;;;;;63133:106;63274:6;;-1:-1:-1;;;63274:6:0;;;;;:27;;-1:-1:-1;;;;;;63284:17:0;;;;;;:11;:17;;;;;;;;63274:27;:46;;;-1:-1:-1;;;;;;63305:15:0;;;;;;:11;:15;;;;;;;;63274:46;63270:110;;;63344:24;63352:4;63358:2;63362:5;63344:7;:24::i;63270:110::-;63433:11;;63411:5;;-1:-1:-1;;;63433:11:0;;;;:33;;;;-1:-1:-1;;;;;;63449:17:0;;;;;;:11;:17;;;;;;;;63448:18;63433:33;:53;;;;-1:-1:-1;;;;;;63471:15:0;;;;;;:11;:15;;;;;;;;63470:16;63433:53;63429:134;;;63514:37;63535:4;63541:2;63545:5;63514:20;:37::i;:::-;63503:48;;63429:134;63577:12;;-1:-1:-1;;;63577:12:0;;;;:34;;;;-1:-1:-1;;;;;;63594:17:0;;;;;;:13;:17;;;;;;;;63593:18;63577:34;:83;;;;;63642:18;:16;:18::i;:::-;63631:8;63615:13;63625:2;63615:9;:13::i;:::-;:24;;;;:::i;:::-;:45;63577:83;63573:189;;;63721:8;63705:13;63715:2;63705:9;:13::i;:::-;:24;;;;:::i;:::-;63731:18;:16;:18::i;:::-;63684:66;;-1:-1:-1;;;63684:66:0;;;;;5423:25:1;;;;5464:18;;;5457:34;5396:18;;63684:66:0;5237:260:1;63573:189:0;-1:-1:-1;;;;;63776:19:0;;;;;;:13;:19;;;;;;;;63772:79;;;63819:20;;-1:-1:-1;;;63819:20:0;;;;;;;;;;;63772:79;63863:27;63871:4;63877:2;63881:8;63863:7;:27::i;68652:455::-;-1:-1:-1;;;;;68768:22:0;;68764:94;;68814:32;;-1:-1:-1;;;68814:32:0;;68843:1;68814:32;;;3489:51:1;3462:18;;68814:32:0;3343:203:1;68764:94:0;-1:-1:-1;;;;;68872:21:0;;68868:92;;68917:31;;-1:-1:-1;;;68917:31:0;;68945:1;68917:31;;;3489:51:1;3462:18;;68917:31:0;3343:203:1;68868:92:0;-1:-1:-1;;;;;68970:21:0;;;;;;;:11;:21;;;;;;;;:30;;;;;;;;;:38;;;69019:81;;;;69073:7;-1:-1:-1;;;;;69054:34:0;69063:8;-1:-1:-1;;;;;69054:34:0;;69082:5;69054:34;;;;1716:25:1;;1704:2;1689:18;;1570:177;69054:34:0;;;;;;;;68652:455;;;;:::o;56560:420::-;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;-1:-1:-1;;56640:10:0::1;:29:::0;56636:78:::1;;56680:31;::::0;-1:-1:-1;;;56680:31:0;;56703:6:::1;56680:31;::::0;::::1;3489:51:1::0;3462:18;;56680:31:0::1;3343:203:1::0;56636:78:0::1;56748:16;::::0;;56762:1:::1;56748:16:::0;;;;;::::1;::::0;;56724:21:::1;::::0;56748:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;56785:6:0::1;::::0;:13:::1;::::0;;-1:-1:-1;;;56785:13:0;;;;56724:40;;-1:-1:-1;;;;;;56785:6:0;;::::1;::::0;:11:::1;::::0;-1:-1:-1;56785:13:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56775:4;56780:1;56775:7;;;;;;;;:::i;:::-;;;;;;:23;-1:-1:-1::0;;;;;56775:23:0::1;;;-1:-1:-1::0;;;;;56775:23:0::1;;;::::0;::::1;56827:4;56809;56814:1;56809:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;56809:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;56845:6:::1;::::0;:127:::1;::::0;-1:-1:-1;;;56845:127:0;;:6;::::1;::::0;:57:::1;::::0;56924:6;;56845:127:::1;::::0;:6:::1;::::0;56946:4;;56952:2;;56956:15:::1;::::0;56845:127:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;27206:6:0;:14;;-1:-1:-1;;;;27206:14:0;;;-1:-1:-1;;;;;;56560:420:0:o;24417:191::-;24491:16;24510:6;;-1:-1:-1;;;;;24527:17:0;;;-1:-1:-1;;;;;;24527:17:0;;;;;;24560:40;;24510:6;;;;;;;24560:40;;24491:16;24560:40;24480:128;24417:191;:::o;23860:220::-;20867:13;:11;:13::i;:::-;-1:-1:-1;;;;;23945:22:0;::::1;23941:93;;23991:31;::::0;-1:-1:-1;;;23991:31:0;;24019:1:::1;23991:31;::::0;::::1;3489:51:1::0;3462:18;;23991:31:0::1;3343:203:1::0;23941:93:0::1;24044:28;24063:8;24044:18;:28::i;6314:295::-:0;6395:23;6421:33;-1:-1:-1;;;;;6421:27:0;;6449:4;6421:27;:33::i;:::-;6395:59;;6469:10;:17;6490:1;6469:22;;:57;;;;;6507:10;6496:30;;;;;;;;;;;;:::i;:::-;6495:31;6469:57;6465:137;;;6550:40;;-1:-1:-1;;;6550:40:0;;-1:-1:-1;;;;;3507:32:1;;6550:40:0;;;3489:51:1;3462:18;;6550:40:0;3343:203:1;64498:518:0;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;-1:-1:-1;;;;;64629:14:0;::::1;64605:7:::0;64629:14;;;:8:::1;:14;::::0;;;;;27170:13;64629:14:::1;:40:::0;::::1;;;-1:-1:-1::0;64648:6:0::1;:16:::0;:20;;64629:40:::1;64625:104;;;64693:24;64704:4;64710:6;64693:10;:24::i;:::-;64686:31;;;;64625:104;-1:-1:-1::0;;;;;64743:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;:39:::0;::::1;;;-1:-1:-1::0;64760:7:0::1;:17:::0;:21;;64743:39:::1;64739:104;;;64806:25;64818:4;64824:6;64806:11;:25::i;64739:104::-;-1:-1:-1::0;;;;;64858:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;;::::1;;64857:15;:32:::0;::::1;;;-1:-1:-1::0;;;;;;64877:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;64876:13;64857:32;:63;;;;-1:-1:-1::0;64894:11:0::1;:21:::0;:25;;64857:63:::1;64853:132;;;64944:29;64960:4;64966:6;64944:15;:29::i;64853:132::-;-1:-1:-1::0;65002:6:0;27194:1:::1;27206:6:::0;:14;;-1:-1:-1;;;;27206:14:0;;;64498:518;;-1:-1:-1;;;64498:518:0:o;40384:136::-;40435:7;25855;40484:11;;40462:19;:17;:19::i;:::-;:33;;;;:::i;:::-;:50;;;;:::i;1684:153::-;1759:12;1791:38;1813:6;1821:4;1827:1;1791:21;:38::i;52677:141::-;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;52781:29:::1;::::0;;::::1;::::0;::::1;::::0;;;27179:4;52781:29;;;52754:7;;52781:29:::1;::::0;52797:4;52803:6;52781:7:::1;:29::i;53160:143::-:0;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;53265:30:::1;::::0;;::::1;::::0;::::1;::::0;;;53273:7:::1;53265:30:::0;;;53238:7;;53265:30:::1;::::0;53282:4;53288:6;53265:7:::1;:30::i;53649:151::-:0;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;53758:34:::1;::::0;;::::1;::::0;::::1;::::0;;;53766:11:::1;53758:34:::0;;;53731:7;;53758:34:::1;::::0;53779:4;53785:6;53758:7:::1;:34::i;2430:398::-:0;2529:12;2582:5;2558:21;:29;2554:110;;;2611:41;;-1:-1:-1;;;2611:41:0;;2646:4;2611:41;;;3489:51:1;3462:18;;2611:41:0;3343:203:1;2554:110:0;2675:12;2689:23;2716:6;-1:-1:-1;;;;;2716:11:0;2735:5;2742:4;2716:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2674:73;;;;2765:55;2792:6;2800:7;2809:10;2765:26;:55::i;:::-;2758:62;2430:398;-1:-1:-1;;;;;;2430:398:0:o;54198:399::-;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;54331:17;;54292:7;;;25855::::1;54379:17;54331::::0;54379:6;:17:::1;:::i;:::-;:34;;;;:::i;:::-;54359:54:::0;-1:-1:-1;54424:17:0::1;54444:18;54359:54:::0;54444:6;:18:::1;:::i;:::-;54424:38:::0;-1:-1:-1;54477:13:0;;54473:90:::1;;54507:44;54516:7;54525:4;54531:9;54542:8;54507;:44::i;:::-;27206:6:::0;:14;;-1:-1:-1;;;;27206:14:0;;;54580:9;54198:399;-1:-1:-1;;;;;;54198:399:0:o;3592:391::-;3706:12;3736:7;3731:245;;3760:19;3768:10;3760:7;:19::i;:::-;3731:245;;;3816:17;;:22;:49;;;;-1:-1:-1;;;;;;3842:18:0;;;:23;3816:49;3812:121;;;3893:24;;-1:-1:-1;;;3893:24:0;;-1:-1:-1;;;;;3507:32:1;;3893:24:0;;;3489:51:1;3462:18;;3893:24:0;3343:203:1;3812:121:0;-1:-1:-1;3954:10:0;3947:17;;54990:286;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;55136:17;;27170:13;;55156:3;;55127:26:::1;::::0;:6;:26:::1;:::i;:::-;:32;;;;:::i;:::-;55100:59;;55170:41;55186:16;55204:6;55170:15;:41::i;:::-;55232:36;55240:4;55254;55261:6;55232:7;:36::i;:::-;-1:-1:-1::0;;27206:6:0;:14;;-1:-1:-1;;;;27206:14:0;;;-1:-1:-1;;;54990:286:0:o;4251:328::-;4321:17;;:21;4317:255;;4416:10;4410:17;4473:15;4460:10;4456:2;4452:19;4445:44;4317:255;4543:17;;-1:-1:-1;;;4543:17:0;;;;;;;;;;;55532:184;27170:6;:13;;-1:-1:-1;;;;27170:13:0;-1:-1:-1;;;27170:13:0;;;55628:12:::1;:42:::0;;55654:16;;55628:12;27170:13;;55628:42:::1;::::0;55654:16;;55628:42:::1;:::i;:::-;;;;;;;;55702:6;55681:17;;:27;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;27206:6:0;:14;;-1:-1:-1;;;;27206:14:0;;;-1:-1:-1;;55532:184:0:o;14:250:1:-;99:1;109:113;123:6;120:1;117:13;109:113;;;199:11;;;193:18;180:11;;;173:39;145:2;138:10;109:113;;;-1:-1:-1;;256:1:1;238:16;;231:27;14:250::o;269:396::-;418:2;407:9;400:21;381:4;450:6;444:13;493:6;488:2;477:9;473:18;466:34;509:79;581:6;576:2;565:9;561:18;556:2;548:6;544:15;509:79;:::i;:::-;649:2;628:15;-1:-1:-1;;624:29:1;609:45;;;;656:2;605:54;;269:396;-1:-1:-1;;269:396:1:o;670:131::-;-1:-1:-1;;;;;745:31:1;;735:42;;725:70;;791:1;788;781:12;806:247;865:6;918:2;906:9;897:7;893:23;889:32;886:52;;;934:1;931;924:12;886:52;973:9;960:23;992:31;1017:5;992:31;:::i;1250:315::-;1318:6;1326;1379:2;1367:9;1358:7;1354:23;1350:32;1347:52;;;1395:1;1392;1385:12;1347:52;1434:9;1421:23;1453:31;1478:5;1453:31;:::i;:::-;1503:5;1555:2;1540:18;;;;1527:32;;-1:-1:-1;;;1250:315:1:o;1752:180::-;1811:6;1864:2;1852:9;1843:7;1839:23;1835:32;1832:52;;;1880:1;1877;1870:12;1832:52;-1:-1:-1;1903:23:1;;1752:180;-1:-1:-1;1752:180: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;2587:118::-;2673:5;2666:13;2659:21;2652:5;2649:32;2639:60;;2695:1;2692;2685:12;2710:382;2775:6;2783;2836:2;2824:9;2815:7;2811:23;2807:32;2804:52;;;2852:1;2849;2842:12;2804:52;2891:9;2878:23;2910:31;2935:5;2910:31;:::i;:::-;2960:5;-1:-1:-1;3017:2:1;3002:18;;2989:32;3030:30;2989:32;3030:30;:::i;:::-;3079:7;3069:17;;;2710:382;;;;;:::o;3097:241::-;3153:6;3206:2;3194:9;3185:7;3181:23;3177:32;3174:52;;;3222:1;3219;3212:12;3174:52;3261:9;3248:23;3280:28;3302:5;3280:28;:::i;3551:388::-;3619:6;3627;3680:2;3668:9;3659:7;3655:23;3651:32;3648:52;;;3696:1;3693;3686:12;3648:52;3735:9;3722:23;3754:31;3779:5;3754:31;:::i;:::-;3804:5;-1:-1:-1;3861:2:1;3846:18;;3833:32;3874:33;3833:32;3874:33;:::i;4595:358::-;4819:2;4808:9;4801:21;4782:4;4839:49;4884:2;4873:9;4869:18;4507:2;4495:15;;-1:-1:-1;;;4535:4:1;4526:14;;4519:37;4581:2;4572:12;;4430:160;4839:49;4831:57;;4938:6;4931:14;4924:22;4919:2;4908:9;4904:18;4897:50;4595:358;;;;:::o;6167:127::-;6228:10;6223:3;6219:20;6216:1;6209:31;6259:4;6256:1;6249:15;6283:4;6280:1;6273:15;6299:128;6366:9;;;6387:11;;;6384:37;;;6401:18;;:::i;6432:345::-;-1:-1:-1;;;;;6652:32:1;;;;6634:51;;6716:2;6701:18;;6694:34;;;;6759:2;6744:18;;6737:34;6622:2;6607:18;;6432:345::o;6782:184::-;6852:6;6905:2;6893:9;6884:7;6880:23;6876:32;6873:52;;;6921:1;6918;6911:12;6873:52;-1:-1:-1;6944:16:1;;6782:184;-1:-1:-1;6782:184:1:o;7750:125::-;7815:9;;;7836:10;;;7833:36;;;7849:18;;:::i;7880:610::-;8182:3;8171:9;8164:22;8145:4;8203:50;8248:3;8237:9;8233:19;4507:2;4495:15;;-1:-1:-1;;;4535:4:1;4526:14;;4519:37;4581:2;4572:12;;4430:160;8203:50;8296:14;;8289:22;8284:2;8269:18;;8262:50;-1:-1:-1;8355:14:1;;8348:22;8343:2;8328:18;;8321:50;-1:-1:-1;;;;;8407:32:1;;;;8402:2;8387:18;;8380:60;8471:3;8456:19;;;8449:35;8195:58;7880:610::o;10907:251::-;10977:6;11030:2;11018:9;11009:7;11005:23;11001:32;10998:52;;;11046:1;11043;11036:12;10998:52;11078:9;11072:16;11097:31;11122:5;11097:31;:::i;13861:168::-;13934:9;;;13965;;13982:15;;;13976:22;;13962:37;13952:71;;14003:18;;:::i;14034:217::-;14074:1;14100;14090:132;;14144:10;14139:3;14135:20;14132:1;14125:31;14179:4;14176:1;14169:15;14207:4;14204:1;14197:15;14090:132;-1:-1:-1;14236:9:1;;14034:217::o;14641:127::-;14702:10;14697:3;14693:20;14690:1;14683:31;14733:4;14730:1;14723:15;14757:4;14754:1;14747:15;15195:461;15248:3;15286:5;15280:12;15313:6;15308:3;15301:19;15339:4;15368:2;15363:3;15359:12;15352:19;;15405:2;15398:5;15394:14;15426:1;15436:195;15450:6;15447:1;15444:13;15436:195;;;15515:13;;-1:-1:-1;;;;;15511:39:1;15499:52;;15571:12;;;;15606:15;;;;15547:1;15465:9;15436:195;;;-1:-1:-1;15647:3:1;;15195:461;-1:-1:-1;;;;;15195:461:1:o;15661:582::-;15960:6;15949:9;15942:25;16003:6;15998:2;15987:9;15983:18;15976:34;16046:3;16041:2;16030:9;16026:18;16019:31;15923:4;16067:57;16119:3;16108:9;16104:19;16096:6;16067:57;:::i;:::-;-1:-1:-1;;;;;16160:32:1;;;;16155:2;16140:18;;16133:60;-1:-1:-1;16224:3:1;16209:19;16202:35;16059:65;15661:582;-1:-1:-1;;;15661:582:1:o;18047:510::-;18318:6;18307:9;18300:25;18361:3;18356:2;18345:9;18341:18;18334:31;18281:4;18382:57;18434:3;18423:9;18419:19;18411:6;18382:57;:::i;:::-;-1:-1:-1;;;;;18475:32:1;;;;18470:2;18455:18;;18448:60;-1:-1:-1;18539:2:1;18524:18;18517:34;18374:65;18047:510;-1:-1:-1;;18047:510:1:o;18562:245::-;18629:6;18682:2;18670:9;18661:7;18657:23;18653:32;18650:52;;;18698:1;18695;18688:12;18650:52;18730:9;18724:16;18749:28;18771:5;18749:28;:::i;18812:287::-;18941:3;18979:6;18973:13;18995:66;19054:6;19049:3;19042:4;19034:6;19030:17;18995:66;:::i;:::-;19077:16;;;;;18812:287;-1:-1:-1;;18812:287:1:o

Swarm Source

ipfs://0722c751dbdd45ceea94b2a7c299c73f6397f7ae0a67e96eaa0c64748ca431e2
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.