ETH Price: $2,283.75 (-3.39%)

Token

Mulτiτensor (MULTIT)
 

Overview

Max Total Supply

1,000,000 MULTIT

Holders

52

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
808.225097472255256428 MULTIT

Value
$0.00
0x5ff545f58f8dc48d15425946ab8726345debef3b
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Multitensor

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-04-10
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

/********************************************************************************************
  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 Mulτiτensor Token Contract
 *
 * @notice Mulτiτensor 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 Multitensor is Ownable, IERC20Metadata, IERC20Errors, ICommonError {

    // DATA

    struct Fee {
        uint256 marketing;
    }

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

    IRouter public router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);

    string private constant NAME = unicode"Mulτiτensor";
    string private constant SYMBOL = "MULTIT";

    uint8 private constant DECIMALS = 18;

    uint256 public constant FEEDENOMINATOR = 100_000;

    uint256 private _totalSupply;
        
    uint256 public tradeStartTime = 0;
    uint256 public tradeStartBlock = 0;
    uint256 public totalTriggerZeusBuyback = 0;
    uint256 public lastTriggerZeusTimestamp = 0;
    uint256 public totalFeeCollected = 0;
    uint256 public totalFeeRedeemed = 0;
    uint256 public minSwap = 100 ether;

    address public projectOwner = 0xfC58a1C02E096C0748887Dd64B2FF5cf08c693f7;
    address public marketingReceiver = 0xb4a00fB37aDaAC0e7325D7f14C6274Fd39F87C3e;
    
    address public pair;
    
    bool public tradeEnabled = false;
    bool public limitEnabled = false;
    bool public isLimitLocked = false;
    bool public isFeeActive = false;
    bool public isFeeLocked = false;
    bool public isReceiverLocked = false;
    bool public isSwapEnabled = false;
    bool public inSwap = false;

    // MAPPING

    mapping(address account => uint256) private _balances;
    mapping(address account => mapping(address spender => uint256)) private _allowances;
    
    mapping(address pair => bool) public isPairLP;
    mapping(address account => bool) public isExemptFee;
    mapping(address account => bool) public isExemptLimit;

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

    // ERROR

    /**
     * @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.
     * @param blockNumber The block when trading was enabled.
     *
     * @dev The `currentState` is required to inform user of the current state of trading.
     */
    error TradeAlreadyEnabled(bool currentState, uint256 timestamp, uint256 blockNumber);

    /**
     * @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 limit has already been removed.
     */
    error LimitAlreadyRemoved();

    /**
     * @notice Error indicating that the anti sniper restriction is active.
     */
    error AntiSniperActive();

    /**
     * @notice Error indicating that the native token cannot be withdrawn from the smart contract.
     */
    error CannotWithdrawNativeToken();

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

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

    /**
     * @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 Mulτiτensor 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;
        }
        
        _mint(msg.sender, 1_000_000 * 10**DECIMALS);

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

    // EVENT

    /**
     * @notice Emits when an automatic or manual redemption occurs, distributing fees
     * and redeeming a specific amount.
     * 
     * @param marketingFeeDistribution The amount distributed for marketing fees.
     * @param amountToRedeem The total amount being redeemed.
     * @param caller The address that triggered the redemption.
     * @param timestamp The timestamp at which the redemption event occurred.
     */
    event AutoRedeem(uint256 marketingFeeDistribution, uint256 amountToRedeem, address caller, uint256 timestamp);

    /**
     * @notice Emitted when the router address is updated.
     * 
     * @param oldRouter The address of the old router.
     * @param newRouter The address of the new router.
     * @param caller The address that triggered the router update.
     * @param timestamp The timestamp when the update occurred.
     */
    event UpdateRouter(address oldRouter, address newRouter, address caller, uint256 timestamp);

    /**
     * @notice Emitted upon setting the status of a specific address type.
     * 
     * @param addressType The type of address status being modified.
     * @param account The address of the account whose status is being updated.
     * @param oldStatus The previous exemption status.
     * @param newStatus The new exemption status.
     * @param caller The address that triggered the status update.
     * @param timestamp The timestamp when the update occurred.
     */
    event SetAddressState(string addressType, address account, bool oldStatus, bool newStatus, address caller, uint256 timestamp); 
    
    /**
     * @notice Emitted when 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 minimum swap value is updated.
     * 
     * @param oldMinSwap The old minimum swap value before the update.
     * @param newMinSwap The new minimum swap value after the update.
     * @param caller The address of the caller who updated the minimum swap value.
     * @param timestamp The timestamp when the update occurred.
     */
    event UpdateMinSwap(uint256 oldMinSwap, uint256 newMinSwap, address caller, uint256 timestamp);

    /**
     * @notice Emitted when the state of a feature is updated.
     * 
     * @param stateType The type of state being updated.
     * @param oldStatus The previous status before the update.
     * @param newStatus The new status after the update.
     * @param caller The address of the caller who updated the state.
     * @param timestamp The timestamp when the update occurred.
     */
    event UpdateState(string stateType, bool oldStatus, bool newStatus, address caller, uint256 timestamp);

    /**
     * @notice Emitted when the 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 trading is enabled for the contract.
     * 
     * @param caller The address that triggered the trading enablement.
     * @param timestamp The timestamp when trading was enabled.
     */
    event TradeEnabled(address caller, uint256 timestamp);

    // FUNCTION

    /* General */
    
    /**
     * @notice Allows the contract to receive Ether.
     * 
     * @dev This is a required feature to have in order to allow the smart contract
     * to be able to receive ether from the swap.
     */
    receive() external payable {}

    /**
     * @notice Withdraws tokens or Ether from the contract to a specified address.
     * 
     * @param tokenAddress The address of the token to withdraw.
     * @param amount The amount of tokens or Ether to withdraw.
     * 
     * @dev You need to use address(0) as `tokenAddress` to withdraw Ether and
     * use 0 as `amount` to withdraw the whole balance amount in the smart contract.
     * Anyone can trigger this function to send the fund to the `marketingReceiver`.
     * Only `marketingReceiver` address will not be able to trigger this function to
     * withdraw Ether from the smart contract by himself/herself. Should throw if try
     * to withdraw any amount of native token from the smart contract. Distribution
     * of native token can only be done through autoRedeem function.
     */
    function wTokens(address tokenAddress, uint256 amount) external {
        uint256 allocated = totalFeeCollected > totalFeeRedeemed ? totalFeeCollected - totalFeeRedeemed : 0;
        uint256 toTransfer = amount;
        address receiver = marketingReceiver;
        
        if (tokenAddress == address(this)) {
            if (allocated >= balanceOf(address(this))) {
                revert CannotWithdrawNativeToken();
            }
            if (amount > balanceOf(address(this)) - allocated) {
                revert ERC20InsufficientBalance(address(this), balanceOf(address(this)) - allocated, amount);
            }
            if (amount == 0) {
                toTransfer = balanceOf(address(this)) - allocated;
            }
            _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).transfer(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, tradeStartBlock);
        }
        if (tradeStartTime != 0 || tradeStartBlock != 0) {
            revert AlreadyFinalized();
        }
        if (isFeeActive) {
            revert AlreadyCurrentState("isFeeActive", isFeeActive);
        }
        if (isSwapEnabled) {
            revert AlreadyCurrentState("isSwapEnabled", isSwapEnabled);
        }
        tradeEnabled = true;
        limitEnabled = true;
        isFeeActive = true;
        isSwapEnabled = true;
        tradeStartTime = block.timestamp;
        tradeStartBlock = 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.
     *
     * @return The limit based on circulating supply of tokens.
     */
    function checkWalletLimit() internal view returns (uint256) {
        uint256 circulating = circulatingSupply();
        if (limitEnabled) {
            circulating = circulating * 1_000 / FEEDENOMINATOR;
        }
        return circulating;
    }

    /* Redeem */

    /**
     * @notice Initiates a manual redemption process by distributing a specific
     * amount of tokens for fee purposes, swapping a portion for ETH.
     *
     * @param amountToRedeem The amount of tokens to be redeemed and distributed
     * for fee.
     *
     * @dev This function calculates the distribution of tokens for fee redeems
     * the specified amount, and triggers a swap for ETH. This function can only
     * be used to manual redeem specified amount by the owner.
     */
    function manualRedeem(uint256 amountToRedeem) external swapping onlyOwner {
        if (amountToRedeem > circulatingSupply() * 500 / FEEDENOMINATOR) {
            revert CannotRedeemMoreThanAllowedTreshold(amountToRedeem, circulatingSupply() * 500 / FEEDENOMINATOR);
        }

        autoRedeem(amountToRedeem);
    }

    /**
     * @notice Initiates an automatic redemption process by distributing a specific
     * amount of tokens for marketing purposes, swapping a portion for ETH. Limited
     * to a maximum of 10% of circulating supply per transaction.
     * 
     * @param amountToRedeem The amount of tokens to be redeemed and distributed
     * for marketing.
     * 
     * @dev This function calculates the distribution of tokens for marketing
     * redeems the specified amount, and triggers a swap for ETH. This function 
     * can be used for both auto and manual redeem of the specified amount.
     */
    function autoRedeem(uint256 amountToRedeem) internal swapping {
        uint256 totalToRedeem = totalFeeCollected - totalFeeRedeemed;
        
        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 AutoRedeem(marketingFeeDistribution, amountToRedeem, msg.sender, block.timestamp);

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

    /* Update */
    
    /**
     * @notice Locks the limit mechanism, preventing further changes once locked.
     * 
     * @dev This function will emits the Lock event.
     */
    function lockLimit() external onlyOwner {
        if (isLimitLocked) {
            revert LimitLocked();
        }
        isLimitLocked = true;
        emit Lock("isLimitLocked", 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 Locks the limit mechanism, preventing further changes once locked.
     * 
     * @dev This function will emits the Lock event.
     */
    function removeLimit() external onlyOwner {
        if (isLimitLocked) {
            revert LimitLocked();
        }
        if (!limitEnabled) {
            revert LimitAlreadyRemoved();
        }
        limitEnabled = false;
        emit UpdateState("limitEnabled", true, false, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the minimum swap value, ensuring it doesn't exceed
     * a certain threshold.
     * 
     * @param newMinSwap The new minimum swap value to be set.
     * 
     * @dev This function will emits the UpdateMinSwap event.
     */
    function updateMinSwap(uint256 newMinSwap) external onlyOwner {
        if (newMinSwap > circulatingSupply() * 10 / FEEDENOMINATOR) {
            revert InvalidValue(newMinSwap);
        }
        if (minSwap == newMinSwap) {
            revert CannotUseCurrentValue(newMinSwap);
        }
        uint256 oldMinSwap = minSwap;
        minSwap = newMinSwap;
        emit UpdateMinSwap(oldMinSwap, newMinSwap, msg.sender, block.timestamp);
    }

    /**
     * @notice Updates the status of fee activation, allowing toggling the fee mechanism.
     * a certain threshold.
     * 
     * @param newStatus The new status for fee activation.
     * 
     * @dev This function will emits the UpdateState event.
     */
    function updateFeeActive(bool newStatus) external 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 Updates the status of swap enabling, allowing toggling the swap mechanism.
     * 
     * @param newStatus The new status for swap enabling.
     * 
     * @dev This function will emits the UpdateState event.
     */
    function updateSwapEnabled(bool newStatus) external onlyOwner {
        if (isSwapEnabled == newStatus) {
            revert CannotUseCurrentState(newStatus);
        }
        bool oldStatus = isSwapEnabled;
        isSwapEnabled = newStatus;
        emit UpdateState("isSwapEnabled", 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 > 20_000) {
            revert InvalidTotalFee(newMarketingFee, 20_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 > 20_000) {
            revert InvalidTotalFee(newMarketingFee, 20_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;
            }
        }
    }

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

    /* 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 (block.timestamp <= tradeStartBlock + 2 && isPairLP[from]) {
            revert AntiSniperActive();
        }
        
        if (inSwap || isExemptFee[from] || isExemptFee[to]) {
            return _update(from, to, value);
        }
        if (from != pair && isSwapEnabled && totalFeeCollected - totalFeeRedeemed >= minSwap && balanceOf(address(this)) >= minSwap) {
            autoRedeem(minSwap);
        }

        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());
        }

        _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":[{"internalType":"string","name":"stateType","type":"string"},{"internalType":"bool","name":"state","type":"bool"}],"name":"AlreadyCurrentState","type":"error"},{"inputs":[],"name":"AlreadyFinalized","type":"error"},{"inputs":[],"name":"AntiSniperActive","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":"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":[],"name":"LimitAlreadyRemoved","type":"error"},{"inputs":[],"name":"LimitLocked","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":"bool","name":"currentState","type":"bool"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"TradeAlreadyEnabled","type":"error"},{"inputs":[],"name":"TradeNotYetEnabled","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"marketingFeeDistribution","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountToRedeem","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AutoRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"addressType","type":"string"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"oldStatus","type":"bool"},{"indexed":false,"internalType":"bool","name":"newStatus","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"SetAddressState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TradeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"feeType","type":"string"},{"indexed":false,"internalType":"uint256","name":"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":"uint256","name":"oldMinSwap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinSwap","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateMinSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"receiverType","type":"string"},{"indexed":false,"internalType":"address","name":"oldReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"newReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRouter","type":"address"},{"indexed":false,"internalType":"address","name":"newRouter","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"stateType","type":"string"},{"indexed":false,"internalType":"bool","name":"oldStatus","type":"bool"},{"indexed":false,"internalType":"bool","name":"newStatus","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"UpdateState","type":"event"},{"inputs":[],"name":"FEEDENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"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":[],"name":"isLimitLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"isPairLP","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReceiverLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSwapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":"lockLimit","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":"minSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeemedFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removeLimit","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":"tradeStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferFee","outputs":[{"internalType":"uint256","name":"marketing","type":"uint256"}],"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":"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":"uint256","name":"newMinSwap","type":"uint256"}],"name":"updateMinSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRouter","type":"address"}],"name":"updateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateSellFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"updateSwapEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMarketingFee","type":"uint256"}],"name":"updateTransferFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

614e206080819052600181905560a0819052600281905560c0819052600355600060e081905260048190556101206040526101008190526005819055600680546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d1790915560088290556009829055600a829055600b829055600c829055600d9190915568056bc75e2d63100000600e55600f8054821673fc58a1c02e096c0748887dd64b2ff5cf08c693f71790556010805490911673b4a00fb37adaac0e7325d7f14c6274fd39f87c3e17905560118054600160a01b600160e01b0319169055348015620000ed57600080fd5b5033806200011657604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200012181620003ce565b50600f80546001600160a01b039081166000908152601560208181526040808420805460ff199081166001908117909255875487168652601680855283872080548316841790556006805489168852958552838720805483168417905594548716865293909252909220805490911690911790559054163314620001d2573360009081526015602090815260408083208054600160ff19918216811790925560169093529220805490911690911790555b620001fa33620001e56012600a620006a4565b620001f490620f4240620006bc565b6200041e565b600660009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200024e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002749190620006d6565b6001600160a01b031663c9c6539630600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002fd9190620006d6565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af11580156200034b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003719190620006d6565b601180546001600160a01b0319166001600160a01b0392831690811782556000908152601460209081526040808320805460ff19908116600190811790925594549095168352601690915290208054909116909117905562000717565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382166200044a5760405163ec442f0560e01b8152600060048201526024016200010d565b62000458600083836200045c565b5050565b6001600160a01b0383166200048b5780600760008282546200047f919062000701565b90915550620004ff9050565b6001600160a01b03831660009081526012602052604090205481811015620004e05760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016200010d565b6001600160a01b03841660009081526012602052604090209082900390555b6001600160a01b0382166200051d576007805482900390556200053c565b6001600160a01b03821660009081526012602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200058291815260200190565b60405180910390a3505050565b634e487b7160e01b600052601160045260246000fd5b600181815b80851115620005e6578160001904821115620005ca57620005ca6200058f565b80851615620005d857918102915b93841c9390800290620005aa565b509250929050565b600082620005ff575060016200069e565b816200060e575060006200069e565b8160018114620006275760028114620006325762000652565b60019150506200069e565b60ff8411156200064657620006466200058f565b50506001821b6200069e565b5060208310610133831016604e8410600b841016171562000677575081810a6200069e565b620006838383620005a5565b80600019048211156200069a576200069a6200058f565b0290505b92915050565b6000620006b560ff841683620005ee565b9392505050565b80820281158282048414176200069e576200069e6200058f565b600060208284031215620006e957600080fd5b81516001600160a01b0381168114620006b557600080fd5b808201808211156200069e576200069e6200058f565b61343c80620007276000396000f3fe6080604052600436106103b05760003560e01c80638da5cb5b116101e7578063aeddf6771161010d578063da4daf71116100a0578063e811f50a1161006f578063e811f50a14610ad4578063f2c4220e14610aeb578063f2fde38b14610b01578063f887ea4014610b2157600080fd5b8063da4daf7114610a5c578063dd62ed3e14610a72578063e2924cd114610a92578063e43504da14610ab357600080fd5b8063cf9769fd116100dc578063cf9769fd146109ee578063d621e81314610a03578063d830678614610a24578063d941907114610a4557600080fd5b8063aeddf67714610982578063b908de8c14610997578063b9b2b5cd146109b8578063c851cc32146109ce57600080fd5b8063a457c2d711610185578063a9059cbb11610154578063a9059cbb1461091f578063ab28a04c1461093f578063ab36629214610956578063acb2ad6f1461096b57600080fd5b8063a457c2d71461089e578063a50ca9ba146108be578063a5949bcf146108df578063a8aa1b31146108ff57600080fd5b806395d89b41116101c157806395d89b411461081957806397e1b9d3146108485780639d48fde91461085e578063a4475ce41461087e57600080fd5b80638da5cb5b146107b2578063924de9b7146107e45780639358928b1461080457600080fd5b80633d6362d6116102d757806363a954921161026a57806371538eed1161023957806371538eed1461072c57806375fed3c7146107425780638577a6d514610762578063891ff84a1461078257600080fd5b806363a95492146106b65780636d800a3c146106d657806370a08231146106f7578063715018a61461071757600080fd5b806359cd9031116102a657806359cd90311461063b5780635d7cc7f5146106515780636225658914610681578063625dd6051461069657600080fd5b80633d6362d6146105c4578063422e6cea146105e4578063467abe0a14610604578063470624021461062457600080fd5b806323b872dd1161034f578063351a964d1161031e578063351a964d14610543578063355496ca1461056457806339509351146105845780633bf31454146105a457600080fd5b806323b872dd146104da5780632b14ca56146104fa5780632c735ef814610511578063313ce5671461052757600080fd5b8063095ea7b31161038b578063095ea7b31461045b57806318160ddd1461047b5780631d933a4a1461049a5780631f685bac146104ba57600080fd5b806299d386146103bc57806306fdde03146103d357806308c436501461041b57600080fd5b366103b757005b600080fd5b3480156103c857600080fd5b506103d1610b41565b005b3480156103df57600080fd5b5060408051808201909152600d81526c26bab667c234e7c232b739b7b960991b60208201525b6040516104129190612fc8565b60405180910390f35b34801561042757600080fd5b5061044b61043636600461302b565b60146020526000908152604090205460ff1681565b6040519015158152602001610412565b34801561046757600080fd5b5061044b61047636600461304f565b610ca5565b34801561048757600080fd5b506007545b604051908152602001610412565b3480156104a657600080fd5b506103d16104b536600461307b565b610cbf565b3480156104c657600080fd5b506103d16104d536600461304f565b610dc0565b3480156104e657600080fd5b5061044b6104f5366004613094565b611013565b34801561050657600080fd5b5060025461048c9081565b34801561051d57600080fd5b5061048c60085481565b34801561053357600080fd5b5060405160128152602001610412565b34801561054f57600080fd5b5060115461044b90600160d01b900460ff1681565b34801561057057600080fd5b506103d161057f3660046130e3565b611037565b34801561059057600080fd5b5061044b61059f36600461304f565b61112e565b3480156105b057600080fd5b506103d16105bf36600461311c565b611154565b3480156105d057600080fd5b506103d16105df36600461302b565b611217565b3480156105f057600080fd5b506103d16105ff3660046130e3565b611365565b34801561061057600080fd5b506103d161061f36600461307b565b611455565b34801561063057600080fd5b5060015461048c9081565b34801561064757600080fd5b5061048c600e5481565b34801561065d57600080fd5b5061044b61066c36600461302b565b60166020526000908152604090205460ff1681565b34801561068d57600080fd5b506103d161154d565b3480156106a257600080fd5b506103d16106b13660046130e3565b611621565b3480156106c257600080fd5b506103d16106d136600461307b565b61182b565b3480156106e257600080fd5b5060115461044b90600160a81b900460ff1681565b34801561070357600080fd5b5061048c61071236600461302b565b611890565b34801561072357600080fd5b506103d16118ab565b34801561073857600080fd5b5061048c600d5481565b34801561074e57600080fd5b506103d161075d36600461307b565b6118bf565b34801561076e57600080fd5b506103d161077d36600461307b565b61197e565b34801561078e57600080fd5b5061044b61079d36600461302b565b60156020526000908152604090205460ff1681565b3480156107be57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610412565b3480156107f057600080fd5b506103d16107ff36600461311c565b611a81565b34801561081057600080fd5b5061048c611b19565b34801561082557600080fd5b5060408051808201909152600681526513555315125560d21b6020820152610405565b34801561085457600080fd5b5061048c600b5481565b34801561086a57600080fd5b506103d161087936600461307b565b611b4c565b34801561088a57600080fd5b50600f546107cc906001600160a01b031681565b3480156108aa57600080fd5b5061044b6108b936600461304f565b611bee565b3480156108ca57600080fd5b5060115461044b90600160b01b900460ff1681565b3480156108eb57600080fd5b506010546107cc906001600160a01b031681565b34801561090b57600080fd5b506011546107cc906001600160a01b031681565b34801561092b57600080fd5b5061044b61093a36600461304f565b611c34565b34801561094b57600080fd5b5061048c620186a081565b34801561096257600080fd5b506103d1611c42565b34801561097757600080fd5b5060035461048c9081565b34801561098e57600080fd5b506103d1611ce3565b3480156109a357600080fd5b5060115461044b90600160c01b900460ff1681565b3480156109c457600080fd5b5061048c600c5481565b3480156109da57600080fd5b506103d16109e936600461302b565b611d86565b3480156109fa57600080fd5b506103d1612173565b348015610a0f57600080fd5b5060115461044b90600160a01b900460ff1681565b348015610a3057600080fd5b5060115461044b90600160d81b900460ff1681565b348015610a5157600080fd5b5060055461048c9081565b348015610a6857600080fd5b5061048c600a5481565b348015610a7e57600080fd5b5061048c610a8d366004613139565b612219565b348015610a9e57600080fd5b5060115461044b90600160c81b900460ff1681565b348015610abf57600080fd5b5060115461044b90600160b81b900460ff1681565b348015610ae057600080fd5b5060045461048c9081565b348015610af757600080fd5b5061048c60095481565b348015610b0d57600080fd5b506103d1610b1c36600461302b565b612244565b348015610b2d57600080fd5b506006546107cc906001600160a01b031681565b610b496122ef565b601154600160a01b900460ff1615610b9d5760115460085460095460405163025ad45560e61b8152600160a01b90930460ff1615156004840152602483019190915260448201526064015b60405180910390fd5b600854151580610bae575060095415155b15610bcc5760405163475a253560e01b815260040160405180910390fd5b601154600160b81b900460ff1615610c0557601154604051633f3e417d60e21b8152610b9491600160b81b900460ff1690600401613167565b601154600160d01b900460ff1615610c3e57601154604051633f3e417d60e21b8152610b9491600160d01b900460ff16906004016131a2565b6011805466ff0000ff00ffff60a01b1916660100000100010160a01b17905542600881905560098190556040805133815260208101929092527f7111af66182bdf8afd5e1cfa53fdb90ebba682d2cc11a7dfead27fcbf50bea8291015b60405180910390a1565b600033610cb381858561232b565b60019150505b92915050565b610cc76122ef565b601154600160c01b900460ff1615610cf25760405163882d29d360e01b815260040160405180910390fd5b614e20811115610d205760405163211a907760e11b815260048101829052614e206024820152604401610b94565b6002548103610d425760405163f6f35fcf60e01b815260040160405180910390fd5b60028054908290556040805160a08082526013908201527273656c6c466565202d204d61726b6574696e6760681b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e0015b60405180910390a15050565b6000600d54600c5411610dd4576000610de4565b600d54600c54610de491906131e5565b60105490915082906001600160a01b03908116903090861603610ea557610e0a30611890565b8310610e29576040516315ea636560e31b815260040160405180910390fd5b82610e3330611890565b610e3d91906131e5565b841115610e76573083610e4f30611890565b610e5991906131e5565b8560405163391434e360e21b8152600401610b94939291906131f8565b83600003610e955782610e8830611890565b610e9291906131e5565b91505b610ea030828461233d565b61100c565b6001600160a01b038516610f245783600003610ebf574791505b6001600160a01b0381163303610ee85760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610f1e573d6000803e3d6000fd5b5061100c565b83600003610f97576040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190613219565b91505b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905286169063a9059cbb906044016020604051808303816000875af1158015610fe6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100a9190613232565b505b5050505050565b600033611021858285612454565b61102c8585856124a7565b506001949350505050565b61103f6122ef565b6001600160a01b03821660009081526015602052604090205481151560ff9091161515036110835760405162a7e72d60e41b81528115156004820152602401610b94565b6001600160a01b038216600081815260156020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea90610100015b60405180910390a1505050565b6000338161113c8286612219565b905061102c828661114d878561324f565b600161279d565b61115c6122ef565b601154600160c01b900460ff16156111875760405163882d29d360e01b815260040160405180910390fd5b801515601160179054906101000a900460ff161515036111bd5760405162a7e72d60e41b81528115156004820152602401610b94565b6011805460ff60b81b198116600160b81b84151581029190911790925560405191900460ff16907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf390610db4908390859033904290613262565b61121f6122ef565b601154600160c81b900460ff161561124a5760405163341e380d60e11b815260040160405180910390fd5b6001600160a01b03811661127457604051634726455360e11b815260006004820152602401610b94565b6010546001600160a01b038083169116036112ad5760405163a936636960e01b81526001600160a01b0382166004820152602401610b94565b6001600160a01b0381163b156112d65760405163259f1ec560e01b815260040160405180910390fd5b601080546001600160a01b031981166001600160a01b038481169182179093556040805160a08082526011908201527036b0b935b2ba34b733a932b1b2b4bb32b960791b60c0820152939092166020840181905291830152336060830152426080830152907ff7df6bc5c0f9735c300a374247b60dcacf1942b6031785957e762d77977ed4209060e001610db4565b61136d6122ef565b6001600160a01b03821660009081526016602052604090205481151560ff9091161515036113b15760405162a7e72d60e41b81528115156004820152602401610b94565b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c0808252600d908201526c1a5cd15e195b5c1d131a5b5a5d609a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611121565b61145d6122ef565b601154600160c01b900460ff16156114885760405163882d29d360e01b815260040160405180910390fd5b614e208111156114b65760405163211a907760e11b815260048101829052614e206024820152604401610b94565b60015481036114d85760405163f6f35fcf60e01b815260040160405180910390fd5b60018054908290556040805160a080825260129082015271627579466565202d204d61726b6574696e6760701b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610db4565b6115556122ef565b601154600160b01b900460ff161561158057604051633368a18760e21b815260040160405180910390fd5b601154600160a81b900460ff166115aa576040516338751c4760e11b815260040160405180910390fd5b6011805460ff60a81b191690556040805160a0808252600c908201526b1b1a5b5a5d115b98589b195960a21b60c0820152600160208201526000918101919091523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610c9b565b6116296122ef565b6001600160a01b03821660009081526014602052604090205481151560ff90911615150361166d5760405162a7e72d60e41b81528115156004820152602401610b94565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d991906132b8565b6001600160a01b0316141580156117635750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611733573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175791906132b8565b6001600160a01b031614155b1561178c57604051634726455360e11b81526001600160a01b0383166004820152602401610b94565b6001600160a01b038216600081815260146020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611121565b6118336122ef565b674563918244f400008111156118665760405163181c9d0b60e21b8152674563918244f400006004820152602401610b94565b80600a6000828254611878919061324f565b909155505042600b5561188d8161dead612872565b50565b6001600160a01b031660009081526012602052604090205490565b6118b36122ef565b6118bd6000612a0b565b565b6118c76122ef565b620186a06118d3611b19565b6118de90600a6132d5565b6118e891906132ec565b81111561190b5760405163181c9d0b60e21b815260048101829052602401610b94565b80600e54036119305760405163657e16cf60e01b815260048101829052602401610b94565b600e805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610db4565b6119866122ef565b601154600160c01b900460ff16156119b15760405163882d29d360e01b815260040160405180910390fd5b614e208111156119df5760405163211a907760e11b815260048101829052614e206024820152604401610b94565b6003548103611a015760405163f6f35fcf60e01b815260040160405180910390fd5b60038054908290556040805160a08082526017908201527f7472616e73666572466565202d204d61726b6574696e6700000000000000000060c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610db4565b611a896122ef565b8015156011601a9054906101000a900460ff16151503611abf5760405162a7e72d60e41b81528115156004820152602401610b94565b6011805460ff60d01b198116600160d01b84151581029190911790925560405191900460ff16907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf390610db490839085903390429061330e565b6000611b256000611890565b611b3061dead611890565b600754611b3d91906131e5565b611b4791906131e5565b905090565b6011805460ff60d81b1916600160d81b179055611b676122ef565b620186a0611b73611b19565b611b7f906101f46132d5565b611b8991906132ec565b811115611bd55780620186a0611b9d611b19565b611ba9906101f46132d5565b611bb391906132ec565b60405163179b4ccd60e31b815260048101929092526024820152604401610b94565b611bde81612a5b565b506011805460ff60d81b19169055565b60003381611bfc8286612219565b905083811015611c2557848185604051637dc7a0d960e11b8152600401610b94939291906131f8565b61102c8286868403600161279d565b600033610cb38185856124a7565b611c4a6122ef565b601154600160c01b900460ff1615611c755760405163882d29d360e01b815260040160405180910390fd5b6011805460ff60c01b1916600160c01b179055604080516060808252600b908201526a1a5cd19959531bd8dad95960aa1b608082015233602082015242918101919091527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610c9b565b611ceb6122ef565b601154600160b01b900460ff1615611d1657604051633368a18760e21b815260040160405180910390fd5b6011805460ff60b01b1916600160b01b179055604080516060808252600d908201526c1a5cd31a5b5a5d131bd8dad959609a1b608082015233602082015242918101919091527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610c9b565b611d8e6122ef565b6006546001600160a01b0390811690821603611dc85760405163a936636960e01b81526001600160a01b0382166004820152602401610b94565b600680546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a16006546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015611e7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea391906132b8565b6001600160a01b031663e6a4390530600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2991906132b8565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9891906132b8565b6001600160a01b03160361216f57600660009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ff9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201d91906132b8565b6001600160a01b031663c9c6539630600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561207f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a391906132b8565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af11580156120f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211491906132b8565b601180546001600160a01b0319166001600160a01b0392909216918217905560009081526014602052604090205460ff1661216f576011546001600160a01b03166000908152601460205260409020805460ff191660011790555b5050565b61217b6122ef565b601154600160c81b900460ff16156121a65760405163341e380d60e11b815260040160405180910390fd5b6011805460ff60c81b1916600160c81b1790556040805160608082526010908201526f1a5cd49958d95a5d995c931bd8dad95960821b608082015233602082015242918101919091527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610c9b565b6001600160a01b03918216600090815260136020908152604080832093909416825291909152205490565b61224c6122ef565b6000546001600160a01b03166001600160a01b0316816001600160a01b0316036122945760405163a936636960e01b81526001600160a01b0382166004820152602401610b94565b61deac196001600160a01b038216016122cb57604051634726455360e11b81526001600160a01b0382166004820152602401610b94565b600f80546001600160a01b0319166001600160a01b03831617905561188d81612ca3565b336123026000546001600160a01b031690565b6001600160a01b0316146118bd5760405163118cdaa760e01b8152336004820152602401610b94565b612338838383600161279d565b505050565b6001600160a01b03831661236857806007600082825461235d919061324f565b909155506123c79050565b6001600160a01b038316600090815260126020526040902054818110156123a85783818360405163391434e360e21b8152600401610b94939291906131f8565b6001600160a01b03841660009081526012602052604090209082900390555b6001600160a01b0382166123e357600780548290039055612402565b6001600160a01b03821660009081526012602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161244791815260200190565b60405180910390a3505050565b60006124608484612219565b905060001981146124a1578181101561249257828183604051637dc7a0d960e11b8152600401610b94939291906131f8565b6124a18484848403600061279d565b50505050565b6001600160a01b0383166124d157604051634b637e8f60e11b815260006004820152602401610b94565b6001600160a01b0382166124fb5760405163ec442f0560e01b815260006004820152602401610b94565b601154600160a01b900460ff1661256c576001600160a01b03831660009081526015602052604090205460ff1615801561254e57506001600160a01b03821660009081526015602052604090205460ff16155b1561256c5760405163ab9827ff60e01b815260040160405180910390fd5b60095461257a90600261324f565b42111580156125a157506001600160a01b03831660009081526014602052604090205460ff165b156125bf57604051637b1aaedf60e11b815260040160405180910390fd5b601154600160d81b900460ff16806125ef57506001600160a01b03831660009081526015602052604090205460ff165b8061261257506001600160a01b03821660009081526015602052604090205460ff165b156126225761233883838361233d565b6011546001600160a01b038481169116148015906126495750601154600160d01b900460ff165b80156126665750600e54600d54600c5461266391906131e5565b10155b801561267c5750600e5461267930611890565b10155b1561268c5761268c600e54612a5b565b6011548190600160b81b900460ff1680156126c057506001600160a01b03841660009081526015602052604090205460ff16155b80156126e557506001600160a01b03831660009081526015602052604090205460ff16155b156126f8576126f5848484612cde565b90505b601154600160a81b900460ff16801561272a57506001600160a01b03831660009081526016602052604090205460ff16155b801561274f5750612739612ddd565b8161274385611890565b61274d919061324f565b115b15612792578061275e84611890565b612768919061324f565b612770612ddd565b6040516335bd477b60e11b815260048101929092526024820152604401610b94565b6124a184848361233d565b6001600160a01b0384166127c75760405163e602df0560e01b815260006004820152602401610b94565b6001600160a01b0383166127f157604051634a1406b160e11b815260006004820152602401610b94565b6001600160a01b03808516600090815260136020908152604080832093871683529290522082905580156124a157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161286491815260200190565b60405180910390a350505050565b6011805460ff60d81b1916600160d81b17905561deac1933016128ac57604051634726455360e11b815261dead6004820152602401610b94565b6040805160028082526060820183526000926020830190803683375050600654604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa158015612916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061293a91906132b8565b8160008151811061294d5761294d61333b565b60200260200101906001600160a01b031690816001600160a01b03168152505030816001815181106129815761298161333b565b6001600160a01b03928316602091820292909201015260065460405163b6f9de9560e01b815291169063b6f9de959085906129c790600090869088904290600401613395565b6000604051808303818588803b1580156129e057600080fd5b505af11580156129f4573d6000803e3d6000fd5b50506011805460ff60d81b19169055505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6011805460ff60d81b1916600160d81b179055600d54600c54600091612a80916131e5565b905080821115612a905750611bde565b600554600454600091612aa2916131e5565b9050600082612ab183866132d5565b612abb91906132ec565b90508060056000016000828254612ad2919061324f565b9250508190555083600d6000828254612aeb919061324f565b90915550506040805160028082526060820183526000926020830190803683370190505090503081600081518110612b2557612b2561333b565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015612b7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba291906132b8565b81600181518110612bb557612bb561333b565b6001600160a01b039283166020918202929092010152600654612bdb913091168761232b565b6040805183815260208101879052338183015242606082015290517fb933c1b294702108551eddf782a9c7d1a018b57f68ecf63bc59a1247daa19c309181900360800190a160065460105460405163791ac94760e01b81526001600160a01b039283169263791ac94792612c5d928792600092889291169042906004016133ca565b600060405180830381600087803b158015612c7757600080fd5b505af1158015612c8b573d6000803e3d6000fd5b5050505050505050506011805460ff60d81b19169055565b612cab6122ef565b6001600160a01b038116612cd557604051631e4fbdf760e01b815260006004820152602401610b94565b61188d81612a0b565b6011805460ff60d81b1916600160d81b1790556001600160a01b03831660009081526014602052604081205460ff168015612d1a575060015415155b15612d3057612d298483612e1f565b9050612dc9565b6001600160a01b03831660009081526014602052604090205460ff168015612d59575060025415155b15612d6857612d298483612e50565b6001600160a01b03841660009081526014602052604090205460ff16158015612daa57506001600160a01b03831660009081526014602052604090205460ff16155b8015612db7575060035415155b15612dc657612d298483612e81565b50805b6011805460ff60d81b191690559392505050565b600080612de8611b19565b601154909150600160a81b900460ff1615612e1a57620186a0612e0d826103e86132d5565b612e1791906132ec565b90505b919050565b6011805460ff60d81b1916600160d81b17905560408051602081019091526001548152600090612dc9908484612eae565b6011805460ff60d81b1916600160d81b17905560408051602081019091526002548152600090612dc9908484612eae565b6011805460ff60d81b1916600160d81b17905560408051602081019091526003548152600090612dc99084845b6011805460ff60d81b1916600160d81b179055825160009081620186a0612ed583866132d5565b612edf91906132ec565b90506000612eed82866131e5565b90508115612f0157612f0187878486612f18565b6011805460ff60d81b191690559695505050505050565b6011805460ff60d81b1916600160d81b17905583516000908290612f3c90856132d5565b612f4691906132ec565b9050612f528184612f71565b612f5d84308561233d565b50506011805460ff60d81b19169055505050565b6011805460ff60d81b1916600160d81b17905560048054839190600090612f9990849061324f565b9250508190555080600c6000828254612fb2919061324f565b90915550506011805460ff60d81b191690555050565b600060208083528351808285015260005b81811015612ff557858101830151858201604001528201612fd9565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b038116811461188d57600080fd5b60006020828403121561303d57600080fd5b813561304881613016565b9392505050565b6000806040838503121561306257600080fd5b823561306d81613016565b946020939093013593505050565b60006020828403121561308d57600080fd5b5035919050565b6000806000606084860312156130a957600080fd5b83356130b481613016565b925060208401356130c481613016565b929592945050506040919091013590565b801515811461188d57600080fd5b600080604083850312156130f657600080fd5b823561310181613016565b91506020830135613111816130d5565b809150509250929050565b60006020828403121561312e57600080fd5b8135613048816130d5565b6000806040838503121561314c57600080fd5b823561315781613016565b9150602083013561311181613016565b60408152600061319260408301600b81526a697346656541637469766560a81b602082015260400190565b9050821515602083015292915050565b60408152600061319260408301600d81526c1a5cd4ddd85c115b98589b1959609a1b602082015260400190565b634e487b7160e01b600052601160045260246000fd5b81810381811115610cb957610cb96131cf565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020828403121561322b57600080fd5b5051919050565b60006020828403121561324457600080fd5b8151613048816130d5565b80820180821115610cb957610cb96131cf565b60a08152600061328d60a08301600b81526a697346656541637469766560a81b602082015260400190565b95151560208301525092151560408401526001600160a01b0391909116606083015260809091015290565b6000602082840312156132ca57600080fd5b815161304881613016565b8082028115828204841417610cb957610cb96131cf565b60008261330957634e487b7160e01b600052601260045260246000fd5b500490565b60a08152600061328d60a08301600d81526c1a5cd4ddd85c115b98589b1959609a1b602082015260400190565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b8381101561338a5781516001600160a01b031687529582019590820190600101613365565b509495945050505050565b8481526080602082015260006133ae6080830186613351565b6001600160a01b03949094166040830152506060015292915050565b85815284602082015260a0604082015260006133e960a0830186613351565b6001600160a01b039490941660608301525060800152939250505056fea26469706673582212204a2706a484307d1a76f5b734628760d953b418a5bda8967a29f759d68653eb1964736f6c63430008120033

Deployed Bytecode

0x6080604052600436106103b05760003560e01c80638da5cb5b116101e7578063aeddf6771161010d578063da4daf71116100a0578063e811f50a1161006f578063e811f50a14610ad4578063f2c4220e14610aeb578063f2fde38b14610b01578063f887ea4014610b2157600080fd5b8063da4daf7114610a5c578063dd62ed3e14610a72578063e2924cd114610a92578063e43504da14610ab357600080fd5b8063cf9769fd116100dc578063cf9769fd146109ee578063d621e81314610a03578063d830678614610a24578063d941907114610a4557600080fd5b8063aeddf67714610982578063b908de8c14610997578063b9b2b5cd146109b8578063c851cc32146109ce57600080fd5b8063a457c2d711610185578063a9059cbb11610154578063a9059cbb1461091f578063ab28a04c1461093f578063ab36629214610956578063acb2ad6f1461096b57600080fd5b8063a457c2d71461089e578063a50ca9ba146108be578063a5949bcf146108df578063a8aa1b31146108ff57600080fd5b806395d89b41116101c157806395d89b411461081957806397e1b9d3146108485780639d48fde91461085e578063a4475ce41461087e57600080fd5b80638da5cb5b146107b2578063924de9b7146107e45780639358928b1461080457600080fd5b80633d6362d6116102d757806363a954921161026a57806371538eed1161023957806371538eed1461072c57806375fed3c7146107425780638577a6d514610762578063891ff84a1461078257600080fd5b806363a95492146106b65780636d800a3c146106d657806370a08231146106f7578063715018a61461071757600080fd5b806359cd9031116102a657806359cd90311461063b5780635d7cc7f5146106515780636225658914610681578063625dd6051461069657600080fd5b80633d6362d6146105c4578063422e6cea146105e4578063467abe0a14610604578063470624021461062457600080fd5b806323b872dd1161034f578063351a964d1161031e578063351a964d14610543578063355496ca1461056457806339509351146105845780633bf31454146105a457600080fd5b806323b872dd146104da5780632b14ca56146104fa5780632c735ef814610511578063313ce5671461052757600080fd5b8063095ea7b31161038b578063095ea7b31461045b57806318160ddd1461047b5780631d933a4a1461049a5780631f685bac146104ba57600080fd5b806299d386146103bc57806306fdde03146103d357806308c436501461041b57600080fd5b366103b757005b600080fd5b3480156103c857600080fd5b506103d1610b41565b005b3480156103df57600080fd5b5060408051808201909152600d81526c26bab667c234e7c232b739b7b960991b60208201525b6040516104129190612fc8565b60405180910390f35b34801561042757600080fd5b5061044b61043636600461302b565b60146020526000908152604090205460ff1681565b6040519015158152602001610412565b34801561046757600080fd5b5061044b61047636600461304f565b610ca5565b34801561048757600080fd5b506007545b604051908152602001610412565b3480156104a657600080fd5b506103d16104b536600461307b565b610cbf565b3480156104c657600080fd5b506103d16104d536600461304f565b610dc0565b3480156104e657600080fd5b5061044b6104f5366004613094565b611013565b34801561050657600080fd5b5060025461048c9081565b34801561051d57600080fd5b5061048c60085481565b34801561053357600080fd5b5060405160128152602001610412565b34801561054f57600080fd5b5060115461044b90600160d01b900460ff1681565b34801561057057600080fd5b506103d161057f3660046130e3565b611037565b34801561059057600080fd5b5061044b61059f36600461304f565b61112e565b3480156105b057600080fd5b506103d16105bf36600461311c565b611154565b3480156105d057600080fd5b506103d16105df36600461302b565b611217565b3480156105f057600080fd5b506103d16105ff3660046130e3565b611365565b34801561061057600080fd5b506103d161061f36600461307b565b611455565b34801561063057600080fd5b5060015461048c9081565b34801561064757600080fd5b5061048c600e5481565b34801561065d57600080fd5b5061044b61066c36600461302b565b60166020526000908152604090205460ff1681565b34801561068d57600080fd5b506103d161154d565b3480156106a257600080fd5b506103d16106b13660046130e3565b611621565b3480156106c257600080fd5b506103d16106d136600461307b565b61182b565b3480156106e257600080fd5b5060115461044b90600160a81b900460ff1681565b34801561070357600080fd5b5061048c61071236600461302b565b611890565b34801561072357600080fd5b506103d16118ab565b34801561073857600080fd5b5061048c600d5481565b34801561074e57600080fd5b506103d161075d36600461307b565b6118bf565b34801561076e57600080fd5b506103d161077d36600461307b565b61197e565b34801561078e57600080fd5b5061044b61079d36600461302b565b60156020526000908152604090205460ff1681565b3480156107be57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610412565b3480156107f057600080fd5b506103d16107ff36600461311c565b611a81565b34801561081057600080fd5b5061048c611b19565b34801561082557600080fd5b5060408051808201909152600681526513555315125560d21b6020820152610405565b34801561085457600080fd5b5061048c600b5481565b34801561086a57600080fd5b506103d161087936600461307b565b611b4c565b34801561088a57600080fd5b50600f546107cc906001600160a01b031681565b3480156108aa57600080fd5b5061044b6108b936600461304f565b611bee565b3480156108ca57600080fd5b5060115461044b90600160b01b900460ff1681565b3480156108eb57600080fd5b506010546107cc906001600160a01b031681565b34801561090b57600080fd5b506011546107cc906001600160a01b031681565b34801561092b57600080fd5b5061044b61093a36600461304f565b611c34565b34801561094b57600080fd5b5061048c620186a081565b34801561096257600080fd5b506103d1611c42565b34801561097757600080fd5b5060035461048c9081565b34801561098e57600080fd5b506103d1611ce3565b3480156109a357600080fd5b5060115461044b90600160c01b900460ff1681565b3480156109c457600080fd5b5061048c600c5481565b3480156109da57600080fd5b506103d16109e936600461302b565b611d86565b3480156109fa57600080fd5b506103d1612173565b348015610a0f57600080fd5b5060115461044b90600160a01b900460ff1681565b348015610a3057600080fd5b5060115461044b90600160d81b900460ff1681565b348015610a5157600080fd5b5060055461048c9081565b348015610a6857600080fd5b5061048c600a5481565b348015610a7e57600080fd5b5061048c610a8d366004613139565b612219565b348015610a9e57600080fd5b5060115461044b90600160c81b900460ff1681565b348015610abf57600080fd5b5060115461044b90600160b81b900460ff1681565b348015610ae057600080fd5b5060045461048c9081565b348015610af757600080fd5b5061048c60095481565b348015610b0d57600080fd5b506103d1610b1c36600461302b565b612244565b348015610b2d57600080fd5b506006546107cc906001600160a01b031681565b610b496122ef565b601154600160a01b900460ff1615610b9d5760115460085460095460405163025ad45560e61b8152600160a01b90930460ff1615156004840152602483019190915260448201526064015b60405180910390fd5b600854151580610bae575060095415155b15610bcc5760405163475a253560e01b815260040160405180910390fd5b601154600160b81b900460ff1615610c0557601154604051633f3e417d60e21b8152610b9491600160b81b900460ff1690600401613167565b601154600160d01b900460ff1615610c3e57601154604051633f3e417d60e21b8152610b9491600160d01b900460ff16906004016131a2565b6011805466ff0000ff00ffff60a01b1916660100000100010160a01b17905542600881905560098190556040805133815260208101929092527f7111af66182bdf8afd5e1cfa53fdb90ebba682d2cc11a7dfead27fcbf50bea8291015b60405180910390a1565b600033610cb381858561232b565b60019150505b92915050565b610cc76122ef565b601154600160c01b900460ff1615610cf25760405163882d29d360e01b815260040160405180910390fd5b614e20811115610d205760405163211a907760e11b815260048101829052614e206024820152604401610b94565b6002548103610d425760405163f6f35fcf60e01b815260040160405180910390fd5b60028054908290556040805160a08082526013908201527273656c6c466565202d204d61726b6574696e6760681b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e0015b60405180910390a15050565b6000600d54600c5411610dd4576000610de4565b600d54600c54610de491906131e5565b60105490915082906001600160a01b03908116903090861603610ea557610e0a30611890565b8310610e29576040516315ea636560e31b815260040160405180910390fd5b82610e3330611890565b610e3d91906131e5565b841115610e76573083610e4f30611890565b610e5991906131e5565b8560405163391434e360e21b8152600401610b94939291906131f8565b83600003610e955782610e8830611890565b610e9291906131e5565b91505b610ea030828461233d565b61100c565b6001600160a01b038516610f245783600003610ebf574791505b6001600160a01b0381163303610ee85760405163a5eb0da960e01b815260040160405180910390fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610f1e573d6000803e3d6000fd5b5061100c565b83600003610f97576040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190613219565b91505b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905286169063a9059cbb906044016020604051808303816000875af1158015610fe6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100a9190613232565b505b5050505050565b600033611021858285612454565b61102c8585856124a7565b506001949350505050565b61103f6122ef565b6001600160a01b03821660009081526015602052604090205481151560ff9091161515036110835760405162a7e72d60e41b81528115156004820152602401610b94565b6001600160a01b038216600081815260156020908152604091829020805485151560ff1982168117909255835160c0808252600b908201526a69734578656d707446656560a81b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea90610100015b60405180910390a1505050565b6000338161113c8286612219565b905061102c828661114d878561324f565b600161279d565b61115c6122ef565b601154600160c01b900460ff16156111875760405163882d29d360e01b815260040160405180910390fd5b801515601160179054906101000a900460ff161515036111bd5760405162a7e72d60e41b81528115156004820152602401610b94565b6011805460ff60b81b198116600160b81b84151581029190911790925560405191900460ff16907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf390610db4908390859033904290613262565b61121f6122ef565b601154600160c81b900460ff161561124a5760405163341e380d60e11b815260040160405180910390fd5b6001600160a01b03811661127457604051634726455360e11b815260006004820152602401610b94565b6010546001600160a01b038083169116036112ad5760405163a936636960e01b81526001600160a01b0382166004820152602401610b94565b6001600160a01b0381163b156112d65760405163259f1ec560e01b815260040160405180910390fd5b601080546001600160a01b031981166001600160a01b038481169182179093556040805160a08082526011908201527036b0b935b2ba34b733a932b1b2b4bb32b960791b60c0820152939092166020840181905291830152336060830152426080830152907ff7df6bc5c0f9735c300a374247b60dcacf1942b6031785957e762d77977ed4209060e001610db4565b61136d6122ef565b6001600160a01b03821660009081526016602052604090205481151560ff9091161515036113b15760405162a7e72d60e41b81528115156004820152602401610b94565b6001600160a01b038216600081815260166020908152604091829020805485151560ff1982168117909255835160c0808252600d908201526c1a5cd15e195b5c1d131a5b5a5d609a1b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611121565b61145d6122ef565b601154600160c01b900460ff16156114885760405163882d29d360e01b815260040160405180910390fd5b614e208111156114b65760405163211a907760e11b815260048101829052614e206024820152604401610b94565b60015481036114d85760405163f6f35fcf60e01b815260040160405180910390fd5b60018054908290556040805160a080825260129082015271627579466565202d204d61726b6574696e6760701b60c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610db4565b6115556122ef565b601154600160b01b900460ff161561158057604051633368a18760e21b815260040160405180910390fd5b601154600160a81b900460ff166115aa576040516338751c4760e11b815260040160405180910390fd5b6011805460ff60a81b191690556040805160a0808252600c908201526b1b1a5b5a5d115b98589b195960a21b60c0820152600160208201526000918101919091523360608201524260808201527fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf39060e001610c9b565b6116296122ef565b6001600160a01b03821660009081526014602052604090205481151560ff90911615150361166d5760405162a7e72d60e41b81528115156004820152602401610b94565b306001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d991906132b8565b6001600160a01b0316141580156117635750306001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611733573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175791906132b8565b6001600160a01b031614155b1561178c57604051634726455360e11b81526001600160a01b0383166004820152602401610b94565b6001600160a01b038216600081815260146020908152604091829020805485151560ff1982168117909255835160c08082526008908201526706973506169724c560c41b60e08201529283019490945260ff9093168015159282019290925260608101929092523360808301524260a0830152907f59efce2bd92f91881f8f3ffb8c70709a05ae83006301d26f9fe6170f3e690aea9061010001611121565b6118336122ef565b674563918244f400008111156118665760405163181c9d0b60e21b8152674563918244f400006004820152602401610b94565b80600a6000828254611878919061324f565b909155505042600b5561188d8161dead612872565b50565b6001600160a01b031660009081526012602052604090205490565b6118b36122ef565b6118bd6000612a0b565b565b6118c76122ef565b620186a06118d3611b19565b6118de90600a6132d5565b6118e891906132ec565b81111561190b5760405163181c9d0b60e21b815260048101829052602401610b94565b80600e54036119305760405163657e16cf60e01b815260048101829052602401610b94565b600e805490829055604080518281526020810184905233918101919091524260608201527f9a9f4704ac409fe039e92a996e415370980275aaff2992936ed5b432886c55c590608001610db4565b6119866122ef565b601154600160c01b900460ff16156119b15760405163882d29d360e01b815260040160405180910390fd5b614e208111156119df5760405163211a907760e11b815260048101829052614e206024820152604401610b94565b6003548103611a015760405163f6f35fcf60e01b815260040160405180910390fd5b60038054908290556040805160a08082526017908201527f7472616e73666572466565202d204d61726b6574696e6700000000000000000060c0820152602081018390529081018390523360608201524260808201527fae95575a673d4e1b8078cc03b3ca2acaffe6d26625496c7bc59d338ff09a4a179060e001610db4565b611a896122ef565b8015156011601a9054906101000a900460ff16151503611abf5760405162a7e72d60e41b81528115156004820152602401610b94565b6011805460ff60d01b198116600160d01b84151581029190911790925560405191900460ff16907fda986e332f97963bfa4bb220bda255b40296aa680cff592b805c2deb80b1dbf390610db490839085903390429061330e565b6000611b256000611890565b611b3061dead611890565b600754611b3d91906131e5565b611b4791906131e5565b905090565b6011805460ff60d81b1916600160d81b179055611b676122ef565b620186a0611b73611b19565b611b7f906101f46132d5565b611b8991906132ec565b811115611bd55780620186a0611b9d611b19565b611ba9906101f46132d5565b611bb391906132ec565b60405163179b4ccd60e31b815260048101929092526024820152604401610b94565b611bde81612a5b565b506011805460ff60d81b19169055565b60003381611bfc8286612219565b905083811015611c2557848185604051637dc7a0d960e11b8152600401610b94939291906131f8565b61102c8286868403600161279d565b600033610cb38185856124a7565b611c4a6122ef565b601154600160c01b900460ff1615611c755760405163882d29d360e01b815260040160405180910390fd5b6011805460ff60c01b1916600160c01b179055604080516060808252600b908201526a1a5cd19959531bd8dad95960aa1b608082015233602082015242918101919091527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610c9b565b611ceb6122ef565b601154600160b01b900460ff1615611d1657604051633368a18760e21b815260040160405180910390fd5b6011805460ff60b01b1916600160b01b179055604080516060808252600d908201526c1a5cd31a5b5a5d131bd8dad959609a1b608082015233602082015242918101919091527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610c9b565b611d8e6122ef565b6006546001600160a01b0390811690821603611dc85760405163a936636960e01b81526001600160a01b0382166004820152602401610b94565b600680546001600160a01b038381166001600160a01b0319831681179093556040805191909216808252602082019390935233918101919091524260608201527fe1cb783288eddc7b22c25642a832d886a558be0dd900747310a34156b9fdcbbb9060800160405180910390a16006546040805163c45a015560e01b815290516000926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015611e7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea391906132b8565b6001600160a01b031663e6a4390530600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2991906132b8565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9891906132b8565b6001600160a01b03160361216f57600660009054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ff9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201d91906132b8565b6001600160a01b031663c9c6539630600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561207f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a391906132b8565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af11580156120f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211491906132b8565b601180546001600160a01b0319166001600160a01b0392909216918217905560009081526014602052604090205460ff1661216f576011546001600160a01b03166000908152601460205260409020805460ff191660011790555b5050565b61217b6122ef565b601154600160c81b900460ff16156121a65760405163341e380d60e11b815260040160405180910390fd5b6011805460ff60c81b1916600160c81b1790556040805160608082526010908201526f1a5cd49958d95a5d995c931bd8dad95960821b608082015233602082015242918101919091527f611312486a6540001c2b69bc849753e64cdefc853bbbc7a576d987821aec28b49060a001610c9b565b6001600160a01b03918216600090815260136020908152604080832093909416825291909152205490565b61224c6122ef565b6000546001600160a01b03166001600160a01b0316816001600160a01b0316036122945760405163a936636960e01b81526001600160a01b0382166004820152602401610b94565b61deac196001600160a01b038216016122cb57604051634726455360e11b81526001600160a01b0382166004820152602401610b94565b600f80546001600160a01b0319166001600160a01b03831617905561188d81612ca3565b336123026000546001600160a01b031690565b6001600160a01b0316146118bd5760405163118cdaa760e01b8152336004820152602401610b94565b612338838383600161279d565b505050565b6001600160a01b03831661236857806007600082825461235d919061324f565b909155506123c79050565b6001600160a01b038316600090815260126020526040902054818110156123a85783818360405163391434e360e21b8152600401610b94939291906131f8565b6001600160a01b03841660009081526012602052604090209082900390555b6001600160a01b0382166123e357600780548290039055612402565b6001600160a01b03821660009081526012602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161244791815260200190565b60405180910390a3505050565b60006124608484612219565b905060001981146124a1578181101561249257828183604051637dc7a0d960e11b8152600401610b94939291906131f8565b6124a18484848403600061279d565b50505050565b6001600160a01b0383166124d157604051634b637e8f60e11b815260006004820152602401610b94565b6001600160a01b0382166124fb5760405163ec442f0560e01b815260006004820152602401610b94565b601154600160a01b900460ff1661256c576001600160a01b03831660009081526015602052604090205460ff1615801561254e57506001600160a01b03821660009081526015602052604090205460ff16155b1561256c5760405163ab9827ff60e01b815260040160405180910390fd5b60095461257a90600261324f565b42111580156125a157506001600160a01b03831660009081526014602052604090205460ff165b156125bf57604051637b1aaedf60e11b815260040160405180910390fd5b601154600160d81b900460ff16806125ef57506001600160a01b03831660009081526015602052604090205460ff165b8061261257506001600160a01b03821660009081526015602052604090205460ff165b156126225761233883838361233d565b6011546001600160a01b038481169116148015906126495750601154600160d01b900460ff165b80156126665750600e54600d54600c5461266391906131e5565b10155b801561267c5750600e5461267930611890565b10155b1561268c5761268c600e54612a5b565b6011548190600160b81b900460ff1680156126c057506001600160a01b03841660009081526015602052604090205460ff16155b80156126e557506001600160a01b03831660009081526015602052604090205460ff16155b156126f8576126f5848484612cde565b90505b601154600160a81b900460ff16801561272a57506001600160a01b03831660009081526016602052604090205460ff16155b801561274f5750612739612ddd565b8161274385611890565b61274d919061324f565b115b15612792578061275e84611890565b612768919061324f565b612770612ddd565b6040516335bd477b60e11b815260048101929092526024820152604401610b94565b6124a184848361233d565b6001600160a01b0384166127c75760405163e602df0560e01b815260006004820152602401610b94565b6001600160a01b0383166127f157604051634a1406b160e11b815260006004820152602401610b94565b6001600160a01b03808516600090815260136020908152604080832093871683529290522082905580156124a157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161286491815260200190565b60405180910390a350505050565b6011805460ff60d81b1916600160d81b17905561deac1933016128ac57604051634726455360e11b815261dead6004820152602401610b94565b6040805160028082526060820183526000926020830190803683375050600654604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa158015612916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061293a91906132b8565b8160008151811061294d5761294d61333b565b60200260200101906001600160a01b031690816001600160a01b03168152505030816001815181106129815761298161333b565b6001600160a01b03928316602091820292909201015260065460405163b6f9de9560e01b815291169063b6f9de959085906129c790600090869088904290600401613395565b6000604051808303818588803b1580156129e057600080fd5b505af11580156129f4573d6000803e3d6000fd5b50506011805460ff60d81b19169055505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6011805460ff60d81b1916600160d81b179055600d54600c54600091612a80916131e5565b905080821115612a905750611bde565b600554600454600091612aa2916131e5565b9050600082612ab183866132d5565b612abb91906132ec565b90508060056000016000828254612ad2919061324f565b9250508190555083600d6000828254612aeb919061324f565b90915550506040805160028082526060820183526000926020830190803683370190505090503081600081518110612b2557612b2561333b565b6001600160a01b03928316602091820292909201810191909152600654604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015612b7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba291906132b8565b81600181518110612bb557612bb561333b565b6001600160a01b039283166020918202929092010152600654612bdb913091168761232b565b6040805183815260208101879052338183015242606082015290517fb933c1b294702108551eddf782a9c7d1a018b57f68ecf63bc59a1247daa19c309181900360800190a160065460105460405163791ac94760e01b81526001600160a01b039283169263791ac94792612c5d928792600092889291169042906004016133ca565b600060405180830381600087803b158015612c7757600080fd5b505af1158015612c8b573d6000803e3d6000fd5b5050505050505050506011805460ff60d81b19169055565b612cab6122ef565b6001600160a01b038116612cd557604051631e4fbdf760e01b815260006004820152602401610b94565b61188d81612a0b565b6011805460ff60d81b1916600160d81b1790556001600160a01b03831660009081526014602052604081205460ff168015612d1a575060015415155b15612d3057612d298483612e1f565b9050612dc9565b6001600160a01b03831660009081526014602052604090205460ff168015612d59575060025415155b15612d6857612d298483612e50565b6001600160a01b03841660009081526014602052604090205460ff16158015612daa57506001600160a01b03831660009081526014602052604090205460ff16155b8015612db7575060035415155b15612dc657612d298483612e81565b50805b6011805460ff60d81b191690559392505050565b600080612de8611b19565b601154909150600160a81b900460ff1615612e1a57620186a0612e0d826103e86132d5565b612e1791906132ec565b90505b919050565b6011805460ff60d81b1916600160d81b17905560408051602081019091526001548152600090612dc9908484612eae565b6011805460ff60d81b1916600160d81b17905560408051602081019091526002548152600090612dc9908484612eae565b6011805460ff60d81b1916600160d81b17905560408051602081019091526003548152600090612dc99084845b6011805460ff60d81b1916600160d81b179055825160009081620186a0612ed583866132d5565b612edf91906132ec565b90506000612eed82866131e5565b90508115612f0157612f0187878486612f18565b6011805460ff60d81b191690559695505050505050565b6011805460ff60d81b1916600160d81b17905583516000908290612f3c90856132d5565b612f4691906132ec565b9050612f528184612f71565b612f5d84308561233d565b50506011805460ff60d81b19169055505050565b6011805460ff60d81b1916600160d81b17905560048054839190600090612f9990849061324f565b9250508190555080600c6000828254612fb2919061324f565b90915550506011805460ff60d81b191690555050565b600060208083528351808285015260005b81811015612ff557858101830151858201604001528201612fd9565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b038116811461188d57600080fd5b60006020828403121561303d57600080fd5b813561304881613016565b9392505050565b6000806040838503121561306257600080fd5b823561306d81613016565b946020939093013593505050565b60006020828403121561308d57600080fd5b5035919050565b6000806000606084860312156130a957600080fd5b83356130b481613016565b925060208401356130c481613016565b929592945050506040919091013590565b801515811461188d57600080fd5b600080604083850312156130f657600080fd5b823561310181613016565b91506020830135613111816130d5565b809150509250929050565b60006020828403121561312e57600080fd5b8135613048816130d5565b6000806040838503121561314c57600080fd5b823561315781613016565b9150602083013561311181613016565b60408152600061319260408301600b81526a697346656541637469766560a81b602082015260400190565b9050821515602083015292915050565b60408152600061319260408301600d81526c1a5cd4ddd85c115b98589b1959609a1b602082015260400190565b634e487b7160e01b600052601160045260246000fd5b81810381811115610cb957610cb96131cf565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020828403121561322b57600080fd5b5051919050565b60006020828403121561324457600080fd5b8151613048816130d5565b80820180821115610cb957610cb96131cf565b60a08152600061328d60a08301600b81526a697346656541637469766560a81b602082015260400190565b95151560208301525092151560408401526001600160a01b0391909116606083015260809091015290565b6000602082840312156132ca57600080fd5b815161304881613016565b8082028115828204841417610cb957610cb96131cf565b60008261330957634e487b7160e01b600052601260045260246000fd5b500490565b60a08152600061328d60a08301600d81526c1a5cd4ddd85c115b98589b1959609a1b602082015260400190565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b8381101561338a5781516001600160a01b031687529582019590820190600101613365565b509495945050505050565b8481526080602082015260006133ae6080830186613351565b6001600160a01b03949094166040830152506060015292915050565b85815284602082015260a0604082015260006133e960a0830186613351565b6001600160a01b039490941660608301525060800152939250505056fea26469706673582212204a2706a484307d1a76f5b734628760d953b418a5bda8967a29f759d68653eb1964736f6c63430008120033

Deployed Bytecode Sourcemap

18619:49671:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32946:781;;;;;;;;;;;;;:::i;:::-;;54146:90;;;;;;;;;;-1:-1:-1;54224:4:0;;;;;;;;;;;;-1:-1:-1;;;54224:4:0;;;;54146:90;;;;;;;:::i;:::-;;;;;;;;20309:45;;;;;;;;;;-1:-1:-1;20309:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1120:14:1;;1113:22;1095:41;;1083:2;1068:18;20309:45:0;955:187:1;57203:194:0;;;;;;;;;;-1:-1:-1;57203:194:0;;;;;:::i;:::-;;:::i;55201:99::-;;;;;;;;;;-1:-1:-1;55280:12:0;;55201:99;;;1613:25:1;;;1601:2;1586:18;55201:99:0;1467:177:1;42269:584:0;;;;;;;;;;-1:-1:-1;42269:584:0;;;;;:::i;:::-;;:::i;31160:1358::-;;;;;;;;;;-1:-1:-1;31160:1358:0;;;;;:::i;:::-;;:::i;57842:247::-;;;;;;;;;;-1:-1:-1;57842:247:0;;;;;:::i;:::-;;:::i;18812:32::-;;;;;;;;;;-1:-1:-1;18812:32:0;;;;;;19314:33;;;;;;;;;;;;;;;;54911:90;;;;;;;;;;-1:-1:-1;54911:90:0;;19201:2;2437:36:1;;2425:2;2410:18;54911:90:0;2295:184:1;20060:33:0;;;;;;;;;;-1:-1:-1;20060:33:0;;;;-1:-1:-1;;;20060:33:0;;;;;;47348:360;;;;;;;;;;-1:-1:-1;47348:360:0;;;;;:::i;:::-;;:::i;67028:297::-;;;;;;;;;;-1:-1:-1;67028:297:0;;;;;:::i;:::-;;:::i;39957:412::-;;;;;;;;;;-1:-1:-1;39957:412:0;;;;;:::i;:::-;;:::i;44184:764::-;;;;;;;;;;-1:-1:-1;44184:764:0;;;;;:::i;:::-;;:::i;48062:370::-;;;;;;;;;;-1:-1:-1;48062:370:0;;;;;:::i;:::-;;:::i;41331:579::-;;;;;;;;;;-1:-1:-1;41331:579:0;;;;;:::i;:::-;;:::i;18774:31::-;;;;;;;;;;-1:-1:-1;18774:31:0;;;;;;19579:34;;;;;;;;;;;;;;;;20419:53;;;;;;;;;;-1:-1:-1;20419:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;38617:326;;;;;;;;;;;;;:::i;45368:528::-;;;;;;;;;;-1:-1:-1;45368:528:0;;;;;:::i;:::-;;:::i;52135:300::-;;;;;;;;;;-1:-1:-1;52135:300:0;;;;;:::i;:::-;;:::i;19862:32::-;;;;;;;;;;-1:-1:-1;19862:32:0;;;;-1:-1:-1;;;19862:32:0;;;;;;55588:118;;;;;;;;;;-1:-1:-1;55588:118:0;;;;;:::i;:::-;;:::i;16771:103::-;;;;;;;;;;;;;:::i;19537:35::-;;;;;;;;;;;;;;;;39218:454;;;;;;;;;;-1:-1:-1;39218:454:0;;;;;:::i;:::-;;:::i;43220:604::-;;;;;;;;;;-1:-1:-1;43220:604:0;;;;;:::i;:::-;;:::i;20361:51::-;;;;;;;;;;-1:-1:-1;20361:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;16047:87;;;;;;;;;;-1:-1:-1;16093:7:0;16120:6;-1:-1:-1;;;;;16120:6:0;16047:87;;;-1:-1:-1;;;;;3404:32:1;;;3386:51;;3374:2;3359:18;16047:87:0;3240:203:1;40624:350:0;;;;;;;;;;-1:-1:-1;40624:350:0;;;;;:::i;:::-;;:::i;34125:151::-;;;;;;;;;;;;;:::i;54430:94::-;;;;;;;;;;-1:-1:-1;54510:6:0;;;;;;;;;;;;-1:-1:-1;;;54510:6:0;;;;54430:94;;19444:43;;;;;;;;;;;;;;;;35248:325;;;;;;;;;;-1:-1:-1;35248:325:0;;;;;:::i;:::-;;:::i;19622:72::-;;;;;;;;;;-1:-1:-1;19622:72:0;;;;-1:-1:-1;;;;;19622:72:0;;;67820:467;;;;;;;;;;-1:-1:-1;67820:467:0;;;;;:::i;:::-;;:::i;19901:33::-;;;;;;;;;;-1:-1:-1;19901:33:0;;;;-1:-1:-1;;;19901:33:0;;;;;;19701:77;;;;;;;;;;-1:-1:-1;19701:77:0;;;;-1:-1:-1;;;;;19701:77:0;;;19791:19;;;;;;;;;;-1:-1:-1;19791:19:0;;;;-1:-1:-1;;;;;19791:19:0;;;56075:186;;;;;;;;;;-1:-1:-1;56075:186:0;;;;;:::i;:::-;;:::i;19212:48::-;;;;;;;;;;;;19253:7;19212:48;;37826:212;;;;;;;;;;;;;:::i;18851:36::-;;;;;;;;;;-1:-1:-1;18851:36:0;;;;;;37431:221;;;;;;;;;;;;;:::i;19979:31::-;;;;;;;;;;-1:-1:-1;19979:31:0;;;;-1:-1:-1;;;19979:31:0;;;;;;19494:36;;;;;;;;;;;;;;;;46363:644;;;;;;;;;;-1:-1:-1;46363:644:0;;;;;:::i;:::-;;:::i;38204:237::-;;;;;;;;;;;;;:::i;19823:32::-;;;;;;;;;;-1:-1:-1;19823:32:0;;;;-1:-1:-1;;;19823:32:0;;;;;;20100:26;;;;;;;;;;-1:-1:-1;20100:26:0;;;;-1:-1:-1;;;20100:26:0;;;;;;18933:31;;;;;;;;;;-1:-1:-1;18933:31:0;;;;;;19395:42;;;;;;;;;;;;;;;;56646:148;;;;;;;;;;-1:-1:-1;56646:148:0;;;;;:::i;:::-;;:::i;20017:36::-;;;;;;;;;;-1:-1:-1;20017:36:0;;;;-1:-1:-1;;;20017:36:0;;;;;;19941:31;;;;;;;;;;-1:-1:-1;19941:31:0;;;;-1:-1:-1;;;19941:31:0;;;;;;18894:32;;;;;;;;;;-1:-1:-1;18894:32:0;;;;;;19354:34;;;;;;;;;;;;;;;;53569:360;;;;;;;;;;-1:-1:-1;53569:360:0;;;;;:::i;:::-;;:::i;18973:75::-;;;;;;;;;;-1:-1:-1;18973:75:0;;;;-1:-1:-1;;;;;18973:75:0;;;32946:781;14312:13;:11;:13::i;:::-;33003:12:::1;::::0;-1:-1:-1;;;33003:12:0;::::1;;;32999:118;;;33059:12;::::0;33073:14:::1;::::0;33089:15:::1;::::0;33039:66:::1;::::0;-1:-1:-1;;;33039:66:0;;-1:-1:-1;;;33059:12:0;;::::1;;;4284:14:1::0;4277:22;33039:66:0::1;::::0;::::1;4259:41:1::0;4316:18;;;4309:34;;;;4359:18;;;4352:34;4232:18;;33039:66:0::1;;;;;;;;32999:118;33131:14;::::0;:19;::::1;::::0;:43:::1;;-1:-1:-1::0;33154:15:0::1;::::0;:20;::::1;33131:43;33127:101;;;33198:18;;-1:-1:-1::0;;;33198:18:0::1;;;;;;;;;;;33127:101;33242:11;::::0;-1:-1:-1;;;33242:11:0;::::1;;;33238:98;;;33312:11;::::0;33277:47:::1;::::0;-1:-1:-1;;;33277:47:0;;::::1;::::0;-1:-1:-1;;;33312:11:0;::::1;;;::::0;33277:47:::1;;;:::i;33238:98::-;33350:13;::::0;-1:-1:-1;;;33350:13:0;::::1;;;33346:104;;;33424:13;::::0;33387:51:::1;::::0;-1:-1:-1;;;33387:51:0;;::::1;::::0;-1:-1:-1;;;33424:13:0;::::1;;;::::0;33387:51:::1;;;:::i;33346:104::-;33460:12;:19:::0;;-1:-1:-1;;;;33549:20:0;-1:-1:-1;;;33549:20:0;;;33597:15:::1;33580:14;:32:::0;;;-1:-1:-1;33623:33:0;;;33674:45:::1;::::0;;33691:10:::1;5629:51:1::0;;5711:2;5696:18;;5689:34;;;;33674:45:0::1;::::0;5602:18:1;33674:45:0::1;;;;;;;;32946:781::o:0;57203:194::-;57276:4;57312:10;57333:34;57312:10;57352:7;57361:5;57333:8;:34::i;:::-;57385:4;57378:11;;;57203:194;;;;;:::o;42269:584::-;14312:13;:11;:13::i;:::-;42351:11:::1;::::0;-1:-1:-1;;;42351:11:0;::::1;;;42347:62;;;42386:11;;-1:-1:-1::0;;;42386:11:0::1;;;;;;;;;;;42347:62;42441:6;42423:15;:24;42419:104;;;42471:40;::::0;-1:-1:-1;;;42471:40:0;;::::1;::::0;::::1;5920:25:1::0;;;42504:6:0::1;5961:18:1::0;;;5954:34;5893:18;;42471:40:0::1;5734:260:1::0;42419:104:0::1;42556:7;:17:::0;42537:36;;42533:102:::1;;42597:26;;-1:-1:-1::0;;;42597:26:0::1;;;;;;;;;;;42533:102;42671:7;:17:::0;;42699:35;;;;42750:95:::1;::::0;;6313:3:1;6295:22;;;6354:2;6333:19;;;6326:31;-1:-1:-1;;;6388:3:1;6373:19;;6366:50;6483:4;6468:20;;6461:36;;;6513:18;;;6506:34;;;42817:10:0::1;-1:-1:-1::0;6556:18:1;;6549:60;42829:15:0::1;-1:-1:-1::0;6625:19:1;;6618:35;42750:95:0::1;::::0;6448:3:1;6433:19;42750:95:0::1;;;;;;;;42336:517;42269:584:::0;:::o;31160:1358::-;31235:17;31275:16;;31255:17;;:36;:79;;31333:1;31255:79;;;31314:16;;31294:17;;:36;;;;:::i;:::-;31402:17;;31235:99;;-1:-1:-1;31366:6:0;;-1:-1:-1;;;;;31402:17:0;;;;31468:4;31444:29;;;;31440:1071;;31507:24;31525:4;31507:9;:24::i;:::-;31494:9;:37;31490:112;;31559:27;;-1:-1:-1;;;31559:27:0;;;;;;;;;;;31490:112;31656:9;31629:24;31647:4;31629:9;:24::i;:::-;:36;;;;:::i;:::-;31620:6;:45;31616:178;;;31726:4;31760:9;31733:24;31751:4;31733:9;:24::i;:::-;:36;;;;:::i;:::-;31771:6;31693:85;;-1:-1:-1;;;31693:85:0;;;;;;;;;;:::i;31616:178::-;31812:6;31822:1;31812:11;31808:101;;31884:9;31857:24;31875:4;31857:9;:24::i;:::-;:36;;;;:::i;:::-;31844:49;;31808:101;31923:44;31939:4;31946:8;31956:10;31923:7;:44::i;:::-;31440:1071;;;-1:-1:-1;;;;;31989:26:0;;31985:526;;32036:6;32046:1;32036:11;32032:86;;32081:21;32068:34;;32032:86;-1:-1:-1;;;;;32136:22:0;;:10;:22;32132:107;;32186:37;;-1:-1:-1;;;32186:37:0;;;;;;;;;;;32132:107;32253:38;;-1:-1:-1;;;;;32253:26:0;;;:38;;;;;32280:10;;32253:38;;;;32280:10;32253:26;:38;;;;;;;;;;;;;;;;;;;;;31985:526;;;32328:6;32338:1;32328:11;32324:110;;32373:45;;-1:-1:-1;;;32373:45:0;;32412:4;32373:45;;;3386:51:1;-1:-1:-1;;;;;32373:30:0;;;;;3359:18:1;;32373:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32360:58;;32324:110;32448:51;;-1:-1:-1;;;32448:51:0;;-1:-1:-1;;;;;5647:32:1;;;32448:51:0;;;5629::1;5696:18;;;5689:34;;;32448:29:0;;;;;5602:18:1;;32448:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;31985:526;31224:1294;;;31160:1358;;:::o;57842:247::-;57929:4;57964:10;57985:37;58001:4;57964:10;58016:5;57985:15;:37::i;:::-;58033:26;58043:4;58049:2;58053:5;58033:9;:26::i;:::-;-1:-1:-1;58077:4:0;;57842:247;-1:-1:-1;;;;57842:247:0:o;47348:360::-;14312:13;:11;:13::i;:::-;-1:-1:-1;;;;;47437:17:0;::::1;;::::0;;;:11:::1;:17;::::0;;;;;:30;::::1;;:17;::::0;;::::1;:30;;::::0;47433:80:::1;;47478:32;::::0;-1:-1:-1;;;47478:32:0;;1120:14:1;;1113:22;47478:32:0::1;::::0;::::1;1095:41:1::0;1068:18;;47478:32:0::1;955:187:1::0;47433:80:0::1;-1:-1:-1::0;;;;;47540:17:0;::::1;47523:14;47540:17:::0;;;:11:::1;:17;::::0;;;;;;;;;;47568:29;::::1;;-1:-1:-1::0;;47568:29:0;::::1;::::0;::::1;::::0;;;47613:87;;8048:3:1;8030:22;;;8089:2;8068:19;;;8061:31;-1:-1:-1;;;8123:3:1;8108:19;;8101:42;8233:20;;;8226:45;;;;47540:17:0::1;::::0;;::::1;8314:14:1::0;;8307:22;8287:18;;;8280:50;;;;8361:2;8346:18;;8339:50;;;;47672:10:0::1;-1:-1:-1::0;8405:19:1;;8398:44;47684:15:0::1;-1:-1:-1::0;8458:19:1;;8451:35;47540:17:0;47613:87:::1;::::0;8175:3:1;8160:19;47613:87:0::1;;;;;;;;47422:286;47348:360:::0;;:::o;67028:297::-;67113:4;67149:10;67113:4;67197:28;67149:10;67217:7;67197:9;:28::i;:::-;67170:55;-1:-1:-1;67236:59:0;67245:8;67255:7;67264:24;67283:5;67170:55;67264:24;:::i;:::-;67290:4;67236:8;:59::i;39957:412::-;14312:13;:11;:13::i;:::-;40032:11:::1;::::0;-1:-1:-1;;;40032:11:0;::::1;;;40028:62;;;40067:11;;-1:-1:-1::0;;;40067:11:0::1;;;;;;;;;;;40028:62;40119:9;40104:24;;:11;;;;;;;;;;;:24;;::::0;40100:96:::1;;40152:32;::::0;-1:-1:-1;;;40152:32:0;;1120:14:1;;1113:22;40152:32:0::1;::::0;::::1;1095:41:1::0;1068:18;;40152:32:0::1;955:187:1::0;40100:96:0::1;40223:11;::::0;;-1:-1:-1;;;;40245:23:0;::::1;-1:-1:-1::0;;;40245:23:0;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;40284:77:::1;::::0;40223:11;;::::1;;;::::0;40284:77:::1;::::0;::::1;::::0;40223:11;;40245:23;;40333:10:::1;::::0;40345:15:::1;::::0;40284:77:::1;:::i;44184:764::-:0;14312:13;:11;:13::i;:::-;44281:16:::1;::::0;-1:-1:-1;;;44281:16:0;::::1;;;44277:72;;;44321:16;;-1:-1:-1::0;;;44321:16:0::1;;;;;;;;;;;44277:72;-1:-1:-1::0;;;;;44363:34:0;::::1;44359:100;;44421:26;::::0;-1:-1:-1;;;44421:26:0;;44444:1:::1;44421:26;::::0;::::1;3386:51:1::0;3359:18;;44421:26:0::1;3240:203:1::0;44359:100:0::1;44473:17;::::0;-1:-1:-1;;;;;44473:41:0;;::::1;:17:::0;::::1;:41:::0;44469:126:::1;;44538:45;::::0;-1:-1:-1;;;44538:45:0;;-1:-1:-1;;;;;3404:32:1;;44538:45:0::1;::::0;::::1;3386:51:1::0;3359:18;;44538:45:0::1;3240:203:1::0;44469:126:0::1;-1:-1:-1::0;;;;;44609:32:0;::::1;;:36:::0;44605:102:::1;;44669:26;;-1:-1:-1::0;;;44669:26:0::1;;;;;;;;;;;44605:102;44748:17;::::0;;-1:-1:-1;;;;;;44776:40:0;::::1;-1:-1:-1::0;;;;;44776:40:0;;::::1;::::0;;::::1;::::0;;;44832:108:::1;::::0;;9556:3:1;9538:22;;;9597:2;9576:19;;;9569:31;-1:-1:-1;;;9631:3:1;9616:19;;9609:48;44748:17:0;;;::::1;9762:4:1::0;9747:20;;9740:45;;;9801:18;;;9794:43;44912:10:0::1;-1:-1:-1::0;9853:18:1;;9846:43;44924:15:0::1;-1:-1:-1::0;9905:19:1;;9898:35;44748:17:0;44832:108:::1;::::0;9689:3:1;9674:19;44832:108:0::1;9242:697:1::0;48062:370:0;14312:13;:11;:13::i;:::-;-1:-1:-1;;;;;48153:19:0;::::1;;::::0;;;:13:::1;:19;::::0;;;;;:32;::::1;;:19;::::0;;::::1;:32;;::::0;48149:82:::1;;48196:32;::::0;-1:-1:-1;;;48196:32:0;;1120:14:1;;1113:22;48196:32:0::1;::::0;::::1;1095:41:1::0;1068:18;;48196:32:0::1;955:187:1::0;48149:82:0::1;-1:-1:-1::0;;;;;48258:19:0;::::1;48241:14;48258:19:::0;;;:13:::1;:19;::::0;;;;;;;;;;48288:31;::::1;;-1:-1:-1::0;;48288:31:0;::::1;::::0;::::1;::::0;;;48335:89;;10274:3:1;10256:22;;;10315:2;10294:19;;;10287:31;-1:-1:-1;;;10349:3:1;10334:19;;10327:44;10461:20;;;10454:45;;;;48258:19:0::1;::::0;;::::1;10542:14:1::0;;10535:22;10515:18;;;10508:50;;;;10589:2;10574:18;;10567:50;;;;48396:10:0::1;-1:-1:-1::0;10633:19:1;;10626:44;48408:15:0::1;-1:-1:-1::0;10686:19:1;;10679:35;48258:19:0;48335:89:::1;::::0;10403:3:1;10388:19;48335:89:0::1;9944:776:1::0;41331:579:0;14312:13;:11;:13::i;:::-;41412:11:::1;::::0;-1:-1:-1;;;41412:11:0;::::1;;;41408:62;;;41447:11;;-1:-1:-1::0;;;41447:11:0::1;;;;;;;;;;;41408:62;41502:6;41484:15;:24;41480:104;;;41532:40;::::0;-1:-1:-1;;;41532:40:0;;::::1;::::0;::::1;5920:25:1::0;;;41565:6:0::1;5961:18:1::0;;;5954:34;5893:18;;41532:40:0::1;5734:260:1::0;41480:104:0::1;41617:6;:16:::0;41598:35;;41594:101:::1;;41657:26;;-1:-1:-1::0;;;41657:26:0::1;;;;;;;;;;;41594:101;41731:6;:16:::0;;41758:34;;;;41808:94:::1;::::0;;11039:3:1;11021:22;;;11080:2;11059:19;;;11052:31;-1:-1:-1;;;11114:3:1;11099:19;;11092:49;11208:4;11193:20;;11186:36;;;11238:18;;;11231:34;;;41874:10:0::1;-1:-1:-1::0;11281:18:1;;11274:60;41886:15:0::1;-1:-1:-1::0;11350:19:1;;11343:35;41808:94:0::1;::::0;11173:3:1;11158:19;41808:94:0::1;10725:659:1::0;38617:326:0;14312:13;:11;:13::i;:::-;38674::::1;::::0;-1:-1:-1;;;38674:13:0;::::1;;;38670:66;;;38711:13;;-1:-1:-1::0;;;38711:13:0::1;;;;;;;;;;;38670:66;38751:12;::::0;-1:-1:-1;;;38751:12:0;::::1;;;38746:74;;38787:21;;-1:-1:-1::0;;;38787:21:0::1;;;;;;;;;;;38746:74;38830:12;:20:::0;;-1:-1:-1;;;;38830:20:0::1;::::0;;38866:69:::1;::::0;;11691:3:1;11673:22;;;11732:2;11711:19;;;11704:31;-1:-1:-1;;;11766:3:1;11751:19;;11744:43;-1:-1:-1;11854:4:1;11839:20;;11832:52;-1:-1:-1;11900:18:1;;;11893:50;;;;38907:10:0::1;-1:-1:-1::0;11959:18:1;;11952:60;38919:15:0::1;-1:-1:-1::0;12028:19:1;;12021:35;38866:69:0::1;::::0;11819:3:1;11804:19;38866:69:0::1;11389:673:1::0;45368:528:0;14312:13;:11;:13::i;:::-;-1:-1:-1;;;;;45453:16:0;::::1;;::::0;;;:8:::1;:16;::::0;;;;;:29;::::1;;:16;::::0;;::::1;:29;;::::0;45449:101:::1;;45506:32;::::0;-1:-1:-1;;;45506:32:0;;1120:14:1;;1113:22;45506:32:0::1;::::0;::::1;1095:41:1::0;1068:18;;45506:32:0::1;955:187:1::0;45449:101:0::1;45598:4;-1:-1:-1::0;;;;;45564:39:0::1;45570:6;-1:-1:-1::0;;;;;45564:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;45564:39:0::1;;;:82;;;;;45641:4;-1:-1:-1::0;;;;;45607:39:0::1;45613:6;-1:-1:-1::0;;;;;45607:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;45607:39:0::1;;;45564:82;45560:144;;;45670:22;::::0;-1:-1:-1;;;45670:22:0;;-1:-1:-1;;;;;3404:32:1;;45670:22:0::1;::::0;::::1;3386:51:1::0;3359:18;;45670:22:0::1;3240:203:1::0;45560:144:0::1;-1:-1:-1::0;;;;;45731:16:0;::::1;45714:14;45731:16:::0;;;:8:::1;:16;::::0;;;;;;;;;;45758:28;::::1;;-1:-1:-1::0;;45758:28:0;::::1;::::0;::::1;::::0;;;45802:86;;12653:3:1;12635:22;;;12694:1;12673:19;;;12666:30;-1:-1:-1;;;12727:3:1;12712:19;;12705:39;12834:20;;;12827:45;;;;45731:16:0::1;::::0;;::::1;12915:14:1::0;;12908:22;12888:18;;;12881:50;;;;12962:2;12947:18;;12940:50;;;;45860:10:0::1;-1:-1:-1::0;13006:19:1;;12999:44;45872:15:0::1;-1:-1:-1::0;13059:19:1;;13052:35;45731:16:0;45802:86:::1;::::0;12776:3:1;12761:19;45802:86:0::1;12323:770:1::0;52135:300:0;14312:13;:11;:13::i;:::-;52222:7:::1;52213:6;:16;52209:77;;;52253:21;::::0;-1:-1:-1;;;52253:21:0;;52266:7:::1;52253:21;::::0;::::1;1613:25:1::0;1586:18;;52253:21:0::1;1467:177:1::0;52209:77:0::1;52323:6;52296:23;;:33;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;52367:15:0::1;52340:24;:42:::0;52393:34:::1;52403:6:::0;52419::::1;52393:9;:34::i;:::-;52135:300:::0;:::o;55588:118::-;-1:-1:-1;;;;;55680:18:0;55653:7;55680:18;;;:9;:18;;;;;;;55588:118::o;16771:103::-;14312:13;:11;:13::i;:::-;16836:30:::1;16863:1;16836:18;:30::i;:::-;16771:103::o:0;39218:454::-;14312:13;:11;:13::i;:::-;19253:7:::1;39308:19;:17;:19::i;:::-;:24;::::0;39330:2:::1;39308:24;:::i;:::-;:41;;;;:::i;:::-;39295:10;:54;39291:118;;;39373:24;::::0;-1:-1:-1;;;39373:24:0;;::::1;::::0;::::1;1613:25:1::0;;;1586:18;;39373:24:0::1;1467:177:1::0;39291:118:0::1;39434:10;39423:7;;:21:::0;39419:94:::1;;39468:33;::::0;-1:-1:-1;;;39468:33:0;;::::1;::::0;::::1;1613:25:1::0;;;1586:18;;39468:33:0::1;1467:177:1::0;39419:94:0::1;39544:7;::::0;;39562:20;;;;39598:66:::1;::::0;;13932:25:1;;;13988:2;13973:18;;13966:34;;;39636:10:0::1;14016:18:1::0;;;14009:60;;;;39648:15:0::1;14100:2:1::0;14085:18;;14078:34;39598:66:0::1;::::0;13919:3:1;13904:19;39598:66:0::1;13701:417:1::0;43220:604:0;14312:13;:11;:13::i;:::-;43306:11:::1;::::0;-1:-1:-1;;;43306:11:0;::::1;;;43302:62;;;43341:11;;-1:-1:-1::0;;;43341:11:0::1;;;;;;;;;;;43302:62;43396:6;43378:15;:24;43374:104;;;43426:40;::::0;-1:-1:-1;;;43426:40:0;;::::1;::::0;::::1;5920:25:1::0;;;43459:6:0::1;5961:18:1::0;;;5954:34;5893:18;;43426:40:0::1;5734:260:1::0;43374:104:0::1;43511:11;:21:::0;43492:40;;43488:106:::1;;43556:26;;-1:-1:-1::0;;;43556:26:0::1;;;;;;;;;;;43488:106;43630:11;:21:::0;;43662:39;;;;43717:99:::1;::::0;;14437:3:1;14419:22;;;14478:2;14457:19;;;14450:31;14518:25;14512:3;14497:19;;14490:54;14611:4;14596:20;;14589:36;;;14641:18;;;14634:34;;;43788:10:0::1;-1:-1:-1::0;14684:18:1;;14677:60;43800:15:0::1;-1:-1:-1::0;14753:19:1;;14746:35;43717:99:0::1;::::0;14576:3:1;14561:19;43717:99:0::1;14123:664:1::0;40624:350:0;14312:13;:11;:13::i;:::-;40718:9:::1;40701:26;;:13;;;;;;;;;;;:26;;::::0;40697:98:::1;;40751:32;::::0;-1:-1:-1;;;40751:32:0;;1120:14:1;;1113:22;40751:32:0::1;::::0;::::1;1095:41:1::0;1068:18;;40751:32:0::1;955:187:1::0;40697:98:0::1;40822:13;::::0;;-1:-1:-1;;;;40846:25:0;::::1;-1:-1:-1::0;;;40846:25:0;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;40887:79:::1;::::0;40822:13;;::::1;;;::::0;40887:79:::1;::::0;::::1;::::0;40822:13;;40846:25;;40938:10:::1;::::0;40950:15:::1;::::0;40887:79:::1;:::i;34125:151::-:0;34175:7;34247:21;34265:1;34247:9;:21::i;:::-;34218:26;34236:6;34218:9;:26::i;:::-;55280:12;;34202:42;;;;:::i;:::-;:66;;;;:::i;:::-;34195:73;;34125:151;:::o;35248:325::-;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;14312::::1;:11;:13::i;:::-;19253:7:::2;35354:19;:17;:19::i;:::-;:25;::::0;35376:3:::2;35354:25;:::i;:::-;:42;;;;:::i;:::-;35337:14;:59;35333:194;;;35456:14;19253:7;35472:19;:17;:19::i;:::-;:25;::::0;35494:3:::2;35472:25;:::i;:::-;:42;;;;:::i;:::-;35420:95;::::0;-1:-1:-1;;;35420:95:0;;::::2;::::0;::::2;5920:25:1::0;;;;5961:18;;;5954:34;5893:18;;35420:95:0::2;5734:260:1::0;35333:194:0::2;35539:26;35550:14;35539:10;:26::i;:::-;-1:-1:-1::0;20665:6:0;:14;;-1:-1:-1;;;;20665:14:0;;;35248:325::o;67820:467::-;67905:4;67941:10;67905:4;67989:28;67941:10;68009:7;67989:9;:28::i;:::-;67962:55;;68051:5;68032:16;:24;68028:124;;;68107:7;68116:16;68134:5;68080:60;;-1:-1:-1;;;68080:60:0;;;;;;;;;;:::i;68028:124::-;68187:59;68196:8;68206:7;68234:5;68215:16;:24;68241:4;68187:8;:59::i;56075:186::-;56144:4;56180:10;56201:30;56180:10;56221:2;56225:5;56201:9;:30::i;37826:212::-;14312:13;:11;:13::i;:::-;37880:11:::1;::::0;-1:-1:-1;;;37880:11:0;::::1;;;37876:62;;;37915:11;;-1:-1:-1::0;;;37915:11:0::1;;;;;;;;;;;37876:62;37948:11;:18:::0;;-1:-1:-1;;;;37948:18:0::1;-1:-1:-1::0;;;37948:18:0::1;::::0;;37982:48:::1;::::0;;15918:2:1;15900:21;;;15957:2;15937:18;;;15930:30;-1:-1:-1;;;15991:3:1;15976:19;;15969:42;38002:10:0::1;16078:4:1::0;16063:20;;16056:62;38014:15:0::1;16134:18:1::0;;;16127:34;;;;37982:48:0::1;::::0;16043:3:1;16028:19;37982:48:0::1;15660:507:1::0;37431:221:0;14312:13;:11;:13::i;:::-;37486::::1;::::0;-1:-1:-1;;;37486:13:0;::::1;;;37482:66;;;37523:13;;-1:-1:-1::0;;;37523:13:0::1;;;;;;;;;;;37482:66;37558:13;:20:::0;;-1:-1:-1;;;;37558:20:0::1;-1:-1:-1::0;;;37558:20:0::1;::::0;;37594:50:::1;::::0;;16430:2:1;16412:21;;;16469:2;16449:18;;;16442:30;-1:-1:-1;;;16503:3:1;16488:19;;16481:44;37616:10:0::1;16592:4:1::0;16577:20;;16570:62;37628:15:0::1;16648:18:1::0;;;16641:34;;;;37594:50:0::1;::::0;16557:3:1;16542:19;37594:50:0::1;16172:509:1::0;46363:644:0;14312:13;:11;:13::i;:::-;46459:6:::1;::::0;-1:-1:-1;;;;;46459:6:0;;::::1;46438:28:::0;;::::1;::::0;46434:102:::1;;46490:34;::::0;-1:-1:-1;;;46490:34:0;;-1:-1:-1;;;;;3404:32:1;;46490:34:0::1;::::0;::::1;3386:51:1::0;3359:18;;46490:34:0::1;3240:203:1::0;46434:102:0::1;46576:6;::::0;;-1:-1:-1;;;;;46594:27:0;;::::1;-1:-1:-1::0;;;;;;46594:27:0;::::1;::::0;::::1;::::0;;;46639:63:::1;::::0;;46576:6;;;::::1;16955:34:1::0;;;17020:2;17005:18;;16998:43;;;;46674:10:0::1;17057:18:1::0;;;17050:43;;;;46686:15:0::1;17124:2:1::0;17109:18;;17102:34;46639:63:0::1;::::0;16904:3:1;16889:19;46639:63:0::1;;;;;;;46736:6;::::0;:16:::1;::::0;;-1:-1:-1;;;46736:16:0;;;;46804:1:::1;::::0;-1:-1:-1;;;;;46736:6:0::1;::::0;:14:::1;::::0;:16:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:6;:16:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;46727:34:0::1;;46770:4;46777:6;;;;;;;;;-1:-1:-1::0;;;;;46777:6:0::1;-1:-1:-1::0;;;;;46777:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46727:64;::::0;-1:-1:-1;;;;;;46727:64:0::1;::::0;;;;;;-1:-1:-1;;;;;17377:15:1;;;46727:64:0::1;::::0;::::1;17359:34:1::0;17429:15;;17409:18;;;17402:43;17294:18;;46727:64:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;46719:87:0::1;::::0;46715:285:::1;;46839:6;;;;;;;;;-1:-1:-1::0;;;;;46839:6:0::1;-1:-1:-1::0;;;;;46839:14:0::1;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;46830:37:0::1;;46876:4;46883:6;;;;;;;;;-1:-1:-1::0;;;;;46883:6:0::1;-1:-1:-1::0;;;;;46883:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46830:67;::::0;-1:-1:-1;;;;;;46830:67:0::1;::::0;;;;;;-1:-1:-1;;;;;17377:15:1;;;46830:67:0::1;::::0;::::1;17359:34:1::0;17429:15;;17409:18;;;17402:43;17294:18;;46830:67:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46823:4;:74:::0;;-1:-1:-1;;;;;;46823:74:0::1;-1:-1:-1::0;;;;;46823:74:0;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;46917:14:0;;;:8:::1;:14;::::0;;;;;::::1;;46912:77;;46961:4;::::0;-1:-1:-1;;;;;46961:4:0::1;46952:14;::::0;;;:8:::1;:14;::::0;;;;:21;;-1:-1:-1;;46952:21:0::1;46969:4;46952:21;::::0;;46912:77:::1;46423:584;46363:644:::0;:::o;38204:237::-;14312:13;:11;:13::i;:::-;38263:16:::1;::::0;-1:-1:-1;;;38263:16:0;::::1;;;38259:72;;;38303:16;;-1:-1:-1::0;;;38303:16:0::1;;;;;;;;;;;38259:72;38341:16;:23:::0;;-1:-1:-1;;;;38341:23:0::1;-1:-1:-1::0;;;38341:23:0::1;::::0;;38380:53:::1;::::0;;17714:2:1;17696:21;;;17753:2;17733:18;;;17726:30;-1:-1:-1;;;17787:3:1;17772:19;;17765:47;38405:10:0::1;17879:4:1::0;17864:20;;17857:62;38417:15:0::1;17935:18:1::0;;;17928:34;;;;38380:53:0::1;::::0;17844:3:1;17829:19;38380:53:0::1;17456:512:1::0;56646:148:0;-1:-1:-1;;;;;56756:21:0;;;56729:7;56756:21;;;:11;:21;;;;;;;;:30;;;;;;;;;;;;;56646:148::o;53569:360::-;14312:13;:11;:13::i;:::-;16093:7;16120:6;-1:-1:-1;;;;;16120:6:0;-1:-1:-1;;;;;53655:19:0::1;:8;-1:-1:-1::0;;;;;53655:19:0::1;::::0;53651:92:::1;;53698:33;::::0;-1:-1:-1;;;53698:33:0;;-1:-1:-1;;;;;3404:32:1;;53698:33:0::1;::::0;::::1;3386:51:1::0;3359:18;;53698:33:0::1;3240:203:1::0;53651:92:0::1;-1:-1:-1::0;;;;;;;53757:27:0;::::1;::::0;53753:91:::1;;53808:24;::::0;-1:-1:-1;;;53808:24:0;;-1:-1:-1;;;;;3404:32:1;;53808:24:0::1;::::0;::::1;3386:51:1::0;3359:18;;53808:24:0::1;3240:203:1::0;53753:91:0::1;53854:12;:23:::0;;-1:-1:-1;;;;;;53854:23:0::1;-1:-1:-1::0;;;;;53854:23:0;::::1;;::::0;;53888:33:::1;53854:23:::0;53888::::1;:33::i;16331:162::-:0;16402:10;16391:7;16093;16120:6;-1:-1:-1;;;;;16120:6:0;;16047:87;16391:7;-1:-1:-1;;;;;16391:21:0;;16387:99;;16436:38;;-1:-1:-1;;;16436:38:0;;16463:10;16436:38;;;3386:51:1;3359:18;;16436:38:0;3240:203:1;64074:136:0;64162:40;64171:8;64181:7;64190:5;64197:4;64162:8;:40::i;:::-;64074:136;;;:::o;62039:730::-;-1:-1:-1;;;;;62129:18:0;;62125:369;;62180:5;62164:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;62125:369:0;;-1:-1:-1;62125:369:0;;-1:-1:-1;;;;;62240:15:0;;62218:19;62240:15;;;:9;:15;;;;;;62274:19;;;62270:117;;;62346:4;62352:11;62365:5;62321:50;;-1:-1:-1;;;62321:50:0;;;;;;;;;;:::i;62270:117::-;-1:-1:-1;;;;;62430:15:0;;;;;;:9;:15;;;;;62448:19;;;;62430:37;;62125:369;-1:-1:-1;;;;;62510:16:0;;62506:213;;62572:12;:21;;;;;;;62506:213;;;-1:-1:-1;;;;;62670:13:0;;;;;;:9;:13;;;;;:22;;;;;;62506:213;62751:2;-1:-1:-1;;;;;62736:25:0;62745:4;-1:-1:-1;;;;;62736:25:0;;62755:5;62736:25;;;;1613::1;;1601:2;1586:18;;1467:177;62736:25:0;;;;;;;;62039:730;;;:::o;65998:496::-;66101:24;66128:28;66138:8;66148:7;66128:9;:28::i;:::-;66101:55;;-1:-1:-1;;66171:16:0;:37;66167:320;;66248:5;66229:16;:24;66225:132;;;66308:7;66317:16;66335:5;66281:60;;-1:-1:-1;;;66281:60:0;;;;;;;;;;:::i;66225:132::-;66400:60;66409:8;66419:7;66447:5;66428:16;:24;66454:5;66400:8;:60::i;:::-;66090:404;65998:496;;;:::o;58936:1293::-;-1:-1:-1;;;;;59020:18:0;;59016:88;;59062:30;;-1:-1:-1;;;59062:30:0;;59089:1;59062:30;;;3386:51:1;3359:18;;59062:30:0;3240:203:1;59016:88:0;-1:-1:-1;;;;;59118:16:0;;59114:88;;59158:32;;-1:-1:-1;;;59158:32:0;;59187:1;59158:32;;;3386:51:1;3359:18;;59158:32:0;3240:203:1;59114:88:0;59217:12;;-1:-1:-1;;;59217:12:0;;;;59212:151;;-1:-1:-1;;;;;59251:17:0;;;;;;:11;:17;;;;;;;;59250:18;:38;;;;-1:-1:-1;;;;;;59273:15:0;;;;;;:11;:15;;;;;;;;59272:16;59250:38;59246:106;;;59316:20;;-1:-1:-1;;;59316:20:0;;;;;;;;;;;59246:106;59398:15;;:19;;59416:1;59398:19;:::i;:::-;59379:15;:38;;:56;;;;-1:-1:-1;;;;;;59421:14:0;;;;;;:8;:14;;;;;;;;59379:56;59375:114;;;59459:18;;-1:-1:-1;;;59459:18:0;;;;;;;;;;;59375:114;59513:6;;-1:-1:-1;;;59513:6:0;;;;;:27;;-1:-1:-1;;;;;;59523:17:0;;;;;;:11;:17;;;;;;;;59513:27;:46;;;-1:-1:-1;;;;;;59544:15:0;;;;;;:11;:15;;;;;;;;59513:46;59509:110;;;59583:24;59591:4;59597:2;59601:5;59583:7;:24::i;59509:110::-;59641:4;;-1:-1:-1;;;;;59633:12:0;;;59641:4;;59633:12;;;;:29;;-1:-1:-1;59649:13:0;;-1:-1:-1;;;59649:13:0;;;;59633:29;:80;;;;;59706:7;;59686:16;;59666:17;;:36;;;;:::i;:::-;:47;;59633:80;:119;;;;;59745:7;;59717:24;59735:4;59717:9;:24::i;:::-;:35;;59633:119;59629:171;;;59769:19;59780:7;;59769:10;:19::i;:::-;59853:11;;59831:5;;-1:-1:-1;;;59853:11:0;;;;:33;;;;-1:-1:-1;;;;;;59869:17:0;;;;;;:11;:17;;;;;;;;59868:18;59853:33;:53;;;;-1:-1:-1;;;;;;59891:15:0;;;;;;:11;:15;;;;;;;;59890:16;59853:53;59849:134;;;59934:37;59955:4;59961:2;59965:5;59934:20;:37::i;:::-;59923:48;;59849:134;59997:12;;-1:-1:-1;;;59997:12:0;;;;:34;;;;-1:-1:-1;;;;;;60014:17:0;;;;;;:13;:17;;;;;;;;60013:18;59997:34;:83;;;;;60062:18;:16;:18::i;:::-;60051:8;60035:13;60045:2;60035:9;:13::i;:::-;:24;;;;:::i;:::-;:45;59997:83;59993:189;;;60141:8;60125:13;60135:2;60125:9;:13::i;:::-;:24;;;;:::i;:::-;60151:18;:16;:18::i;:::-;60104:66;;-1:-1:-1;;;60104:66:0;;;;;5920:25:1;;;;5961:18;;;5954:34;5893:18;;60104:66:0;5734:260:1;59993:189:0;60194:27;60202:4;60208:2;60212:8;60194:7;:27::i;64983:455::-;-1:-1:-1;;;;;65099:22:0;;65095:94;;65145:32;;-1:-1:-1;;;65145:32:0;;65174:1;65145:32;;;3386:51:1;3359:18;;65145:32:0;3240:203:1;65095:94:0;-1:-1:-1;;;;;65203:21:0;;65199:92;;65248:31;;-1:-1:-1;;;65248:31:0;;65276:1;65248:31;;;3386:51:1;3359:18;;65248:31:0;3240:203:1;65199:92:0;-1:-1:-1;;;;;65301:21:0;;;;;;;:11;:21;;;;;;;;:30;;;;;;;;;:38;;;65350:81;;;;65404:7;-1:-1:-1;;;;;65385:34:0;65394:8;-1:-1:-1;;;;;65385:34:0;;65413:5;65385:34;;;;1613:25:1;;1601:2;1586:18;;1467:177;65385:34:0;;;;;;;;64983:455;;;;:::o;52673:420::-;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;-1:-1:-1;;52753:10:0::1;:29:::0;52749:78:::1;;52793:31;::::0;-1:-1:-1;;;52793:31:0;;52816:6:::1;52793:31;::::0;::::1;3386:51:1::0;3359:18;;52793:31:0::1;3240:203:1::0;52749:78:0::1;52861:16;::::0;;52875:1:::1;52861:16:::0;;;;;::::1;::::0;;52837:21:::1;::::0;52861:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;52898:6:0::1;::::0;:13:::1;::::0;;-1:-1:-1;;;52898:13:0;;;;52837:40;;-1:-1:-1;;;;;;52898:6:0;;::::1;::::0;:11:::1;::::0;-1:-1:-1;52898:13:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52888:4;52893:1;52888:7;;;;;;;;:::i;:::-;;;;;;:23;-1:-1:-1::0;;;;;52888:23:0::1;;;-1:-1:-1::0;;;;;52888:23:0::1;;;::::0;::::1;52940:4;52922;52927:1;52922:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;52922:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;52958:6:::1;::::0;:127:::1;::::0;-1:-1:-1;;;52958:127:0;;:6;::::1;::::0;:57:::1;::::0;53037:6;;52958:127:::1;::::0;:6:::1;::::0;53059:4;;53065:2;;53069:15:::1;::::0;52958:127:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;20665:6:0;:14;;-1:-1:-1;;;;20665:14:0;;;-1:-1:-1;;;;;;52673:420:0:o;17862:191::-;17936:16;17955:6;;-1:-1:-1;;;;;17972:17:0;;;-1:-1:-1;;;;;;17972:17:0;;;;;;18005:40;;17955:6;;;;;;;18005:40;;17936:16;18005:40;17925:128;17862:191;:::o;36197:1038::-;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;36314:16:::1;::::0;36294:17:::1;::::0;20629:13;;36294:36:::1;::::0;::::1;:::i;:::-;36270:60;;36372:13;36355:14;:30;36351:69;;;36402:7;;;36351:69;36483:11;:21:::0;36458:12:::1;:22:::0;36430:25:::1;::::0;36458:46:::1;::::0;::::1;:::i;:::-;36430:74:::0;-1:-1:-1;36525:32:0::1;36597:13:::0;36560:34:::1;36430:74:::0;36560:14;:34:::1;:::i;:::-;:50;;;;:::i;:::-;36525:85;;36648:24;36623:11;:21;;;:49;;;;;;;:::i;:::-;;;;;;;;36703:14;36683:16;;:34;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;36754:16:0::1;::::0;;36768:1:::1;36754:16:::0;;;;;::::1;::::0;;36730:21:::1;::::0;36754:16:::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;36754:16:0::1;36730:40;;36799:4;36781;36786:1;36781:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;36781:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;;:23;;;;36825:6:::1;::::0;:13:::1;::::0;;-1:-1:-1;;;36825:13:0;;;;:6;;;::::1;::::0;:11:::1;::::0;:13:::1;::::0;;::::1;::::0;36781:7;;36825:13;;;;;:6;:13:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36815:4;36820:1;36815:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;36815:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;:23;36883:6:::1;::::0;36851:56:::1;::::0;36868:4:::1;::::0;36883:6:::1;36892:14:::0;36851:8:::1;:56::i;:::-;36929:81;::::0;;13932:25:1;;;13988:2;13973:18;;13966:34;;;36982:10:0::1;14016:18:1::0;;;14009:60;36994:15:0::1;14100:2:1::0;14085:18;;14078:34;36929:81:0;;::::1;::::0;;;;13919:3:1;36929:81:0;;::::1;37023:6;::::0;37169:17:::1;::::0;37023:204:::1;::::0;-1:-1:-1;;;37023:204:0;;-1:-1:-1;;;;;37023:6:0;;::::1;::::0;:57:::1;::::0;:204:::1;::::0;37095:24;;37023:6:::1;::::0;37150:4;;37169:17;::::1;::::0;37201:15:::1;::::0;37023:204:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;36259:976;;;;-1:-1:-1::0;20665:6:0;:14;;-1:-1:-1;;;;20665:14:0;;;36197:1038::o;17305:220::-;14312:13;:11;:13::i;:::-;-1:-1:-1;;;;;17390:22:0;::::1;17386:93;;17436:31;::::0;-1:-1:-1;;;17436:31:0;;17464:1:::1;17436:31;::::0;::::1;3386:51:1::0;3359:18;;17436:31:0::1;3240:203:1::0;17386:93:0::1;17489:28;17508:8;17489:18;:28::i;60829:518::-:0;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;-1:-1:-1;;;;;60960:14:0;::::1;60936:7:::0;60960:14;;;:8:::1;:14;::::0;;;;;20629:13;60960:14:::1;:40:::0;::::1;;;-1:-1:-1::0;60979:6:0::1;:16:::0;:20;;60960:40:::1;60956:104;;;61024:24;61035:4;61041:6;61024:10;:24::i;:::-;61017:31;;;;60956:104;-1:-1:-1::0;;;;;61074:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;:39:::0;::::1;;;-1:-1:-1::0;61091:7:0::1;:17:::0;:21;;61074:39:::1;61070:104;;;61137:25;61149:4;61155:6;61137:11;:25::i;61070:104::-;-1:-1:-1::0;;;;;61189:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;;::::1;;61188:15;:32:::0;::::1;;;-1:-1:-1::0;;;;;;61208:12:0;::::1;;::::0;;;:8:::1;:12;::::0;;;;;::::1;;61207:13;61188:32;:63;;;;-1:-1:-1::0;61225:11:0::1;:21:::0;:25;;61188:63:::1;61184:132;;;61275:29;61291:4;61297:6;61275:15;:29::i;61184:132::-;-1:-1:-1::0;61333:6:0;20653:1:::1;20665:6:::0;:14;;-1:-1:-1;;;;20665:14:0;;;60829:518;;-1:-1:-1;;;60829:518:0:o;34454:254::-;34505:7;34525:19;34547;:17;:19::i;:::-;34581:12;;34525:41;;-1:-1:-1;;;;34581:12:0;;;;34577:95;;;19253:7;34624:19;:11;34638:5;34624:19;:::i;:::-;:36;;;;:::i;:::-;34610:50;;34577:95;34689:11;34454:254;-1:-1:-1;34454:254:0:o;48790:141::-;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;48894:29:::1;::::0;;::::1;::::0;::::1;::::0;;;20638:4;48894:29;;;48867:7;;48894:29:::1;::::0;48910:4;48916:6;48894:7:::1;:29::i;49273:143::-:0;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;49378:30:::1;::::0;;::::1;::::0;::::1;::::0;;;49386:7:::1;49378:30:::0;;;49351:7;;49378:30:::1;::::0;49395:4;49401:6;49378:7:::1;:30::i;49762:151::-:0;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;49871:34:::1;::::0;;::::1;::::0;::::1;::::0;;;49879:11:::1;49871:34:::0;;;49844:7;;49871:34:::1;::::0;49892:4;49898:6;50311:399;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;50444:17;;50405:7;;;19253::::1;50492:17;50444::::0;50492:6;:17:::1;:::i;:::-;:34;;;;:::i;:::-;50472:54:::0;-1:-1:-1;50537:17:0::1;50557:18;50472:54:::0;50557:6;:18:::1;:::i;:::-;50537:38:::0;-1:-1:-1;50590:13:0;;50586:90:::1;;50620:44;50629:7;50638:4;50644:9;50655:8;50620;:44::i;:::-;20665:6:::0;:14;;-1:-1:-1;;;;20665:14:0;;;50693:9;50311:399;-1:-1:-1;;;;;;50311:399:0:o;51103:286::-;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;51249:17;;20629:13;;51269:3;;51240:26:::1;::::0;:6;:26:::1;:::i;:::-;:32;;;;:::i;:::-;51213:59;;51283:41;51299:16;51317:6;51283:15;:41::i;:::-;51345:36;51353:4;51367;51374:6;51345:7;:36::i;:::-;-1:-1:-1::0;;20665:6:0;:14;;-1:-1:-1;;;;20665:14:0;;;-1:-1:-1;;;51103:286:0:o;51645:184::-;20629:6;:13;;-1:-1:-1;;;;20629:13:0;-1:-1:-1;;;20629:13:0;;;51741:12:::1;:42:::0;;51767:16;;51741:12;20629:13;;51741:42:::1;::::0;51767:16;;51741:42:::1;:::i;:::-;;;;;;;;51815:6;51794:17;;:27;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;20665:6:0;:14;;-1:-1:-1;;;;20665:14:0;;;-1:-1:-1;;51645:184:0:o;14:548:1:-;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;298:3;483:1;478:2;469:6;458:9;454:22;450:31;443:42;553:2;546;542:7;537:2;529:6;525:15;521:29;510:9;506:45;502:54;494:62;;;;14:548;;;;:::o;567:131::-;-1:-1:-1;;;;;642:31:1;;632:42;;622:70;;688:1;685;678:12;703:247;762:6;815:2;803:9;794:7;790:23;786:32;783:52;;;831:1;828;821:12;783:52;870:9;857:23;889:31;914:5;889:31;:::i;:::-;939:5;703:247;-1:-1:-1;;;703:247:1:o;1147:315::-;1215:6;1223;1276:2;1264:9;1255:7;1251:23;1247:32;1244:52;;;1292:1;1289;1282:12;1244:52;1331:9;1318:23;1350:31;1375:5;1350:31;:::i;:::-;1400:5;1452:2;1437:18;;;;1424:32;;-1:-1:-1;;;1147:315:1:o;1649:180::-;1708:6;1761:2;1749:9;1740:7;1736:23;1732:32;1729:52;;;1777:1;1774;1767:12;1729:52;-1:-1:-1;1800:23:1;;1649:180;-1:-1:-1;1649:180:1:o;1834:456::-;1911:6;1919;1927;1980:2;1968:9;1959:7;1955:23;1951:32;1948:52;;;1996:1;1993;1986:12;1948:52;2035:9;2022:23;2054:31;2079:5;2054:31;:::i;:::-;2104:5;-1:-1:-1;2161:2:1;2146:18;;2133:32;2174:33;2133:32;2174:33;:::i;:::-;1834:456;;2226:7;;-1:-1:-1;;;2280:2:1;2265:18;;;;2252:32;;1834:456::o;2484:118::-;2570:5;2563:13;2556:21;2549:5;2546:32;2536:60;;2592:1;2589;2582:12;2607:382;2672:6;2680;2733:2;2721:9;2712:7;2708:23;2704:32;2701:52;;;2749:1;2746;2739:12;2701:52;2788:9;2775:23;2807:31;2832:5;2807:31;:::i;:::-;2857:5;-1:-1:-1;2914:2:1;2899:18;;2886:32;2927:30;2886:32;2927:30;:::i;:::-;2976:7;2966:17;;;2607:382;;;;;:::o;2994:241::-;3050:6;3103:2;3091:9;3082:7;3078:23;3074:32;3071:52;;;3119:1;3116;3109:12;3071:52;3158:9;3145:23;3177:28;3199:5;3177:28;:::i;3448:388::-;3516:6;3524;3577:2;3565:9;3556:7;3552:23;3548:32;3545:52;;;3593:1;3590;3583:12;3545:52;3632:9;3619:23;3651:31;3676:5;3651:31;:::i;:::-;3701:5;-1:-1:-1;3758:2:1;3743:18;;3730:32;3771:33;3730:32;3771:33;:::i;4562:358::-;4786:2;4775:9;4768:21;4749:4;4806:49;4851:2;4840:9;4836:18;4474:2;4462:15;;-1:-1:-1;;;4502:4:1;4493:14;;4486:37;4548:2;4539:12;;4397:160;4806:49;4798:57;;4905:6;4898:14;4891:22;4886:2;4875:9;4871:18;4864:50;4562:358;;;;:::o;5092:::-;5316:2;5305:9;5298:21;5279:4;5336:49;5381:2;5370:9;5366:18;5002:2;4990:15;;-1:-1:-1;;;5030:4:1;5021:14;;5014:39;5078:2;5069:12;;4925:162;6664:127;6725:10;6720:3;6716:20;6713:1;6706:31;6756:4;6753:1;6746:15;6780:4;6777:1;6770:15;6796:128;6863:9;;;6884:11;;;6881:37;;;6898:18;;:::i;6929:345::-;-1:-1:-1;;;;;7149:32:1;;;;7131:51;;7213:2;7198:18;;7191:34;;;;7256:2;7241:18;;7234:34;7119:2;7104:18;;6929:345::o;7279:184::-;7349:6;7402:2;7390:9;7381:7;7377:23;7373:32;7370:52;;;7418:1;7415;7408:12;7370:52;-1:-1:-1;7441:16:1;;7279:184;-1:-1:-1;7279:184:1:o;7468:245::-;7535:6;7588:2;7576:9;7567:7;7563:23;7559:32;7556:52;;;7604:1;7601;7594:12;7556:52;7636:9;7630:16;7655:28;7677:5;7655:28;:::i;8497:125::-;8562:9;;;8583:10;;;8580:36;;;8596:18;;:::i;8627:610::-;8929:3;8918:9;8911:22;8892:4;8950:50;8995:3;8984:9;8980:19;4474:2;4462:15;;-1:-1:-1;;;4502:4:1;4493:14;;4486:37;4548:2;4539:12;;4397:160;8950:50;9043:14;;9036:22;9031:2;9016:18;;9009:50;-1:-1:-1;9102:14:1;;9095:22;9090:2;9075:18;;9068:50;-1:-1:-1;;;;;9154:32:1;;;;9149:2;9134:18;;9127:60;9218:3;9203:19;;;9196:35;8942:58;8627:610::o;12067:251::-;12137:6;12190:2;12178:9;12169:7;12165:23;12161:32;12158:52;;;12206:1;12203;12196:12;12158:52;12238:9;12232:16;12257:31;12282:5;12257:31;:::i;13306:168::-;13379:9;;;13410;;13427:15;;;13421:22;;13407:37;13397:71;;13448:18;;:::i;13479:217::-;13519:1;13545;13535:132;;13589:10;13584:3;13580:20;13577:1;13570:31;13624:4;13621:1;13614:15;13652:4;13649:1;13642:15;13535:132;-1:-1:-1;13681:9:1;;13479:217::o;14792:610::-;15094:3;15083:9;15076:22;15057:4;15115:50;15160:3;15149:9;15145:19;5002:2;4990:15;;-1:-1:-1;;;5030:4:1;5021:14;;5014:39;5078:2;5069:12;;4925:162;18105:127;18166:10;18161:3;18157:20;18154:1;18147:31;18197:4;18194:1;18187:15;18221:4;18218:1;18211:15;18237:461;18290:3;18328:5;18322:12;18355:6;18350:3;18343:19;18381:4;18410:2;18405:3;18401:12;18394:19;;18447:2;18440:5;18436:14;18468:1;18478:195;18492:6;18489:1;18486:13;18478:195;;;18557:13;;-1:-1:-1;;;;;18553:39:1;18541:52;;18613:12;;;;18648:15;;;;18589:1;18507:9;18478:195;;;-1:-1:-1;18689:3:1;;18237:461;-1:-1:-1;;;;;18237:461:1:o;18703:510::-;18974:6;18963:9;18956:25;19017:3;19012:2;19001:9;18997:18;18990:31;18937:4;19038:57;19090:3;19079:9;19075:19;19067:6;19038:57;:::i;:::-;-1:-1:-1;;;;;19131:32:1;;;;19126:2;19111:18;;19104:60;-1:-1:-1;19195:2:1;19180:18;19173:34;19030:65;18703:510;-1:-1:-1;;18703:510:1:o;19218:582::-;19517:6;19506:9;19499:25;19560:6;19555:2;19544:9;19540:18;19533:34;19603:3;19598:2;19587:9;19583:18;19576:31;19480:4;19624:57;19676:3;19665:9;19661:19;19653:6;19624:57;:::i;:::-;-1:-1:-1;;;;;19717:32:1;;;;19712:2;19697:18;;19690:60;-1:-1:-1;19781:3:1;19766:19;19759:35;19616:65;19218:582;-1:-1:-1;;;19218:582:1:o

Swarm Source

ipfs://4a2706a484307d1a76f5b734628760d953b418a5bda8967a29f759d68653eb19
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.