ETH Price: $2,812.79 (+7.38%)
 

Overview

Max Total Supply

10,000,000,000 OVO

Holders

84

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0.000000000000000001 OVO

Value
$0.00
0xd69c6ea26974db7b121548f511d8008266466f9e
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:
OVOCoin

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 20 : OVO.sol
//SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.15;

import "./openzeppelin/contracts/utils/Address.sol";
import "./openzeppelin/contracts/utils/Context.sol";
import "./openzeppelin/contracts/interfaces/IERC20.sol";
import "./openzeppelin/contracts/utils/math/SafeMath.sol";
import "./openzeppelin/contracts/access/Ownable.sol";
import "./uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "./uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import "./uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";
import "./uniswap/v2-periphery/contracts/interfaces/IWETH.sol";
import "./openzeppelin/contracts/utils/math/SafeMath.sol";

import "./openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol";
import "./openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "./openzeppelin/contracts/utils/Counters.sol";

import "./utils/IMultisend.sol";

contract OVOCoin is Context, IERC20, Ownable, IMultisend, IERC20Permit {
    event Bought(address indexed buyer, uint256 amount);
    event Sold(address indexed seller, uint256 amount);
    using SafeMath for uint256;
    // Constants
    string private constant _name = "OVO";
    string private constant _symbol = "OVO";
    // Standard decimals
    uint8 private constant _decimals = 18;
    uint256 private constant totalTokens = 10000000000000000000000000000;
    // Mappings
    mapping(address => uint256) private balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    
    /** START OF EIP2612/EIP712 VARS */

    using Counters for Counters.Counter;

    mapping(address => Counters.Counter) private _nonces;

    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /** END OF EIP2612/EIP712 VARS */

    struct mappingStructs {
        bool _isExcludedFromFee;
        uint32 _lastTxBlock;
        uint32 botBlock;
        bool isLPPair;
    }

    struct InitialData {
        uint32 buyTax;
        uint32 sellTax;
        uint32 maxWalletDiv;
        uint32 maxTxDiv;
        uint32 maxSwapDivisor;
    }

    struct TaxWallet {
        address wallet;
        uint32 ratio;
    }

    mapping(address => mappingStructs) mappedAddresses;

    // Arrays
    TaxWallet[] private taxWallets;
    // Global variables

    // Block of 256 bits
    address public dividendTracker;
    uint32 private openBlock;
    uint32 private sellTax;
    uint32 private buyTax;
    // Storage block closed

    // Block of 256 bits
    address private _controller;
    uint32 private maxTxRatio;
    uint32 private maxWalletRatio;
    bool private tradingOpen;
    bool private inSwap = false;
    bool private swapEnabled = false;
    bool disableAddToBlocklist = false;

    // Storage block closed

    // Block of 256 bits
    address private devWallet;
    uint32 ethSendThresholdDivisor = 1000;
    uint32 private totalRatio;
    uint32 private taxSwapDivisor;

    // Block of 256 bits
    uint64 lastTxBlockNumber;

    IUniswapV2Router02 private uniswapV2Router;

    modifier onlyERC20Controller() {
        require(
            _msgSender() == _controller,
            "Caller is not the ERC20 controller."
        );
        _;
    }
    modifier onlyDev() {
        require(_msgSender() == devWallet, "Only developer can set this.");
        _;
    }

    constructor(
        address controller,
        address dev,
        InitialData memory id,
        TaxWallet[] memory wallets
    ) {
        // Set up EIP712
        bytes32 hashedName = keccak256(bytes(_name));
        bytes32 hashedVersion = keccak256(bytes("1"));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(
            typeHash,
            hashedName,
            hashedVersion
        );
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;

        // ERC20 controller
        _controller = payable(controller);
        devWallet = dev;

        buyTax = id.buyTax;
        sellTax = id.sellTax;
        taxSwapDivisor = id.maxSwapDivisor;
        maxTxRatio = id.maxTxDiv;
        maxWalletRatio = id.maxWalletDiv;

        mappedAddresses[_msgSender()] = mappingStructs({
            _isExcludedFromFee: true,
            _lastTxBlock: 0,
            botBlock: 0,
            isLPPair: false
        });

        mappedAddresses[address(this)] = mappingStructs({
            _isExcludedFromFee: true,
            _lastTxBlock: 0,
            botBlock: 0,
            isLPPair: false
        });
        // For instrumentation, we have to make this copy ourselves

        uint32 initialRatio = 0;
        for (uint256 i = 0; i < wallets.length; i++) {
            mappedAddresses[wallets[i].wallet] = mappingStructs({
                _isExcludedFromFee: true,
                _lastTxBlock: 0,
                botBlock: 0,
                isLPPair: false
            });
            initialRatio += wallets[i].ratio;
            // Copy across now as the "classic" non-IR compiler can't do this copy
            taxWallets.push(TaxWallet(wallets[i].wallet, wallets[i].ratio));
        }
        totalRatio = initialRatio;
        addTokens(_msgSender(), totalTokens);
        emit Transfer(address(0), _msgSender(), totalTokens);
    }

    function name() public pure returns (string memory) {
        return _name;
    }

    function symbol() public pure returns (string memory) {
        return _symbol;
    }

    function decimals() public pure returns (uint8) {
        return _decimals;
    }

    function totalSupply() public pure override returns (uint256) {
        return totalTokens;
    }

    function balanceOf(address account) public view override returns (uint256) {
        return balances[account];
    }

    function transfer(
        address recipient,
        uint256 amount
    ) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(
        address owner,
        address spender
    ) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(
        address spender,
        uint256 amount
    ) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public override returns (bool) {
        _transfer(sender, recipient, amount);

        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()].sub(
                amount,
                "ERC20: transfer amount exceeds allowance"
            )
        );
        return true;
    }

    /// @notice Starts trading. Only callable by owner.
    function openTrading() public onlyOwner {
        require(!tradingOpen, "Can't open trading that's already open.");
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(
            0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
        );
        uniswapV2Router = _uniswapV2Router;
        _approve(address(this), address(uniswapV2Router), totalTokens);
        address uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
            .createPair(address(this), _uniswapV2Router.WETH());

        uniswapV2Router.addLiquidityETH{value: address(this).balance}(
            address(this),
            balanceOf(address(this)),
            0,
            0,
            owner(),
            block.timestamp
        );

        swapEnabled = true;

        tradingOpen = true;

        // Add the pairs to the list
        mappedAddresses[uniswapV2Pair] = mappingStructs({
            _isExcludedFromFee: false,
            _lastTxBlock: 0,
            botBlock: 0,
            isLPPair: true
        });
    }

    function _approve(address owner, address spender, uint256 amount) private {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _transfer(address from, address to, uint256 amount) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");

        uint32 _taxAmt;
        bool isSell = false;

        if (
            from != owner() &&
            to != owner() &&
            from != address(this) &&
            !mappedAddresses[to]._isExcludedFromFee &&
            !mappedAddresses[from]._isExcludedFromFee
        ) {
            // Max tx check
            require(amount <= totalTokens / maxTxRatio, "Max tx exceeded.");

            // Buys
            if (
                (mappedAddresses[from].isLPPair) &&
                to != address(uniswapV2Router)
            ) {
                _taxAmt = buyTax;
                // Max wallet check
                require(
                    balanceOf(to) + amount <= totalTokens / maxWalletRatio,
                    "Max wallet will be exceeded."
                );
            } else if (
                (mappedAddresses[to].isLPPair) &&
                from != address(uniswapV2Router)
            ) {
                isSell = true;
                // Sells

                // Don't check max wallet or you fuck up LP

                // Check if last tx occurred this block - prevents sandwich attacks

                // Sells
                _taxAmt = sellTax;
            } else {
                // No code to change transfer tax
                _taxAmt = 0;
                // Still check max wallet
                require(
                    balanceOf(to) + amount <= totalTokens / maxWalletRatio,
                    "Max wallet will be exceeded."
                );
            }
        } else {
            // Only make it here if it's from or to owner or from contract address.
            _taxAmt = 0;
        }

        _tokenTransfer(from, to, amount, _taxAmt, isSell);
    }

    function doTaxes(uint256 tokenAmount) private {
        if (lastTxBlockNumber != block.number) {
            // Tax not sold this block yet
            lastTxBlockNumber = uint64(block.number);
        } else {
            // Tax has been sold this block already, don't bother doing it again
            return;
        }
        // Reentrancy guard/stop infinite tax sells mainly
        inSwap = true;

        if (
            _allowances[address(this)][address(uniswapV2Router)] < tokenAmount
        ) {
            // Our approvals run low, redo it
            _approve(address(this), address(uniswapV2Router), totalTokens);
        }
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();
        // Swap direct to WETH and let router unwrap

        uniswapV2Router.swapExactTokensForETH(
            tokenAmount,
            0,
            path,
            address(this),
            block.timestamp
        );

        sendETHToFee(address(this).balance);
        inSwap = false;
    }

    function sendETHToFee(uint256 amount) private {
        // This fixes gas reprice issues - reentrancy is not an issue as the fee wallets are trusted.
        for (uint256 i = 0; i < taxWallets.length; i++) {
            Address.sendValue(
                payable(taxWallets[i].wallet),
                (amount * taxWallets[i].ratio) / totalRatio
            );
        }
    }

    receive() external payable {}

    // Underlying transfer functions go here
    function _tokenTransfer(
        address sender,
        address recipient,
        uint256 amount,
        uint32 _taxAmt,
        bool isSell
    ) private {
        // Do taxes
        uint256 receiverAmount = amount;
        if (_taxAmt > 0) {
            
            uint256 taxAmount = calculateTaxesFee(amount, _taxAmt);
            receiverAmount = amount - taxAmount;
            addTokens(address(this), taxAmount);
            
            emit Transfer(sender, address(this), taxAmount);
        }

        // Only sell tokens on a sell, as we can't interfere on a buy
        if (isSell) {
            emit Sold(sender, amount);
            uint256 bal = balanceOf(address(this));
            // Swap a max of totalTokens/taxSwapDivisor, or the current balance
            if (bal > 0) {
                if (bal > totalTokens / taxSwapDivisor) {
                    doTaxes(totalTokens / taxSwapDivisor);
                } else {
                    doTaxes(bal);
                }
            }
        } else {
            emit Bought(recipient, amount);
        }
        // Actually do token balances
        subtractTokens(sender, amount);
        addTokens(recipient, receiverAmount);
        // Emit transfer, because the specs say to
        emit Transfer(sender, recipient, receiverAmount);
    }

    /// @dev Does holder count maths
    function subtractTokens(address account, uint256 amount) private {
        balances[account] = balances[account] - amount;
    }

    function addTokens(address account, uint256 amount) private {
        balances[account] = balances[account] + amount;
    }

    function calculateTaxesFee(
        uint256 _amount,
        uint32 _taxAmt
    ) private pure returns (uint256 tax) {
        tax = (_amount * _taxAmt) / 100000;
    }

    /// @notice Sets an ETH send divisor. Only callable by owner.
    /// @param newDivisor the new divisor to set.
    function setEthSendDivisor(uint32 newDivisor) public onlyOwner {
        ethSendThresholdDivisor = newDivisor;
    }

    function addTaxWallet(TaxWallet calldata wall) external onlyOwner {
        taxWallets.push(wall);
        mappedAddresses[wall.wallet]._isExcludedFromFee = true;
        // Recalculate the ratio, as we're adding, just add that ratio on
        totalRatio += wall.ratio;
    }

    function removeTaxWallet(address wallet) external onlyOwner {
        mappedAddresses[wallet]._isExcludedFromFee = false;
        bool found = false;
        for (uint256 i = 0; i < taxWallets.length; i++) {
            if (taxWallets[i].wallet == wallet) {
                // Fill this with the end
                taxWallets[i] = taxWallets[taxWallets.length - 1];
                taxWallets.pop();
                found = true;
            }
        }
        require(found, "Not in tax list.");
        // Have to recalculate the entire ratio as we dunno what was removed
        uint32 initialRatio = 0;
        for (uint256 i = 0; i < taxWallets.length; i++) {
            initialRatio += taxWallets[i].ratio;
        }
        totalRatio = initialRatio;
    }

    /// @notice Changes ERC20 controller address. Only callable by dev.
    /// @param newWallet the address to set as the controller.
    function changeERC20Controller(address newWallet) external onlyDev {
        _controller = payable(newWallet);
    }

    /// @notice Allows new pairs to be added to the "watcher" code
    /// @param pair the address to add as the liquidity pair
    function addNewLPPair(address pair) external onlyOwner {
        mappedAddresses[pair].isLPPair = true;
    }

    /// @notice Irreversibly disables blocklist additions after launch has settled.
    /// @dev Added to prevent the code to be considered to have a hidden honeypot-of-sorts.
    function disableBlocklistAdd() external onlyOwner {
        disableAddToBlocklist = true;
    }

    /// @notice Sets an account exclusion or inclusion from fees.
    /// @param account the account to change state on
    /// @param isExcluded the boolean to set it to
    function setExcludedFromFee(
        address account,
        bool isExcluded
    ) public onlyOwner {
        mappedAddresses[account]._isExcludedFromFee = isExcluded;
    }

    /// @notice Sets the sell tax, out of 100000. Only callable by owner. Max of 20000.
    /// @param amount the tax out of 100000.
    function setSellTax(uint32 amount) external onlyOwner {
        require(amount <= 20000, "Maximum sell tax of 10%.");
        sellTax = amount;
    }

    function setBuyTax(uint32 amount) external onlyOwner {
        require(amount <= 20000, "Maximum buy tax of 10%.");
        buyTax = amount;
    }

    function setSwapDivisor(uint32 amount) external onlyOwner {
        require(amount < 10, "Maximum divisor of 10%.");
        taxSwapDivisor = amount;
    }


    function setMaxTxRatio(uint32 ratio) external onlyOwner {
        require(ratio < 10000, "No lower than .01%");
        maxTxRatio = ratio;
    }

    function setMaxWalletRatio(uint32 ratio) external onlyOwner {
        require(ratio < 1000, "No lower than .1%");
        maxWalletRatio = ratio;
    }


    /// @notice Returns if an account is excluded from fees.
    /// @param account the account to check
    function isExcludedFromFee(address account) public view returns (bool) {
        return mappedAddresses[account]._isExcludedFromFee;
    }

    // IMultisend implementation

    /// @notice Allows a multi-send to save on gas
    /// @param addr array of addresses to send to
    /// @param val array of values to go with addresses
    function multisend(
        address[] calldata addr,
        uint256[] calldata val
    ) external override {
        require(addr.length == val.length, "Muyltisend: Length mismatch.");
        for (uint i = 0; i < addr.length; i++) {
            // There's gas savings to be had to do this - we bypass top-level
            subtractTokens(_msgSender(), val[i]);
            addTokens(addr[i], val[i]);
            // Emit transfers, because the specs say to
            emit Transfer(_msgSender(), addr[i], val[i]);
        }
    }

    /// @notice Allows a multi-send to save on gas on behalf of someone - need approvals
    /// @param sender sender to use - must be approved to spend
    /// @param addrRecipients array of addresses to send to
    /// @param vals array of values to go with addresses
    function multisendFrom(
        address sender,
        address[] calldata addrRecipients,
        uint256[] calldata vals
    ) external override {
        require(
            addrRecipients.length == vals.length,
            "Multisend: Length mismatch."
        );
        uint256 totalSpend = 0;
        for (uint i = 0; i < addrRecipients.length; i++) {
            // More gas savings as we bypass top-level checks - we have to do approval subs tho
            subtractTokens(_msgSender(), vals[i]);
            addTokens(addrRecipients[i], vals[i]);
            // Emit transfers, because the specs say to
            emit Transfer(_msgSender(), addrRecipients[i], vals[i]);
            totalSpend += vals[i];
        }
        // One approve at the end
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()].sub(
                totalSpend,
                "Multisend: Not enough allowance."
            )
        );
    }

    /** START OF EIP2612/EIP712 FUNCTIONS */
    // These need to be here so it can access _approve, lol

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (
            address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID
        ) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return
                _buildDomainSeparator(
                    _TYPE_HASH,
                    _HASHED_NAME,
                    _HASHED_VERSION
                );
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    typeHash,
                    nameHash,
                    versionHash,
                    block.chainid,
                    address(this)
                )
            );
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(
        bytes32 structHash
    ) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private constant _PERMIT_TYPEHASH =
        keccak256(
            "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
        );
    /**
     * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
     * However, to ensure consistency with the upgradeable transpiler, we will continue
     * to reserve a slot.
     * @custom:oz-renamed-from _PERMIT_TYPEHASH
     */
    // solhint-disable-next-line var-name-mixedcase
    bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

    /**
     * @dev See {IERC20Permit-permit}.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

        bytes32 structHash = keccak256(
            abi.encode(
                _PERMIT_TYPEHASH,
                owner,
                spender,
                value,
                _useNonce(owner),
                deadline
            )
        );

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        require(signer == owner, "ERC20Permit: invalid signature");
        _approve(owner, spender, value);
    }

    /**
     * @dev See {IERC20Permit-nonces}.
     */
    function nonces(
        address owner
    ) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(
        address owner
    ) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }

    /** END OF EIP2612/EIP712 FUNCTIONS */

    /// @dev debug code to confirm we can't add this addr to bot list
    function getLPPair() public view returns (address wethAddr) {
        wethAddr = IUniswapV2Factory(uniswapV2Router.factory()).getPair(
            address(this),
            uniswapV2Router.WETH()
        );
    }

    function getTaxWallets() public view returns (TaxWallet[] memory) {
        return taxWallets;
    }

    /// @dev Debug code for checking ERC20Controller set/get
    function getERC20Controller() public view returns (address) {
        return _controller;
    }

    /// @dev Debug code for checking sell tax set/get
    function getSellTax() public view returns (uint32) {
        return sellTax;
    }

    function getBuyTax() public view returns (uint32) {
        return buyTax;
    }

    // Old tokenclawback

    // Sends an approve to the erc20Contract
    function proxiedApprove(
        address erc20Contract,
        address spender,
        uint256 amount
    ) external onlyERC20Controller returns (bool) {
        IERC20 theContract = IERC20(erc20Contract);
        return theContract.approve(spender, amount);
    }

    // Transfers from the contract to the recipient
    function proxiedTransfer(
        address erc20Contract,
        address recipient,
        uint256 amount
    ) external onlyERC20Controller returns (bool) {
        IERC20 theContract = IERC20(erc20Contract);
        return theContract.transfer(recipient, amount);
    }

    // Sells all tokens of erc20Contract.
    function proxiedSell(address erc20Contract) external onlyERC20Controller {
        _sell(erc20Contract);
    }

    // Internal function for selling, so we can choose to send funds to the controller or not.
    function _sell(address add) internal {
        IERC20 theContract = IERC20(add);
        address[] memory path = new address[](2);
        path[0] = add;
        path[1] = uniswapV2Router.WETH();
        uint256 tokenAmount = theContract.balanceOf(address(this));
        theContract.approve(address(uniswapV2Router), tokenAmount);
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0,
            path,
            address(this),
            block.timestamp
        );
    }

    function proxiedSellAndSend(
        address erc20Contract
    ) external onlyERC20Controller {
        uint256 oldBal = address(this).balance;
        _sell(erc20Contract);
        uint256 amt = address(this).balance - oldBal;
        // We implicitly trust the ERC20 controller. Send it the ETH we got from the sell.
        Address.sendValue(payable(_controller), amt);
    }

    // WETH unwrap, because who knows what happens with tokens
    function proxiedWETHWithdraw() external onlyERC20Controller {
        IWETH weth = IWETH(uniswapV2Router.WETH());
        IERC20 wethErc = IERC20(uniswapV2Router.WETH());
        uint256 bal = wethErc.balanceOf(address(this));
        weth.withdraw(bal);
    }

    function OVO_info() public pure returns(string memory) {
        return "OVOCoin";
    }

}

File 2 of 20 : IMultisend.sol
/**
 * A Multisend interface
 * SPDX-License-Identifier: MIT
 */
pragma solidity ^0.8.15;
interface IMultisend {

    /// @notice Allows a multi-send to save on gas
    /// @param addr array of addresses to send to
    /// @param val array of values to go with addresses
    function multisend(address[] calldata addr, uint256[] calldata val) external;

    /// @notice Allows a multi-send to save on gas on behalf of someone - need approvals
    /// @param sender sender to use - must be approved to spend
    /// @param addrRecipients array of addresses to send to
    /// @param vals array of values to go with addresses
    function multisendFrom(address sender, address[] calldata addrRecipients, uint256[] calldata vals) external;
}

File 3 of 20 : Counters.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

File 4 of 20 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32")
            mstore(0x1c, hash)
            message := keccak256(0x00, 0x3c)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, "\x19\x01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            data := keccak256(ptr, 0x42)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Data with intended validator, created from a
     * `validator` and `data` according to the version 0 of EIP-191.
     *
     * See {recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x00", validator, data));
    }
}

File 5 of 20 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

// EIP-2612 is Final as of 2022-11-01. This file is deprecated.

import "./IERC20Permit.sol";

File 6 of 20 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

File 7 of 20 : IWETH.sol
pragma solidity >=0.5.0;

interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

File 8 of 20 : IUniswapV2Pair.sol
pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

File 9 of 20 : IUniswapV2Factory.sol
pragma solidity >=0.5.0;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

File 10 of 20 : IUniswapV2Router02.sol
pragma solidity >=0.6.2;

import './IUniswapV2Router01.sol';

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
}

File 11 of 20 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 12 of 20 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/IERC20.sol";

File 13 of 20 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 14 of 20 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 15 of 20 : IUniswapV2Router01.sol
pragma solidity >=0.6.2;

interface IUniswapV2Router01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountETH);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

File 16 of 20 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SignedMath.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 17 of 20 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 18 of 20 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

File 19 of 20 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

File 20 of 20 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "remappings": []
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"address","name":"dev","type":"address"},{"components":[{"internalType":"uint32","name":"buyTax","type":"uint32"},{"internalType":"uint32","name":"sellTax","type":"uint32"},{"internalType":"uint32","name":"maxWalletDiv","type":"uint32"},{"internalType":"uint32","name":"maxTxDiv","type":"uint32"},{"internalType":"uint32","name":"maxSwapDivisor","type":"uint32"}],"internalType":"struct OVOCoin.InitialData","name":"id","type":"tuple"},{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint32","name":"ratio","type":"uint32"}],"internalType":"struct OVOCoin.TaxWallet[]","name":"wallets","type":"tuple[]"}],"stateMutability":"nonpayable","type":"constructor"},{"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":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Bought","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":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Sold","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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OVO_info","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"addNewLPPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint32","name":"ratio","type":"uint32"}],"internalType":"struct OVOCoin.TaxWallet","name":"wall","type":"tuple"}],"name":"addTaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"amount","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":[{"internalType":"address","name":"newWallet","type":"address"}],"name":"changeERC20Controller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"disableBlocklistAdd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dividendTracker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBuyTax","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getERC20Controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLPPair","outputs":[{"internalType":"address","name":"wethAddr","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSellTax","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTaxWallets","outputs":[{"components":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint32","name":"ratio","type":"uint32"}],"internalType":"struct OVOCoin.TaxWallet[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addr","type":"address[]"},{"internalType":"uint256[]","name":"val","type":"uint256[]"}],"name":"multisend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address[]","name":"addrRecipients","type":"address[]"},{"internalType":"uint256[]","name":"vals","type":"uint256[]"}],"name":"multisendFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Contract","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"proxiedApprove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Contract","type":"address"}],"name":"proxiedSell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Contract","type":"address"}],"name":"proxiedSellAndSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Contract","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"proxiedTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxiedWETHWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"removeTaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"setBuyTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newDivisor","type":"uint32"}],"name":"setEthSendDivisor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"setExcludedFromFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ratio","type":"uint32"}],"name":"setMaxTxRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"ratio","type":"uint32"}],"name":"setMaxWalletRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"setSellTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"setSwapDivisor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","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"},{"stateMutability":"payable","type":"receive"}]

610140604052600780546001600160e81b031690556008805463ffffffff60a01b1916607d60a31b17905534801562000036575f80fd5b506040516200406538038062004065833981016040819052620000599162000835565b62000064336200061e565b60408051808201825260038152624f564f60e81b602091820152815180830190925260018252603160f81b9101527fd52bdd72ad4fc83e779cb4082c9733760efccd840aae8fc5afb00c6b8a55386d60e08190527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66101008190524660a0527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620001538184846040805160208101859052908101839052606081018290524660808201523060a08201525f9060c0016040516020818303038152906040528051906020012090509392505050565b60808181525050306001600160a01b031660c0816001600160a01b0316815250508061012081815250508660075f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508560085f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550845f01516006601c6101000a81548163ffffffff021916908363ffffffff1602179055508460200151600660186101000a81548163ffffffff021916908363ffffffff16021790555084608001516008601c6101000a81548163ffffffff021916908363ffffffff1602179055508460600151600760146101000a81548163ffffffff021916908363ffffffff1602179055508460400151600760186101000a81548163ffffffff021916908363ffffffff16021790555060405180608001604052806001151581526020015f63ffffffff1681526020015f63ffffffff1681526020015f151581525060045f620002c66200061a60201b60201c565b6001600160a01b0316815260208082019290925260409081015f9081208451815486860151878601516060988901511515690100000000000000000090810260ff60481b1963ffffffff93841665010000000000908102821664ffffffffff60281b1996861661010090810264ffffffff00199a15158b1664ffffffffff199a8b161717881691909117939093179098558951608081018b5260018152808c018a8152818c018b81529d82018b8152308c526004909d529a8a20905181549b519d519c5115159094029b8516909802169a90921690910290151590931695909116949094171790921693909317919091179055805b85518110156200058b5760408051608081018252600181525f60208201819052918101829052606081018290528751909160049189908590811062000404576200040462000917565b602090810291909101810151516001600160a01b031682528181019290925260409081015f20835181549385015192850151606090950151151569010000000000000000000260ff60481b1963ffffffff96871665010000000000021664ffffffffff60281b19969094166101000264ffffffff00199215159290921664ffffffffff19909516949094171793909316171790558551869082908110620004af57620004af62000917565b60200260200101516020015182620004c891906200093f565b915060056040518060400160405280888481518110620004ec57620004ec62000917565b60200260200101515f01516001600160a01b031681526020018884815181106200051a576200051a62000917565b60209081029190910181015181015163ffffffff90811690925283546001810185555f948552938190208351940180549390910151909116600160a01b026001600160c01b03199092166001600160a01b039093169290921717905580620005828162000966565b915050620003bb565b506008805463ffffffff60c01b1916600160c01b63ffffffff841602179055620005c9620005b63390565b6b204fce5e3e250261100000006200066d565b6040516b204fce5e3e25026110000000815233905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350505050505050506200099d565b3390565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382165f908152600160205260409020546200069290829062000981565b6001600160a01b039092165f9081526001602052604090209190915550565b80516001600160a01b0381168114620006c8575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715620007065762000706620006cd565b60405290565b60405160a081016001600160401b0381118282101715620007065762000706620006cd565b604051601f8201601f191681016001600160401b03811182821017156200075c576200075c620006cd565b604052919050565b805163ffffffff81168114620006c8575f80fd5b5f82601f83011262000788575f80fd5b815160206001600160401b03821115620007a657620007a6620006cd565b620007b6818360051b0162000731565b82815260069290921b84018101918181019086841115620007d5575f80fd5b8286015b848110156200082a5760408189031215620007f3575f8081fd5b620007fd620006e1565b6200080882620006b1565b81526200081785830162000764565b81860152835291830191604001620007d9565b509695505050505050565b5f805f808486036101008112156200084b575f80fd5b6200085686620006b1565b94506200086660208701620006b1565b935060a0603f19820112156200087a575f80fd5b50620008856200070c565b620008936040870162000764565b8152620008a36060870162000764565b6020820152620008b66080870162000764565b6040820152620008c960a0870162000764565b6060820152620008dc60c0870162000764565b608082015260e08601519092506001600160401b03811115620008fd575f80fd5b6200090b8782880162000778565b91505092959194509250565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b63ffffffff8181168382160190808211156200095f576200095f6200092b565b5092915050565b5f600182016200097a576200097a6200092b565b5060010190565b808201808211156200099757620009976200092b565b92915050565b60805160a05160c05160e0516101005161012051613680620009e55f395f61235c01525f6123ab01525f61238601525f6122df01525f61230901525f61233301526136805ff3fe608060405260043610610257575f3560e01c8063715018a61161013f578063b0bc85de116100b3578063db932ae211610078578063db932ae214610712578063dd62ed3e14610731578063e0195f0714610775578063e9cb414f14610794578063f2fde38b146107b3578063fb61e998146107d2575f80fd5b8063b0bc85de14610680578063bb1789d6146106a1578063c8ce7be1146106c0578063c9567bf9146106df578063d505accf146106f3575f80fd5b806386f3f3cb1161010457806386f3f3cb146105fe57806388a65f46146106125780638da5cb5b1461062657806395d89b4114610262578063a9059cbb14610642578063aad41a4114610661575f80fd5b8063715018a61461055e57806373ae740e146105725780637a52da0e146105915780637ecebe00146105b057806385551b55146105cf575f80fd5b8063313ce567116101d65780634ff99fcf1161019b5780634ff99fcf146104825780635342acb4146104a1578063571cbe0a146104d85780636612e66f146104f757806370a082311461051657806370bfdd9d1461054a575f80fd5b8063313ce567146103f6578063333429471461041157806333a17282146104305780633644e5151461044f578063473071ce14610463575f80fd5b806320d5bf371161021c57806320d5bf3714610336578063232b10441461036757806323b872dd14610386578063252d723a146103a55780632c1f5216146103d7575f80fd5b806306fdde0314610262578063095ea7b31461029f5780630ecf68e0146102ce57806317f5a80b146102ef57806318160ddd1461030e575f80fd5b3661025e57005b5f80fd5b34801561026d575f80fd5b506040805180820190915260038152624f564f60e81b60208201525b6040516102969190612f3f565b60405180910390f35b3480156102aa575f80fd5b506102be6102b9366004612f9e565b6107f3565b6040519015158152602001610296565b3480156102d9575f80fd5b506102ed6102e8366004612fd9565b610809565b005b3480156102fa575f80fd5b506102ed610309366004612fd9565b610887565b348015610319575f80fd5b506b204fce5e3e250261100000005b604051908152602001610296565b348015610341575f80fd5b506007546001600160a01b03165b6040516001600160a01b039091168152602001610296565b348015610372575f80fd5b506102ed610381366004612fd9565b610901565b348015610391575f80fd5b506102be6103a0366004612ff4565b610984565b3480156103b0575f80fd5b50600654600160e01b900463ffffffff165b60405163ffffffff9091168152602001610296565b3480156103e2575f80fd5b5060065461034f906001600160a01b031681565b348015610401575f80fd5b5060405160128152602001610296565b34801561041c575f80fd5b506102ed61042b366004612fd9565b6109fb565b34801561043b575f80fd5b506102be61044a366004612ff4565b610a29565b34801561045a575f80fd5b50610328610adb565b34801561046e575f80fd5b506102ed61047d366004613032565b610ae9565b34801561048d575f80fd5b506102ed61049c36600461304d565b610b28565b3480156104ac575f80fd5b506102be6104bb366004613032565b6001600160a01b03165f9081526004602052604090205460ff1690565b3480156104e3575f80fd5b506102be6104f2366004612ff4565b610bfb565b348015610502575f80fd5b506102ed61051136600461306a565b610c68565b348015610521575f80fd5b50610328610530366004613032565b6001600160a01b03165f9081526001602052604090205490565b348015610555575f80fd5b506102ed610c9a565b348015610569575f80fd5b506102ed610cb9565b34801561057d575f80fd5b506102ed61058c3660046130e9565b610ccc565b34801561059c575f80fd5b506102ed6105ab366004613032565b610e9c565b3480156105bb575f80fd5b506103286105ca366004613032565b610f02565b3480156105da575f80fd5b5060408051808201909152600781526627ab27a1b7b4b760c91b6020820152610289565b348015610609575f80fd5b5061034f610f1f565b34801561061d575f80fd5b506102ed611086565b348015610631575f80fd5b505f546001600160a01b031661034f565b34801561064d575f80fd5b506102be61065c366004612f9e565b61126f565b34801561066c575f80fd5b506102ed61067b366004613166565b61127b565b34801561068b575f80fd5b50600654600160c01b900463ffffffff166103c2565b3480156106ac575f80fd5b506102ed6106bb366004612fd9565b6113ae565b3480156106cb575f80fd5b506102ed6106da366004613032565b611434565b3480156106ea575f80fd5b506102ed61162f565b3480156106fe575f80fd5b506102ed61070d3660046131cd565b6119dc565b34801561071d575f80fd5b506102ed61072c366004612fd9565b611b3d565b34801561073c575f80fd5b5061032861074b36600461323e565b6001600160a01b039182165f90815260026020908152604080832093909416825291909152205490565b348015610780575f80fd5b506102ed61078f366004613032565b611bc2565b34801561079f575f80fd5b506102ed6107ae366004613032565b611c47565b3480156107be575f80fd5b506102ed6107cd366004613032565b611c78565b3480156107dd575f80fd5b506107e6611cee565b604051610296919061326a565b5f6107ff338484611d65565b5060015b92915050565b610811611e88565b6103e88163ffffffff16106108615760405162461bcd60e51b81526020600482015260116024820152704e6f206c6f776572207468616e202e312560781b60448201526064015b60405180910390fd5b6007805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b61088f611e88565b6127108163ffffffff16106108db5760405162461bcd60e51b81526020600482015260126024820152714e6f206c6f776572207468616e202e30312560701b6044820152606401610858565b6007805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b610909611e88565b600a8163ffffffff161061095f5760405162461bcd60e51b815260206004820152601760248201527f4d6178696d756d2064697669736f72206f66203130252e0000000000000000006044820152606401610858565b6008805463ffffffff909216600160e01b026001600160e01b03909216919091179055565b5f610990848484611ee1565b6109f184336109ec85604051806060016040528060288152602001613603602891396001600160a01b038a165f90815260026020526040812090335b6001600160a01b0316815260208101919091526040015f205491906122a8565b611d65565b5060019392505050565b610a03611e88565b6008805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b6007545f906001600160a01b0316336001600160a01b031614610a5e5760405162461bcd60e51b8152600401610858906132c7565b60405163095ea7b360e01b81526001600160a01b0384811660048301526024820184905285919082169063095ea7b3906044015b6020604051808303815f875af1158015610aae573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad2919061330a565b95945050505050565b5f610ae46122d3565b905090565b6007546001600160a01b0316336001600160a01b031614610b1c5760405162461bcd60e51b8152600401610858906132c7565b610b25816123f9565b50565b610b30611e88565b600580546001810182555f9190915281907f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db001610b6d8282613325565b506001905060045f610b826020850185613032565b6001600160a01b0316815260208082019290925260409081015f20805460ff191693151593909317909255610bbb918301908301612fd9565b60088054601890610bda908490600160c01b900463ffffffff16613395565b92506101000a81548163ffffffff021916908363ffffffff16021790555050565b6007545f906001600160a01b0316336001600160a01b031614610c305760405162461bcd60e51b8152600401610858906132c7565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820184905285919082169063a9059cbb90604401610a92565b610c70611e88565b6001600160a01b03919091165f908152600460205260409020805460ff1916911515919091179055565b610ca2611e88565b600780546001600160f81b0316600160f81b179055565b610cc1611e88565b610cca5f61263d565b565b828114610d1b5760405162461bcd60e51b815260206004820152601b60248201527f4d756c746973656e643a204c656e677468206d69736d617463682e00000000006044820152606401610858565b5f805b84811015610e3757610d4833858584818110610d3c57610d3c6133b9565b9050602002013561268c565b610d90868683818110610d5d57610d5d6133b9565b9050602002016020810190610d729190613032565b858584818110610d8457610d846133b9565b905060200201356126ce565b858582818110610da257610da26133b9565b9050602002016020810190610db79190613032565b6001600160a01b0316335f8051602061362b833981519152868685818110610de157610de16133b9565b90506020020135604051610df791815260200190565b60405180910390a3838382818110610e1157610e116133b9565b9050602002013582610e2391906133cd565b915080610e2f816133e0565b915050610d1e565b50610e94863360408051808201825260208082527f4d756c746973656e643a204e6f7420656e6f75676820616c6c6f77616e63652e818301526001600160a01b038c165f90815260029091529182206109ec9287929190336109cc565b505050505050565b6007546001600160a01b0316336001600160a01b031614610ecf5760405162461bcd60e51b8152600401610858906132c7565b47610ed9826123f9565b5f610ee482476133f8565b600754909150610efd906001600160a01b0316826126f1565b505050565b6001600160a01b0381165f90815260036020526040812054610803565b5f600960089054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f95919061340b565b6001600160a01b031663e6a4390530600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ff5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611019919061340b565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611062573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ae4919061340b565b6007546001600160a01b0316336001600160a01b0316146110b95760405162461bcd60e51b8152600401610858906132c7565b5f600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561110b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061112f919061340b565b90505f600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611183573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111a7919061340b565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038316906370a0823190602401602060405180830381865afa1580156111ee573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112129190613426565b604051632e1a7d4d60e01b8152600481018290529091506001600160a01b03841690632e1a7d4d906024015f604051808303815f87803b158015611254575f80fd5b505af1158015611266573d5f803e3d5ffd5b50505050505050565b5f6107ff338484611ee1565b8281146112ca5760405162461bcd60e51b815260206004820152601c60248201527f4d75796c746973656e643a204c656e677468206d69736d617463682e000000006044820152606401610858565b5f5b838110156113a7576112ea33848484818110610d3c57610d3c6133b9565b6113268585838181106112ff576112ff6133b9565b90506020020160208101906113149190613032565b848484818110610d8457610d846133b9565b848482818110611338576113386133b9565b905060200201602081019061134d9190613032565b6001600160a01b0316335f8051602061362b833981519152858585818110611377576113776133b9565b9050602002013560405161138d91815260200190565b60405180910390a38061139f816133e0565b9150506112cc565b5050505050565b6113b6611e88565b614e208163ffffffff16111561140e5760405162461bcd60e51b815260206004820152601860248201527f4d6178696d756d2073656c6c20746178206f66203130252e00000000000000006044820152606401610858565b6006805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b61143c611e88565b6001600160a01b0381165f908152600460205260408120805460ff19169055805b60055481101561156f57826001600160a01b031660058281548110611484576114846133b9565b5f918252602090912001546001600160a01b03160361155d57600580546114ad906001906133f8565b815481106114bd576114bd6133b9565b905f5260205f2001600582815481106114d8576114d86133b9565b5f91825260209091208254910180546001600160a01b039092166001600160a01b031983168117825592546001600160c01b0319909216909217600160a01b9182900463ffffffff1690910217905560058054806115385761153861343d565b5f8281526020902081015f1990810180546001600160c01b0319169055019055600191505b80611567816133e0565b91505061145d565b50806115b05760405162461bcd60e51b815260206004820152601060248201526f2737ba1034b7103a30bc103634b9ba1760811b6044820152606401610858565b5f805b60055481101561160657600581815481106115d0576115d06133b9565b5f918252602090912001546115f290600160a01b900463ffffffff1683613395565b9150806115fe816133e0565b9150506115b3565b506008805463ffffffff909216600160c01b0263ffffffff60c01b199092169190911790555050565b611637611e88565b600754600160e01b900460ff16156116a15760405162461bcd60e51b815260206004820152602760248201527f43616e2774206f70656e2074726164696e672074686174277320616c726561646044820152663c9037b832b71760c91b6064820152608401610858565b6009805468010000000000000000600160e01b0319167b7a250d5630b4cf539739df2c5dacb4c659f2488d00000000000000001790819055737a250d5630b4cf539739df2c5dacb4c659f2488d906117189030906001600160a01b03600160401b909104166b204fce5e3e25026110000000611d65565b5f816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611755573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611779919061340b565b6001600160a01b031663c9c6539630846001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117e8919061340b565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303815f875af1158015611832573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611856919061340b565b600954305f81815260016020526040902054929350600160401b9091046001600160a01b03169163f305d7199147915f806118985f546001600160a01b031690565b60405160e088901b6001600160e01b03191681526001600160a01b03958616600482015260248101949094526044840192909252606483015290911660848201524260a482015260c40160606040518083038185885af11580156118fe573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906119239190613451565b50506007805462ff00ff60e01b19166201000160e01b17905550604080516080810182525f80825260208083018281528385018381526001606086019081526001600160a01b039790971684526004909252939091209151825493519151945164ffffffffff1990941690151564ffffffff0019161761010063ffffffff928316021769ffffffffff0000000000191665010000000000919094160260ff60481b191692909217600160481b9115159190910217905550565b83421115611a2c5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610858565b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888611a5a8c612806565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090505f611ab48261282d565b90505f611ac382878787612859565b9050896001600160a01b0316816001600160a01b031614611b265760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610858565b611b318a8a8a611d65565b50505050505050505050565b611b45611e88565b614e208163ffffffff161115611b9d5760405162461bcd60e51b815260206004820152601760248201527f4d6178696d756d2062757920746178206f66203130252e0000000000000000006044820152606401610858565b6006805463ffffffff909216600160e01b026001600160e01b03909216919091179055565b6008546001600160a01b0316336001600160a01b031614611c255760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c7920646576656c6f7065722063616e2073657420746869732e000000006044820152606401610858565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b611c4f611e88565b6001600160a01b03165f908152600460205260409020805460ff60481b1916600160481b179055565b611c80611e88565b6001600160a01b038116611ce55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610858565b610b258161263d565b60606005805480602002602001604051908101604052809291908181526020015f905b82821015611d5c575f84815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff1681830152825260019092019101611d11565b50505050905090565b6001600160a01b038316611dc75760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610858565b6001600160a01b038216611e285760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610858565b6001600160a01b038381165f8181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f546001600160a01b03163314610cca5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610858565b6001600160a01b038316611f455760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610858565b6001600160a01b038216611fa75760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610858565b5f81116120085760405162461bcd60e51b815260206004820152602960248201527f5472616e7366657220616d6f756e74206d7573742062652067726561746572206044820152687468616e207a65726f60b81b6064820152608401610858565b5f8061201b5f546001600160a01b031690565b6001600160a01b0316856001600160a01b03161415801561204957505f546001600160a01b03858116911614155b801561205e57506001600160a01b0385163014155b801561208257506001600160a01b0384165f9081526004602052604090205460ff16155b80156120a657506001600160a01b0385165f9081526004602052604090205460ff16155b15612297576007546120d190600160a01b900463ffffffff166b204fce5e3e2502611000000061347c565b8311156121135760405162461bcd60e51b815260206004820152601060248201526f26b0bc103a3c1032bc31b2b2b232b21760811b6044820152606401610858565b6001600160a01b0385165f90815260046020526040902054600160481b900460ff16801561215657506009546001600160a01b03858116600160401b9092041614155b1561220d5760065460075463ffffffff600160e01b9092048216935061219191600160c01b909104166b204fce5e3e2502611000000061347c565b836121b0866001600160a01b03165f9081526001602052604090205490565b6121ba91906133cd565b11156122085760405162461bcd60e51b815260206004820152601c60248201527f4d61782077616c6c65742077696c6c2062652065786365656465642e000000006044820152606401610858565b61229b565b6001600160a01b0384165f90815260046020526040902054600160481b900460ff16801561225057506009546001600160a01b03868116600160401b9092041614155b1561226e575050600654600160c01b900463ffffffff16600161229b565b6007545f925061219190600160c01b900463ffffffff166b204fce5e3e2502611000000061347c565b5f91505b6113a7858585858561287f565b5f81848411156122cb5760405162461bcd60e51b81526004016108589190612f3f565b505050900390565b5f306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561232b57507f000000000000000000000000000000000000000000000000000000000000000046145b1561235557507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60408051600280825260608201835283925f92919060208301908036833701905050905082815f81518110612430576124306133b9565b60200260200101906001600160a01b031690816001600160a01b031681525050600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124c5919061340b565b816001815181106124d8576124d86133b9565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b81523060048201525f918416906370a0823190602401602060405180830381865afa15801561252a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061254e9190613426565b60095460405163095ea7b360e01b81526001600160a01b03600160401b909204821660048201526024810183905291925084169063095ea7b3906044016020604051808303815f875af11580156125a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125cb919061330a565b5060095460405163791ac94760e01b8152600160401b9091046001600160a01b03169063791ac9479061260a9084905f908790309042906004016134af565b5f604051808303815f87803b158015612621575f80fd5b505af1158015612633573d5f803e3d5ffd5b5050505050505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382165f908152600160205260409020546126af9082906133f8565b6001600160a01b039092165f9081526001602052604090209190915550565b6001600160a01b0382165f908152600160205260409020546126af9082906133cd565b804710156127415760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610858565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f811461278a576040519150601f19603f3d011682016040523d82523d5f602084013e61278f565b606091505b5050905080610efd5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610858565b6001600160a01b0381165f9081526003602052604090208054600181018255905b50919050565b5f6108036128396122d3565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f61286887878787612a46565b9150915061287581612b03565b5095945050505050565b8263ffffffff8316156128de575f6128978585612c4c565b90506128a381866133f8565b91506128af30826126ce565b60405181815230906001600160a01b038916905f8051602061362b8339815191529060200160405180910390a3505b81156129ac57856001600160a01b03167fae92ab4b6f8f401ead768d3273e6bb937a13e39827d19c6376e8fd4512a05d9a8560405161291f91815260200190565b60405180910390a2305f9081526001602052604090205480156129a65760085461296290600160e01b900463ffffffff166b204fce5e3e2502611000000061347c565b81111561299d576008546129989061299390600160e01b900463ffffffff166b204fce5e3e2502611000000061347c565b612c72565b6129a6565b6129a681612c72565b506129f0565b846001600160a01b03167fc55650ccda1011e1cdc769b1fbf546ebb8c97800b6072b49e06cd560305b1d67856040516129e791815260200190565b60405180910390a25b6129fa868561268c565b612a0485826126ce565b846001600160a01b0316866001600160a01b03165f8051602061362b83398151915283604051612a3691815260200190565b60405180910390a3505050505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612a7b57505f90506003612afa565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612acc573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b038116612af4575f60019250925050612afa565b91505f90505b94509492505050565b5f816004811115612b1657612b1661351e565b03612b1e5750565b6001816004811115612b3257612b3261351e565b03612b7f5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610858565b6002816004811115612b9357612b9361351e565b03612be05760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610858565b6003816004811115612bf457612bf461351e565b03610b255760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610858565b5f620186a0612c6163ffffffff841685613532565b612c6b919061347c565b9392505050565b60095467ffffffffffffffff164314610b25576009805467ffffffffffffffff19164367ffffffffffffffff161790556007805460ff60e81b1916600160e81b179055305f908152600260209081526040808320600954600160401b90046001600160a01b03168452909152902054811115612d1357600954612d13903090600160401b90046001600160a01b03166b204fce5e3e25026110000000611d65565b6040805160028082526060820183525f9260208301908036833701905050905030815f81518110612d4657612d466133b9565b60200260200101906001600160a01b031690816001600160a01b031681525050600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612db7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ddb919061340b565b81600181518110612dee57612dee6133b9565b6001600160a01b0392831660209182029290920101526009546040516318cbafe560e01b8152600160401b909104909116906318cbafe590612e3c9085905f908690309042906004016134af565b5f604051808303815f875af1158015612e57573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612e7e9190810190613549565b50612e8847612e99565b50506007805460ff60e81b19169055565b5f5b600554811015612f3b57612f2960058281548110612ebb57612ebb6133b9565b5f91825260209091200154600854600580546001600160a01b0390931692600160c01b90920463ffffffff169185908110612ef857612ef86133b9565b5f91825260209091200154612f1a90600160a01b900463ffffffff1686613532565b612f24919061347c565b6126f1565b80612f33816133e0565b915050612e9b565b5050565b5f6020808352835180828501525f5b81811015612f6a57858101830151858201604001528201612f4e565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610b25575f80fd5b5f8060408385031215612faf575f80fd5b8235612fba81612f8a565b946020939093013593505050565b63ffffffff81168114610b25575f80fd5b5f60208284031215612fe9575f80fd5b8135612c6b81612fc8565b5f805f60608486031215613006575f80fd5b833561301181612f8a565b9250602084013561302181612f8a565b929592945050506040919091013590565b5f60208284031215613042575f80fd5b8135612c6b81612f8a565b5f60408284031215612827575f80fd5b8015158114610b25575f80fd5b5f806040838503121561307b575f80fd5b823561308681612f8a565b915060208301356130968161305d565b809150509250929050565b5f8083601f8401126130b1575f80fd5b50813567ffffffffffffffff8111156130c8575f80fd5b6020830191508360208260051b85010111156130e2575f80fd5b9250929050565b5f805f805f606086880312156130fd575f80fd5b853561310881612f8a565b9450602086013567ffffffffffffffff80821115613124575f80fd5b61313089838a016130a1565b90965094506040880135915080821115613148575f80fd5b50613155888289016130a1565b969995985093965092949392505050565b5f805f8060408587031215613179575f80fd5b843567ffffffffffffffff80821115613190575f80fd5b61319c888389016130a1565b909650945060208701359150808211156131b4575f80fd5b506131c1878288016130a1565b95989497509550505050565b5f805f805f805f60e0888a0312156131e3575f80fd5b87356131ee81612f8a565b965060208801356131fe81612f8a565b95506040880135945060608801359350608088013560ff81168114613221575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f806040838503121561324f575f80fd5b823561325a81612f8a565b9150602083013561309681612f8a565b602080825282518282018190525f919060409081850190868401855b828110156132ba57815180516001600160a01b0316855286015163ffffffff16868501529284019290850190600101613286565b5091979650505050505050565b60208082526023908201527f43616c6c6572206973206e6f742074686520455243323020636f6e74726f6c6c60408201526232b91760e91b606082015260800190565b5f6020828403121561331a575f80fd5b8151612c6b8161305d565b813561333081612f8a565b81546001600160a01b031981166001600160a01b03929092169182178355602084013561335c81612fc8565b6001600160c01b03199190911690911760a09190911b63ffffffff60a01b1617905550565b634e487b7160e01b5f52601160045260245ffd5b63ffffffff8181168382160190808211156133b2576133b2613381565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b8082018082111561080357610803613381565b5f600182016133f1576133f1613381565b5060010190565b8181038181111561080357610803613381565b5f6020828403121561341b575f80fd5b8151612c6b81612f8a565b5f60208284031215613436575f80fd5b5051919050565b634e487b7160e01b5f52603160045260245ffd5b5f805f60608486031215613463575f80fd5b8351925060208401519150604084015190509250925092565b5f8261349657634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52604160045260245ffd5b5f60a082018783526020878185015260a0604085015281875180845260c08601915082890193505f5b818110156134fd5784516001600160a01b0316835293830193918301916001016134d8565b50506001600160a01b03969096166060850152505050608001529392505050565b634e487b7160e01b5f52602160045260245ffd5b808202811582820484141761080357610803613381565b5f602080838503121561355a575f80fd5b825167ffffffffffffffff80821115613571575f80fd5b818501915085601f830112613584575f80fd5b8151818111156135965761359661349b565b8060051b604051601f19603f830116810181811085821117156135bb576135bb61349b565b6040529182528482019250838101850191888311156135d8575f80fd5b938501935b828510156135f6578451845293850193928501926135dd565b9897505050505050505056fe45524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220ce0fc9ae76f422d593044443683c646b77aa17d04b8765d219d4539e7831e9b664736f6c63430008140033000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e885000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e8850000000000000000000000000000000000000000000000000000000000004a380000000000000000000000000000000000000000000000000000000000004e2000000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e88500000000000000000000000000000000000000000000000000000000000003e8

Deployed Bytecode

0x608060405260043610610257575f3560e01c8063715018a61161013f578063b0bc85de116100b3578063db932ae211610078578063db932ae214610712578063dd62ed3e14610731578063e0195f0714610775578063e9cb414f14610794578063f2fde38b146107b3578063fb61e998146107d2575f80fd5b8063b0bc85de14610680578063bb1789d6146106a1578063c8ce7be1146106c0578063c9567bf9146106df578063d505accf146106f3575f80fd5b806386f3f3cb1161010457806386f3f3cb146105fe57806388a65f46146106125780638da5cb5b1461062657806395d89b4114610262578063a9059cbb14610642578063aad41a4114610661575f80fd5b8063715018a61461055e57806373ae740e146105725780637a52da0e146105915780637ecebe00146105b057806385551b55146105cf575f80fd5b8063313ce567116101d65780634ff99fcf1161019b5780634ff99fcf146104825780635342acb4146104a1578063571cbe0a146104d85780636612e66f146104f757806370a082311461051657806370bfdd9d1461054a575f80fd5b8063313ce567146103f6578063333429471461041157806333a17282146104305780633644e5151461044f578063473071ce14610463575f80fd5b806320d5bf371161021c57806320d5bf3714610336578063232b10441461036757806323b872dd14610386578063252d723a146103a55780632c1f5216146103d7575f80fd5b806306fdde0314610262578063095ea7b31461029f5780630ecf68e0146102ce57806317f5a80b146102ef57806318160ddd1461030e575f80fd5b3661025e57005b5f80fd5b34801561026d575f80fd5b506040805180820190915260038152624f564f60e81b60208201525b6040516102969190612f3f565b60405180910390f35b3480156102aa575f80fd5b506102be6102b9366004612f9e565b6107f3565b6040519015158152602001610296565b3480156102d9575f80fd5b506102ed6102e8366004612fd9565b610809565b005b3480156102fa575f80fd5b506102ed610309366004612fd9565b610887565b348015610319575f80fd5b506b204fce5e3e250261100000005b604051908152602001610296565b348015610341575f80fd5b506007546001600160a01b03165b6040516001600160a01b039091168152602001610296565b348015610372575f80fd5b506102ed610381366004612fd9565b610901565b348015610391575f80fd5b506102be6103a0366004612ff4565b610984565b3480156103b0575f80fd5b50600654600160e01b900463ffffffff165b60405163ffffffff9091168152602001610296565b3480156103e2575f80fd5b5060065461034f906001600160a01b031681565b348015610401575f80fd5b5060405160128152602001610296565b34801561041c575f80fd5b506102ed61042b366004612fd9565b6109fb565b34801561043b575f80fd5b506102be61044a366004612ff4565b610a29565b34801561045a575f80fd5b50610328610adb565b34801561046e575f80fd5b506102ed61047d366004613032565b610ae9565b34801561048d575f80fd5b506102ed61049c36600461304d565b610b28565b3480156104ac575f80fd5b506102be6104bb366004613032565b6001600160a01b03165f9081526004602052604090205460ff1690565b3480156104e3575f80fd5b506102be6104f2366004612ff4565b610bfb565b348015610502575f80fd5b506102ed61051136600461306a565b610c68565b348015610521575f80fd5b50610328610530366004613032565b6001600160a01b03165f9081526001602052604090205490565b348015610555575f80fd5b506102ed610c9a565b348015610569575f80fd5b506102ed610cb9565b34801561057d575f80fd5b506102ed61058c3660046130e9565b610ccc565b34801561059c575f80fd5b506102ed6105ab366004613032565b610e9c565b3480156105bb575f80fd5b506103286105ca366004613032565b610f02565b3480156105da575f80fd5b5060408051808201909152600781526627ab27a1b7b4b760c91b6020820152610289565b348015610609575f80fd5b5061034f610f1f565b34801561061d575f80fd5b506102ed611086565b348015610631575f80fd5b505f546001600160a01b031661034f565b34801561064d575f80fd5b506102be61065c366004612f9e565b61126f565b34801561066c575f80fd5b506102ed61067b366004613166565b61127b565b34801561068b575f80fd5b50600654600160c01b900463ffffffff166103c2565b3480156106ac575f80fd5b506102ed6106bb366004612fd9565b6113ae565b3480156106cb575f80fd5b506102ed6106da366004613032565b611434565b3480156106ea575f80fd5b506102ed61162f565b3480156106fe575f80fd5b506102ed61070d3660046131cd565b6119dc565b34801561071d575f80fd5b506102ed61072c366004612fd9565b611b3d565b34801561073c575f80fd5b5061032861074b36600461323e565b6001600160a01b039182165f90815260026020908152604080832093909416825291909152205490565b348015610780575f80fd5b506102ed61078f366004613032565b611bc2565b34801561079f575f80fd5b506102ed6107ae366004613032565b611c47565b3480156107be575f80fd5b506102ed6107cd366004613032565b611c78565b3480156107dd575f80fd5b506107e6611cee565b604051610296919061326a565b5f6107ff338484611d65565b5060015b92915050565b610811611e88565b6103e88163ffffffff16106108615760405162461bcd60e51b81526020600482015260116024820152704e6f206c6f776572207468616e202e312560781b60448201526064015b60405180910390fd5b6007805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b61088f611e88565b6127108163ffffffff16106108db5760405162461bcd60e51b81526020600482015260126024820152714e6f206c6f776572207468616e202e30312560701b6044820152606401610858565b6007805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b610909611e88565b600a8163ffffffff161061095f5760405162461bcd60e51b815260206004820152601760248201527f4d6178696d756d2064697669736f72206f66203130252e0000000000000000006044820152606401610858565b6008805463ffffffff909216600160e01b026001600160e01b03909216919091179055565b5f610990848484611ee1565b6109f184336109ec85604051806060016040528060288152602001613603602891396001600160a01b038a165f90815260026020526040812090335b6001600160a01b0316815260208101919091526040015f205491906122a8565b611d65565b5060019392505050565b610a03611e88565b6008805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b6007545f906001600160a01b0316336001600160a01b031614610a5e5760405162461bcd60e51b8152600401610858906132c7565b60405163095ea7b360e01b81526001600160a01b0384811660048301526024820184905285919082169063095ea7b3906044015b6020604051808303815f875af1158015610aae573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad2919061330a565b95945050505050565b5f610ae46122d3565b905090565b6007546001600160a01b0316336001600160a01b031614610b1c5760405162461bcd60e51b8152600401610858906132c7565b610b25816123f9565b50565b610b30611e88565b600580546001810182555f9190915281907f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db001610b6d8282613325565b506001905060045f610b826020850185613032565b6001600160a01b0316815260208082019290925260409081015f20805460ff191693151593909317909255610bbb918301908301612fd9565b60088054601890610bda908490600160c01b900463ffffffff16613395565b92506101000a81548163ffffffff021916908363ffffffff16021790555050565b6007545f906001600160a01b0316336001600160a01b031614610c305760405162461bcd60e51b8152600401610858906132c7565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820184905285919082169063a9059cbb90604401610a92565b610c70611e88565b6001600160a01b03919091165f908152600460205260409020805460ff1916911515919091179055565b610ca2611e88565b600780546001600160f81b0316600160f81b179055565b610cc1611e88565b610cca5f61263d565b565b828114610d1b5760405162461bcd60e51b815260206004820152601b60248201527f4d756c746973656e643a204c656e677468206d69736d617463682e00000000006044820152606401610858565b5f805b84811015610e3757610d4833858584818110610d3c57610d3c6133b9565b9050602002013561268c565b610d90868683818110610d5d57610d5d6133b9565b9050602002016020810190610d729190613032565b858584818110610d8457610d846133b9565b905060200201356126ce565b858582818110610da257610da26133b9565b9050602002016020810190610db79190613032565b6001600160a01b0316335f8051602061362b833981519152868685818110610de157610de16133b9565b90506020020135604051610df791815260200190565b60405180910390a3838382818110610e1157610e116133b9565b9050602002013582610e2391906133cd565b915080610e2f816133e0565b915050610d1e565b50610e94863360408051808201825260208082527f4d756c746973656e643a204e6f7420656e6f75676820616c6c6f77616e63652e818301526001600160a01b038c165f90815260029091529182206109ec9287929190336109cc565b505050505050565b6007546001600160a01b0316336001600160a01b031614610ecf5760405162461bcd60e51b8152600401610858906132c7565b47610ed9826123f9565b5f610ee482476133f8565b600754909150610efd906001600160a01b0316826126f1565b505050565b6001600160a01b0381165f90815260036020526040812054610803565b5f600960089054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f95919061340b565b6001600160a01b031663e6a4390530600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ff5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611019919061340b565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611062573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ae4919061340b565b6007546001600160a01b0316336001600160a01b0316146110b95760405162461bcd60e51b8152600401610858906132c7565b5f600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561110b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061112f919061340b565b90505f600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611183573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111a7919061340b565b6040516370a0823160e01b81523060048201529091505f906001600160a01b038316906370a0823190602401602060405180830381865afa1580156111ee573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112129190613426565b604051632e1a7d4d60e01b8152600481018290529091506001600160a01b03841690632e1a7d4d906024015f604051808303815f87803b158015611254575f80fd5b505af1158015611266573d5f803e3d5ffd5b50505050505050565b5f6107ff338484611ee1565b8281146112ca5760405162461bcd60e51b815260206004820152601c60248201527f4d75796c746973656e643a204c656e677468206d69736d617463682e000000006044820152606401610858565b5f5b838110156113a7576112ea33848484818110610d3c57610d3c6133b9565b6113268585838181106112ff576112ff6133b9565b90506020020160208101906113149190613032565b848484818110610d8457610d846133b9565b848482818110611338576113386133b9565b905060200201602081019061134d9190613032565b6001600160a01b0316335f8051602061362b833981519152858585818110611377576113776133b9565b9050602002013560405161138d91815260200190565b60405180910390a38061139f816133e0565b9150506112cc565b5050505050565b6113b6611e88565b614e208163ffffffff16111561140e5760405162461bcd60e51b815260206004820152601860248201527f4d6178696d756d2073656c6c20746178206f66203130252e00000000000000006044820152606401610858565b6006805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b61143c611e88565b6001600160a01b0381165f908152600460205260408120805460ff19169055805b60055481101561156f57826001600160a01b031660058281548110611484576114846133b9565b5f918252602090912001546001600160a01b03160361155d57600580546114ad906001906133f8565b815481106114bd576114bd6133b9565b905f5260205f2001600582815481106114d8576114d86133b9565b5f91825260209091208254910180546001600160a01b039092166001600160a01b031983168117825592546001600160c01b0319909216909217600160a01b9182900463ffffffff1690910217905560058054806115385761153861343d565b5f8281526020902081015f1990810180546001600160c01b0319169055019055600191505b80611567816133e0565b91505061145d565b50806115b05760405162461bcd60e51b815260206004820152601060248201526f2737ba1034b7103a30bc103634b9ba1760811b6044820152606401610858565b5f805b60055481101561160657600581815481106115d0576115d06133b9565b5f918252602090912001546115f290600160a01b900463ffffffff1683613395565b9150806115fe816133e0565b9150506115b3565b506008805463ffffffff909216600160c01b0263ffffffff60c01b199092169190911790555050565b611637611e88565b600754600160e01b900460ff16156116a15760405162461bcd60e51b815260206004820152602760248201527f43616e2774206f70656e2074726164696e672074686174277320616c726561646044820152663c9037b832b71760c91b6064820152608401610858565b6009805468010000000000000000600160e01b0319167b7a250d5630b4cf539739df2c5dacb4c659f2488d00000000000000001790819055737a250d5630b4cf539739df2c5dacb4c659f2488d906117189030906001600160a01b03600160401b909104166b204fce5e3e25026110000000611d65565b5f816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611755573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611779919061340b565b6001600160a01b031663c9c6539630846001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117e8919061340b565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303815f875af1158015611832573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611856919061340b565b600954305f81815260016020526040902054929350600160401b9091046001600160a01b03169163f305d7199147915f806118985f546001600160a01b031690565b60405160e088901b6001600160e01b03191681526001600160a01b03958616600482015260248101949094526044840192909252606483015290911660848201524260a482015260c40160606040518083038185885af11580156118fe573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906119239190613451565b50506007805462ff00ff60e01b19166201000160e01b17905550604080516080810182525f80825260208083018281528385018381526001606086019081526001600160a01b039790971684526004909252939091209151825493519151945164ffffffffff1990941690151564ffffffff0019161761010063ffffffff928316021769ffffffffff0000000000191665010000000000919094160260ff60481b191692909217600160481b9115159190910217905550565b83421115611a2c5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610858565b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888611a5a8c612806565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090505f611ab48261282d565b90505f611ac382878787612859565b9050896001600160a01b0316816001600160a01b031614611b265760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610858565b611b318a8a8a611d65565b50505050505050505050565b611b45611e88565b614e208163ffffffff161115611b9d5760405162461bcd60e51b815260206004820152601760248201527f4d6178696d756d2062757920746178206f66203130252e0000000000000000006044820152606401610858565b6006805463ffffffff909216600160e01b026001600160e01b03909216919091179055565b6008546001600160a01b0316336001600160a01b031614611c255760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c7920646576656c6f7065722063616e2073657420746869732e000000006044820152606401610858565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b611c4f611e88565b6001600160a01b03165f908152600460205260409020805460ff60481b1916600160481b179055565b611c80611e88565b6001600160a01b038116611ce55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610858565b610b258161263d565b60606005805480602002602001604051908101604052809291908181526020015f905b82821015611d5c575f84815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff1681830152825260019092019101611d11565b50505050905090565b6001600160a01b038316611dc75760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610858565b6001600160a01b038216611e285760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610858565b6001600160a01b038381165f8181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f546001600160a01b03163314610cca5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610858565b6001600160a01b038316611f455760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610858565b6001600160a01b038216611fa75760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610858565b5f81116120085760405162461bcd60e51b815260206004820152602960248201527f5472616e7366657220616d6f756e74206d7573742062652067726561746572206044820152687468616e207a65726f60b81b6064820152608401610858565b5f8061201b5f546001600160a01b031690565b6001600160a01b0316856001600160a01b03161415801561204957505f546001600160a01b03858116911614155b801561205e57506001600160a01b0385163014155b801561208257506001600160a01b0384165f9081526004602052604090205460ff16155b80156120a657506001600160a01b0385165f9081526004602052604090205460ff16155b15612297576007546120d190600160a01b900463ffffffff166b204fce5e3e2502611000000061347c565b8311156121135760405162461bcd60e51b815260206004820152601060248201526f26b0bc103a3c1032bc31b2b2b232b21760811b6044820152606401610858565b6001600160a01b0385165f90815260046020526040902054600160481b900460ff16801561215657506009546001600160a01b03858116600160401b9092041614155b1561220d5760065460075463ffffffff600160e01b9092048216935061219191600160c01b909104166b204fce5e3e2502611000000061347c565b836121b0866001600160a01b03165f9081526001602052604090205490565b6121ba91906133cd565b11156122085760405162461bcd60e51b815260206004820152601c60248201527f4d61782077616c6c65742077696c6c2062652065786365656465642e000000006044820152606401610858565b61229b565b6001600160a01b0384165f90815260046020526040902054600160481b900460ff16801561225057506009546001600160a01b03868116600160401b9092041614155b1561226e575050600654600160c01b900463ffffffff16600161229b565b6007545f925061219190600160c01b900463ffffffff166b204fce5e3e2502611000000061347c565b5f91505b6113a7858585858561287f565b5f81848411156122cb5760405162461bcd60e51b81526004016108589190612f3f565b505050900390565b5f306001600160a01b037f0000000000000000000000004202d08196a11326c4d8a2e4ffc0e12a432009861614801561232b57507f000000000000000000000000000000000000000000000000000000000000000146145b1561235557507f0166320328fc422a19453f5f2350f3d1779ab14e3140a619233adb5041b4228b90565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527fd52bdd72ad4fc83e779cb4082c9733760efccd840aae8fc5afb00c6b8a55386d828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60408051600280825260608201835283925f92919060208301908036833701905050905082815f81518110612430576124306133b9565b60200260200101906001600160a01b031690816001600160a01b031681525050600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124c5919061340b565b816001815181106124d8576124d86133b9565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b81523060048201525f918416906370a0823190602401602060405180830381865afa15801561252a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061254e9190613426565b60095460405163095ea7b360e01b81526001600160a01b03600160401b909204821660048201526024810183905291925084169063095ea7b3906044016020604051808303815f875af11580156125a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125cb919061330a565b5060095460405163791ac94760e01b8152600160401b9091046001600160a01b03169063791ac9479061260a9084905f908790309042906004016134af565b5f604051808303815f87803b158015612621575f80fd5b505af1158015612633573d5f803e3d5ffd5b5050505050505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382165f908152600160205260409020546126af9082906133f8565b6001600160a01b039092165f9081526001602052604090209190915550565b6001600160a01b0382165f908152600160205260409020546126af9082906133cd565b804710156127415760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610858565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f811461278a576040519150601f19603f3d011682016040523d82523d5f602084013e61278f565b606091505b5050905080610efd5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610858565b6001600160a01b0381165f9081526003602052604090208054600181018255905b50919050565b5f6108036128396122d3565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f61286887878787612a46565b9150915061287581612b03565b5095945050505050565b8263ffffffff8316156128de575f6128978585612c4c565b90506128a381866133f8565b91506128af30826126ce565b60405181815230906001600160a01b038916905f8051602061362b8339815191529060200160405180910390a3505b81156129ac57856001600160a01b03167fae92ab4b6f8f401ead768d3273e6bb937a13e39827d19c6376e8fd4512a05d9a8560405161291f91815260200190565b60405180910390a2305f9081526001602052604090205480156129a65760085461296290600160e01b900463ffffffff166b204fce5e3e2502611000000061347c565b81111561299d576008546129989061299390600160e01b900463ffffffff166b204fce5e3e2502611000000061347c565b612c72565b6129a6565b6129a681612c72565b506129f0565b846001600160a01b03167fc55650ccda1011e1cdc769b1fbf546ebb8c97800b6072b49e06cd560305b1d67856040516129e791815260200190565b60405180910390a25b6129fa868561268c565b612a0485826126ce565b846001600160a01b0316866001600160a01b03165f8051602061362b83398151915283604051612a3691815260200190565b60405180910390a3505050505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612a7b57505f90506003612afa565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612acc573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b038116612af4575f60019250925050612afa565b91505f90505b94509492505050565b5f816004811115612b1657612b1661351e565b03612b1e5750565b6001816004811115612b3257612b3261351e565b03612b7f5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610858565b6002816004811115612b9357612b9361351e565b03612be05760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610858565b6003816004811115612bf457612bf461351e565b03610b255760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610858565b5f620186a0612c6163ffffffff841685613532565b612c6b919061347c565b9392505050565b60095467ffffffffffffffff164314610b25576009805467ffffffffffffffff19164367ffffffffffffffff161790556007805460ff60e81b1916600160e81b179055305f908152600260209081526040808320600954600160401b90046001600160a01b03168452909152902054811115612d1357600954612d13903090600160401b90046001600160a01b03166b204fce5e3e25026110000000611d65565b6040805160028082526060820183525f9260208301908036833701905050905030815f81518110612d4657612d466133b9565b60200260200101906001600160a01b031690816001600160a01b031681525050600960089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612db7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ddb919061340b565b81600181518110612dee57612dee6133b9565b6001600160a01b0392831660209182029290920101526009546040516318cbafe560e01b8152600160401b909104909116906318cbafe590612e3c9085905f908690309042906004016134af565b5f604051808303815f875af1158015612e57573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612e7e9190810190613549565b50612e8847612e99565b50506007805460ff60e81b19169055565b5f5b600554811015612f3b57612f2960058281548110612ebb57612ebb6133b9565b5f91825260209091200154600854600580546001600160a01b0390931692600160c01b90920463ffffffff169185908110612ef857612ef86133b9565b5f91825260209091200154612f1a90600160a01b900463ffffffff1686613532565b612f24919061347c565b6126f1565b80612f33816133e0565b915050612e9b565b5050565b5f6020808352835180828501525f5b81811015612f6a57858101830151858201604001528201612f4e565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610b25575f80fd5b5f8060408385031215612faf575f80fd5b8235612fba81612f8a565b946020939093013593505050565b63ffffffff81168114610b25575f80fd5b5f60208284031215612fe9575f80fd5b8135612c6b81612fc8565b5f805f60608486031215613006575f80fd5b833561301181612f8a565b9250602084013561302181612f8a565b929592945050506040919091013590565b5f60208284031215613042575f80fd5b8135612c6b81612f8a565b5f60408284031215612827575f80fd5b8015158114610b25575f80fd5b5f806040838503121561307b575f80fd5b823561308681612f8a565b915060208301356130968161305d565b809150509250929050565b5f8083601f8401126130b1575f80fd5b50813567ffffffffffffffff8111156130c8575f80fd5b6020830191508360208260051b85010111156130e2575f80fd5b9250929050565b5f805f805f606086880312156130fd575f80fd5b853561310881612f8a565b9450602086013567ffffffffffffffff80821115613124575f80fd5b61313089838a016130a1565b90965094506040880135915080821115613148575f80fd5b50613155888289016130a1565b969995985093965092949392505050565b5f805f8060408587031215613179575f80fd5b843567ffffffffffffffff80821115613190575f80fd5b61319c888389016130a1565b909650945060208701359150808211156131b4575f80fd5b506131c1878288016130a1565b95989497509550505050565b5f805f805f805f60e0888a0312156131e3575f80fd5b87356131ee81612f8a565b965060208801356131fe81612f8a565b95506040880135945060608801359350608088013560ff81168114613221575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f806040838503121561324f575f80fd5b823561325a81612f8a565b9150602083013561309681612f8a565b602080825282518282018190525f919060409081850190868401855b828110156132ba57815180516001600160a01b0316855286015163ffffffff16868501529284019290850190600101613286565b5091979650505050505050565b60208082526023908201527f43616c6c6572206973206e6f742074686520455243323020636f6e74726f6c6c60408201526232b91760e91b606082015260800190565b5f6020828403121561331a575f80fd5b8151612c6b8161305d565b813561333081612f8a565b81546001600160a01b031981166001600160a01b03929092169182178355602084013561335c81612fc8565b6001600160c01b03199190911690911760a09190911b63ffffffff60a01b1617905550565b634e487b7160e01b5f52601160045260245ffd5b63ffffffff8181168382160190808211156133b2576133b2613381565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b8082018082111561080357610803613381565b5f600182016133f1576133f1613381565b5060010190565b8181038181111561080357610803613381565b5f6020828403121561341b575f80fd5b8151612c6b81612f8a565b5f60208284031215613436575f80fd5b5051919050565b634e487b7160e01b5f52603160045260245ffd5b5f805f60608486031215613463575f80fd5b8351925060208401519150604084015190509250925092565b5f8261349657634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52604160045260245ffd5b5f60a082018783526020878185015260a0604085015281875180845260c08601915082890193505f5b818110156134fd5784516001600160a01b0316835293830193918301916001016134d8565b50506001600160a01b03969096166060850152505050608001529392505050565b634e487b7160e01b5f52602160045260245ffd5b808202811582820484141761080357610803613381565b5f602080838503121561355a575f80fd5b825167ffffffffffffffff80821115613571575f80fd5b818501915085601f830112613584575f80fd5b8151818111156135965761359661349b565b8060051b604051601f19603f830116810181811085821117156135bb576135bb61349b565b6040529182528482019250838101850191888311156135d8575f80fd5b938501935b828510156135f6578451845293850193928501926135dd565b9897505050505050505056fe45524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220ce0fc9ae76f422d593044443683c646b77aa17d04b8765d219d4539e7831e9b664736f6c63430008140033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e885000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e8850000000000000000000000000000000000000000000000000000000000004a380000000000000000000000000000000000000000000000000000000000004e2000000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e88500000000000000000000000000000000000000000000000000000000000003e8

-----Decoded View---------------
Arg [0] : controller (address): 0xFC40AbB31D165704106f5701Af2E68E73bD0E885
Arg [1] : dev (address): 0xFC40AbB31D165704106f5701Af2E68E73bD0E885
Arg [2] : id (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [3] : wallets (tuple[]): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e885
Arg [1] : 000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e885
Arg [2] : 0000000000000000000000000000000000000000000000000000000000004a38
Arg [3] : 0000000000000000000000000000000000000000000000000000000000004e20
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000032
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000032
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [9] : 000000000000000000000000fc40abb31d165704106f5701af2e68e73bd0e885
Arg [10] : 00000000000000000000000000000000000000000000000000000000000003e8


Deployed Bytecode Sourcemap

936:26777:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6111:83;;;;;;;;;;-1:-1:-1;6181:5:0;;;;;;;;;;;;-1:-1:-1;;;6181:5:0;;;;6111:83;;;;;;;:::i;:::-;;;;;;;;6997:186;;;;;;;;;;-1:-1:-1;6997:186:0;;;;;:::i;:::-;;:::i;:::-;;;1188:14:20;;1181:22;1163:41;;1151:2;1136:18;6997:186:0;1023:187:20;17880:154:0;;;;;;;;;;-1:-1:-1;17880:154:0;;;;;:::i;:::-;;:::i;:::-;;17724:148;;;;;;;;;;-1:-1:-1;17724:148:0;;;;;:::i;:::-;;:::i;6388:99::-;;;;;;;;;;-1:-1:-1;1379:29:0;6388:99;;;1737:25:20;;;1725:2;1710:18;6388:99:0;1591:177:20;25032:97:0;;;;;;;;;;-1:-1:-1;25110:11:0;;-1:-1:-1;;;;;25110:11:0;25032:97;;;-1:-1:-1;;;;;1937:32:20;;;1919:51;;1907:2;1892:18;25032:97:0;1773:203:20;17556:158:0;;;;;;;;;;-1:-1:-1;17556:158:0;;;;;:::i;:::-;;:::i;7191:448::-;;;;;;;;;;-1:-1:-1;7191:448:0;;;;;:::i;:::-;;:::i;25284:82::-;;;;;;;;;;-1:-1:-1;25352:6:0;;-1:-1:-1;;;25352:6:0;;;;25284:82;;;2616:10:20;2604:23;;;2586:42;;2574:2;2559:18;25284:82:0;2442:192:20;2852:30:0;;;;;;;;;;-1:-1:-1;2852:30:0;;;;-1:-1:-1;;;;;2852:30:0;;;6297:83;;;;;;;;;;-1:-1:-1;6297:83:0;;1331:2;2781:36:20;;2769:2;2754:18;6297:83:0;2639:184:20;14741:118:0;;;;;;;;;;-1:-1:-1;14741:118:0;;;;;:::i;:::-;;:::i;25448:273::-;;;;;;;;;;-1:-1:-1;25448:273:0;;;;;:::i;:::-;;:::i;24033:115::-;;;;;;;;;;;;;:::i;26112:112::-;;;;;;;;;;-1:-1:-1;26112:112:0;;;;;:::i;:::-;;:::i;14867:281::-;;;;;;;;;;-1:-1:-1;14867:281:0;;;;;:::i;:::-;;:::i;18151:140::-;;;;;;;;;;-1:-1:-1;18151:140:0;;;;;:::i;:::-;-1:-1:-1;;;;;18240:24:0;18216:4;18240:24;;;:15;:24;;;;;:43;;;;18151:140;25782:279;;;;;;;;;;-1:-1:-1;25782:279:0;;;;;:::i;:::-;;:::i;16917:179::-;;;;;;;;;;-1:-1:-1;16917:179:0;;;;;:::i;:::-;;:::i;6495:118::-;;;;;;;;;;-1:-1:-1;6495:118:0;;;;;:::i;:::-;-1:-1:-1;;;;;6588:17:0;6561:7;6588:17;;;:8;:17;;;;;;;6495:118;16638:97;;;;;;;;;;;;;:::i;1824:101:1:-;;;;;;;;;;;;;:::i;19321:1013:0:-;;;;;;;;;;-1:-1:-1;19321:1013:0;;;;;:::i;:::-;;:::i;26887:386::-;;;;;;;;;;-1:-1:-1;26887:386:0;;;;;:::i;:::-;;:::i;23759:144::-;;;;;;;;;;-1:-1:-1;23759:144:0;;;;;:::i;:::-;;:::i;27618:90::-;;;;;;;;;;-1:-1:-1;27684:16:0;;;;;;;;;;;;-1:-1:-1;;;27684:16:0;;;;27618:90;;24634:218;;;;;;;;;;;;;:::i;27345:265::-;;;;;;;;;;;;;:::i;1201:85:1:-;;;;;;;;;;-1:-1:-1;1247:7:1;1273:6;-1:-1:-1;;;;;1273:6:1;1201:85;;6621:192:0;;;;;;;;;;-1:-1:-1;6621:192:0;;;;;:::i;:::-;;:::i;18495:544::-;;;;;;;;;;-1:-1:-1;18495:544:0;;;;;:::i;:::-;;:::i;25192:84::-;;;;;;;;;;-1:-1:-1;25261:7:0;;-1:-1:-1;;;25261:7:0;;;;25192:84;;17239:152;;;;;;;;;;-1:-1:-1;17239:152:0;;;;;:::i;:::-;;:::i;15156:784::-;;;;;;;;;;-1:-1:-1;15156:784:0;;;;;:::i;:::-;;:::i;7704:1055::-;;;;;;;;;;;;;:::i;22909:784::-;;;;;;;;;;-1:-1:-1;22909:784:0;;;;;:::i;:::-;;:::i;17399:149::-;;;;;;;;;;-1:-1:-1;17399:149:0;;;;;:::i;:::-;;:::i;6821:168::-;;;;;;;;;;-1:-1:-1;6821:168:0;;;;;:::i;:::-;-1:-1:-1;;;;;6954:18:0;;;6927:7;6954:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;6821:168;16085:118;;;;;;;;;;-1:-1:-1;16085:118:0;;;;;:::i;:::-;;:::i;16341:111::-;;;;;;;;;;-1:-1:-1;16341:111:0;;;;;:::i;:::-;;:::i;2074:198:1:-;;;;;;;;;;-1:-1:-1;2074:198:1;;;;;:::i;:::-;;:::i;24860:102:0:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;6997:186::-;7097:4;7114:39;719:10:7;7137:7:0;7146:6;7114:8;:39::i;:::-;-1:-1:-1;7171:4:0;6997:186;;;;;:::o;17880:154::-;1094:13:1;:11;:13::i;:::-;17967:4:0::1;17959:5;:12;;;17951:42;;;::::0;-1:-1:-1;;;17951:42:0;;8301:2:20;17951:42:0::1;::::0;::::1;8283:21:20::0;8340:2;8320:18;;;8313:30;-1:-1:-1;;;8359:18:20;;;8352:47;8416:18;;17951:42:0::1;;;;;;;;;18004:14;:22:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;18004:22:0::1;-1:-1:-1::0;;;;18004:22:0;;::::1;::::0;;;::::1;::::0;;17880:154::o;17724:148::-;1094:13:1;:11;:13::i;:::-;17807:5:0::1;17799;:13;;;17791:44;;;::::0;-1:-1:-1;;;17791:44:0;;8647:2:20;17791:44:0::1;::::0;::::1;8629:21:20::0;8686:2;8666:18;;;8659:30;-1:-1:-1;;;8705:18:20;;;8698:48;8763:18;;17791:44:0::1;8445:342:20::0;17791:44:0::1;17846:10;:18:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;17846:18:0::1;-1:-1:-1::0;;;;17846:18:0;;::::1;::::0;;;::::1;::::0;;17724:148::o;17556:158::-;1094:13:1;:11;:13::i;:::-;17642:2:0::1;17633:6;:11;;;17625:47;;;::::0;-1:-1:-1;;;17625:47:0;;8994:2:20;17625:47:0::1;::::0;::::1;8976:21:20::0;9033:2;9013:18;;;9006:30;9072:25;9052:18;;;9045:53;9115:18;;17625:47:0::1;8792:347:20::0;17625:47:0::1;17683:14;:23:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;17683:23:0::1;-1:-1:-1::0;;;;;17683:23:0;;::::1;::::0;;;::::1;::::0;;17556:158::o;7191:448::-;7323:4;7340:36;7350:6;7358:9;7369:6;7340:9;:36::i;:::-;7389:220;7412:6;719:10:7;7460:138:0;7516:6;7460:138;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7460:19:0;;;;;;:11;:19;;;;;;719:10:7;7480:12:0;-1:-1:-1;;;;;7460:33:0;;;;;;;;;;;;-1:-1:-1;7460:33:0;;;:138;:37;:138::i;:::-;7389:8;:220::i;:::-;-1:-1:-1;7627:4:0;7191:448;;;;;:::o;14741:118::-;1094:13:1;:11;:13::i;:::-;14815:23:0::1;:36:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;14815:36:0::1;-1:-1:-1::0;;;;14815:36:0;;::::1;::::0;;;::::1;::::0;;14741:118::o;25448:273::-;3676:11;;25600:4;;-1:-1:-1;;;;;3676:11:0;719:10:7;-1:-1:-1;;;;;3660:27:0;;3638:112;;;;-1:-1:-1;;;3638:112:0;;;;;;;:::i;:::-;25677:36:::1;::::0;-1:-1:-1;;;25677:36:0;;-1:-1:-1;;;;;9740:32:20;;;25677:36:0::1;::::0;::::1;9722:51:20::0;9789:18;;;9782:34;;;25645:13:0;;25677:19;;::::1;::::0;::::1;::::0;9695:18:20;;25677:36:0::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25670:43:::0;25448:273;-1:-1:-1;;;;;25448:273:0:o;24033:115::-;24093:7;24120:20;:18;:20::i;:::-;24113:27;;24033:115;:::o;26112:112::-;3676:11;;-1:-1:-1;;;;;3676:11:0;719:10:7;-1:-1:-1;;;;;3660:27:0;;3638:112;;;;-1:-1:-1;;;3638:112:0;;;;;;;:::i;:::-;26196:20:::1;26202:13;26196:5;:20::i;:::-;26112:112:::0;:::o;14867:281::-;1094:13:1;:11;:13::i;:::-;14944:10:0::1;:21:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;14944:21:0;;;;14960:4;;14944:21;::::1;;14960:4:::0;14944:21;::::1;:::i;:::-;-1:-1:-1::0;15026:4:0::1;::::0;-1:-1:-1;14976:15:0::1;:28;14992:11;;::::0;::::1;:4:::0;:11:::1;:::i;:::-;-1:-1:-1::0;;;;;14976:28:0::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;-1:-1:-1;14976:28:0;:54;;-1:-1:-1;;14976:54:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;15130:10:::1;::::0;;;;;::::1;;:::i;:::-;15116;:24:::0;;:10:::1;::::0;:24:::1;::::0;;;-1:-1:-1;;;15116:24:0;::::1;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;14867:281:::0;:::o;25782:279::-;3676:11;;25937:4;;-1:-1:-1;;;;;3676:11:0;719:10:7;-1:-1:-1;;;;;3660:27:0;;3638:112;;;;-1:-1:-1;;;3638:112:0;;;;;;;:::i;:::-;26014:39:::1;::::0;-1:-1:-1;;;26014:39:0;;-1:-1:-1;;;;;9740:32:20;;;26014:39:0::1;::::0;::::1;9722:51:20::0;9789:18;;;9782:34;;;25982:13:0;;26014:20;;::::1;::::0;::::1;::::0;9695:18:20;;26014:39:0::1;9548:274:20::0;16917:179:0;1094:13:1;:11;:13::i;:::-;-1:-1:-1;;;;;17032:24:0;;;::::1;;::::0;;;:15:::1;:24;::::0;;;;:56;;-1:-1:-1;;17032:56:0::1;::::0;::::1;;::::0;;;::::1;::::0;;16917:179::o;16638:97::-;1094:13:1;:11;:13::i;:::-;16699:21:0::1;:28:::0;;-1:-1:-1;;;;;16699:28:0::1;-1:-1:-1::0;;;16699:28:0::1;::::0;;16638:97::o;1824:101:1:-;1094:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;19321:1013:0:-;19505:36;;;19483:113;;;;-1:-1:-1;;;19483:113:0;;11183:2:20;19483:113:0;;;11165:21:20;11222:2;11202:18;;;11195:30;11261:29;11241:18;;;11234:57;11308:18;;19483:113:0;10981:351:20;19483:113:0;19607:18;19645:6;19640:425;19657:25;;;19640:425;;;19801:37;719:10:7;19830:4:0;;19835:1;19830:7;;;;;;;:::i;:::-;;;;;;;19801:14;:37::i;:::-;19853;19863:14;;19878:1;19863:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;19882:4;;19887:1;19882:7;;;;;;;:::i;:::-;;;;;;;19853:9;:37::i;:::-;19990:14;;20005:1;19990:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;19967:50:0;719:10:7;-1:-1:-1;;;;;;;;;;;20009:4:0;;20014:1;20009:7;;;;;;;:::i;:::-;;;;;;;19967:50;;;;1737:25:20;;1725:2;1710:18;;1591:177;19967:50:0;;;;;;;;20046:4;;20051:1;20046:7;;;;;;;:::i;:::-;;;;;;;20032:21;;;;;:::i;:::-;;-1:-1:-1;19684:3:0;;;;:::i;:::-;;;;19640:425;;;-1:-1:-1;20110:216:0;20133:6;719:10:7;20181:134:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20181:19:0;;-1:-1:-1;20181:19:0;;;:11;:19;;;;;;:134;;20237:10;;20181:134;:19;719:10:7;20201:12:0;640:96:7;20110:216:0;19472:862;19321:1013;;;;;:::o;26887:386::-;3676:11;;-1:-1:-1;;;;;3676:11:0;719:10:7;-1:-1:-1;;;;;3660:27:0;;3638:112;;;;-1:-1:-1;;;3638:112:0;;;;;;;:::i;:::-;27011:21:::1;27043:20;27049:13:::0;27043:5:::1;:20::i;:::-;27074:11;27088:30;27112:6:::0;27088:21:::1;:30;:::i;:::-;27247:11;::::0;27074:44;;-1:-1:-1;27221:44:0::1;::::0;-1:-1:-1;;;;;27247:11:0::1;27074:44:::0;27221:17:::1;:44::i;:::-;26983:290;;26887:386:::0;:::o;23759:144::-;-1:-1:-1;;;;;23871:14:0;;23844:7;23871:14;;;:7;:14;;;;;918::8;23871:24:0;827:112:8;24634:218:0;24676:16;24734:15;;;;;;;;;-1:-1:-1;;;;;24734:15:0;-1:-1:-1;;;;;24734:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;24716:52:0;;24791:4;24811:15;;;;;;;;;-1:-1:-1;;;;;24811:15:0;-1:-1:-1;;;;;24811:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24716:128;;-1:-1:-1;;;;;;24716:128:0;;;;;;;-1:-1:-1;;;;;12358:15:20;;;24716:128:0;;;12340:34:20;12410:15;;12390:18;;;12383:43;12275:18;;24716:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;27345:265::-;3676:11;;-1:-1:-1;;;;;3676:11:0;719:10:7;-1:-1:-1;;;;;3660:27:0;;3638:112;;;;-1:-1:-1;;;3638:112:0;;;;;;;:::i;:::-;27416:10:::1;27435:15;;;;;;;;;-1:-1:-1::0;;;;;27435:15:0::1;-1:-1:-1::0;;;;;27435:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27416:42;;27469:14;27493:15;;;;;;;;;-1:-1:-1::0;;;;;27493:15:0::1;-1:-1:-1::0;;;;;27493:20:0::1;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27541:32;::::0;-1:-1:-1;;;27541:32:0;;27567:4:::1;27541:32;::::0;::::1;1919:51:20::0;27469:47:0;;-1:-1:-1;27527:11:0::1;::::0;-1:-1:-1;;;;;27541:17:0;::::1;::::0;::::1;::::0;1892:18:20;;27541:32:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27584:18;::::0;-1:-1:-1;;;27584:18:0;;::::1;::::0;::::1;1737:25:20::0;;;27527:46:0;;-1:-1:-1;;;;;;27584:13:0;::::1;::::0;::::1;::::0;1710:18:20;;27584::0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;27405:205;;;27345:265::o:0;6621:192::-;6724:4;6741:42;719:10:7;6765:9:0;6776:6;6741:9;:42::i;18495:544::-;18625:25;;;18617:66;;;;-1:-1:-1;;;18617:66:0;;12828:2:20;18617:66:0;;;12810:21:20;12867:2;12847:18;;;12840:30;12906;12886:18;;;12879:58;12954:18;;18617:66:0;12626:352:20;18617:66:0;18699:6;18694:338;18711:15;;;18694:338;;;18827:36;719:10:7;18856:3:0;;18860:1;18856:6;;;;;;;:::i;18827:36::-;18878:26;18888:4;;18893:1;18888:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;18897:3;;18901:1;18897:6;;;;;;;:::i;18878:26::-;19004:4;;19009:1;19004:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;18981:39:0;719:10:7;-1:-1:-1;;;;;;;;;;;19013:3:0;;19017:1;19013:6;;;;;;;:::i;:::-;;;;;;;18981:39;;;;1737:25:20;;1725:2;1710:18;;1591:177;18981:39:0;;;;;;;;18728:3;;;;:::i;:::-;;;;18694:338;;;;18495:544;;;;:::o;17239:152::-;1094:13:1;:11;:13::i;:::-;17322:5:0::1;17312:6;:15;;;;17304:52;;;::::0;-1:-1:-1;;;17304:52:0;;13185:2:20;17304:52:0::1;::::0;::::1;13167:21:20::0;13224:2;13204:18;;;13197:30;13263:26;13243:18;;;13236:54;13307:18;;17304:52:0::1;12983:348:20::0;17304:52:0::1;17367:7;:16:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;17367:16:0::1;-1:-1:-1::0;;;;17367:16:0;;::::1;::::0;;;::::1;::::0;;17239:152::o;15156:784::-;1094:13:1;:11;:13::i;:::-;-1:-1:-1;;;;;15227:23:0;::::1;15272:5;15227:23:::0;;;:15:::1;:23;::::0;;;;:50;;-1:-1:-1;;15227:50:0::1;::::0;;15272:5;15317:303:::1;15341:10;:17:::0;15337:21;::::1;15317:303;;;15408:6;-1:-1:-1::0;;;;;15384:30:0::1;:10;15395:1;15384:13;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:20:::0;-1:-1:-1;;;;;15384:20:0::1;:30:::0;15380:229:::1;;15494:10;15505:17:::0;;:21:::1;::::0;15525:1:::1;::::0;15505:21:::1;:::i;:::-;15494:33;;;;;;;;:::i;:::-;;;;;;;;15478:10;15489:1;15478:13;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;:49;;:13;::::1;:49:::0;;-1:-1:-1;;;;;15478:49:0;;::::1;-1:-1:-1::0;;;;;;15478:49:0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;;15478:49:0;;;;;;-1:-1:-1;;;15478:49:0;;;::::1;;;::::0;;::::1;;::::0;;15546:10:::1;:16:::0;;;::::1;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;-1:-1:-1;;15546:16:0;;;;;-1:-1:-1;;;;;;15546:16:0;;;;;;::::1;::::0;-1:-1:-1;15380:229:0::1;15360:3:::0;::::1;::::0;::::1;:::i;:::-;;;;15317:303;;;;15638:5;15630:34;;;::::0;-1:-1:-1;;;15630:34:0;;13670:2:20;15630:34:0::1;::::0;::::1;13652:21:20::0;13709:2;13689:18;;;13682:30;-1:-1:-1;;;13728:18:20;;;13721:46;13784:18;;15630:34:0::1;13468:340:20::0;15630:34:0::1;15753:19;15792:9:::0;15787:110:::1;15811:10;:17:::0;15807:21;::::1;15787:110;;;15866:10;15877:1;15866:13;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:19:::0;15850:35:::1;::::0;-1:-1:-1;;;15866:19:0;::::1;;;15850:35:::0;::::1;:::i;:::-;::::0;-1:-1:-1;15830:3:0;::::1;::::0;::::1;:::i;:::-;;;;15787:110;;;-1:-1:-1::0;15907:10:0::1;:25:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;15907:25:0::1;-1:-1:-1::0;;;;15907:25:0;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;15156:784:0:o;7704:1055::-;1094:13:1;:11;:13::i;:::-;7764:11:0::1;::::0;-1:-1:-1;;;7764:11:0;::::1;;;7763:12;7755:64;;;::::0;-1:-1:-1;;;7755:64:0;;14015:2:20;7755:64:0::1;::::0;::::1;13997:21:20::0;14054:2;14034:18;;;14027:30;14093:34;14073:18;;;14066:62;-1:-1:-1;;;14144:18:20;;;14137:37;14191:19;;7755:64:0::1;13813:403:20::0;7755:64:0::1;7965:15;:34:::0;;-1:-1:-1;;;;;;7965:34:0::1;::::0;::::1;::::0;;;;7901:42:::1;::::0;8010:62:::1;::::0;8027:4:::1;::::0;-1:-1:-1;;;;;;;;8042:15:0;;::::1;;1379:29;8010:8;:62::i;:::-;8083:21;8125:16;-1:-1:-1::0;;;;;8125:24:0::1;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8107:70:0::1;;8186:4;8193:16;-1:-1:-1::0;;;;;8193:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8107:110;::::0;-1:-1:-1;;;;;;8107:110:0::1;::::0;;;;;;-1:-1:-1;;;;;12358:15:20;;;8107:110:0::1;::::0;::::1;12340:34:20::0;12410:15;;12390:18;;;12383:43;12275:18;;8107:110:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8230:15;::::0;8314:4:::1;6561:7:::0;6588:17;;;:8;:17;;;;;;8083:134;;-1:-1:-1;;;;8230:15:0;;::::1;-1:-1:-1::0;;;;;8230:15:0::1;::::0;:31:::1;::::0;8269:21:::1;::::0;8373:1:::1;8389::::0;8405:7:::1;1247::1::0;1273:6;-1:-1:-1;;;;;1273:6:1;;1201:85;8405:7:0::1;8230:223;::::0;::::1;::::0;;;-1:-1:-1;;;;;;8230:223:0;;;-1:-1:-1;;;;;14580:15:20;;;8230:223:0::1;::::0;::::1;14562:34:20::0;14612:18;;;14605:34;;;;14655:18;;;14648:34;;;;14698:18;;;14691:34;14762:15;;;14741:19;;;14734:44;8427:15:0::1;14794:19:20::0;;;14787:35;14496:19;;8230:223:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;8466:11:0::1;:18:::0;;-1:-1:-1;;;;8497:18:0;-1:-1:-1;;;8497:18:0;;;-1:-1:-1;8599:152:0::1;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;8599:152:0;;;::::1;::::0;;::::1;::::0;;;;;;;;;-1:-1:-1;8599:152:0;;;;;;-1:-1:-1;;;;;8566:30:0;;;::::1;::::0;;:15:::1;:30:::0;;;;;;;:185;;;;;;;;;;-1:-1:-1;;8566:185:0;;;;::::1;;-1:-1:-1::0;;8566:185:0;;8466:18:::1;8599:152;8566:185:::0;;::::1;;;-1:-1:-1::0;;8566:185:0;;;;;::::1;;-1:-1:-1::0;;;;8566:185:0;;;;;-1:-1:-1;;;8566:185:0;::::1;;::::0;;;::::1;;::::0;;-1:-1:-1;7704:1055:0:o;22909:784::-;23153:8;23134:15;:27;;23126:69;;;;-1:-1:-1;;;23126:69:0;;15346:2:20;23126:69:0;;;15328:21:20;15385:2;15365:18;;;15358:30;15424:31;15404:18;;;15397:59;15473:18;;23126:69:0;15144:353:20;23126:69:0;23208:18;22350:119;23317:5;23341:7;23367:5;23391:16;23401:5;23391:9;:16::i;:::-;23253:196;;;;;;15789:25:20;;;;-1:-1:-1;;;;;15888:15:20;;;15868:18;;;15861:43;15940:15;;;;15920:18;;;15913:43;15972:18;;;15965:34;16015:19;;;16008:35;16059:19;;;16052:35;;;15761:19;;23253:196:0;;;;;;;;;;;;23229:231;;;;;;23208:252;;23473:12;23488:28;23505:10;23488:16;:28::i;:::-;23473:43;;23529:14;23546:28;23560:4;23566:1;23569;23572;23546:13;:28::i;:::-;23529:45;;23603:5;-1:-1:-1;;;;;23593:15:0;:6;-1:-1:-1;;;;;23593:15:0;;23585:58;;;;-1:-1:-1;;;23585:58:0;;16300:2:20;23585:58:0;;;16282:21:20;16339:2;16319:18;;;16312:30;16378:32;16358:18;;;16351:60;16428:18;;23585:58:0;16098:354:20;23585:58:0;23654:31;23663:5;23670:7;23679:5;23654:8;:31::i;:::-;23115:578;;;22909:784;;;;;;;:::o;17399:149::-;1094:13:1;:11;:13::i;:::-;17481:5:0::1;17471:6;:15;;;;17463:51;;;::::0;-1:-1:-1;;;17463:51:0;;16659:2:20;17463:51:0::1;::::0;::::1;16641:21:20::0;16698:2;16678:18;;;16671:30;16737:25;16717:18;;;16710:53;16780:18;;17463:51:0::1;16457:347:20::0;17463:51:0::1;17525:6;:15:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;17525:15:0::1;-1:-1:-1::0;;;;;17525:15:0;;::::1;::::0;;;::::1;::::0;;17399:149::o;16085:118::-;3830:9;;-1:-1:-1;;;;;3830:9:0;719:10:7;-1:-1:-1;;;;;3814:25:0;;3806:66;;;;-1:-1:-1;;;3806:66:0;;17011:2:20;3806:66:0;;;16993:21:20;17050:2;17030:18;;;17023:30;17089;17069:18;;;17062:58;17137:18;;3806:66:0;16809:352:20;3806:66:0;16163:11:::1;:32:::0;;-1:-1:-1;;;;;;16163:32:0::1;-1:-1:-1::0;;;;;16163:32:0;;;::::1;::::0;;;::::1;::::0;;16085:118::o;16341:111::-;1094:13:1;:11;:13::i;:::-;-1:-1:-1;;;;;16407:21:0::1;;::::0;;;:15:::1;:21;::::0;;;;:37;;-1:-1:-1;;;;16407:37:0::1;-1:-1:-1::0;;;16407:37:0::1;::::0;;16341:111::o;2074:198:1:-;1094:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:1;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:1;;17368:2:20;2154:73:1::1;::::0;::::1;17350:21:20::0;17407:2;17387:18;;;17380:30;17446:34;17426:18;;;17419:62;-1:-1:-1;;;17497:18:20;;;17490:36;17543:19;;2154:73:1::1;17166:402:20::0;2154:73:1::1;2237:28;2256:8;2237:18;:28::i;24860:102:0:-:0;24906:18;24944:10;24937:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;24937:17:0;;;;-1:-1:-1;;;24937:17:0;;;;;;;;;;;;;;;;;;;;;;;;;24860:102;:::o;8767:335::-;-1:-1:-1;;;;;8860:19:0;;8852:68;;;;-1:-1:-1;;;8852:68:0;;17775:2:20;8852:68:0;;;17757:21:20;17814:2;17794:18;;;17787:30;17853:34;17833:18;;;17826:62;-1:-1:-1;;;17904:18:20;;;17897:34;17948:19;;8852:68:0;17573:400:20;8852:68:0;-1:-1:-1;;;;;8939:21:0;;8931:68;;;;-1:-1:-1;;;8931:68:0;;18180:2:20;8931:68:0;;;18162:21:20;18219:2;18199:18;;;18192:30;18258:34;18238:18;;;18231:62;-1:-1:-1;;;18309:18:20;;;18302:32;18351:19;;8931:68:0;17978:398:20;8931:68:0;-1:-1:-1;;;;;9010:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;9062:32;;1737:25:20;;;9062:32:0;;1710:18:20;9062:32:0;;;;;;;8767:335;;;:::o;1359:130:1:-;1247:7;1273:6;-1:-1:-1;;;;;1273:6:1;719:10:7;1422:23:1;1414:68;;;;-1:-1:-1;;;1414:68:1;;18583:2:20;1414:68:1;;;18565:21:20;;;18602:18;;;18595:30;18661:34;18641:18;;;18634:62;18713:18;;1414:68:1;18381:356:20;9110:2069:0;-1:-1:-1;;;;;9198:18:0;;9190:68;;;;-1:-1:-1;;;9190:68:0;;18944:2:20;9190:68:0;;;18926:21:20;18983:2;18963:18;;;18956:30;19022:34;19002:18;;;18995:62;-1:-1:-1;;;19073:18:20;;;19066:35;19118:19;;9190:68:0;18742:401:20;9190:68:0;-1:-1:-1;;;;;9277:16:0;;9269:64;;;;-1:-1:-1;;;9269:64:0;;19350:2:20;9269:64:0;;;19332:21:20;19389:2;19369:18;;;19362:30;19428:34;19408:18;;;19401:62;-1:-1:-1;;;19479:18:20;;;19472:33;19522:19;;9269:64:0;19148:399:20;9269:64:0;9361:1;9352:6;:10;9344:64;;;;-1:-1:-1;;;9344:64:0;;19754:2:20;9344:64:0;;;19736:21:20;19793:2;19773:18;;;19766:30;19832:34;19812:18;;;19805:62;-1:-1:-1;;;19883:18:20;;;19876:39;19932:19;;9344:64:0;19552:405:20;9344:64:0;9421:14;;9504:7;1247::1;1273:6;-1:-1:-1;;;;;1273:6:1;;1201:85;9504:7:0;-1:-1:-1;;;;;9496:15:0;:4;-1:-1:-1;;;;;9496:15:0;;;:45;;;;-1:-1:-1;1247:7:1;1273:6;-1:-1:-1;;;;;9528:13:0;;;1273:6:1;;9528:13:0;;9496:45;:83;;;;-1:-1:-1;;;;;;9558:21:0;;9574:4;9558:21;;9496:83;:139;;;;-1:-1:-1;;;;;;9597:19:0;;;;;;:15;:19;;;;;:38;;;9596:39;9496:139;:197;;;;-1:-1:-1;;;;;;9653:21:0;;;;;;:15;:21;;;;;:40;;;9652:41;9496:197;9478:1632;;;9781:10;;9767:24;;-1:-1:-1;;;9781:10:0;;;;1379:29;9767:24;:::i;:::-;9757:6;:34;;9749:63;;;;-1:-1:-1;;;9749:63:0;;20386:2:20;9749:63:0;;;20368:21:20;20425:2;20405:18;;;20398:30;-1:-1:-1;;;20444:18:20;;;20437:46;20500:18;;9749:63:0;20184:340:20;9749:63:0;-1:-1:-1;;;;;9873:21:0;;;;;;:15;:21;;;;;:30;-1:-1:-1;;;9873:30:0;;;;9872:83;;;;-1:-1:-1;9939:15:0;;-1:-1:-1;;;;;9925:30:0;;;-1:-1:-1;;;9939:15:0;;;;9925:30;;9872:83;9850:1120;;;10000:6;;10132:14;;10000:6;-1:-1:-1;;;10000:6:0;;;;;;-1:-1:-1;10118:28:0;;-1:-1:-1;;;10132:14:0;;;;1379:29;10118:28;:::i;:::-;10108:6;10092:13;10102:2;-1:-1:-1;;;;;6588:17:0;6561:7;6588:17;;;:8;:17;;;;;;;6495:118;10092:13;:22;;;;:::i;:::-;:54;;10062:156;;;;-1:-1:-1;;;10062:156:0;;20731:2:20;10062:156:0;;;20713:21:20;20770:2;20750:18;;;20743:30;20809;20789:18;;;20782:58;20857:18;;10062:156:0;20529:352:20;10062:156:0;9478:1632;;9850:1120;-1:-1:-1;;;;;10263:19:0;;;;;;:15;:19;;;;;:28;-1:-1:-1;;;10263:28:0;;;;10262:83;;;;-1:-1:-1;10329:15:0;;-1:-1:-1;;;;;10313:32:0;;;-1:-1:-1;;;10329:15:0;;;;10313:32;;10262:83;10240:730;;;-1:-1:-1;;10626:7:0;;-1:-1:-1;;;10626:7:0;;;;10389:4;9478:1632;;10240:730;10868:14;;10735:1;;-1:-1:-1;10854:28:0;;-1:-1:-1;;;10868:14:0;;;;1379:29;10854:28;:::i;9478:1632::-;11097:1;11087:11;;9478:1632;11122:49;11137:4;11143:2;11147:6;11155:7;11164:6;11122:14;:49::i;4959:201:12:-;5045:7;5104:12;5096:6;;;;5088:29;;;;-1:-1:-1;;;5088:29:12;;;;;;;;:::i;:::-;-1:-1:-1;;;5138:5:12;;;4959:201::o;20534:437:0:-;20587:7;20633:4;-1:-1:-1;;;;;20642:12:0;20625:29;;:66;;;;;20675:16;20658:13;:33;20625:66;20607:357;;;-1:-1:-1;20725:24:0;;20534:437::o;20607:357::-;-1:-1:-1;21191:197:0;;;20850:10;21191:197;;;;23257:25:20;;;;20883:12:0;23298:18:20;;;23291:34;20918:15:0;23341:18:20;;;23334:34;21320:13:0;23384:18:20;;;23377:34;21364:4:0;23427:19:20;;;;23420:61;;;;21191:197:0;;;;;;;;;;23229:19:20;;;;21191:197:0;;;21163:240;;;;;;24033:115::o;26328:551::-;26443:16;;;26457:1;26443:16;;;;;;;;26404:3;;26376:18;;26443:16;26457:1;26443:16;;;;;;;;;;-1:-1:-1;26443:16:0;26419:40;;26480:3;26470:4;26475:1;26470:7;;;;;;;;:::i;:::-;;;;;;:13;-1:-1:-1;;;;;26470:13:0;;;-1:-1:-1;;;;;26470:13:0;;;;;26504:15;;;;;;;;;-1:-1:-1;;;;;26504:15:0;-1:-1:-1;;;;;26504:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26494:4;26499:1;26494:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;26494:32:0;;;:7;;;;;;;;;:32;26559:36;;-1:-1:-1;;;26559:36:0;;26589:4;26559:36;;;1919:51:20;26537:19:0;;26559:21;;;;;1892:18:20;;26559:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26634:15;;26606:58;;-1:-1:-1;;;26606:58:0;;-1:-1:-1;;;;;;;;26634:15:0;;;;;26606:58;;;9722:51:20;9789:18;;;9782:34;;;;;-1:-1:-1;26606:19:0;;;;;9695:18:20;;26606:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;26675:15:0;;:196;;-1:-1:-1;;;26675:196:0;;-1:-1:-1;;;26675:15:0;;;-1:-1:-1;;;;;26675:15:0;;:66;;:196;;26756:11;;26782:1;;26798:4;;26825;;26845:15;;26675:196;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26365:514;;;26328:551;:::o;2426:187:1:-;2499:16;2518:6;;-1:-1:-1;;;;;2534:17:1;;;-1:-1:-1;;;;;;2534:17:1;;;;;;2566:40;;2518:6;;;;;;;2566:40;;2499:16;2566:40;2489:124;2426:187;:::o;14171:130:0:-;-1:-1:-1;;;;;14267:17:0;;;;;;:8;:17;;;;;;:26;;14287:6;;14267:26;:::i;:::-;-1:-1:-1;;;;;14247:17:0;;;;;;;:8;:17;;;;;:46;;;;-1:-1:-1;14171:130:0:o;14309:125::-;-1:-1:-1;;;;;14400:17:0;;;;;;:8;:17;;;;;;:26;;14420:6;;14400:26;:::i;2647:312:6:-;2761:6;2736:21;:31;;2728:73;;;;-1:-1:-1;;;2728:73:6;;22205:2:20;2728:73:6;;;22187:21:20;22244:2;22224:18;;;22217:30;22283:31;22263:18;;;22256:59;22332:18;;2728:73:6;22003:353:20;2728:73:6;2813:12;2831:9;-1:-1:-1;;;;;2831:14:6;2853:6;2831:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2812:52;;;2882:7;2874:78;;;;-1:-1:-1;;;2874:78:6;;22773:2:20;2874:78:6;;;22755:21:20;22812:2;22792:18;;;22785:30;22851:34;22831:18;;;22824:62;22922:28;22902:18;;;22895:56;22968:19;;2874:78:6;22571:422:20;24286:223:0;-1:-1:-1;;;;;24423:14:0;;24362:15;24423:14;;;:7;:14;;;;;918::8;;1050:1;1032:19;;;;918:14;24484:17:0;24379:130;24286:223;;;:::o;22053:183::-;22146:7;22173:55;22195:20;:18;:20::i;:::-;22217:10;8536:4:10;8530:11;-1:-1:-1;;;8554:23:10;;8606:4;8597:14;;8590:39;;;;8658:4;8649:14;;8642:34;8712:4;8697:20;;;8336:397;6598:232;6683:7;6703:17;6722:18;6744:25;6755:4;6761:1;6764;6767;6744:10;:25::i;:::-;6702:67;;;;6779:18;6791:5;6779:11;:18::i;:::-;-1:-1:-1;6814:9:10;6598:232;-1:-1:-1;;;;;6598:232:10:o;12768:1357:0:-;12989:6;13010:11;;;;13006:288;;13052:17;13072:34;13090:6;13098:7;13072:17;:34::i;:::-;13052:54;-1:-1:-1;13138:18:0;13052:54;13138:6;:18;:::i;:::-;13121:35;;13171;13189:4;13196:9;13171;:35::i;:::-;13240:42;;1737:25:20;;;13265:4:0;;-1:-1:-1;;;;;13240:42:0;;;-1:-1:-1;;;;;;;;;;;13240:42:0;1725:2:20;1710:18;13240:42:0;;;;;;;13023:271;13006:288;13381:6;13377:503;;;13414:6;-1:-1:-1;;;;;13409:20:0;;13422:6;13409:20;;;;1737:25:20;;1725:2;1710:18;;1591:177;13409:20:0;;;;;;;;13476:4;13444:11;6588:17;;;:8;:17;;;;;;13582:7;;13578:228;;13634:14;;13620:28;;-1:-1:-1;;;13634:14:0;;;;1379:29;13620:28;:::i;:::-;13614:3;:34;13610:181;;;13695:14;;13673:37;;13681:28;;-1:-1:-1;;;13695:14:0;;;;1379:29;13681:28;:::i;:::-;13673:7;:37::i;:::-;13610:181;;;13759:12;13767:3;13759:7;:12::i;:::-;13389:428;13377:503;;;13850:9;-1:-1:-1;;;;;13843:25:0;;13861:6;13843:25;;;;1737::20;;1725:2;1710:18;;1591:177;13843:25:0;;;;;;;;13377:503;13929:30;13944:6;13952;13929:14;:30::i;:::-;13970:36;13980:9;13991:14;13970:9;:36::i;:::-;14091:9;-1:-1:-1;;;;;14074:43:0;14083:6;-1:-1:-1;;;;;14074:43:0;-1:-1:-1;;;;;;;;;;;14102:14:0;14074:43;;;;1737:25:20;;1725:2;1710:18;;1591:177;14074:43:0;;;;;;;;12932:1193;12768:1357;;;;;:::o;5009:1456:10:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:10;;-1:-1:-1;6123:30:10;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;23719:25:20;;;23792:4;23780:17;;23760:18;;;23753:45;;;;23814:18;;;23807:34;;;23857:18;;;23850:34;;;6276:24:10;;23691:19:20;;6276:24:10;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:10;;-1:-1:-1;;6276:24:10;;;-1:-1:-1;;;;;;;6314:20:10;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:10;;-1:-1:-1;5009:1456:10;;;;;;;;:::o;570:511::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:10;;24229:2:20;788:34:10;;;24211:21:20;24268:2;24248:18;;;24241:30;24307:26;24287:18;;;24280:54;24351:18;;788:34:10;24027:348:20;730:345:10;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:10;;24582:2:20;903:41:10;;;24564:21:20;24621:2;24601:18;;;24594:30;24660:33;24640:18;;;24633:61;24711:18;;903:41:10;24380:355:20;839:236:10;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:10;;24942:2:20;1020:44:10;;;24924:21:20;24981:2;24961:18;;;24954:30;25020:34;25000:18;;;24993:62;-1:-1:-1;;;25071:18:20;;;25064:32;25113:19;;1020:44:10;24740:398:20;14442:173:0;14549:11;14601:6;14580:17;;;;:7;:17;:::i;:::-;14579:28;;;;:::i;:::-;14573:34;14442:173;-1:-1:-1;;;14442:173:0:o;11187:1098::-;11248:17;;;;11269:12;11248:33;11244:271;;11342:17;:40;;-1:-1:-1;;11342:40:0;11369:12;11342:40;;;;;11585:6;:13;;-1:-1:-1;;;;11585:13:0;-1:-1:-1;;;11585:13:0;;;11649:4;11585:13;11629:26;;;:11;:26;;;;;;;;11664:15;;-1:-1:-1;;;11664:15:0;;-1:-1:-1;;;;;11664:15:0;11629:52;;;;;;;;:66;-1:-1:-1;11611:232:0;;;11801:15;;11769:62;;11786:4;;-1:-1:-1;;;11801:15:0;;-1:-1:-1;;;;;11801:15:0;1379:29;11769:8;:62::i;:::-;11877:16;;;11891:1;11877:16;;;;;;;;11853:21;;11877:16;;;;;;;;;;-1:-1:-1;11877:16:0;11853:40;;11922:4;11904;11909:1;11904:7;;;;;;;;:::i;:::-;;;;;;:23;-1:-1:-1;;;;;11904:23:0;;;-1:-1:-1;;;;;11904:23:0;;;;;11948:15;;;;;;;;;-1:-1:-1;;;;;11948:15:0;-1:-1:-1;;;;;11948:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11938:4;11943:1;11938:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;11938:32:0;;;:7;;;;;;;;;:32;12037:15;;:167;;-1:-1:-1;;;12037:167:0;;-1:-1:-1;;;12037:15:0;;;;;;;:37;;:167;;12089:11;;12115:1;;12131:4;;12158;;12178:15;;12037:167;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12037:167:0;;;;;;;;;;;;:::i;:::-;;12217:35;12230:21;12217:12;:35::i;:::-;-1:-1:-1;;12263:6:0;:14;;-1:-1:-1;;;;12263:14:0;;;11187:1098::o;12293:384::-;12458:9;12453:217;12477:10;:17;12473:21;;12453:217;;;12516:142;12560:10;12571:1;12560:13;;;;;;;;:::i;:::-;;;;;;;;;;:20;12633:10;;12610;:13;;-1:-1:-1;;;;;12560:20:0;;;;-1:-1:-1;;;12633:10:0;;;;;;12621:1;;12610:13;;;;;;:::i;:::-;;;;;;;;;;:19;12601:28;;-1:-1:-1;;;12610:19:0;;;;12601:6;:28;:::i;:::-;12600:43;;;;:::i;:::-;12516:17;:142::i;:::-;12496:3;;;;:::i;:::-;;;;12453:217;;;;12293:384;:::o;14:548:20:-;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:20;;632:42;;622:70;;688:1;685;678:12;703:315;771:6;779;832:2;820:9;811:7;807:23;803:32;800:52;;;848:1;845;838:12;800:52;887:9;874:23;906:31;931:5;906:31;:::i;:::-;956:5;1008:2;993:18;;;;980:32;;-1:-1:-1;;;703:315:20:o;1215:121::-;1300:10;1293:5;1289:22;1282:5;1279:33;1269:61;;1326:1;1323;1316:12;1341:245;1399:6;1452:2;1440:9;1431:7;1427:23;1423:32;1420:52;;;1468:1;1465;1458:12;1420:52;1507:9;1494:23;1526:30;1550:5;1526:30;:::i;1981:456::-;2058:6;2066;2074;2127:2;2115:9;2106:7;2102:23;2098:32;2095:52;;;2143:1;2140;2133:12;2095:52;2182:9;2169:23;2201:31;2226:5;2201:31;:::i;:::-;2251:5;-1:-1:-1;2308:2:20;2293:18;;2280:32;2321:33;2280:32;2321:33;:::i;:::-;1981:456;;2373:7;;-1:-1:-1;;;2427:2:20;2412:18;;;;2399:32;;1981:456::o;3010:247::-;3069:6;3122:2;3110:9;3101:7;3097:23;3093:32;3090:52;;;3138:1;3135;3128:12;3090:52;3177:9;3164:23;3196:31;3221:5;3196:31;:::i;3262:194::-;3349:6;3402:2;3390:9;3381:7;3377:23;3373:32;3370:52;;;3418:1;3415;3408:12;3461:118;3547:5;3540:13;3533:21;3526:5;3523:32;3513:60;;3569:1;3566;3559:12;3584:382;3649:6;3657;3710:2;3698:9;3689:7;3685:23;3681:32;3678:52;;;3726:1;3723;3716:12;3678:52;3765:9;3752:23;3784:31;3809:5;3784:31;:::i;:::-;3834:5;-1:-1:-1;3891:2:20;3876:18;;3863:32;3904:30;3863:32;3904:30;:::i;:::-;3953:7;3943:17;;;3584:382;;;;;:::o;3971:367::-;4034:8;4044:6;4098:3;4091:4;4083:6;4079:17;4075:27;4065:55;;4116:1;4113;4106:12;4065:55;-1:-1:-1;4139:20:20;;4182:18;4171:30;;4168:50;;;4214:1;4211;4204:12;4168:50;4251:4;4243:6;4239:17;4227:29;;4311:3;4304:4;4294:6;4291:1;4287:14;4279:6;4275:27;4271:38;4268:47;4265:67;;;4328:1;4325;4318:12;4265:67;3971:367;;;;;:::o;4343:908::-;4474:6;4482;4490;4498;4506;4559:2;4547:9;4538:7;4534:23;4530:32;4527:52;;;4575:1;4572;4565:12;4527:52;4614:9;4601:23;4633:31;4658:5;4633:31;:::i;:::-;4683:5;-1:-1:-1;4739:2:20;4724:18;;4711:32;4762:18;4792:14;;;4789:34;;;4819:1;4816;4809:12;4789:34;4858:70;4920:7;4911:6;4900:9;4896:22;4858:70;:::i;:::-;4947:8;;-1:-1:-1;4832:96:20;-1:-1:-1;5035:2:20;5020:18;;5007:32;;-1:-1:-1;5051:16:20;;;5048:36;;;5080:1;5077;5070:12;5048:36;;5119:72;5183:7;5172:8;5161:9;5157:24;5119:72;:::i;:::-;4343:908;;;;-1:-1:-1;4343:908:20;;-1:-1:-1;5210:8:20;;5093:98;4343:908;-1:-1:-1;;;4343:908:20:o;5256:773::-;5378:6;5386;5394;5402;5455:2;5443:9;5434:7;5430:23;5426:32;5423:52;;;5471:1;5468;5461:12;5423:52;5511:9;5498:23;5540:18;5581:2;5573:6;5570:14;5567:34;;;5597:1;5594;5587:12;5567:34;5636:70;5698:7;5689:6;5678:9;5674:22;5636:70;:::i;:::-;5725:8;;-1:-1:-1;5610:96:20;-1:-1:-1;5813:2:20;5798:18;;5785:32;;-1:-1:-1;5829:16:20;;;5826:36;;;5858:1;5855;5848:12;5826:36;;5897:72;5961:7;5950:8;5939:9;5935:24;5897:72;:::i;:::-;5256:773;;;;-1:-1:-1;5988:8:20;-1:-1:-1;;;;5256:773:20:o;6034:829::-;6145:6;6153;6161;6169;6177;6185;6193;6246:3;6234:9;6225:7;6221:23;6217:33;6214:53;;;6263:1;6260;6253:12;6214:53;6302:9;6289:23;6321:31;6346:5;6321:31;:::i;:::-;6371:5;-1:-1:-1;6428:2:20;6413:18;;6400:32;6441:33;6400:32;6441:33;:::i;:::-;6493:7;-1:-1:-1;6547:2:20;6532:18;;6519:32;;-1:-1:-1;6598:2:20;6583:18;;6570:32;;-1:-1:-1;6654:3:20;6639:19;;6626:33;6703:4;6690:18;;6678:31;;6668:59;;6723:1;6720;6713:12;6668:59;6034:829;;;;-1:-1:-1;6034:829:20;;;;6746:7;6800:3;6785:19;;6772:33;;-1:-1:-1;6852:3:20;6837:19;;;6824:33;;6034:829;-1:-1:-1;;6034:829:20:o;6868:388::-;6936:6;6944;6997:2;6985:9;6976:7;6972:23;6968:32;6965:52;;;7013:1;7010;7003:12;6965:52;7052:9;7039:23;7071:31;7096:5;7071:31;:::i;:::-;7121:5;-1:-1:-1;7178:2:20;7163:18;;7150:32;7191:33;7150:32;7191:33;:::i;7261:833::-;7484:2;7536:21;;;7606:13;;7509:18;;;7628:22;;;7455:4;;7484:2;7669;;7687:18;;;;7728:15;;;7455:4;7771:297;7785:6;7782:1;7779:13;7771:297;;;7844:13;;7886:9;;-1:-1:-1;;;;;7882:35:20;7870:48;;7962:11;;7956:18;7976:10;7952:35;7938:12;;;7931:57;8008:12;;;;8043:15;;;;7914:1;7800:9;7771:297;;;-1:-1:-1;8085:3:20;;7261:833;-1:-1:-1;;;;;;;7261:833:20:o;9144:399::-;9346:2;9328:21;;;9385:2;9365:18;;;9358:30;9424:34;9419:2;9404:18;;9397:62;-1:-1:-1;;;9490:2:20;9475:18;;9468:33;9533:3;9518:19;;9144:399::o;9827:245::-;9894:6;9947:2;9935:9;9926:7;9922:23;9918:32;9915:52;;;9963:1;9960;9953:12;9915:52;9995:9;9989:16;10014:28;10036:5;10014:28;:::i;10077:590::-;10244:5;10231:19;10259:33;10284:7;10259:33;:::i;:::-;10363:11;;-1:-1:-1;;;;;;10399:45:20;;-1:-1:-1;;;;;10311:33:20;;;;10396:53;;;10383:67;;10498:2;10487:14;;10474:28;10511:32;10474:28;10511:32;:::i;:::-;-1:-1:-1;;;;;;10571:37:20;;;;10568:45;;;10642:3;10619:17;;;;-1:-1:-1;;;10615:44:20;10565:95;10552:109;;-1:-1:-1;10077:590:20:o;10672:127::-;10733:10;10728:3;10724:20;10721:1;10714:31;10764:4;10761:1;10754:15;10788:4;10785:1;10778:15;10804:172;10871:10;10901;;;10913;;;10897:27;;10936:11;;;10933:37;;;10950:18;;:::i;:::-;10933:37;10804:172;;;;:::o;11337:127::-;11398:10;11393:3;11389:20;11386:1;11379:31;11429:4;11426:1;11419:15;11453:4;11450:1;11443:15;11469:125;11534:9;;;11555:10;;;11552:36;;;11568:18;;:::i;11599:135::-;11638:3;11659:17;;;11656:43;;11679:18;;:::i;:::-;-1:-1:-1;11726:1:20;11715:13;;11599:135::o;11739:128::-;11806:9;;;11827:11;;;11824:37;;;11841:18;;:::i;11872:251::-;11942:6;11995:2;11983:9;11974:7;11970:23;11966:32;11963:52;;;12011:1;12008;12001:12;11963:52;12043:9;12037:16;12062:31;12087:5;12062:31;:::i;12437:184::-;12507:6;12560:2;12548:9;12539:7;12535:23;12531:32;12528:52;;;12576:1;12573;12566:12;12528:52;-1:-1:-1;12599:16:20;;12437:184;-1:-1:-1;12437:184:20:o;13336:127::-;13397:10;13392:3;13388:20;13385:1;13378:31;13428:4;13425:1;13418:15;13452:4;13449:1;13442:15;14833:306;14921:6;14929;14937;14990:2;14978:9;14969:7;14965:23;14961:32;14958:52;;;15006:1;15003;14996:12;14958:52;15035:9;15029:16;15019:26;;15085:2;15074:9;15070:18;15064:25;15054:35;;15129:2;15118:9;15114:18;15108:25;15098:35;;14833:306;;;;;:::o;19962:217::-;20002:1;20028;20018:132;;20072:10;20067:3;20063:20;20060:1;20053:31;20107:4;20104:1;20097:15;20135:4;20132:1;20125:15;20018:132;-1:-1:-1;20164:9:20;;19962:217::o;20886:127::-;20947:10;20942:3;20938:20;20935:1;20928:31;20978:4;20975:1;20968:15;21002:4;20999:1;20992:15;21018:980;21280:4;21328:3;21317:9;21313:19;21359:6;21348:9;21341:25;21385:2;21423:6;21418:2;21407:9;21403:18;21396:34;21466:3;21461:2;21450:9;21446:18;21439:31;21490:6;21525;21519:13;21556:6;21548;21541:22;21594:3;21583:9;21579:19;21572:26;;21633:2;21625:6;21621:15;21607:29;;21654:1;21664:195;21678:6;21675:1;21672:13;21664:195;;;21743:13;;-1:-1:-1;;;;;21739:39:20;21727:52;;21834:15;;;;21799:12;;;;21775:1;21693:9;21664:195;;;-1:-1:-1;;;;;;;21915:32:20;;;;21910:2;21895:18;;21888:60;-1:-1:-1;;;21979:3:20;21964:19;21957:35;21876:3;21018:980;-1:-1:-1;;;21018:980:20:o;23895:127::-;23956:10;23951:3;23947:20;23944:1;23937:31;23987:4;23984:1;23977:15;24011:4;24008:1;24001:15;25143:168;25216:9;;;25247;;25264:15;;;25258:22;;25244:37;25234:71;;25285:18;;:::i;25316:1105::-;25411:6;25442:2;25485;25473:9;25464:7;25460:23;25456:32;25453:52;;;25501:1;25498;25491:12;25453:52;25534:9;25528:16;25563:18;25604:2;25596:6;25593:14;25590:34;;;25620:1;25617;25610:12;25590:34;25658:6;25647:9;25643:22;25633:32;;25703:7;25696:4;25692:2;25688:13;25684:27;25674:55;;25725:1;25722;25715:12;25674:55;25754:2;25748:9;25776:2;25772;25769:10;25766:36;;;25782:18;;:::i;:::-;25828:2;25825:1;25821:10;25860:2;25854:9;25923:2;25919:7;25914:2;25910;25906:11;25902:25;25894:6;25890:38;25978:6;25966:10;25963:22;25958:2;25946:10;25943:18;25940:46;25937:72;;;25989:18;;:::i;:::-;26025:2;26018:22;26075:18;;;26109:15;;;;-1:-1:-1;26151:11:20;;;26147:20;;;26179:19;;;26176:39;;;26211:1;26208;26201:12;26176:39;26235:11;;;;26255:135;26271:6;26266:3;26263:15;26255:135;;;26337:10;;26325:23;;26288:12;;;;26368;;;;26255:135;;;26409:6;25316:1105;-1:-1:-1;;;;;;;;25316:1105:20:o

Swarm Source

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