ETH Price: $2,508.95 (+0.29%)
Gas: 2.79 Gwei

Token

Blueberry (BLB)
 

Overview

Max Total Supply

1,000,000,000 BLB

Holders

446

Market

Price

$0.00 @ 0.000001 ETH (+0.25%)

Onchain Market Cap

$1,387,780.00

Circulating Supply Market Cap

$0.00

Other Info

Token Contract (WITH 18 Decimals)

Balance
900 BLB

Value
$1.25 ( ~0.000498217011856699 Eth) [0.0001%]
0x4aab1f7fe5373b0719029b76351f0d98723a4dad
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Blueberry is a fully decentralized, permissionless marketplace for lending and leveraged borrowing. Borrowers can access leverage for the best delta-neutral strategies in DeFi, from stablecoins to LST's to RWA's.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
BlueberryToken

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 6 : BlueberryToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./IBlueberryToken.sol";

contract BlueberryToken is IBlueberryToken {
    using SafeERC20 for IERC20;

    // EIP-20 token name for this token
    string public constant override name = "Blueberry";

    // EIP-20 token symbol for this token
    string public constant override symbol = "BLB";

    // EIP-20 token decimals for this token
    uint8 public constant override decimals = 18;

    // Total number of tokens in circulation
    // Initially capped at 1 billion BLB
    // On top of it 2% extra (inflactionary) tokens can be minted in 1 year intervals
    uint256 public override totalSupply = 1_000_000_000e18;

    // Address which may mint inflationary tokens
    address public override minter;

    // The timestamp after which inflationary minting may occur
    uint256 public override mintingAllowedAfter;

    // Minimum time between inflationary mints
    uint32 public constant override minimumTimeBetweenMints = 1 days * 365;

    // Cap on the percentage of totalSupply that can be minted at each inflationary mint
    uint8 public constant override mintCap = 2;

    // constant that represents 100%
    uint256 constant PERCENT = 100;

    address constant NULL_ADDRESS = address(0);

    // Allowance amounts on behalf of others
    mapping(address => mapping(address => uint96)) internal allowances;

    // Official record of token balances for each account
    mapping(address => uint96) internal balances;

    // A record of each accounts delegate
    mapping(address => address) public override delegates;

    // A checkpoint for marking number of votes from a given block
    struct Checkpoint {
        uint32 fromBlock;
        uint96 votes;
    }

    // A record of votes checkpoints for each account, by index
    mapping(address => mapping(uint32 => Checkpoint))
        public
        override checkpoints;

    // The number of checkpoints for each account
    mapping(address => uint32) public override numCheckpoints;

    // The EIP-712 typehash for the contract's domain
    bytes32 public constant override DOMAIN_TYPEHASH =
        keccak256(
            "EIP712Domain(string name,uint256 chainId,address verifyingContract)"
        );

    // The EIP-712 typehash for the delegation struct used by the contract
    bytes32 public constant override DELEGATION_TYPEHASH =
        keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    // The EIP-712 typehash for the permit struct used by the contract
    bytes32 public constant override PERMIT_TYPEHASH =
        keccak256(
            "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
        );

    // A record of states for signing / validating signatures
    mapping(address => uint256) public override nonces;

    /**
     * @notice Construct a new Blueberry token
     * @param account The initial account to grant 1 billion tokens
     * @param minter_ The account with minting ability
     * @param mintingAllowedAfter_ The timestamp after which inflationary minting may occur
     */
    constructor(
        address account,
        address minter_,
        uint256 mintingAllowedAfter_
    ) {
        require(
            mintingAllowedAfter_ >= block.timestamp,
            "BlueberryToken.constructor: minting can only begin after deployment"
        );
        require(
            account != NULL_ADDRESS && minter_ != NULL_ADDRESS,
            "BlueberryToken.constructor: cannot init with zero addresses"
        );

        balances[account] = uint96(totalSupply);
        minter = minter_;
        mintingAllowedAfter = mintingAllowedAfter_;

        emit Transfer(NULL_ADDRESS, account, totalSupply);
        emit MinterChanged(NULL_ADDRESS, minter);
    }

    /**
     * @notice Change the minter address
     * @param minter_ The address of the new minter
     */
    function setMinter(address minter_) external override {
        require(
            msg.sender == minter,
            "BlueberryToken.setMinter: only the minter can change the minter address"
        );
        require(
            minter_ != NULL_ADDRESS,
            "BlueberryToken.setMinter: cannot use zero address"
        );
        emit MinterChanged(minter, minter_);
        minter = minter_;
    }

    /**
     * @notice Mint new tokens
     * @param dst The address of the destination account
     * @param amount The number of tokens to be minted
     */
    function mint(address dst, uint256 amount) external override {
        require(
            msg.sender == minter,
            "BlueberryToken.mint: only the minter can mint"
        );
        require(
            block.timestamp >= mintingAllowedAfter,
            "BlueberryToken.mint: minting not allowed yet"
        );
        require(
            dst != NULL_ADDRESS,
            "BlueberryToken.mint: cannot transfer to the zero address"
        );

        // record the mint
        mintingAllowedAfter = block.timestamp + minimumTimeBetweenMints;

        // mint the amount
        uint96 amount96 = safe96(
            amount,
            "BlueberryToken.mint: amount exceeds 96 bits"
        );
        require(
            amount <= (totalSupply * mintCap) / PERCENT,
            "BlueberryToken.mint: exceeded mint cap"
        );
        totalSupply = uint256(
            safe96(
                totalSupply + amount,
                "BlueberryToken.mint: totalSupply exceeds 96 bits"
            )
        );

        // transfer the amount to the recipient
        balances[dst] = add96(
            balances[dst],
            amount96,
            "BlueberryToken.mint: destination balance overflows"
        );
        emit Transfer(NULL_ADDRESS, dst, amount);

        // move delegates
        _moveDelegates(NULL_ADDRESS, delegates[dst], amount96);
    }

    /**
     * @notice Get the number of tokens `spender` is approved to spend on behalf of `account`
     * @param _owner The address of the account holding the funds
     * @param _spender The address of the account spending the funds
     * @return The number of tokens approved
     */
    function allowance(address _owner, address _spender)
        external
        view
        override
        returns (uint256)
    {
        return uint256(allowances[_owner][_spender]);
    }

    /**
     * @notice Approve `spender` to transfer up to `amount` from `src`
     * @dev This will overwrite the approval amount for `spender`
     *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)
     * @param _spender The address of the account which may transfer tokens
     * @param _value The number of tokens that are approved (2^256-1 means infinite)
     * @return Whether or not the approval succeeded
     */
    function approve(address _spender, uint256 _value)
        external
        override
        returns (bool)
    {
        uint96 amount;
        if (_value == type(uint256).max) {
            amount = type(uint96).max;
        } else {
            amount = safe96(
                _value,
                "BlueberryToken.approve: amount exceeds 96 bits"
            );
        }

        allowances[msg.sender][_spender] = amount;

        emit Approval(msg.sender, _spender, uint256(amount));
        return true;
    }

    /**
     * @notice Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}.
     * @return domain separator
     */
    function DOMAIN_SEPARATOR() public view override returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    DOMAIN_TYPEHASH,
                    keccak256(bytes(name)),
                    getChainId(),
                    address(this)
                )
            );
    }

    /**
     * @notice Triggers an approval from owner to spends
     * @param owner The address to approve from
     * @param spender The address to be approved
     * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)
     * @param deadline The time at which to expire the signature
     * @param v The recovery byte of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function permit(
        address owner,
        address spender,
        uint256 rawAmount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external override {
        uint96 amount;
        if (rawAmount == type(uint256).max) {
            amount = type(uint96).max;
        } else {
            amount = safe96(
                rawAmount,
                "BlueberryToken.permit: amount exceeds 96 bits"
            );
        }

        bytes32 structHash = keccak256(
            abi.encode(
                PERMIT_TYPEHASH,
                owner,
                spender,
                rawAmount,
                nonces[owner]++,
                deadline
            )
        );
        bytes32 digest = keccak256(
            abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), structHash)
        );
        address signatory = ecrecover(digest, v, r, s);
        require(
            signatory != NULL_ADDRESS,
            "BlueberryToken.permit: invalid signature"
        );
        require(signatory == owner, "BlueberryToken.permit: unauthorized");
        require(
            block.timestamp <= deadline,
            "BlueberryToken.permit: signature expired"
        );

        allowances[owner][spender] = amount;

        emit Approval(owner, spender, uint256(amount));
    }

    /**
     * @notice Get the number of tokens held by the `account`
     * @param _owner The address of the account to get the balance of
     * @return The number of tokens held
     */
    function balanceOf(address _owner)
        external
        view
        override
        returns (uint256)
    {
        return uint256(balances[_owner]);
    }

    /**
     * @notice Transfer `amount` tokens from `msg.sender` to `dst`
     * @param _to The address of the destination account
     * @param _value The number of tokens to transfer
     * @return Whether or not the transfer succeeded
     */
    function transfer(address _to, uint256 _value)
        external
        override
        returns (bool)
    {
        uint96 amount = safe96(
            _value,
            "BlueberryToken.transfer: amount exceeds 96 bits"
        );
        _transferTokens(msg.sender, _to, amount);
        return true;
    }

    /**
     * @notice Transfer `amount` tokens from `src` to `dst`
     * @param _from The address of the source account
     * @param _to The address of the destination account
     * @param _value The number of tokens to transfer
     * @return Whether or not the transfer succeeded
     */
    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    ) external override returns (bool) {
        address spender = msg.sender;
        uint96 spenderAllowance = allowances[_from][spender];
        uint96 amount96 = safe96(
            _value,
            "BlueberryToken.approve: amount exceeds 96 bits"
        );

        if (spender != _from && spenderAllowance != type(uint96).max) {
            uint96 newAllowance = sub96(
                spenderAllowance,
                amount96,
                "BlueberryToken.transferFrom: transfer amount exceeds spender allowance"
            );
            allowances[_from][spender] = newAllowance;

            emit Approval(_from, spender, uint256(newAllowance));
        }

        _transferTokens(_from, _to, amount96);
        return true;
    }

    /**
     * @notice Delegate votes from `msg.sender` to `delegatee`
     * @param delegatee The address to delegate votes to
     */
    function delegate(address delegatee) public override {
        return _delegate(msg.sender, delegatee);
    }

    /**
     * @notice Delegates votes from signatory to `delegatee`
     * @param delegatee The address to delegate votes to
     * @param nonce The contract state required to match the signature
     * @param expiry The time at which to expire the signature
     * @param v The recovery byte of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public override {
        bytes32 structHash = keccak256(
            abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry)
        );
        bytes32 digest = keccak256(
            abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), structHash)
        );
        address signatory = ecrecover(digest, v, r, s);
        require(
            signatory != NULL_ADDRESS,
            "BlueberryToken.delegateBySig: invalid signature"
        );
        require(
            nonce == nonces[signatory]++,
            "BlueberryToken.delegateBySig: invalid nonce"
        );
        require(
            block.timestamp <= expiry,
            "BlueberryToken.delegateBySig: signature expired"
        );
        return _delegate(signatory, delegatee);
    }

    /**
     * @notice Gets the current votes balance for `account`
     * @param account The address to get votes balance
     * @return The number of current votes for `account`
     */
    function getCurrentVotes(address account)
        external
        view
        override
        returns (uint96)
    {
        uint32 nCheckpoints = numCheckpoints[account];
        return
            nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
    }

    /**
     * @notice Determine the prior number of votes for an account as of a block number
     * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
     * @param account The address of the account to check
     * @param blockNumber The block number to get the vote balance at
     * @return The number of votes the account had as of the given block
     */
    function getPriorVotes(address account, uint256 blockNumber)
        public
        view
        override
        returns (uint96)
    {
        require(
            blockNumber < block.number,
            "BlueberryToken.getPriorVotes: not yet determined"
        );

        uint32 nCheckpoints = numCheckpoints[account];
        if (nCheckpoints == 0) {
            return 0;
        }

        // First check most recent balance
        if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
            return checkpoints[account][nCheckpoints - 1].votes;
        }

        // Next check implicit zero balance
        if (checkpoints[account][0].fromBlock > blockNumber) {
            return 0;
        }

        uint32 lower = 0;
        uint32 upper = nCheckpoints - 1;
        while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
            Checkpoint memory cp = checkpoints[account][center];
            if (cp.fromBlock == blockNumber) {
                return cp.votes;
            } else if (cp.fromBlock < blockNumber) {
                lower = center;
            } else {
                upper = center - 1;
            }
        }
        return checkpoints[account][lower].votes;
    }

    /**
     * @notice Delegate votes from `delegator` to `delegatee`
     * @param delegator The address of the delegator
     * @param delegatee The address to delegate votes to
     */
    function _delegate(address delegator, address delegatee) internal {
        address currentDelegate = delegates[delegator];
        uint96 delegatorBalance = balances[delegator];
        delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveDelegates(currentDelegate, delegatee, delegatorBalance);
    }

    /**
     * @notice Transfer `amount` tokens from `src` to `dst`
     * @param src The address of the source account
     * @param dst The address of the destination account
     * @param amount The number of tokens to transfer
     */
    function _transferTokens(
        address src,
        address dst,
        uint96 amount
    ) internal {
        require(
            src != NULL_ADDRESS,
            "BlueberryToken._transferTokens: cannot transfer from the zero address"
        );
        require(
            dst != NULL_ADDRESS,
            "BlueberryToken._transferTokens: cannot transfer to the zero address"
        );

        balances[src] = sub96(
            balances[src],
            amount,
            "BlueberryToken._transferTokens: transfer amount exceeds balance"
        );
        balances[dst] = add96(
            balances[dst],
            amount,
            "BlueberryToken._transferTokens: transfer amount overflows"
        );
        emit Transfer(src, dst, amount);

        _moveDelegates(delegates[src], delegates[dst], amount);
    }

    /**
     * @notice Move delegate votes from `delegator` to `delegatee`
     * @param srcRep The address of the delegator
     * @param dstRep The address to delegate votes to
     * @param amount The number of tokens to delegate
     */
    function _moveDelegates(
        address srcRep,
        address dstRep,
        uint96 amount
    ) internal {
        if (srcRep != dstRep && amount > 0) {
            if (srcRep != NULL_ADDRESS) {
                uint32 srcRepNum = numCheckpoints[srcRep];
                uint96 srcRepOld = srcRepNum > 0
                    ? checkpoints[srcRep][srcRepNum - 1].votes
                    : 0;
                uint96 srcRepNew = sub96(
                    srcRepOld,
                    amount,
                    "BlueberryToken._moveVotes: vote amount underflows"
                );
                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
            }

            if (dstRep != NULL_ADDRESS) {
                uint32 dstRepNum = numCheckpoints[dstRep];
                uint96 dstRepOld = dstRepNum > 0
                    ? checkpoints[dstRep][dstRepNum - 1].votes
                    : 0;
                uint96 dstRepNew = add96(
                    dstRepOld,
                    amount,
                    "BlueberryToken._moveVotes: vote amount overflows"
                );
                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
            }
        }
    }

    /**
     * @notice Create new votes checkpoint for a `delegatee`
     * @param delegatee The address of the delegatee
     * @param nCheckpoints Current number of checkpoints for the `delegatee`
     * @param oldVotes Old number of votes
     * @param newVotes New number of votes
     */
    function _writeCheckpoint(
        address delegatee,
        uint32 nCheckpoints,
        uint96 oldVotes,
        uint96 newVotes
    ) internal {
        uint32 blockNumber = safe32(
            block.number,
            "BlueberryToken._writeCheckpoint: block number exceeds 32 bits"
        );

        if (
            nCheckpoints > 0 &&
            checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber
        ) {
            checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
        } else {
            checkpoints[delegatee][nCheckpoints] = Checkpoint(
                blockNumber,
                newVotes
            );
            numCheckpoints[delegatee] = nCheckpoints + 1;
        }

        emit DelegateVotesChanged(
            delegatee,
            uint256(oldVotes),
            uint256(newVotes)
        );
    }

    /**
     * @notice safe conversion to uint32
     * @param n number to convert
     * @param errorMessage error raised during the conversion
     * @return converted unit32 number
     */
    function safe32(uint256 n, string memory errorMessage)
        internal
        pure
        returns (uint32)
    {
        require(n < 2**32, errorMessage);
        return uint32(n);
    }

    /**
     * @notice safe conversion to uint96
     * @param n number to convert
     * @param errorMessage error raised during the conversion
     * @return converted unit96 number
     */
    function safe96(uint256 n, string memory errorMessage)
        internal
        pure
        returns (uint96)
    {
        require(n < 2**96, errorMessage);
        return uint96(n);
    }

    /**
     * @notice safe addition for uint96
     * @param a number to add
     * @param b number to add
     * @param errorMessage error raised during the conversion
     * @return the result of the addition
     */
    function add96(
        uint96 a,
        uint96 b,
        string memory errorMessage
    ) internal pure returns (uint96) {
        uint96 c = a + b;
        require(c >= a, errorMessage);
        return c;
    }

    /**
     * @notice safe subtraction for uint96
     * @param a initial number
     * @param b number to subtract
     * @param errorMessage error raised during the conversion
     * @return the result of the subtraction
     */
    function sub96(
        uint96 a,
        uint96 b,
        string memory errorMessage
    ) internal pure returns (uint96) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @notice returns the chain ID
     * @return chain ID
     */
    function getChainId() internal view returns (uint256) {
        uint256 chainId;
        assembly {
            chainId := chainid()
        }
        return chainId;
    }
}

File 2 of 6 : IBlueberryToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol";

interface IBlueberryToken is IERC20, IERC20Permit {
    // EIP-20 token name for this token
    function name() external view returns (string memory);

    // EIP-20 token symbol for this token
    function symbol() external view returns (string memory);

    // EIP-20 token decimals for this token
    function decimals() external view returns (uint8);

    // Address which may mint inflationary tokens
    function minter() external view returns (address);

    // The timestamp after which inflationary minting may occur
    function mintingAllowedAfter() external view returns (uint256);

    // Minimum time between inflationary mints
    function minimumTimeBetweenMints() external view returns (uint32);

    // Cap on the percentage of totalSupply that can be minted at each inflationary mint
    function mintCap() external view returns (uint8);

    // A record of each accounts delegate
    function delegates(address) external view returns (address);

    // A record of votes checkpoints for each account, by index
    function checkpoints(address, uint32)
        external
        view
        returns (uint32, uint96);

    // The number of checkpoints for each account
    function numCheckpoints(address) external view returns (uint32);

    // The EIP-712 typehash for the contract's domain
    function DOMAIN_TYPEHASH() external view returns (bytes32);

    // The EIP-712 typehash for the delegation struct used by the contract
    function DELEGATION_TYPEHASH() external view returns (bytes32);

    // The EIP-712 typehash for the permit struct used by the contract
    function PERMIT_TYPEHASH() external view returns (bytes32);

    // An event thats emitted when the minter address is changed
    event MinterChanged(address minter, address newMinter);

    // An event thats emitted when an account changes its delegate
    event DelegateChanged(
        address indexed delegator,
        address indexed fromDelegate,
        address indexed toDelegate
    );

    // An event thats emitted when a delegate account's vote balance changes
    event DelegateVotesChanged(
        address indexed delegate,
        uint256 previousBalance,
        uint256 newBalance
    );

    /**
     * @notice Change the minter address
     * @param minter_ The address of the new minter
     */
    function setMinter(address minter_) external;

    /**
     * @notice Mint new tokens
     * @param dst The address of the destination account
     * @param rawAmount The number of tokens to be minted
     */
    function mint(address dst, uint256 rawAmount) external;

    /**
     * @notice Delegate votes from `msg.sender` to `delegatee`
     * @param delegatee The address to delegate votes to
     */
    function delegate(address delegatee) external;

    /**
     * @notice Delegates votes from signatory to `delegatee`
     * @param delegatee The address to delegate votes to
     * @param nonce The contract state required to match the signature
     * @param expiry The time at which to expire the signature
     * @param v The recovery byte of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @notice Gets the current votes balance for `account`
     * @param account The address to get votes balance
     * @return The number of current votes for `account`
     */
    function getCurrentVotes(address account) external view returns (uint96);

    /**
     * @notice Determine the prior number of votes for an account as of a block number
     * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
     * @param account The address of the account to check
     * @param blockNumber The block number to get the vote balance at
     * @return The number of votes the account had as of the given block
     */
    function getPriorVotes(address account, uint256 blockNumber)
        external
        view
        returns (uint96);
}

File 3 of 6 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 4 of 6 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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 5 of 6 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.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 6 of 6 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.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
     * ====
     *
     * [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://diligence.consensys.net/posts/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.5.11/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);
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"minter_","type":"address"},{"internalType":"uint256","name":"mintingAllowedAfter_","type":"uint256"}],"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":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"address","name":"newMinter","type":"address"}],"name":"MinterChanged","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":"DELEGATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint32","name":"","type":"uint32"}],"name":"checkpoints","outputs":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint96","name":"votes","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPriorVotes","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumTimeBetweenMints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintCap","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintingAllowedAfter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"rawAmount","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":"minter_","type":"address"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60806040526b033b2e3c9fd0803ce80000006000553480156200002157600080fd5b506040516200484b3803806200484b833981810160405281019062000047919062000368565b428110156200008d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000849062000471565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015620000f85750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6200013a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001319062000509565b60405180910390fd5b600054600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806002819055508273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6000546040516200025491906200053c565b60405180910390a37f3b0007eb941cf645526cbb3a4fdaecda9d28ce4843167d9263b536a1f1edc0f66000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051620002b29291906200056a565b60405180910390a150505062000597565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002f582620002c8565b9050919050565b6200030781620002e8565b81146200031357600080fd5b50565b6000815190506200032781620002fc565b92915050565b6000819050919050565b62000342816200032d565b81146200034e57600080fd5b50565b600081519050620003628162000337565b92915050565b600080600060608486031215620003845762000383620002c3565b5b6000620003948682870162000316565b9350506020620003a78682870162000316565b9250506040620003ba8682870162000351565b9150509250925092565b600082825260208201905092915050565b7f426c75656265727279546f6b656e2e636f6e7374727563746f723a206d696e7460008201527f696e672063616e206f6e6c7920626567696e206166746572206465706c6f796d60208201527f656e740000000000000000000000000000000000000000000000000000000000604082015250565b600062000459604383620003c4565b91506200046682620003d5565b606082019050919050565b600060208201905081810360008301526200048c816200044a565b9050919050565b7f426c75656265727279546f6b656e2e636f6e7374727563746f723a2063616e6e60008201527f6f7420696e69742077697468207a65726f206164647265737365730000000000602082015250565b6000620004f1603b83620003c4565b9150620004fe8262000493565b604082019050919050565b600060208201905081810360008301526200052481620004e2565b9050919050565b62000536816200032d565b82525050565b60006020820190506200055360008301846200052b565b92915050565b6200056481620002e8565b82525050565b600060408201905062000581600083018562000559565b62000590602083018462000559565b9392505050565b6142a480620005a76000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80636fcfff45116100f9578063b4b5ea5711610097578063dd62ed3e11610071578063dd62ed3e14610533578063e7a324dc14610563578063f1127ed814610581578063fca3b5aa146105b2576101c4565b8063b4b5ea57146104cb578063c3cda520146104fb578063d505accf14610517576101c4565b8063782d6fe1116100d3578063782d6fe11461041d5780637ecebe001461044d57806395d89b411461047d578063a9059cbb1461049b576101c4565b80636fcfff451461039f57806370a08231146103cf57806376c71ca1146103ff576101c4565b806330b36cef1161016657806340c10f191161014057806340c10f1914610319578063587cde1e146103355780635c11d62f146103655780635c19a95c14610383576101c4565b806330b36cef146102bf578063313ce567146102dd5780633644e515146102fb576101c4565b806318160ddd116101a257806318160ddd1461023557806320606b701461025357806323b872dd1461027157806330adf81f146102a1576101c4565b806306fdde03146101c957806307546172146101e7578063095ea7b314610205575b600080fd5b6101d16105ce565b6040516101de9190612ca6565b60405180910390f35b6101ef610607565b6040516101fc9190612d09565b60405180910390f35b61021f600480360381019061021a9190612d8b565b61062d565b60405161022c9190612de6565b60405180910390f35b61023d6107b9565b60405161024a9190612e10565b60405180910390f35b61025b6107bf565b6040516102689190612e44565b60405180910390f35b61028b60048036038101906102869190612e5f565b6107e3565b6040516102989190612de6565b60405180910390f35b6102a9610a65565b6040516102b69190612e44565b60405180910390f35b6102c7610a89565b6040516102d49190612e10565b60405180910390f35b6102e5610a8f565b6040516102f29190612ece565b60405180910390f35b610303610a94565b6040516103109190612e44565b60405180910390f35b610333600480360381019061032e9190612d8b565b610b2b565b005b61034f600480360381019061034a9190612ee9565b610f11565b60405161035c9190612d09565b60405180910390f35b61036d610f44565b60405161037a9190612f35565b60405180910390f35b61039d60048036038101906103989190612ee9565b610f4c565b005b6103b960048036038101906103b49190612ee9565b610f59565b6040516103c69190612f35565b60405180910390f35b6103e960048036038101906103e49190612ee9565b610f7c565b6040516103f69190612e10565b60405180910390f35b610407610feb565b6040516104149190612ece565b60405180910390f35b61043760048036038101906104329190612d8b565b610ff0565b6040516104449190612f77565b60405180910390f35b61046760048036038101906104629190612ee9565b611429565b6040516104749190612e10565b60405180910390f35b610485611441565b6040516104929190612ca6565b60405180910390f35b6104b560048036038101906104b09190612d8b565b61147a565b6040516104c29190612de6565b60405180910390f35b6104e560048036038101906104e09190612ee9565b6114b7565b6040516104f29190612f77565b60405180910390f35b61051560048036038101906105109190612fea565b6115ae565b005b610531600480360381019061052c9190613077565b6117e2565b005b61054d60048036038101906105489190613119565b611bbe565b60405161055a9190612e10565b60405180910390f35b61056b611c6b565b6040516105789190612e44565b60405180910390f35b61059b60048036038101906105969190613185565b611c8f565b6040516105a99291906131c5565b60405180910390f35b6105cc60048036038101906105c79190612ee9565b611ce8565b005b6040518060400160405280600981526020017f426c75656265727279000000000000000000000000000000000000000000000081525081565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830361066b576bffffffffffffffffffffffff9050610690565b61068d836040518060600160405280602e8152602001614140602e9139611e86565b90505b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836bffffffffffffffffffffffff166040516107a69190612e10565b60405180910390a3600191505092915050565b60005481565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6000803390506000600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff16905060006108a6856040518060600160405280602e8152602001614140602e9139611e86565b90508673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561090057506bffffffffffffffffffffffff8016826bffffffffffffffffffffffff1614155b15610a4c57600061092a83836040518060800160405280604681526020016140bb60469139611ee4565b905080600360008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836bffffffffffffffffffffffff16604051610a429190612e10565b60405180910390a3505b610a57878783611f5e565b600193505050509392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025481565b601281565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8666040518060400160405280600981526020017f426c75656265727279000000000000000000000000000000000000000000000081525080519060200120610afc61233d565b30604051602001610b1094939291906131ee565b60405160208183030381529060405280519060200120905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb2906132a5565b60405180910390fd5b600254421015610c00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf790613337565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610c6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c66906133c9565b60405180910390fd5b6301e1338063ffffffff1642610c859190613418565b6002819055506000610caf826040518060600160405280602b8152602001614244602b9139611e86565b90506064600260ff16600054610cc5919061344c565b610ccf91906134d5565b821115610d11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0890613578565b60405180910390fd5b610d4082600054610d229190613418565b6040518060600160405280603081526020016141ab60309139611e86565b6bffffffffffffffffffffffff16600081905550610dce600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff1682604051806060016040528060328152602001613ffc6032913961234a565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e999190612e10565b60405180910390a3610f0c6000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836123c9565b505050565b60056020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6301e1338081565b610f5633826126d6565b50565b60076020528060005260406000206000915054906101000a900463ffffffff1681565b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050919050565b600281565b6000438210611034576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102b9061360a565b60405180910390fd5b6000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900463ffffffff16905060008163ffffffff16036110a0576000915050611423565b82600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006001846110ef919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160009054906101000a900463ffffffff1663ffffffff16116111b457600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600183611176919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff16915050611423565b82600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008063ffffffff16815260200190815260200160002060000160009054906101000a900463ffffffff1663ffffffff161115611235576000915050611423565b600080600183611245919061362a565b90505b8163ffffffff168163ffffffff1611156113a55760006002838361126c919061362a565b6112769190613662565b82611281919061362a565b90506000600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008363ffffffff1663ffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681525050905086816000015163ffffffff160361137457806020015195505050505050611423565b86816000015163ffffffff16101561138e5781935061139e565b60018261139b919061362a565b92505b5050611248565b600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008363ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff1693505050505b92915050565b60086020528060005260406000206000915090505481565b6040518060400160405280600381526020017f424c42000000000000000000000000000000000000000000000000000000000081525081565b60008061149f836040518060600160405280602f815260200161405f602f9139611e86565b90506114ac338583611f5e565b600191505092915050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900463ffffffff16905060008163ffffffff16116115215760006115a6565b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600060018361156f919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff165b915050919050565b60007fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8787876040516020016115e79493929190613693565b6040516020818303038152906040528051906020012090506000611609610a94565b8260405160200161161b929190613750565b6040516020818303038152906040528051906020012090506000600182878787604051600081526020016040526040516116589493929190613787565b6020604051602081039080840390855afa15801561167a573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061383e565b60405180910390fd5b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906117459061385e565b91905055881461178a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178190613918565b60405180910390fd5b864211156117cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c4906139aa565b60405180910390fd5b6117d7818a6126d6565b505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff860361181f576bffffffffffffffffffffffff9050611844565b611841866040518060600160405280602d815260200161408e602d9139611e86565b90505b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9898989600860008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906118ba9061385e565b919050558a6040516020016118d4969594939291906139ca565b60405160208183030381529060405280519060200120905060006118f6610a94565b82604051602001611908929190613750565b6040516020818303038152906040528051906020012090506000600182888888604051600081526020016040526040516119459493929190613787565b6020604051602081039080840390855afa158015611967573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d990613a9d565b60405180910390fd5b8a73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4790613b2f565b60405180910390fd5b87421115611a93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8a90613bc1565b60405180910390fd5b83600360008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508973ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925866bffffffffffffffffffffffff16604051611ba99190612e10565b60405180910390a35050505050505050505050565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff16905092915050565b7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b6006602052816000526040600020602052806000526040600020600091509150508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046bffffffffffffffffffffffff16905082565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d6f90613c79565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dde90613d0b565b60405180910390fd5b7f3b0007eb941cf645526cbb3a4fdaecda9d28ce4843167d9263b536a1f1edc0f6600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682604051611e3a929190613d2b565b60405180910390a180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006c0100000000000000000000000083108290611eda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ed19190612ca6565b60405180910390fd5b5082905092915050565b6000836bffffffffffffffffffffffff16836bffffffffffffffffffffffff1611158290611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f9190612ca6565b60405180910390fd5b508284611f559190613d54565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611fcd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc490613e2c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361203c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203390613ee4565b60405180910390fd5b6120b6600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff16826040518060600160405280603f8152602001614101603f9139611ee4565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061219d600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff16826040518060600160405280603981526020016141db6039913961234a565b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516122679190613f3f565b60405180910390a3612338600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836123c9565b505050565b6000804690508091505090565b60008083856123599190613f5a565b9050846bffffffffffffffffffffffff16816bffffffffffffffffffffffff16101583906123bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b49190612ca6565b60405180910390fd5b50809150509392505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561241357506000816bffffffffffffffffffffffff16115b156126d157600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612574576000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900463ffffffff1690506000808263ffffffff16116124b657600061253b565b600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600184612504919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff165b90506000612562828560405180606001604052806031815260200161402e60319139611ee4565b905061257086848484612896565b5050505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146126d0576000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900463ffffffff1690506000808263ffffffff1611612612576000612697565b600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600184612660919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff165b905060006126be82856040518060600160405280603081526020016142146030913961234a565b90506126cc85848484612896565b5050505b5b505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff16905082600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46128908284836123c9565b50505050565b60006128ba436040518060600160405280603d815260200161416e603d9139612bc0565b905060008463ffffffff1611801561295857508063ffffffff16600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600187612922919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160009054906101000a900463ffffffff1663ffffffff16145b156129fc5781600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006001876129ac919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160046101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550612b4d565b60405180604001604052808263ffffffff168152602001836bffffffffffffffffffffffff16815250600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008663ffffffff1663ffffffff16815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050600184612aef9190613f9a565b600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548163ffffffff021916908363ffffffff1602179055505b8473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724846bffffffffffffffffffffffff16846bffffffffffffffffffffffff16604051612bb1929190613fd2565b60405180910390a25050505050565b600064010000000083108290612c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c039190612ca6565b60405180910390fd5b5082905092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612c50578082015181840152602081019050612c35565b60008484015250505050565b6000601f19601f8301169050919050565b6000612c7882612c16565b612c828185612c21565b9350612c92818560208601612c32565b612c9b81612c5c565b840191505092915050565b60006020820190508181036000830152612cc08184612c6d565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612cf382612cc8565b9050919050565b612d0381612ce8565b82525050565b6000602082019050612d1e6000830184612cfa565b92915050565b600080fd5b612d3281612ce8565b8114612d3d57600080fd5b50565b600081359050612d4f81612d29565b92915050565b6000819050919050565b612d6881612d55565b8114612d7357600080fd5b50565b600081359050612d8581612d5f565b92915050565b60008060408385031215612da257612da1612d24565b5b6000612db085828601612d40565b9250506020612dc185828601612d76565b9150509250929050565b60008115159050919050565b612de081612dcb565b82525050565b6000602082019050612dfb6000830184612dd7565b92915050565b612e0a81612d55565b82525050565b6000602082019050612e256000830184612e01565b92915050565b6000819050919050565b612e3e81612e2b565b82525050565b6000602082019050612e596000830184612e35565b92915050565b600080600060608486031215612e7857612e77612d24565b5b6000612e8686828701612d40565b9350506020612e9786828701612d40565b9250506040612ea886828701612d76565b9150509250925092565b600060ff82169050919050565b612ec881612eb2565b82525050565b6000602082019050612ee36000830184612ebf565b92915050565b600060208284031215612eff57612efe612d24565b5b6000612f0d84828501612d40565b91505092915050565b600063ffffffff82169050919050565b612f2f81612f16565b82525050565b6000602082019050612f4a6000830184612f26565b92915050565b60006bffffffffffffffffffffffff82169050919050565b612f7181612f50565b82525050565b6000602082019050612f8c6000830184612f68565b92915050565b612f9b81612eb2565b8114612fa657600080fd5b50565b600081359050612fb881612f92565b92915050565b612fc781612e2b565b8114612fd257600080fd5b50565b600081359050612fe481612fbe565b92915050565b60008060008060008060c0878903121561300757613006612d24565b5b600061301589828a01612d40565b965050602061302689828a01612d76565b955050604061303789828a01612d76565b945050606061304889828a01612fa9565b935050608061305989828a01612fd5565b92505060a061306a89828a01612fd5565b9150509295509295509295565b600080600080600080600060e0888a03121561309657613095612d24565b5b60006130a48a828b01612d40565b97505060206130b58a828b01612d40565b96505060406130c68a828b01612d76565b95505060606130d78a828b01612d76565b94505060806130e88a828b01612fa9565b93505060a06130f98a828b01612fd5565b92505060c061310a8a828b01612fd5565b91505092959891949750929550565b600080604083850312156131305761312f612d24565b5b600061313e85828601612d40565b925050602061314f85828601612d40565b9150509250929050565b61316281612f16565b811461316d57600080fd5b50565b60008135905061317f81613159565b92915050565b6000806040838503121561319c5761319b612d24565b5b60006131aa85828601612d40565b92505060206131bb85828601613170565b9150509250929050565b60006040820190506131da6000830185612f26565b6131e76020830184612f68565b9392505050565b60006080820190506132036000830187612e35565b6132106020830186612e35565b61321d6040830185612e01565b61322a6060830184612cfa565b95945050505050565b7f426c75656265727279546f6b656e2e6d696e743a206f6e6c7920746865206d6960008201527f6e7465722063616e206d696e7400000000000000000000000000000000000000602082015250565b600061328f602d83612c21565b915061329a82613233565b604082019050919050565b600060208201905081810360008301526132be81613282565b9050919050565b7f426c75656265727279546f6b656e2e6d696e743a206d696e74696e67206e6f7460008201527f20616c6c6f776564207965740000000000000000000000000000000000000000602082015250565b6000613321602c83612c21565b915061332c826132c5565b604082019050919050565b6000602082019050818103600083015261335081613314565b9050919050565b7f426c75656265727279546f6b656e2e6d696e743a2063616e6e6f74207472616e60008201527f7366657220746f20746865207a65726f20616464726573730000000000000000602082015250565b60006133b3603883612c21565b91506133be82613357565b604082019050919050565b600060208201905081810360008301526133e2816133a6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061342382612d55565b915061342e83612d55565b9250828201905080821115613446576134456133e9565b5b92915050565b600061345782612d55565b915061346283612d55565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561349b5761349a6133e9565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006134e082612d55565b91506134eb83612d55565b9250826134fb576134fa6134a6565b5b828204905092915050565b7f426c75656265727279546f6b656e2e6d696e743a206578636565646564206d6960008201527f6e74206361700000000000000000000000000000000000000000000000000000602082015250565b6000613562602683612c21565b915061356d82613506565b604082019050919050565b6000602082019050818103600083015261359181613555565b9050919050565b7f426c75656265727279546f6b656e2e6765745072696f72566f7465733a206e6f60008201527f74207965742064657465726d696e656400000000000000000000000000000000602082015250565b60006135f4603083612c21565b91506135ff82613598565b604082019050919050565b60006020820190508181036000830152613623816135e7565b9050919050565b600061363582612f16565b915061364083612f16565b9250828203905063ffffffff81111561365c5761365b6133e9565b5b92915050565b600061366d82612f16565b915061367883612f16565b925082613688576136876134a6565b5b828204905092915050565b60006080820190506136a86000830187612e35565b6136b56020830186612cfa565b6136c26040830185612e01565b6136cf6060830184612e01565b95945050505050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b60006137196002836136d8565b9150613724826136e3565b600282019050919050565b6000819050919050565b61374a61374582612e2b565b61372f565b82525050565b600061375b8261370c565b91506137678285613739565b6020820191506137778284613739565b6020820191508190509392505050565b600060808201905061379c6000830187612e35565b6137a96020830186612ebf565b6137b66040830185612e35565b6137c36060830184612e35565b95945050505050565b7f426c75656265727279546f6b656e2e64656c656761746542795369673a20696e60008201527f76616c6964207369676e61747572650000000000000000000000000000000000602082015250565b6000613828602f83612c21565b9150613833826137cc565b604082019050919050565b600060208201905081810360008301526138578161381b565b9050919050565b600061386982612d55565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361389b5761389a6133e9565b5b600182019050919050565b7f426c75656265727279546f6b656e2e64656c656761746542795369673a20696e60008201527f76616c6964206e6f6e6365000000000000000000000000000000000000000000602082015250565b6000613902602b83612c21565b915061390d826138a6565b604082019050919050565b60006020820190508181036000830152613931816138f5565b9050919050565b7f426c75656265727279546f6b656e2e64656c656761746542795369673a20736960008201527f676e617475726520657870697265640000000000000000000000000000000000602082015250565b6000613994602f83612c21565b915061399f82613938565b604082019050919050565b600060208201905081810360008301526139c381613987565b9050919050565b600060c0820190506139df6000830189612e35565b6139ec6020830188612cfa565b6139f96040830187612cfa565b613a066060830186612e01565b613a136080830185612e01565b613a2060a0830184612e01565b979650505050505050565b7f426c75656265727279546f6b656e2e7065726d69743a20696e76616c6964207360008201527f69676e6174757265000000000000000000000000000000000000000000000000602082015250565b6000613a87602883612c21565b9150613a9282613a2b565b604082019050919050565b60006020820190508181036000830152613ab681613a7a565b9050919050565b7f426c75656265727279546f6b656e2e7065726d69743a20756e617574686f726960008201527f7a65640000000000000000000000000000000000000000000000000000000000602082015250565b6000613b19602383612c21565b9150613b2482613abd565b604082019050919050565b60006020820190508181036000830152613b4881613b0c565b9050919050565b7f426c75656265727279546f6b656e2e7065726d69743a207369676e617475726560008201527f2065787069726564000000000000000000000000000000000000000000000000602082015250565b6000613bab602883612c21565b9150613bb682613b4f565b604082019050919050565b60006020820190508181036000830152613bda81613b9e565b9050919050565b7f426c75656265727279546f6b656e2e7365744d696e7465723a206f6e6c79207460008201527f6865206d696e7465722063616e206368616e676520746865206d696e7465722060208201527f6164647265737300000000000000000000000000000000000000000000000000604082015250565b6000613c63604783612c21565b9150613c6e82613be1565b606082019050919050565b60006020820190508181036000830152613c9281613c56565b9050919050565b7f426c75656265727279546f6b656e2e7365744d696e7465723a2063616e6e6f7460008201527f20757365207a65726f2061646472657373000000000000000000000000000000602082015250565b6000613cf5603183612c21565b9150613d0082613c99565b604082019050919050565b60006020820190508181036000830152613d2481613ce8565b9050919050565b6000604082019050613d406000830185612cfa565b613d4d6020830184612cfa565b9392505050565b6000613d5f82612f50565b9150613d6a83612f50565b925082820390506bffffffffffffffffffffffff811115613d8e57613d8d6133e9565b5b92915050565b7f426c75656265727279546f6b656e2e5f7472616e73666572546f6b656e733a2060008201527f63616e6e6f74207472616e736665722066726f6d20746865207a65726f20616460208201527f6472657373000000000000000000000000000000000000000000000000000000604082015250565b6000613e16604583612c21565b9150613e2182613d94565b606082019050919050565b60006020820190508181036000830152613e4581613e09565b9050919050565b7f426c75656265727279546f6b656e2e5f7472616e73666572546f6b656e733a2060008201527f63616e6e6f74207472616e7366657220746f20746865207a65726f206164647260208201527f6573730000000000000000000000000000000000000000000000000000000000604082015250565b6000613ece604383612c21565b9150613ed982613e4c565b606082019050919050565b60006020820190508181036000830152613efd81613ec1565b9050919050565b6000819050919050565b6000613f29613f24613f1f84612f50565b613f04565b612d55565b9050919050565b613f3981613f0e565b82525050565b6000602082019050613f546000830184613f30565b92915050565b6000613f6582612f50565b9150613f7083612f50565b925082820190506bffffffffffffffffffffffff811115613f9457613f936133e9565b5b92915050565b6000613fa582612f16565b9150613fb083612f16565b9250828201905063ffffffff811115613fcc57613fcb6133e9565b5b92915050565b6000604082019050613fe76000830185612e01565b613ff46020830184612e01565b939250505056fe426c75656265727279546f6b656e2e6d696e743a2064657374696e6174696f6e2062616c616e6365206f766572666c6f7773426c75656265727279546f6b656e2e5f6d6f7665566f7465733a20766f746520616d6f756e7420756e646572666c6f7773426c75656265727279546f6b656e2e7472616e736665723a20616d6f756e7420657863656564732039362062697473426c75656265727279546f6b656e2e7065726d69743a20616d6f756e7420657863656564732039362062697473426c75656265727279546f6b656e2e7472616e7366657246726f6d3a207472616e7366657220616d6f756e742065786365656473207370656e64657220616c6c6f77616e6365426c75656265727279546f6b656e2e5f7472616e73666572546f6b656e733a207472616e7366657220616d6f756e7420657863656564732062616c616e6365426c75656265727279546f6b656e2e617070726f76653a20616d6f756e7420657863656564732039362062697473426c75656265727279546f6b656e2e5f7772697465436865636b706f696e743a20626c6f636b206e756d62657220657863656564732033322062697473426c75656265727279546f6b656e2e6d696e743a20746f74616c537570706c7920657863656564732039362062697473426c75656265727279546f6b656e2e5f7472616e73666572546f6b656e733a207472616e7366657220616d6f756e74206f766572666c6f7773426c75656265727279546f6b656e2e5f6d6f7665566f7465733a20766f746520616d6f756e74206f766572666c6f7773426c75656265727279546f6b656e2e6d696e743a20616d6f756e7420657863656564732039362062697473a264697066735822122025d57fbf1b13b860b9366aee6ba5c4a70159b790059e7605e5a7bb2d39a1483364736f6c63430008100033000000000000000000000000e4d701c6e3bfba3e50d1045a3cef4797b6165119000000000000000000000000e4d701c6e3bfba3e50d1045a3cef4797b616511900000000000000000000000000000000000000000000000000000000677582a0

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80636fcfff45116100f9578063b4b5ea5711610097578063dd62ed3e11610071578063dd62ed3e14610533578063e7a324dc14610563578063f1127ed814610581578063fca3b5aa146105b2576101c4565b8063b4b5ea57146104cb578063c3cda520146104fb578063d505accf14610517576101c4565b8063782d6fe1116100d3578063782d6fe11461041d5780637ecebe001461044d57806395d89b411461047d578063a9059cbb1461049b576101c4565b80636fcfff451461039f57806370a08231146103cf57806376c71ca1146103ff576101c4565b806330b36cef1161016657806340c10f191161014057806340c10f1914610319578063587cde1e146103355780635c11d62f146103655780635c19a95c14610383576101c4565b806330b36cef146102bf578063313ce567146102dd5780633644e515146102fb576101c4565b806318160ddd116101a257806318160ddd1461023557806320606b701461025357806323b872dd1461027157806330adf81f146102a1576101c4565b806306fdde03146101c957806307546172146101e7578063095ea7b314610205575b600080fd5b6101d16105ce565b6040516101de9190612ca6565b60405180910390f35b6101ef610607565b6040516101fc9190612d09565b60405180910390f35b61021f600480360381019061021a9190612d8b565b61062d565b60405161022c9190612de6565b60405180910390f35b61023d6107b9565b60405161024a9190612e10565b60405180910390f35b61025b6107bf565b6040516102689190612e44565b60405180910390f35b61028b60048036038101906102869190612e5f565b6107e3565b6040516102989190612de6565b60405180910390f35b6102a9610a65565b6040516102b69190612e44565b60405180910390f35b6102c7610a89565b6040516102d49190612e10565b60405180910390f35b6102e5610a8f565b6040516102f29190612ece565b60405180910390f35b610303610a94565b6040516103109190612e44565b60405180910390f35b610333600480360381019061032e9190612d8b565b610b2b565b005b61034f600480360381019061034a9190612ee9565b610f11565b60405161035c9190612d09565b60405180910390f35b61036d610f44565b60405161037a9190612f35565b60405180910390f35b61039d60048036038101906103989190612ee9565b610f4c565b005b6103b960048036038101906103b49190612ee9565b610f59565b6040516103c69190612f35565b60405180910390f35b6103e960048036038101906103e49190612ee9565b610f7c565b6040516103f69190612e10565b60405180910390f35b610407610feb565b6040516104149190612ece565b60405180910390f35b61043760048036038101906104329190612d8b565b610ff0565b6040516104449190612f77565b60405180910390f35b61046760048036038101906104629190612ee9565b611429565b6040516104749190612e10565b60405180910390f35b610485611441565b6040516104929190612ca6565b60405180910390f35b6104b560048036038101906104b09190612d8b565b61147a565b6040516104c29190612de6565b60405180910390f35b6104e560048036038101906104e09190612ee9565b6114b7565b6040516104f29190612f77565b60405180910390f35b61051560048036038101906105109190612fea565b6115ae565b005b610531600480360381019061052c9190613077565b6117e2565b005b61054d60048036038101906105489190613119565b611bbe565b60405161055a9190612e10565b60405180910390f35b61056b611c6b565b6040516105789190612e44565b60405180910390f35b61059b60048036038101906105969190613185565b611c8f565b6040516105a99291906131c5565b60405180910390f35b6105cc60048036038101906105c79190612ee9565b611ce8565b005b6040518060400160405280600981526020017f426c75656265727279000000000000000000000000000000000000000000000081525081565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff830361066b576bffffffffffffffffffffffff9050610690565b61068d836040518060600160405280602e8152602001614140602e9139611e86565b90505b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836bffffffffffffffffffffffff166040516107a69190612e10565b60405180910390a3600191505092915050565b60005481565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6000803390506000600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff16905060006108a6856040518060600160405280602e8152602001614140602e9139611e86565b90508673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561090057506bffffffffffffffffffffffff8016826bffffffffffffffffffffffff1614155b15610a4c57600061092a83836040518060800160405280604681526020016140bb60469139611ee4565b905080600360008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836bffffffffffffffffffffffff16604051610a429190612e10565b60405180910390a3505b610a57878783611f5e565b600193505050509392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025481565b601281565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8666040518060400160405280600981526020017f426c75656265727279000000000000000000000000000000000000000000000081525080519060200120610afc61233d565b30604051602001610b1094939291906131ee565b60405160208183030381529060405280519060200120905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb2906132a5565b60405180910390fd5b600254421015610c00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf790613337565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610c6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c66906133c9565b60405180910390fd5b6301e1338063ffffffff1642610c859190613418565b6002819055506000610caf826040518060600160405280602b8152602001614244602b9139611e86565b90506064600260ff16600054610cc5919061344c565b610ccf91906134d5565b821115610d11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0890613578565b60405180910390fd5b610d4082600054610d229190613418565b6040518060600160405280603081526020016141ab60309139611e86565b6bffffffffffffffffffffffff16600081905550610dce600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff1682604051806060016040528060328152602001613ffc6032913961234a565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e999190612e10565b60405180910390a3610f0c6000600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836123c9565b505050565b60056020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6301e1338081565b610f5633826126d6565b50565b60076020528060005260406000206000915054906101000a900463ffffffff1681565b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050919050565b600281565b6000438210611034576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102b9061360a565b60405180910390fd5b6000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900463ffffffff16905060008163ffffffff16036110a0576000915050611423565b82600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006001846110ef919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160009054906101000a900463ffffffff1663ffffffff16116111b457600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600183611176919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff16915050611423565b82600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008063ffffffff16815260200190815260200160002060000160009054906101000a900463ffffffff1663ffffffff161115611235576000915050611423565b600080600183611245919061362a565b90505b8163ffffffff168163ffffffff1611156113a55760006002838361126c919061362a565b6112769190613662565b82611281919061362a565b90506000600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008363ffffffff1663ffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff1681525050905086816000015163ffffffff160361137457806020015195505050505050611423565b86816000015163ffffffff16101561138e5781935061139e565b60018261139b919061362a565b92505b5050611248565b600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008363ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff1693505050505b92915050565b60086020528060005260406000206000915090505481565b6040518060400160405280600381526020017f424c42000000000000000000000000000000000000000000000000000000000081525081565b60008061149f836040518060600160405280602f815260200161405f602f9139611e86565b90506114ac338583611f5e565b600191505092915050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900463ffffffff16905060008163ffffffff16116115215760006115a6565b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600060018361156f919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff165b915050919050565b60007fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8787876040516020016115e79493929190613693565b6040516020818303038152906040528051906020012090506000611609610a94565b8260405160200161161b929190613750565b6040516020818303038152906040528051906020012090506000600182878787604051600081526020016040526040516116589493929190613787565b6020604051602081039080840390855afa15801561167a573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036116f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ec9061383e565b60405180910390fd5b600860008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906117459061385e565b91905055881461178a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178190613918565b60405180910390fd5b864211156117cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c4906139aa565b60405180910390fd5b6117d7818a6126d6565b505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff860361181f576bffffffffffffffffffffffff9050611844565b611841866040518060600160405280602d815260200161408e602d9139611e86565b90505b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9898989600860008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906118ba9061385e565b919050558a6040516020016118d4969594939291906139ca565b60405160208183030381529060405280519060200120905060006118f6610a94565b82604051602001611908929190613750565b6040516020818303038152906040528051906020012090506000600182888888604051600081526020016040526040516119459493929190613787565b6020604051602081039080840390855afa158015611967573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d990613a9d565b60405180910390fd5b8a73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4790613b2f565b60405180910390fd5b87421115611a93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8a90613bc1565b60405180910390fd5b83600360008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508973ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925866bffffffffffffffffffffffff16604051611ba99190612e10565b60405180910390a35050505050505050505050565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff16905092915050565b7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b6006602052816000526040600020602052806000526040600020600091509150508060000160009054906101000a900463ffffffff16908060000160049054906101000a90046bffffffffffffffffffffffff16905082565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d6f90613c79565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dde90613d0b565b60405180910390fd5b7f3b0007eb941cf645526cbb3a4fdaecda9d28ce4843167d9263b536a1f1edc0f6600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682604051611e3a929190613d2b565b60405180910390a180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006c0100000000000000000000000083108290611eda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ed19190612ca6565b60405180910390fd5b5082905092915050565b6000836bffffffffffffffffffffffff16836bffffffffffffffffffffffff1611158290611f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3f9190612ca6565b60405180910390fd5b508284611f559190613d54565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611fcd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc490613e2c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361203c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203390613ee4565b60405180910390fd5b6120b6600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff16826040518060600160405280603f8152602001614101603f9139611ee4565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061219d600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff16826040518060600160405280603981526020016141db6039913961234a565b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516122679190613f3f565b60405180910390a3612338600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836123c9565b505050565b6000804690508091505090565b60008083856123599190613f5a565b9050846bffffffffffffffffffffffff16816bffffffffffffffffffffffff16101583906123bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b49190612ca6565b60405180910390fd5b50809150509392505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561241357506000816bffffffffffffffffffffffff16115b156126d157600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612574576000600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900463ffffffff1690506000808263ffffffff16116124b657600061253b565b600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600184612504919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff165b90506000612562828560405180606001604052806031815260200161402e60319139611ee4565b905061257086848484612896565b5050505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146126d0576000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900463ffffffff1690506000808263ffffffff1611612612576000612697565b600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600184612660919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046bffffffffffffffffffffffff165b905060006126be82856040518060600160405280603081526020016142146030913961234a565b90506126cc85848484612896565b5050505b5b505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046bffffffffffffffffffffffff16905082600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46128908284836123c9565b50505050565b60006128ba436040518060600160405280603d815260200161416e603d9139612bc0565b905060008463ffffffff1611801561295857508063ffffffff16600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000600187612922919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160009054906101000a900463ffffffff1663ffffffff16145b156129fc5781600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006001876129ac919061362a565b63ffffffff1663ffffffff16815260200190815260200160002060000160046101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550612b4d565b60405180604001604052808263ffffffff168152602001836bffffffffffffffffffffffff16815250600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008663ffffffff1663ffffffff16815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050600184612aef9190613f9a565b600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548163ffffffff021916908363ffffffff1602179055505b8473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724846bffffffffffffffffffffffff16846bffffffffffffffffffffffff16604051612bb1929190613fd2565b60405180910390a25050505050565b600064010000000083108290612c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c039190612ca6565b60405180910390fd5b5082905092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612c50578082015181840152602081019050612c35565b60008484015250505050565b6000601f19601f8301169050919050565b6000612c7882612c16565b612c828185612c21565b9350612c92818560208601612c32565b612c9b81612c5c565b840191505092915050565b60006020820190508181036000830152612cc08184612c6d565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612cf382612cc8565b9050919050565b612d0381612ce8565b82525050565b6000602082019050612d1e6000830184612cfa565b92915050565b600080fd5b612d3281612ce8565b8114612d3d57600080fd5b50565b600081359050612d4f81612d29565b92915050565b6000819050919050565b612d6881612d55565b8114612d7357600080fd5b50565b600081359050612d8581612d5f565b92915050565b60008060408385031215612da257612da1612d24565b5b6000612db085828601612d40565b9250506020612dc185828601612d76565b9150509250929050565b60008115159050919050565b612de081612dcb565b82525050565b6000602082019050612dfb6000830184612dd7565b92915050565b612e0a81612d55565b82525050565b6000602082019050612e256000830184612e01565b92915050565b6000819050919050565b612e3e81612e2b565b82525050565b6000602082019050612e596000830184612e35565b92915050565b600080600060608486031215612e7857612e77612d24565b5b6000612e8686828701612d40565b9350506020612e9786828701612d40565b9250506040612ea886828701612d76565b9150509250925092565b600060ff82169050919050565b612ec881612eb2565b82525050565b6000602082019050612ee36000830184612ebf565b92915050565b600060208284031215612eff57612efe612d24565b5b6000612f0d84828501612d40565b91505092915050565b600063ffffffff82169050919050565b612f2f81612f16565b82525050565b6000602082019050612f4a6000830184612f26565b92915050565b60006bffffffffffffffffffffffff82169050919050565b612f7181612f50565b82525050565b6000602082019050612f8c6000830184612f68565b92915050565b612f9b81612eb2565b8114612fa657600080fd5b50565b600081359050612fb881612f92565b92915050565b612fc781612e2b565b8114612fd257600080fd5b50565b600081359050612fe481612fbe565b92915050565b60008060008060008060c0878903121561300757613006612d24565b5b600061301589828a01612d40565b965050602061302689828a01612d76565b955050604061303789828a01612d76565b945050606061304889828a01612fa9565b935050608061305989828a01612fd5565b92505060a061306a89828a01612fd5565b9150509295509295509295565b600080600080600080600060e0888a03121561309657613095612d24565b5b60006130a48a828b01612d40565b97505060206130b58a828b01612d40565b96505060406130c68a828b01612d76565b95505060606130d78a828b01612d76565b94505060806130e88a828b01612fa9565b93505060a06130f98a828b01612fd5565b92505060c061310a8a828b01612fd5565b91505092959891949750929550565b600080604083850312156131305761312f612d24565b5b600061313e85828601612d40565b925050602061314f85828601612d40565b9150509250929050565b61316281612f16565b811461316d57600080fd5b50565b60008135905061317f81613159565b92915050565b6000806040838503121561319c5761319b612d24565b5b60006131aa85828601612d40565b92505060206131bb85828601613170565b9150509250929050565b60006040820190506131da6000830185612f26565b6131e76020830184612f68565b9392505050565b60006080820190506132036000830187612e35565b6132106020830186612e35565b61321d6040830185612e01565b61322a6060830184612cfa565b95945050505050565b7f426c75656265727279546f6b656e2e6d696e743a206f6e6c7920746865206d6960008201527f6e7465722063616e206d696e7400000000000000000000000000000000000000602082015250565b600061328f602d83612c21565b915061329a82613233565b604082019050919050565b600060208201905081810360008301526132be81613282565b9050919050565b7f426c75656265727279546f6b656e2e6d696e743a206d696e74696e67206e6f7460008201527f20616c6c6f776564207965740000000000000000000000000000000000000000602082015250565b6000613321602c83612c21565b915061332c826132c5565b604082019050919050565b6000602082019050818103600083015261335081613314565b9050919050565b7f426c75656265727279546f6b656e2e6d696e743a2063616e6e6f74207472616e60008201527f7366657220746f20746865207a65726f20616464726573730000000000000000602082015250565b60006133b3603883612c21565b91506133be82613357565b604082019050919050565b600060208201905081810360008301526133e2816133a6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061342382612d55565b915061342e83612d55565b9250828201905080821115613446576134456133e9565b5b92915050565b600061345782612d55565b915061346283612d55565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561349b5761349a6133e9565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006134e082612d55565b91506134eb83612d55565b9250826134fb576134fa6134a6565b5b828204905092915050565b7f426c75656265727279546f6b656e2e6d696e743a206578636565646564206d6960008201527f6e74206361700000000000000000000000000000000000000000000000000000602082015250565b6000613562602683612c21565b915061356d82613506565b604082019050919050565b6000602082019050818103600083015261359181613555565b9050919050565b7f426c75656265727279546f6b656e2e6765745072696f72566f7465733a206e6f60008201527f74207965742064657465726d696e656400000000000000000000000000000000602082015250565b60006135f4603083612c21565b91506135ff82613598565b604082019050919050565b60006020820190508181036000830152613623816135e7565b9050919050565b600061363582612f16565b915061364083612f16565b9250828203905063ffffffff81111561365c5761365b6133e9565b5b92915050565b600061366d82612f16565b915061367883612f16565b925082613688576136876134a6565b5b828204905092915050565b60006080820190506136a86000830187612e35565b6136b56020830186612cfa565b6136c26040830185612e01565b6136cf6060830184612e01565b95945050505050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b60006137196002836136d8565b9150613724826136e3565b600282019050919050565b6000819050919050565b61374a61374582612e2b565b61372f565b82525050565b600061375b8261370c565b91506137678285613739565b6020820191506137778284613739565b6020820191508190509392505050565b600060808201905061379c6000830187612e35565b6137a96020830186612ebf565b6137b66040830185612e35565b6137c36060830184612e35565b95945050505050565b7f426c75656265727279546f6b656e2e64656c656761746542795369673a20696e60008201527f76616c6964207369676e61747572650000000000000000000000000000000000602082015250565b6000613828602f83612c21565b9150613833826137cc565b604082019050919050565b600060208201905081810360008301526138578161381b565b9050919050565b600061386982612d55565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361389b5761389a6133e9565b5b600182019050919050565b7f426c75656265727279546f6b656e2e64656c656761746542795369673a20696e60008201527f76616c6964206e6f6e6365000000000000000000000000000000000000000000602082015250565b6000613902602b83612c21565b915061390d826138a6565b604082019050919050565b60006020820190508181036000830152613931816138f5565b9050919050565b7f426c75656265727279546f6b656e2e64656c656761746542795369673a20736960008201527f676e617475726520657870697265640000000000000000000000000000000000602082015250565b6000613994602f83612c21565b915061399f82613938565b604082019050919050565b600060208201905081810360008301526139c381613987565b9050919050565b600060c0820190506139df6000830189612e35565b6139ec6020830188612cfa565b6139f96040830187612cfa565b613a066060830186612e01565b613a136080830185612e01565b613a2060a0830184612e01565b979650505050505050565b7f426c75656265727279546f6b656e2e7065726d69743a20696e76616c6964207360008201527f69676e6174757265000000000000000000000000000000000000000000000000602082015250565b6000613a87602883612c21565b9150613a9282613a2b565b604082019050919050565b60006020820190508181036000830152613ab681613a7a565b9050919050565b7f426c75656265727279546f6b656e2e7065726d69743a20756e617574686f726960008201527f7a65640000000000000000000000000000000000000000000000000000000000602082015250565b6000613b19602383612c21565b9150613b2482613abd565b604082019050919050565b60006020820190508181036000830152613b4881613b0c565b9050919050565b7f426c75656265727279546f6b656e2e7065726d69743a207369676e617475726560008201527f2065787069726564000000000000000000000000000000000000000000000000602082015250565b6000613bab602883612c21565b9150613bb682613b4f565b604082019050919050565b60006020820190508181036000830152613bda81613b9e565b9050919050565b7f426c75656265727279546f6b656e2e7365744d696e7465723a206f6e6c79207460008201527f6865206d696e7465722063616e206368616e676520746865206d696e7465722060208201527f6164647265737300000000000000000000000000000000000000000000000000604082015250565b6000613c63604783612c21565b9150613c6e82613be1565b606082019050919050565b60006020820190508181036000830152613c9281613c56565b9050919050565b7f426c75656265727279546f6b656e2e7365744d696e7465723a2063616e6e6f7460008201527f20757365207a65726f2061646472657373000000000000000000000000000000602082015250565b6000613cf5603183612c21565b9150613d0082613c99565b604082019050919050565b60006020820190508181036000830152613d2481613ce8565b9050919050565b6000604082019050613d406000830185612cfa565b613d4d6020830184612cfa565b9392505050565b6000613d5f82612f50565b9150613d6a83612f50565b925082820390506bffffffffffffffffffffffff811115613d8e57613d8d6133e9565b5b92915050565b7f426c75656265727279546f6b656e2e5f7472616e73666572546f6b656e733a2060008201527f63616e6e6f74207472616e736665722066726f6d20746865207a65726f20616460208201527f6472657373000000000000000000000000000000000000000000000000000000604082015250565b6000613e16604583612c21565b9150613e2182613d94565b606082019050919050565b60006020820190508181036000830152613e4581613e09565b9050919050565b7f426c75656265727279546f6b656e2e5f7472616e73666572546f6b656e733a2060008201527f63616e6e6f74207472616e7366657220746f20746865207a65726f206164647260208201527f6573730000000000000000000000000000000000000000000000000000000000604082015250565b6000613ece604383612c21565b9150613ed982613e4c565b606082019050919050565b60006020820190508181036000830152613efd81613ec1565b9050919050565b6000819050919050565b6000613f29613f24613f1f84612f50565b613f04565b612d55565b9050919050565b613f3981613f0e565b82525050565b6000602082019050613f546000830184613f30565b92915050565b6000613f6582612f50565b9150613f7083612f50565b925082820190506bffffffffffffffffffffffff811115613f9457613f936133e9565b5b92915050565b6000613fa582612f16565b9150613fb083612f16565b9250828201905063ffffffff811115613fcc57613fcb6133e9565b5b92915050565b6000604082019050613fe76000830185612e01565b613ff46020830184612e01565b939250505056fe426c75656265727279546f6b656e2e6d696e743a2064657374696e6174696f6e2062616c616e6365206f766572666c6f7773426c75656265727279546f6b656e2e5f6d6f7665566f7465733a20766f746520616d6f756e7420756e646572666c6f7773426c75656265727279546f6b656e2e7472616e736665723a20616d6f756e7420657863656564732039362062697473426c75656265727279546f6b656e2e7065726d69743a20616d6f756e7420657863656564732039362062697473426c75656265727279546f6b656e2e7472616e7366657246726f6d3a207472616e7366657220616d6f756e742065786365656473207370656e64657220616c6c6f77616e6365426c75656265727279546f6b656e2e5f7472616e73666572546f6b656e733a207472616e7366657220616d6f756e7420657863656564732062616c616e6365426c75656265727279546f6b656e2e617070726f76653a20616d6f756e7420657863656564732039362062697473426c75656265727279546f6b656e2e5f7772697465436865636b706f696e743a20626c6f636b206e756d62657220657863656564732033322062697473426c75656265727279546f6b656e2e6d696e743a20746f74616c537570706c7920657863656564732039362062697473426c75656265727279546f6b656e2e5f7472616e73666572546f6b656e733a207472616e7366657220616d6f756e74206f766572666c6f7773426c75656265727279546f6b656e2e5f6d6f7665566f7465733a20766f746520616d6f756e74206f766572666c6f7773426c75656265727279546f6b656e2e6d696e743a20616d6f756e7420657863656564732039362062697473a264697066735822122025d57fbf1b13b860b9366aee6ba5c4a70159b790059e7605e5a7bb2d39a1483364736f6c63430008100033

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

000000000000000000000000e4d701c6e3bfba3e50d1045a3cef4797b6165119000000000000000000000000e4d701c6e3bfba3e50d1045a3cef4797b616511900000000000000000000000000000000000000000000000000000000677582a0

-----Decoded View---------------
Arg [0] : account (address): 0xE4D701c6E3bFbA3e50D1045A3cef4797b6165119
Arg [1] : minter_ (address): 0xE4D701c6E3bFbA3e50D1045A3cef4797b6165119
Arg [2] : mintingAllowedAfter_ (uint256): 1735754400

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000e4d701c6e3bfba3e50d1045a3cef4797b6165119
Arg [1] : 000000000000000000000000e4d701c6e3bfba3e50d1045a3cef4797b6165119
Arg [2] : 00000000000000000000000000000000000000000000000000000000677582a0


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.