ETH Price: $3,354.29 (+1.65%)
 

Overview

Max Total Supply

590,752.264906585457379067 SSP

Holders

143

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
17,636.436358729226030452 SSP

Value
$0.00
0xdF9945e3f7D1F565141528adEADf4fD7495a0bD2
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
NFTMiner

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-04-15
*/

// Sources flattened with hardhat v2.13.0 https://hardhat.org

// File @openzeppelin/contracts/utils/[email protected]

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

pragma solidity ^0.8.0;

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

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


// File @openzeppelin/contracts/access/[email protected]


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/token/ERC20/[email protected]


// 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 @openzeppelin/contracts/token/ERC20/extensions/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}


// File @openzeppelin/contracts/token/ERC20/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;



/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}


// File @openzeppelin/contracts/token/ERC20/extensions/[email protected]


// 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 @openzeppelin/contracts/utils/[email protected]


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


// File @openzeppelin/contracts/token/ERC20/utils/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;



/**
 * @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 @openzeppelin/contracts/security/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}


// File @openzeppelin/contracts/utils/math/[email protected]


// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/structs/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}


// File contracts/interfaces/IMasterChefBSC.sol


pragma solidity ^0.8.0;

interface IMasterChefBSC {
    function pendingCake(uint256 pid, address user) external view returns (uint256);

    function deposit(uint256 pid, uint256 amount) external;

    function withdraw(uint256 pid, uint256 amount) external;

    function emergencyWithdraw(uint256 pid) external;
}


// File contracts/interfaces/IMintNft.sol


pragma solidity ^0.8.0;

interface IMintNft {
    function mint(address to) external;
}


// File contracts/NFTMiner.sol



pragma solidity ^0.8.0;








contract NFTMiner is Ownable, ERC20 {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    using EnumerableSet for EnumerableSet.AddressSet;
    EnumerableSet.AddressSet private _multLP;

    // Info of each user.
    struct UserInfo {
        uint256 amount;     // How many LP tokens the user has provided.
        uint256 rewardDebt; // Reward debt.
        uint256 multLpRewardDebt; //multLp Reward debt.
    }

    // Info of each pool.
    struct PoolInfo {
        IERC20 lpToken;           // Address of LP token contract.
        uint256 allocPoint;       // How many allocation points assigned to this pool. coins to distribute per block.
        uint256 lastRewardBlock;  // Last block number that coins distribution occurs.
        uint256 accPerShare; // Accumulated coins per share, times 1e12.
        uint256 accMultLpPerShare; //Accumulated multLp per share
        uint256 totalAmount;    // Total amount of current pool deposit.
    }

    // coin tokens created per block.
    uint256 public perBlock = 500000000000000000;
//    uint256 public perBlock = 100*10**18;
    // Info of each pool.
    PoolInfo[] public poolInfo;
    // Info of each user that stakes LP tokens.
    mapping(uint256 => mapping(address => UserInfo)) public userInfo;
    // Corresponding to the pid of the multLP pool
    mapping(uint256 => uint256) public poolCorrespond;
    // pid corresponding address
    mapping(address => uint256) public LpOfPid;
    // Control mining
    bool public paused = false;
    // Total allocation points. Must be the sum of all allocation points in all pools.
    uint256 public totalAllocPoint = 0;
    // The block number when coin mining starts.
    uint256 public startBlock;
    uint256 public endBlock;
    // multLP MasterChef
    address public multLpChef;
    // multLP Token
    address public multLpToken;
    // How many blocks are halved
    uint256 public halvingPeriod = 999999999;
    uint256 public perNFTBurn = 100 * 10 ** 18;
    address public nft;
    uint256 public totalQuota;
    uint256 public soldQuota;

    event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
    event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);

    constructor(string memory name_, string memory symbol_,
        uint256 _startBlock, uint256 _endBlock, address _nft, uint256 _quota
    ) ERC20(name_, symbol_){
        startBlock = _startBlock;
        endBlock = _endBlock;
        nft = _nft;
        totalQuota = _quota;
    }
    function setNFT(address _nft) public onlyOwner {
        require(_nft != address(0), 'Address is zero address');
        nft = _nft;
    }
    modifier isOpening() {
        uint256 b = block.number;
        require(startBlock <= b && b <= endBlock, "Not in opening period");
        _;
    }
    // Set the number of coin produced by each block
    function setPerBlock(uint256 newPerBlock) public onlyOwner {
        massUpdatePools();
        perBlock = newPerBlock;
    }
    function poolLength() public view returns (uint256) {
        return poolInfo.length;
    }

    function addMultLP(address _addLP) public onlyOwner returns (bool) {
        require(_addLP != address(0), "LP is the zero address");
        IERC20(_addLP).approve(multLpChef, type(uint256).max);
        return EnumerableSet.add(_multLP, _addLP);
    }

    function isMultLP(address _LP) public view returns (bool) {
        return EnumerableSet.contains(_multLP, _LP);
    }

    function getMultLPLength() public view returns (uint256) {
        return EnumerableSet.length(_multLP);
    }

    function getMultLPAddress(uint256 _pid) public view returns (address){
        require(_pid <= getMultLPLength() - 1, "not find this multLP");
        return EnumerableSet.at(_multLP, _pid);
    }

    function setPause() public onlyOwner {
        paused = !paused;
    }

    function setMultLP(address _multLpToken, address _multLpChef) public onlyOwner {
        require(_multLpToken != address(0) && _multLpChef != address(0), "is the zero address");
        multLpToken = _multLpToken;
        multLpChef = _multLpChef;
    }

    function replaceMultLP(address _multLpToken, address _multLpChef) public onlyOwner {
        require(_multLpToken != address(0) && _multLpChef != address(0), "is the zero address");
        require(paused == true, "No mining suspension");
        multLpToken = _multLpToken;
        multLpChef = _multLpChef;
        uint256 length = getMultLPLength();
        while (length > 0) {
            address dAddress = EnumerableSet.at(_multLP, 0);
            uint256 pid = LpOfPid[dAddress];
            IMasterChefBSC(multLpChef).emergencyWithdraw(poolCorrespond[pid]);
            EnumerableSet.remove(_multLP, dAddress);
            length--;
        }
    }

    // Add a new lp to the pool. Can only be called by the owner.
    // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.
    function add(uint256 _allocPoint, IERC20 _lpToken, bool _withUpdate) public onlyOwner {
        require(address(_lpToken) != address(0), "_lpToken is the zero address");
        if (_withUpdate) {
            massUpdatePools();
        }
        uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
        totalAllocPoint = totalAllocPoint.add(_allocPoint);
        poolInfo.push(PoolInfo({
        lpToken : _lpToken,
        allocPoint : _allocPoint,
        lastRewardBlock : lastRewardBlock,
        accPerShare : 0,
        accMultLpPerShare : 0,
        totalAmount : 0
        }));
        LpOfPid[address(_lpToken)] = poolLength() - 1;
    }

    // Update the given pool's coin allocation point. Can only be called by the owner.
    function set(uint256 _pid, uint256 _allocPoint, bool _withUpdate) public onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
        poolInfo[_pid].allocPoint = _allocPoint;
    }

    // The current pool corresponds to the pid of the multLP pool
    function setPoolCorr(uint256 _pid, uint256 _sid) public onlyOwner {
        require(_pid <= poolLength() - 1, "not find this pool");
        poolCorrespond[_pid] = _sid;
    }

    function phase(uint256 blockNumber) public view returns (uint256) {
        if (halvingPeriod == 0) {
            return 0;
        }
        if (blockNumber > startBlock) {
            return (blockNumber.sub(startBlock).sub(1)).div(halvingPeriod);
        }
        return 0;
    }

    function reward(uint256 blockNumber) public view returns (uint256) {
        uint256 _phase = phase(blockNumber);
        return perBlock.div(2 ** _phase).mul(poolLength());
    }

    function getBlockReward(uint256 _lastRewardBlock) public view returns (uint256) {
        uint256 blockReward = 0;
        uint256 n = phase(_lastRewardBlock);
        uint256 m = phase(block.number);
        while (n < m) {
            n++;
            uint256 r = n.mul(halvingPeriod).add(startBlock);
            blockReward = blockReward.add((r.sub(_lastRewardBlock)).mul(reward(r)));
            _lastRewardBlock = r;
        }
        blockReward = blockReward.add((block.number.sub(_lastRewardBlock)).mul(reward(block.number)));
        return blockReward;
    }

    // Update reward variables for all pools. Be careful of gas spending!
    function massUpdatePools() public {
        uint256 length = poolInfo.length;
        for (uint256 pid = 0; pid < length; ++pid) {
            updatePool(pid);
        }
    }

    // Update reward variables of the given pool to be up-to-date.
    function updatePool(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        if (block.number <= pool.lastRewardBlock) {
            return;
        }
        uint256 lpSupply;
        if (isMultLP(address(pool.lpToken))) {
            if (pool.totalAmount == 0) {
                pool.lastRewardBlock = block.number;
                return;
            }
            lpSupply = pool.totalAmount;
        } else {
            lpSupply = pool.lpToken.balanceOf(address(this));
            if (lpSupply == 0) {
                pool.lastRewardBlock = block.number;
                return;
            }
        }
        uint256 blockReward = getBlockReward(pool.lastRewardBlock);
        if (blockReward <= 0) {
            return;
        }
        uint256 coinReward = blockReward.mul(pool.allocPoint).div(totalAllocPoint);

        pool.accPerShare = pool.accPerShare.add(coinReward.mul(1e12).div(lpSupply));
        pool.lastRewardBlock = block.number;
    }

    // View function to see pending coins on frontend.
    function pending(uint256 _pid, address _user) external view returns (uint256, uint256){
        PoolInfo storage pool = poolInfo[_pid];
        if (isMultLP(address(pool.lpToken))) {
            (uint256 amount, uint256 tokenAmount) = pendingCoinAndToken(_pid, _user);
            return (amount, tokenAmount);
        } else {
            uint256 amount = pendingCoin(_pid, _user);
            return (amount, 0);
        }
    }

    function pendingCoinAndToken(uint256 _pid, address _user) private view returns (uint256, uint256){
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        uint256 accPerShare = pool.accPerShare;
        uint256 accMultLpPerShare = pool.accMultLpPerShare;
        if (user.amount > 0) {
            uint256 TokenPending = IMasterChefBSC(multLpChef).pendingCake(poolCorrespond[_pid], address(this));
            accMultLpPerShare = accMultLpPerShare.add(TokenPending.mul(1e12).div(pool.totalAmount));
            uint256 userPending = user.amount.mul(accMultLpPerShare).div(1e12).sub(user.multLpRewardDebt);
            if (block.number > pool.lastRewardBlock) {
                uint256 blockReward = getBlockReward(pool.lastRewardBlock);
                uint256 coinReward = blockReward.mul(pool.allocPoint).div(totalAllocPoint);
                accPerShare = accPerShare.add(coinReward.mul(1e12).div(pool.totalAmount));
                return (user.amount.mul(accPerShare).div(1e12).sub(user.rewardDebt), userPending);
            }
            if (block.number == pool.lastRewardBlock) {
                return (user.amount.mul(accPerShare).div(1e12).sub(user.rewardDebt), userPending);
            }
        }
        return (0, 0);
    }

    function pendingCoin(uint256 _pid, address _user) private view returns (uint256){
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        uint256 accPerShare = pool.accPerShare;
        uint256 lpSupply = pool.lpToken.balanceOf(address(this));
        if (user.amount > 0) {
            if (block.number > pool.lastRewardBlock) {
                uint256 blockReward = getBlockReward(pool.lastRewardBlock);
                uint256 coinReward = blockReward.mul(pool.allocPoint).div(totalAllocPoint);
                accPerShare = accPerShare.add(coinReward.mul(1e12).div(lpSupply));
                return user.amount.mul(accPerShare).div(1e12).sub(user.rewardDebt);
            }
            if (block.number == pool.lastRewardBlock) {
                return user.amount.mul(accPerShare).div(1e12).sub(user.rewardDebt);
            }
        }
        return 0;
    }

    // Deposit LP tokens to BSCPool for coin allocation.
    function deposit(uint256 _pid, uint256 _amount) public notPause isOpening {
        PoolInfo storage pool = poolInfo[_pid];
        if (isMultLP(address(pool.lpToken))) {
            depositCoinAndToken(_pid, _amount, msg.sender);
        } else {
            depositCoin(_pid, _amount, msg.sender);
        }
    }

    function depositCoinAndToken(uint256 _pid, uint256 _amount, address _user) private {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        updatePool(_pid);
        if (user.amount > 0) {
            uint256 pendingAmount = user.amount.mul(pool.accPerShare).div(1e12).sub(user.rewardDebt);
            if (pendingAmount > 0) {
                safeCoinTransfer(_user, pendingAmount);
            }
            uint256 beforeToken = IERC20(multLpToken).balanceOf(address(this));
            IMasterChefBSC(multLpChef).deposit(poolCorrespond[_pid], 0);
            uint256 afterToken = IERC20(multLpToken).balanceOf(address(this));
            pool.accMultLpPerShare = pool.accMultLpPerShare.add(afterToken.sub(beforeToken).mul(1e12).div(pool.totalAmount));
            uint256 tokenPending = user.amount.mul(pool.accMultLpPerShare).div(1e12).sub(user.multLpRewardDebt);
            if (tokenPending > 0) {
                IERC20(multLpToken).safeTransfer(_user, tokenPending);
            }
        }
        if (_amount > 0) {
            pool.lpToken.safeTransferFrom(_user, address(this), _amount);
            if (pool.totalAmount == 0) {
                IMasterChefBSC(multLpChef).deposit(poolCorrespond[_pid], _amount);
                user.amount = user.amount.add(_amount);
                pool.totalAmount = pool.totalAmount.add(_amount);
            } else {
                uint256 beforeToken = IERC20(multLpToken).balanceOf(address(this));
                IMasterChefBSC(multLpChef).deposit(poolCorrespond[_pid], _amount);
                uint256 afterToken = IERC20(multLpToken).balanceOf(address(this));
                pool.accMultLpPerShare = pool.accMultLpPerShare.add(afterToken.sub(beforeToken).mul(1e12).div(pool.totalAmount));
                user.amount = user.amount.add(_amount);
                pool.totalAmount = pool.totalAmount.add(_amount);
            }
        }
        user.rewardDebt = user.amount.mul(pool.accPerShare).div(1e12);
        user.multLpRewardDebt = user.amount.mul(pool.accMultLpPerShare).div(1e12);
        emit Deposit(_user, _pid, _amount);
    }

    function depositCoin(uint256 _pid, uint256 _amount, address _user) private {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        updatePool(_pid);
        if (user.amount > 0) {
            uint256 pendingAmount = user.amount.mul(pool.accPerShare).div(1e12).sub(user.rewardDebt);
            if (pendingAmount > 0) {
                safeCoinTransfer(_user, pendingAmount);
            }
        }
        if (_amount > 0) {
            pool.lpToken.safeTransferFrom(_user, address(this), _amount);
            user.amount = user.amount.add(_amount);
            pool.totalAmount = pool.totalAmount.add(_amount);
        }
        user.rewardDebt = user.amount.mul(pool.accPerShare).div(1e12);
        emit Deposit(_user, _pid, _amount);
    }

    // Withdraw LP tokens from BSCPool.
    function withdraw(uint256 _pid, uint256 _amount) public notPause {
        PoolInfo storage pool = poolInfo[_pid];
        if (isMultLP(address(pool.lpToken))) {
            withdrawCoinAndToken(_pid, _amount, msg.sender);
        } else {
            withdrawCoin(_pid, _amount, msg.sender);
        }
    }

    function withdrawCoinAndToken(uint256 _pid, uint256 _amount, address _user) private {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        require(user.amount >= _amount, "withdrawCoinAndToken: not good");
        updatePool(_pid);
        uint256 pendingAmount = user.amount.mul(pool.accPerShare).div(1e12).sub(user.rewardDebt);
        if (pendingAmount > 0) {
            safeCoinTransfer(_user, pendingAmount);
        }
        if (_amount > 0) {
            uint256 beforeToken = IERC20(multLpToken).balanceOf(address(this));
            IMasterChefBSC(multLpChef).withdraw(poolCorrespond[_pid], _amount);
            uint256 afterToken = IERC20(multLpToken).balanceOf(address(this));
            pool.accMultLpPerShare = pool.accMultLpPerShare.add(afterToken.sub(beforeToken).mul(1e12).div(pool.totalAmount));
            uint256 tokenPending = user.amount.mul(pool.accMultLpPerShare).div(1e12).sub(user.multLpRewardDebt);
            if (tokenPending > 0) {
                IERC20(multLpToken).safeTransfer(_user, tokenPending);
            }
            user.amount = user.amount.sub(_amount);
            pool.totalAmount = pool.totalAmount.sub(_amount);
            pool.lpToken.safeTransfer(_user, _amount);
        }
        user.rewardDebt = user.amount.mul(pool.accPerShare).div(1e12);
        user.multLpRewardDebt = user.amount.mul(pool.accMultLpPerShare).div(1e12);
        emit Withdraw(_user, _pid, _amount);
    }

    function withdrawCoin(uint256 _pid, uint256 _amount, address _user) private {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        require(user.amount >= _amount, "withdrawCoin: not good");
        updatePool(_pid);
        uint256 pendingAmount = user.amount.mul(pool.accPerShare).div(1e12).sub(user.rewardDebt);
        if (pendingAmount > 0) {
            safeCoinTransfer(_user, pendingAmount);
        }
        if (_amount > 0) {
            user.amount = user.amount.sub(_amount);
            pool.totalAmount = pool.totalAmount.sub(_amount);
            pool.lpToken.safeTransfer(_user, _amount);
        }
        user.rewardDebt = user.amount.mul(pool.accPerShare).div(1e12);
        emit Withdraw(_user, _pid, _amount);
    }

    // Withdraw without caring about rewards. EMERGENCY ONLY.
    function emergencyWithdraw(uint256 _pid) public notPause {
        PoolInfo storage pool = poolInfo[_pid];
        if (isMultLP(address(pool.lpToken))) {
            emergencyWithdrawCoinAndToken(_pid, msg.sender);
        } else {
            emergencyWithdrawCoin(_pid, msg.sender);
        }
    }

    function emergencyWithdrawCoinAndToken(uint256 _pid, address _user) private {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        uint256 amount = user.amount;
        uint256 beforeToken = IERC20(multLpToken).balanceOf(address(this));
        IMasterChefBSC(multLpChef).withdraw(poolCorrespond[_pid], amount);
        uint256 afterToken = IERC20(multLpToken).balanceOf(address(this));
        pool.accMultLpPerShare = pool.accMultLpPerShare.add(afterToken.sub(beforeToken).mul(1e12).div(pool.totalAmount));
        user.amount = 0;
        user.rewardDebt = 0;
        pool.lpToken.safeTransfer(_user, amount);
        pool.totalAmount = pool.totalAmount.sub(amount);
        emit EmergencyWithdraw(_user, _pid, amount);
    }

    function emergencyWithdrawCoin(uint256 _pid, address _user) private {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        uint256 amount = user.amount;
        user.amount = 0;
        user.rewardDebt = 0;
        pool.lpToken.safeTransfer(_user, amount);
        pool.totalAmount = pool.totalAmount.sub(amount);
        emit EmergencyWithdraw(_user, _pid, amount);
    }

    // Safe coin transfer function, just in case if rounding error causes pool to not have enough coins.
    function safeCoinTransfer(address _to, uint256 _amount) internal {
        super._mint(_to, _amount);
    }

    modifier notPause() {
        require(!paused, "Mining has been suspended");
        _;
    }
    modifier hasQuota() {
        require(soldQuota < totalQuota, "not enough quota");
        _;
    }
    function burnForExchangeNFT(uint256 _pid) external hasQuota {
        withdrawCoin(_pid, 0, msg.sender);
        if (balanceOf(msg.sender) >= perNFTBurn) {
            _burn(msg.sender, perNFTBurn);
            soldQuota = soldQuota.add(1);
            IMintNft(nft).mint(msg.sender);
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_endBlock","type":"uint256"},{"internalType":"address","name":"_nft","type":"address"},{"internalType":"uint256","name":"_quota","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":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"LpOfPid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IERC20","name":"_lpToken","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addLP","type":"address"}],"name":"addMultLP","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"burnForExchangeNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastRewardBlock","type":"uint256"}],"name":"getBlockReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getMultLPAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMultLPLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"halvingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_LP","type":"address"}],"name":"isMultLP","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"multLpChef","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multLpToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nft","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pending","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"perBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"perNFTBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"phase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolCorrespond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accPerShare","type":"uint256"},{"internalType":"uint256","name":"accMultLpPerShare","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_multLpToken","type":"address"},{"internalType":"address","name":"_multLpChef","type":"address"}],"name":"replaceMultLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"reward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_multLpToken","type":"address"},{"internalType":"address","name":"_multLpChef","type":"address"}],"name":"setMultLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nft","type":"address"}],"name":"setNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPerBlock","type":"uint256"}],"name":"setPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_sid","type":"uint256"}],"name":"setPoolCorr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"soldQuota","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalQuota","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"amount","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":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"multLpRewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526706f05b59d3b20000600855600d805460ff191690556000600e55633b9ac9ff60135568056bc75e2d631000006014553480156200004157600080fd5b506040516200430e3803806200430e8339810160408190526200006491620001dd565b85856200007133620000c8565b60046200007f838262000316565b5060056200008e828262000316565b505050600f93909355601091909155601580546001600160a01b0319166001600160a01b0390921691909117905560165550620003e29050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014057600080fd5b81516001600160401b03808211156200015d576200015d62000118565b604051601f8301601f19908116603f0116810190828211818310171562000188576200018862000118565b81604052838152602092508683858801011115620001a557600080fd5b600091505b83821015620001c95785820183015181830184015290820190620001aa565b600093810190920192909252949350505050565b60008060008060008060c08789031215620001f757600080fd5b86516001600160401b03808211156200020f57600080fd5b6200021d8a838b016200012e565b975060208901519150808211156200023457600080fd5b506200024389828a016200012e565b604089015160608a015160808b0151929850909650945090506001600160a01b03811681146200027257600080fd5b8092505060a087015190509295509295509295565b600181811c908216806200029c57607f821691505b602082108103620002bd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200031157600081815260208120601f850160051c81016020861015620002ec5750805b601f850160051c820191505b818110156200030d57828155600101620002f8565b5050505b505050565b81516001600160401b0381111562000332576200033262000118565b6200034a8162000343845462000287565b84620002c3565b602080601f831160018114620003825760008415620003695750858301515b600019600386901b1c1916600185901b1785556200030d565b600085815260208120601f198616915b82811015620003b35788860151825594840194600190910190840162000392565b5085821015620003d25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b613f1c80620003f26000396000f3fe608060405234801561001057600080fd5b50600436106103575760003560e01c806370a08231116101c8578063b0c7044b11610104578063e2bbb158116100a2578063e715e2341161007c578063e715e23414610779578063f2fde38b1461078c578063f56e9c661461079f578063fff09256146107b257600080fd5b8063e2bbb15814610736578063e4c75c2714610749578063e6ab8d481461077157600080fd5b8063d431b1ac116100de578063d431b1ac146106d9578063dbd8e476146106e1578063dd62ed3e146106ea578063dfc7b95b1461072357600080fd5b8063b0c7044b14610686578063b337d32c146106a6578063cb4502c4146106b957600080fd5b806393f1a40b11610171578063a457c2d71161014b578063a457c2d71461063a578063a9059cbb1461064d578063a9fb763c14610660578063aaae43cc1461067357600080fd5b806393f1a40b146105ca57806394f7f62b1461061f57806395d89b411461063257600080fd5b806381952c24116101a257806381952c241461059d5780638adaee58146105b05780638da5cb5b146105b957600080fd5b806370a0823114610559578063715018a6146105825780637fe6f5ac1461058a57600080fd5b80633cdd5e97116102975780635312ea8e116102405780635c975abb1161021a5780635c975abb1461051e578063630b5ba11461052b57806364482f7914610533578063705bbc011461054657600080fd5b80635312ea8e146104ef57806356c5867d146105025780635a3e251f1461051557600080fd5b806347ccca021161027157806347ccca02146104c057806348cd4cb1146104d357806351eb05a6146104dc57600080fd5b80633cdd5e97146104795780634315490714610482578063441a3e70146104ad57600080fd5b806317caf6f1116103045780631eaaa045116102de5780631eaaa0451461042f57806323b872dd14610444578063313ce56714610457578063395093511461046657600080fd5b806317caf6f11461041557806318160ddd1461041e5780631c779c2f1461042657600080fd5b8063095ea7b311610335578063095ea7b314610395578063135f8aa7146103b85780631526fe27146103cb57600080fd5b806306fdde031461035c578063081e3eda1461037a578063083c63231461038c575b600080fd5b6103646107c5565b6040516103719190613a1c565b60405180910390f35b6009545b604051908152602001610371565b61037e60105481565b6103a86103a3366004613a82565b610857565b6040519015158152602001610371565b61037e6103c6366004613aae565b610871565b6103de6103d9366004613aae565b6108c3565b604080516001600160a01b0390971687526020870195909552938501929092526060840152608083015260a082015260c001610371565b61037e600e5481565b60035461037e565b61037e60145481565b61044261043d366004613ad5565b610913565b005b6103a8610452366004613b17565b610b3b565b60405160128152602001610371565b6103a8610474366004613a82565b610b5f565b61037e60175481565b610495610490366004613aae565b610b9e565b6040516001600160a01b039091168152602001610371565b6104426104bb366004613b58565b610c0e565b601554610495906001600160a01b031681565b61037e600f5481565b6104426104ea366004613aae565b610cbd565b6104426104fd366004613aae565b610e3e565b6103a8610510366004613b7a565b610eea565b61037e60135481565b600d546103a89060ff1681565b610442610fe7565b610442610541366004613b97565b61100e565b601254610495906001600160a01b031681565b61037e610567366004613b7a565b6001600160a01b031660009081526001602052604090205490565b61044261109b565b6103a8610598366004613b7a565b6110af565b6104426105ab366004613aae565b6110bc565b61037e60165481565b6000546001600160a01b0316610495565b6106046105d8366004613bc5565b600a60209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610371565b61037e61062d366004613aae565b6110d1565b61036461117b565b6103a8610648366004613a82565b61118a565b6103a861065b366004613a82565b611234565b61037e61066e366004613aae565b611242565b610442610681366004613bf5565b61127a565b61037e610694366004613b7a565b600c6020526000908152604090205481565b6104426106b4366004613b58565b611470565b61037e6106c7366004613aae565b600b6020526000908152604090205481565b6104426114ee565b61037e60085481565b61037e6106f8366004613bf5565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b601154610495906001600160a01b031681565b610442610744366004613b58565b611528565b61075c610757366004613bc5565b61163f565b60408051928352602083019190915201610371565b61037e6116c1565b610442610787366004613bf5565b6116d2565b61044261079a366004613b7a565b61178c565b6104426107ad366004613b7a565b61181c565b6104426107c0366004613aae565b6118b4565b6060600480546107d490613c23565b80601f016020809104026020016040519081016040528092919081815260200182805461080090613c23565b801561084d5780601f106108225761010080835404028352916020019161084d565b820191906000526020600020905b81548152906001019060200180831161083057829003601f168201915b5050505050905090565b6000336108658185856119c1565b60019150505b92915050565b600060135460000361088557506000919050565b600f548211156108bb5761086b6013546108b560016108af600f5487611b1990919063ffffffff16565b90611b19565b90611b25565b506000919050565b600981815481106108d357600080fd5b60009182526020909120600690910201805460018201546002830154600384015460048501546005909501546001600160a01b0390941695509193909286565b61091b611b31565b6001600160a01b0382166109765760405162461bcd60e51b815260206004820152601c60248201527f5f6c70546f6b656e20697320746865207a65726f20616464726573730000000060448201526064015b60405180910390fd5b801561098457610984610fe7565b6000600f54431161099757600f54610999565b435b600e549091506109a99085611b8b565b600e556040805160c0810182526001600160a01b038581168252602082018781529282018481526000606084018181526080850182815260a0860183815260098054600180820183559582905297517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af600690990298890180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919098161790965596517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b087015592517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b1860155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b285015590517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b384015592517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b49092019190915554610b199190613ca5565b6001600160a01b039093166000908152600c6020526040902092909255505050565b600033610b49858285611b97565b610b54858585611c23565b506001949350505050565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091906108659082908690610b99908790613cb8565b6119c1565b60006001610baa6116c1565b610bb49190613ca5565b821115610c035760405162461bcd60e51b815260206004820152601460248201527f6e6f742066696e642074686973206d756c744c50000000000000000000000000604482015260640161096d565b61086b600683611e17565b600d5460ff1615610c615760405162461bcd60e51b815260206004820152601960248201527f4d696e696e6720686173206265656e2073757370656e64656400000000000000604482015260640161096d565b600060098381548110610c7657610c76613ccb565b600091825260209091206006909102018054909150610c9d906001600160a01b03166110af565b15610cb257610cad838333611e23565b505050565b610cad8383336121e9565b600060098281548110610cd257610cd2613ccb565b9060005260206000209060060201905080600201544311610cf1575050565b8054600090610d08906001600160a01b03166110af565b15610d2f578160050154600003610d2457504360029091015550565b506005810154610dc8565b81546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db39190613cfa565b905080600003610dc857504360029091015550565b6000610dd783600201546110d1565b905060008111610de75750505050565b6000610e06600e546108b586600101548561236490919063ffffffff16565b9050610e29610e1e846108b58464e8d4a51000612364565b600386015490611b8b565b60038501555050436002909201919091555050565b600d5460ff1615610e915760405162461bcd60e51b815260206004820152601960248201527f4d696e696e6720686173206265656e2073757370656e64656400000000000000604482015260640161096d565b600060098281548110610ea657610ea6613ccb565b600091825260209091206006909102018054909150610ecd906001600160a01b03166110af565b15610ee057610edc8233612370565b5050565b610edc82336125fc565b6000610ef4611b31565b6001600160a01b038216610f4a5760405162461bcd60e51b815260206004820152601660248201527f4c5020697320746865207a65726f206164647265737300000000000000000000604482015260640161096d565b6011546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260001960248201529083169063095ea7b3906044016020604051808303816000875af1158015610fb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdb9190613d13565b5061086b6006836126bb565b60095460005b81811015610edc57610ffe81610cbd565b61100781613d30565b9050610fed565b611016611b31565b801561102457611024610fe7565b611067826110616009868154811061103e5761103e613ccb565b906000526020600020906006020160010154600e54611b1990919063ffffffff16565b90611b8b565b600e81905550816009848154811061108157611081613ccb565b906000526020600020906006020160010181905550505050565b6110a3611b31565b6110ad60006126d0565b565b600061086b600683612738565b6110c4611b31565b6110cc610fe7565b600855565b600080806110de84610871565b905060006110eb43610871565b90505b80821015611152578161110081613d30565b9250506000611120600f546110616013548661236490919063ffffffff16565b905061114861114161113183611242565b61113b848a611b19565b90612364565b8590611b8b565b90955092506110ee565b61117261116b61116143611242565b61113b4389611b19565b8490611b8b565b95945050505050565b6060600580546107d490613c23565b3360008181526002602090815260408083206001600160a01b0387168452909152812054909190838110156112275760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161096d565b610b5482868684036119c1565b600033610865818585611c23565b60008061124e83610871565b905061127361125c60095490565b61113b61126a846002613e26565b60085490611b25565b9392505050565b611282611b31565b6001600160a01b038216158015906112a257506001600160a01b03811615155b6112ee5760405162461bcd60e51b815260206004820152601360248201527f697320746865207a65726f206164647265737300000000000000000000000000604482015260640161096d565b600d5460ff1615156001146113455760405162461bcd60e51b815260206004820152601460248201527f4e6f206d696e696e672073757370656e73696f6e000000000000000000000000604482015260640161096d565b601280546001600160a01b038085167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255601180549284169290911691909117905560006113976116c1565b90505b8015610cad5760006113ae60066000611e17565b6001600160a01b038082166000908152600c6020908152604080832054601154818552600b909352928190205490517f5312ea8e0000000000000000000000000000000000000000000000000000000081529495509193921691635312ea8e9161141e9160040190815260200190565b600060405180830381600087803b15801561143857600080fd5b505af115801561144c573d6000803e3d6000fd5b5050505061145b60068361275a565b508261146681613e32565b935050505061139a565b611478611b31565b600161148360095490565b61148d9190613ca5565b8211156114dc5760405162461bcd60e51b815260206004820152601260248201527f6e6f742066696e64207468697320706f6f6c0000000000000000000000000000604482015260640161096d565b6000918252600b602052604090912055565b6114f6611b31565b600d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b600d5460ff161561157b5760405162461bcd60e51b815260206004820152601960248201527f4d696e696e6720686173206265656e2073757370656e64656400000000000000604482015260640161096d565b600f544390811080159061159157506010548111155b6115dd5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420696e206f70656e696e6720706572696f640000000000000000000000604482015260640161096d565b6000600984815481106115f2576115f2613ccb565b600091825260209091206006909102018054909150611619906001600160a01b03166110af565b1561162e5761162984843361276f565b611639565b611639848433612d78565b50505050565b60008060006009858154811061165757611657613ccb565b60009182526020909120600690910201805490915061167e906001600160a01b03166110af565b1561169e576000806116908787612ead565b90955093506116ba92505050565b60006116aa86866130fa565b9350600092506116ba915050565b505b9250929050565b60006116cd60066132a8565b905090565b6116da611b31565b6001600160a01b038216158015906116fa57506001600160a01b03811615155b6117465760405162461bcd60e51b815260206004820152601360248201527f697320746865207a65726f206164647265737300000000000000000000000000604482015260640161096d565b601280546001600160a01b039384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560118054929093169116179055565b611794611b31565b6001600160a01b0381166118105760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161096d565b611819816126d0565b50565b611824611b31565b6001600160a01b03811661187a5760405162461bcd60e51b815260206004820152601760248201527f41646472657373206973207a65726f2061646472657373000000000000000000604482015260640161096d565b601580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b601654601754106119075760405162461bcd60e51b815260206004820152601060248201527f6e6f7420656e6f7567682071756f746100000000000000000000000000000000604482015260640161096d565b611913816000336121e9565b601454336000908152600160205260409020541061181957611937336014546132b2565b601754611945906001611b8b565b6017556015546040517f6a6278420000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911690636a62784290602401600060405180830381600087803b1580156119a657600080fd5b505af11580156119ba573d6000803e3d6000fd5b5050505050565b6001600160a01b038316611a3c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b038216611ab85760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006112738284613ca5565b60006112738284613e49565b6000546001600160a01b031633146110ad5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161096d565b60006112738284613cb8565b6001600160a01b0383811660009081526002602090815260408083209386168352929052205460001981146116395781811015611c165760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161096d565b61163984848484036119c1565b6001600160a01b038316611c9f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b038216611d1b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b03831660009081526001602052604090205481811015611daa5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b0380851660008181526001602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611e0a9086815260200190565b60405180910390a3611639565b6000611273838361341d565b600060098481548110611e3857611e38613ccb565b60009182526020808320878452600a825260408085206001600160a01b03881686529092529220805460069092029092019250841115611eba5760405162461bcd60e51b815260206004820152601e60248201527f7769746864726177436f696e416e64546f6b656e3a206e6f7420676f6f640000604482015260640161096d565b611ec385610cbd565b6000611ef182600101546108af64e8d4a510006108b58760030154876000015461236490919063ffffffff16565b90508015611f0357611f038482613447565b8415612160576012546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8f9190613cfa565b6011546000898152600b6020526040908190205490517f441a3e700000000000000000000000000000000000000000000000000000000081526004810191909152602481018990529192506001600160a01b03169063441a3e7090604401600060405180830381600087803b15801561200757600080fd5b505af115801561201b573d6000803e3d6000fd5b50506012546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa158015612083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a79190613cfa565b90506120db6120d086600501546108b564e8d4a5100061113b8787611b1990919063ffffffff16565b600487015490611b8b565b600486018190556002850154855460009261210592916108af9164e8d4a51000916108b591612364565b9050801561212457601254612124906001600160a01b03168883613451565b84546121309089611b19565b855560058601546121419089611b19565b6005870155855461215c906001600160a01b0316888a613451565b5050505b6003830154825461217b9164e8d4a51000916108b591612364565b60018301556004830154825461219b9164e8d4a51000916108b591612364565b600283015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020015b60405180910390a3505050505050565b6000600984815481106121fe576121fe613ccb565b60009182526020808320878452600a825260408085206001600160a01b038816865290925292208054600690920290920192508411156122805760405162461bcd60e51b815260206004820152601660248201527f7769746864726177436f696e3a206e6f7420676f6f6400000000000000000000604482015260640161096d565b61228985610cbd565b60006122b782600101546108af64e8d4a510006108b58760030154876000015461236490919063ffffffff16565b905080156122c9576122c98482613447565b84156123075781546122db9086611b19565b825560058301546122ec9086611b19565b60058401558254612307906001600160a01b03168587613451565b600383015482546123229164e8d4a51000916108b591612364565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020016121d9565b60006112738284613e84565b60006009838154811061238557612385613ccb565b60009182526020808320868452600a825260408085206001600160a01b0388811687529352808520805460125492517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526006969096029093019650949193919216906370a0823190602401602060405180830381865afa158015612415573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124399190613cfa565b6011546000888152600b6020526040908190205490517f441a3e700000000000000000000000000000000000000000000000000000000081526004810191909152602481018590529192506001600160a01b03169063441a3e7090604401600060405180830381600087803b1580156124b157600080fd5b505af11580156124c5573d6000803e3d6000fd5b50506012546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa15801561252d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125519190613cfa565b905061257a6120d086600501546108b564e8d4a5100061113b8787611b1990919063ffffffff16565b600486015560008085556001850155845461259f906001600160a01b03168785613451565b60058501546125ae9084611b19565b600586015560405183815287906001600160a01b038816907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a350505050505050565b60006009838154811061261157612611613ccb565b60009182526020808320868452600a825260408085206001600160a01b0380891687529352842080548582556001820195909555600690930201805490945091929161265f91168583613451565b600583015461266e9082611b19565b600584015560405181815285906001600160a01b038616907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595906020015b60405180910390a35050505050565b6000611273836001600160a01b038416613518565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811660009081526001830160205260408120541515611273565b6000611273836001600160a01b038416613567565b60006009848154811061278457612784613ccb565b60009182526020808320878452600a825260408085206001600160a01b03881686529092529220600690910290910191506127be85610cbd565b805415612a1a5760006127f382600101546108af64e8d4a510006108b58760030154876000015461236490919063ffffffff16565b90508015612805576128058482613447565b6012546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061288b9190613cfa565b6011546000898152600b60205260408082205490517fe2bbb158000000000000000000000000000000000000000000000000000000008152600481019190915260248101919091529192506001600160a01b03169063e2bbb15890604401600060405180830381600087803b15801561290357600080fd5b505af1158015612917573d6000803e3d6000fd5b50506012546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa15801561297f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a39190613cfa565b90506129cc6120d086600501546108b564e8d4a5100061113b8787611b1990919063ffffffff16565b60048601819055600285015485546000926129f692916108af9164e8d4a51000916108b591612364565b90508015612a1557601254612a15906001600160a01b03168883613451565b505050505b8315612cfb578154612a37906001600160a01b031684308761365a565b8160050154600003612aff576011546000868152600b6020526040908190205490517fe2bbb1580000000000000000000000000000000000000000000000000000000081526001600160a01b039092169163e2bbb15891612aa5918890600401918252602082015260400190565b600060405180830381600087803b158015612abf57600080fd5b505af1158015612ad3573d6000803e3d6000fd5b50508254612ae49250905085611b8b565b81556005820154612af59085611b8b565b6005830155612cfb565b6012546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b859190613cfa565b6011546000888152600b6020526040908190205490517fe2bbb1580000000000000000000000000000000000000000000000000000000081526004810191909152602481018890529192506001600160a01b03169063e2bbb15890604401600060405180830381600087803b158015612bfd57600080fd5b505af1158015612c11573d6000803e3d6000fd5b50506012546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa158015612c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9d9190613cfa565b9050612cd1612cc685600501546108b564e8d4a5100061113b8787611b1990919063ffffffff16565b600486015490611b8b565b60048501558254612ce29087611b8b565b83556005840154612cf39087611b8b565b600585015550505b60038201548154612d169164e8d4a51000916108b591612364565b600182015560048201548154612d369164e8d4a51000916108b591612364565b600282015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15906020016126ac565b600060098481548110612d8d57612d8d613ccb565b60009182526020808320878452600a825260408085206001600160a01b0388168652909252922060069091029091019150612dc785610cbd565b805415612e10576000612dfc82600101546108af64e8d4a510006108b58760030154876000015461236490919063ffffffff16565b90508015612e0e57612e0e8482613447565b505b8315612e50578154612e2d906001600160a01b031684308761365a565b8054612e399085611b8b565b81556005820154612e4a9085611b8b565b60058301555b60038201548154612e6b9164e8d4a51000916108b591612364565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15906020016126ac565b600080600060098581548110612ec557612ec5613ccb565b60009182526020808320888452600a825260408085206001600160a01b038a16865290925292206003600690920290920190810154600482015483549294509091156130ea576011546000898152600b60205260408082205490517f1175a1dd000000000000000000000000000000000000000000000000000000008152600481019190915230602482015290916001600160a01b031690631175a1dd90604401602060405180830381865afa158015612f83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa79190613cfa565b9050612fd3612fcc86600501546108b564e8d4a510008561236490919063ffffffff16565b8390611b8b565b91506000612fff85600201546108af64e8d4a510006108b5878a6000015461236490919063ffffffff16565b905085600201544311156130a557600061301c87600201546110d1565b9050600061303d600e546108b58a600101548561236490919063ffffffff16565b905061306961306289600501546108b564e8d4a510008561236490919063ffffffff16565b8790611b8b565b955061309387600101546108af64e8d4a510006108b58a8c6000015461236490919063ffffffff16565b839950995050505050505050506116ba565b856002015443036130e7576130d885600101546108af64e8d4a510006108b5888a6000015461236490919063ffffffff16565b975095506116ba945050505050565b50505b5060009788975095505050505050565b6000806009848154811061311057613110613ccb565b60009182526020808320878452600a825260408085206001600160a01b03898116875293528085206006949094029091016003810154815492517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015291965093949291909116906370a0823190602401602060405180830381865afa1580156131a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c89190613cfa565b83549091501561329b57836002015443111561325d5760006131ed85600201546110d1565b9050600061320e600e546108b588600101548561236490919063ffffffff16565b9050613226611141846108b58464e8d4a51000612364565b935061325085600101546108af64e8d4a510006108b5888a6000015461236490919063ffffffff16565b965050505050505061086b565b8360020154430361329b5761329083600101546108af64e8d4a510006108b586886000015461236490919063ffffffff16565b94505050505061086b565b5060009695505050505050565b600061086b825490565b6001600160a01b03821661332e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b038216600090815260016020526040902054818110156133bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b03831660008181526001602090815260408083208686039055600380548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b600082600001828154811061343457613434613ccb565b9060005260206000200154905092915050565b610edc82826136ab565b6040516001600160a01b038316602482015260448101829052610cad9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261376c565b600081815260018301602052604081205461355f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561086b565b50600061086b565b6000818152600183016020526040812054801561365057600061358b600183613ca5565b855490915060009061359f90600190613ca5565b90508181146136045760008660000182815481106135bf576135bf613ccb565b90600052602060002001549050808760000184815481106135e2576135e2613ccb565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061361557613615613e9b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061086b565b600091505061086b565b6040516001600160a01b03808516602483015283166044820152606481018290526116399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401613496565b6001600160a01b0382166137015760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161096d565b80600360008282546137139190613cb8565b90915550506001600160a01b0382166000818152600160209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60006137c1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138519092919063ffffffff16565b805190915015610cad57808060200190518101906137df9190613d13565b610cad5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161096d565b60606138608484600085613868565b949350505050565b6060824710156138e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161096d565b600080866001600160a01b031685876040516138fc9190613eca565b60006040518083038185875af1925050503d8060008114613939576040519150601f19603f3d011682016040523d82523d6000602084013e61393e565b606091505b509150915061394f8783838761395a565b979650505050505050565b606083156139c95782516000036139c2576001600160a01b0385163b6139c25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161096d565b5081613860565b61386083838151156139de5781518083602001fd5b8060405162461bcd60e51b815260040161096d9190613a1c565b60005b83811015613a135781810151838201526020016139fb565b50506000910152565b6020815260008251806020840152613a3b8160408501602087016139f8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6001600160a01b038116811461181957600080fd5b60008060408385031215613a9557600080fd5b8235613aa081613a6d565b946020939093013593505050565b600060208284031215613ac057600080fd5b5035919050565b801515811461181957600080fd5b600080600060608486031215613aea57600080fd5b833592506020840135613afc81613a6d565b91506040840135613b0c81613ac7565b809150509250925092565b600080600060608486031215613b2c57600080fd5b8335613b3781613a6d565b92506020840135613b4781613a6d565b929592945050506040919091013590565b60008060408385031215613b6b57600080fd5b50508035926020909101359150565b600060208284031215613b8c57600080fd5b813561127381613a6d565b600080600060608486031215613bac57600080fd5b83359250602084013591506040840135613b0c81613ac7565b60008060408385031215613bd857600080fd5b823591506020830135613bea81613a6d565b809150509250929050565b60008060408385031215613c0857600080fd5b8235613c1381613a6d565b91506020830135613bea81613a6d565b600181811c90821680613c3757607f821691505b602082108103613c70577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561086b5761086b613c76565b8082018082111561086b5761086b613c76565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215613d0c57600080fd5b5051919050565b600060208284031215613d2557600080fd5b815161127381613ac7565b60006000198203613d4357613d43613c76565b5060010190565b600181815b808511156116b8578160001904821115613d6b57613d6b613c76565b80851615613d7857918102915b93841c9390800290613d4f565b600082613d945750600161086b565b81613da15750600061086b565b8160018114613db75760028114613dc157613ddd565b600191505061086b565b60ff841115613dd257613dd2613c76565b50506001821b61086b565b5060208310610133831016604e8410600b8410161715613e00575081810a61086b565b613e0a8383613d4a565b8060001904821115613e1e57613e1e613c76565b029392505050565b60006112738383613d85565b600081613e4157613e41613c76565b506000190190565b600082613e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761086b5761086b613c76565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251613edc8184602087016139f8565b919091019291505056fea26469706673582212205bd89e0e2878a2b6e95eff8bbc6ec985a2874655ee1d45b097cfdbbf487dfce664736f6c6343000813003300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001042f47000000000000000000000000000000000000000000000000000000000115221d000000000000000000000000a58eb817dda3415fb68cb040021f5049350deb450000000000000000000000000000000000000000000000000000000000001af400000000000000000000000000000000000000000000000000000000000000155370696e6674205370616365506920506c616e6574000000000000000000000000000000000000000000000000000000000000000000000000000000000000035353500000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103575760003560e01c806370a08231116101c8578063b0c7044b11610104578063e2bbb158116100a2578063e715e2341161007c578063e715e23414610779578063f2fde38b1461078c578063f56e9c661461079f578063fff09256146107b257600080fd5b8063e2bbb15814610736578063e4c75c2714610749578063e6ab8d481461077157600080fd5b8063d431b1ac116100de578063d431b1ac146106d9578063dbd8e476146106e1578063dd62ed3e146106ea578063dfc7b95b1461072357600080fd5b8063b0c7044b14610686578063b337d32c146106a6578063cb4502c4146106b957600080fd5b806393f1a40b11610171578063a457c2d71161014b578063a457c2d71461063a578063a9059cbb1461064d578063a9fb763c14610660578063aaae43cc1461067357600080fd5b806393f1a40b146105ca57806394f7f62b1461061f57806395d89b411461063257600080fd5b806381952c24116101a257806381952c241461059d5780638adaee58146105b05780638da5cb5b146105b957600080fd5b806370a0823114610559578063715018a6146105825780637fe6f5ac1461058a57600080fd5b80633cdd5e97116102975780635312ea8e116102405780635c975abb1161021a5780635c975abb1461051e578063630b5ba11461052b57806364482f7914610533578063705bbc011461054657600080fd5b80635312ea8e146104ef57806356c5867d146105025780635a3e251f1461051557600080fd5b806347ccca021161027157806347ccca02146104c057806348cd4cb1146104d357806351eb05a6146104dc57600080fd5b80633cdd5e97146104795780634315490714610482578063441a3e70146104ad57600080fd5b806317caf6f1116103045780631eaaa045116102de5780631eaaa0451461042f57806323b872dd14610444578063313ce56714610457578063395093511461046657600080fd5b806317caf6f11461041557806318160ddd1461041e5780631c779c2f1461042657600080fd5b8063095ea7b311610335578063095ea7b314610395578063135f8aa7146103b85780631526fe27146103cb57600080fd5b806306fdde031461035c578063081e3eda1461037a578063083c63231461038c575b600080fd5b6103646107c5565b6040516103719190613a1c565b60405180910390f35b6009545b604051908152602001610371565b61037e60105481565b6103a86103a3366004613a82565b610857565b6040519015158152602001610371565b61037e6103c6366004613aae565b610871565b6103de6103d9366004613aae565b6108c3565b604080516001600160a01b0390971687526020870195909552938501929092526060840152608083015260a082015260c001610371565b61037e600e5481565b60035461037e565b61037e60145481565b61044261043d366004613ad5565b610913565b005b6103a8610452366004613b17565b610b3b565b60405160128152602001610371565b6103a8610474366004613a82565b610b5f565b61037e60175481565b610495610490366004613aae565b610b9e565b6040516001600160a01b039091168152602001610371565b6104426104bb366004613b58565b610c0e565b601554610495906001600160a01b031681565b61037e600f5481565b6104426104ea366004613aae565b610cbd565b6104426104fd366004613aae565b610e3e565b6103a8610510366004613b7a565b610eea565b61037e60135481565b600d546103a89060ff1681565b610442610fe7565b610442610541366004613b97565b61100e565b601254610495906001600160a01b031681565b61037e610567366004613b7a565b6001600160a01b031660009081526001602052604090205490565b61044261109b565b6103a8610598366004613b7a565b6110af565b6104426105ab366004613aae565b6110bc565b61037e60165481565b6000546001600160a01b0316610495565b6106046105d8366004613bc5565b600a60209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610371565b61037e61062d366004613aae565b6110d1565b61036461117b565b6103a8610648366004613a82565b61118a565b6103a861065b366004613a82565b611234565b61037e61066e366004613aae565b611242565b610442610681366004613bf5565b61127a565b61037e610694366004613b7a565b600c6020526000908152604090205481565b6104426106b4366004613b58565b611470565b61037e6106c7366004613aae565b600b6020526000908152604090205481565b6104426114ee565b61037e60085481565b61037e6106f8366004613bf5565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b601154610495906001600160a01b031681565b610442610744366004613b58565b611528565b61075c610757366004613bc5565b61163f565b60408051928352602083019190915201610371565b61037e6116c1565b610442610787366004613bf5565b6116d2565b61044261079a366004613b7a565b61178c565b6104426107ad366004613b7a565b61181c565b6104426107c0366004613aae565b6118b4565b6060600480546107d490613c23565b80601f016020809104026020016040519081016040528092919081815260200182805461080090613c23565b801561084d5780601f106108225761010080835404028352916020019161084d565b820191906000526020600020905b81548152906001019060200180831161083057829003601f168201915b5050505050905090565b6000336108658185856119c1565b60019150505b92915050565b600060135460000361088557506000919050565b600f548211156108bb5761086b6013546108b560016108af600f5487611b1990919063ffffffff16565b90611b19565b90611b25565b506000919050565b600981815481106108d357600080fd5b60009182526020909120600690910201805460018201546002830154600384015460048501546005909501546001600160a01b0390941695509193909286565b61091b611b31565b6001600160a01b0382166109765760405162461bcd60e51b815260206004820152601c60248201527f5f6c70546f6b656e20697320746865207a65726f20616464726573730000000060448201526064015b60405180910390fd5b801561098457610984610fe7565b6000600f54431161099757600f54610999565b435b600e549091506109a99085611b8b565b600e556040805160c0810182526001600160a01b038581168252602082018781529282018481526000606084018181526080850182815260a0860183815260098054600180820183559582905297517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af600690990298890180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919098161790965596517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b087015592517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b1860155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b285015590517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b384015592517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b49092019190915554610b199190613ca5565b6001600160a01b039093166000908152600c6020526040902092909255505050565b600033610b49858285611b97565b610b54858585611c23565b506001949350505050565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091906108659082908690610b99908790613cb8565b6119c1565b60006001610baa6116c1565b610bb49190613ca5565b821115610c035760405162461bcd60e51b815260206004820152601460248201527f6e6f742066696e642074686973206d756c744c50000000000000000000000000604482015260640161096d565b61086b600683611e17565b600d5460ff1615610c615760405162461bcd60e51b815260206004820152601960248201527f4d696e696e6720686173206265656e2073757370656e64656400000000000000604482015260640161096d565b600060098381548110610c7657610c76613ccb565b600091825260209091206006909102018054909150610c9d906001600160a01b03166110af565b15610cb257610cad838333611e23565b505050565b610cad8383336121e9565b600060098281548110610cd257610cd2613ccb565b9060005260206000209060060201905080600201544311610cf1575050565b8054600090610d08906001600160a01b03166110af565b15610d2f578160050154600003610d2457504360029091015550565b506005810154610dc8565b81546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db39190613cfa565b905080600003610dc857504360029091015550565b6000610dd783600201546110d1565b905060008111610de75750505050565b6000610e06600e546108b586600101548561236490919063ffffffff16565b9050610e29610e1e846108b58464e8d4a51000612364565b600386015490611b8b565b60038501555050436002909201919091555050565b600d5460ff1615610e915760405162461bcd60e51b815260206004820152601960248201527f4d696e696e6720686173206265656e2073757370656e64656400000000000000604482015260640161096d565b600060098281548110610ea657610ea6613ccb565b600091825260209091206006909102018054909150610ecd906001600160a01b03166110af565b15610ee057610edc8233612370565b5050565b610edc82336125fc565b6000610ef4611b31565b6001600160a01b038216610f4a5760405162461bcd60e51b815260206004820152601660248201527f4c5020697320746865207a65726f206164647265737300000000000000000000604482015260640161096d565b6011546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260001960248201529083169063095ea7b3906044016020604051808303816000875af1158015610fb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdb9190613d13565b5061086b6006836126bb565b60095460005b81811015610edc57610ffe81610cbd565b61100781613d30565b9050610fed565b611016611b31565b801561102457611024610fe7565b611067826110616009868154811061103e5761103e613ccb565b906000526020600020906006020160010154600e54611b1990919063ffffffff16565b90611b8b565b600e81905550816009848154811061108157611081613ccb565b906000526020600020906006020160010181905550505050565b6110a3611b31565b6110ad60006126d0565b565b600061086b600683612738565b6110c4611b31565b6110cc610fe7565b600855565b600080806110de84610871565b905060006110eb43610871565b90505b80821015611152578161110081613d30565b9250506000611120600f546110616013548661236490919063ffffffff16565b905061114861114161113183611242565b61113b848a611b19565b90612364565b8590611b8b565b90955092506110ee565b61117261116b61116143611242565b61113b4389611b19565b8490611b8b565b95945050505050565b6060600580546107d490613c23565b3360008181526002602090815260408083206001600160a01b0387168452909152812054909190838110156112275760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161096d565b610b5482868684036119c1565b600033610865818585611c23565b60008061124e83610871565b905061127361125c60095490565b61113b61126a846002613e26565b60085490611b25565b9392505050565b611282611b31565b6001600160a01b038216158015906112a257506001600160a01b03811615155b6112ee5760405162461bcd60e51b815260206004820152601360248201527f697320746865207a65726f206164647265737300000000000000000000000000604482015260640161096d565b600d5460ff1615156001146113455760405162461bcd60e51b815260206004820152601460248201527f4e6f206d696e696e672073757370656e73696f6e000000000000000000000000604482015260640161096d565b601280546001600160a01b038085167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255601180549284169290911691909117905560006113976116c1565b90505b8015610cad5760006113ae60066000611e17565b6001600160a01b038082166000908152600c6020908152604080832054601154818552600b909352928190205490517f5312ea8e0000000000000000000000000000000000000000000000000000000081529495509193921691635312ea8e9161141e9160040190815260200190565b600060405180830381600087803b15801561143857600080fd5b505af115801561144c573d6000803e3d6000fd5b5050505061145b60068361275a565b508261146681613e32565b935050505061139a565b611478611b31565b600161148360095490565b61148d9190613ca5565b8211156114dc5760405162461bcd60e51b815260206004820152601260248201527f6e6f742066696e64207468697320706f6f6c0000000000000000000000000000604482015260640161096d565b6000918252600b602052604090912055565b6114f6611b31565b600d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b600d5460ff161561157b5760405162461bcd60e51b815260206004820152601960248201527f4d696e696e6720686173206265656e2073757370656e64656400000000000000604482015260640161096d565b600f544390811080159061159157506010548111155b6115dd5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420696e206f70656e696e6720706572696f640000000000000000000000604482015260640161096d565b6000600984815481106115f2576115f2613ccb565b600091825260209091206006909102018054909150611619906001600160a01b03166110af565b1561162e5761162984843361276f565b611639565b611639848433612d78565b50505050565b60008060006009858154811061165757611657613ccb565b60009182526020909120600690910201805490915061167e906001600160a01b03166110af565b1561169e576000806116908787612ead565b90955093506116ba92505050565b60006116aa86866130fa565b9350600092506116ba915050565b505b9250929050565b60006116cd60066132a8565b905090565b6116da611b31565b6001600160a01b038216158015906116fa57506001600160a01b03811615155b6117465760405162461bcd60e51b815260206004820152601360248201527f697320746865207a65726f206164647265737300000000000000000000000000604482015260640161096d565b601280546001600160a01b039384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560118054929093169116179055565b611794611b31565b6001600160a01b0381166118105760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161096d565b611819816126d0565b50565b611824611b31565b6001600160a01b03811661187a5760405162461bcd60e51b815260206004820152601760248201527f41646472657373206973207a65726f2061646472657373000000000000000000604482015260640161096d565b601580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b601654601754106119075760405162461bcd60e51b815260206004820152601060248201527f6e6f7420656e6f7567682071756f746100000000000000000000000000000000604482015260640161096d565b611913816000336121e9565b601454336000908152600160205260409020541061181957611937336014546132b2565b601754611945906001611b8b565b6017556015546040517f6a6278420000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911690636a62784290602401600060405180830381600087803b1580156119a657600080fd5b505af11580156119ba573d6000803e3d6000fd5b5050505050565b6001600160a01b038316611a3c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b038216611ab85760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006112738284613ca5565b60006112738284613e49565b6000546001600160a01b031633146110ad5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161096d565b60006112738284613cb8565b6001600160a01b0383811660009081526002602090815260408083209386168352929052205460001981146116395781811015611c165760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161096d565b61163984848484036119c1565b6001600160a01b038316611c9f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b038216611d1b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b03831660009081526001602052604090205481811015611daa5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b0380851660008181526001602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611e0a9086815260200190565b60405180910390a3611639565b6000611273838361341d565b600060098481548110611e3857611e38613ccb565b60009182526020808320878452600a825260408085206001600160a01b03881686529092529220805460069092029092019250841115611eba5760405162461bcd60e51b815260206004820152601e60248201527f7769746864726177436f696e416e64546f6b656e3a206e6f7420676f6f640000604482015260640161096d565b611ec385610cbd565b6000611ef182600101546108af64e8d4a510006108b58760030154876000015461236490919063ffffffff16565b90508015611f0357611f038482613447565b8415612160576012546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8f9190613cfa565b6011546000898152600b6020526040908190205490517f441a3e700000000000000000000000000000000000000000000000000000000081526004810191909152602481018990529192506001600160a01b03169063441a3e7090604401600060405180830381600087803b15801561200757600080fd5b505af115801561201b573d6000803e3d6000fd5b50506012546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa158015612083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a79190613cfa565b90506120db6120d086600501546108b564e8d4a5100061113b8787611b1990919063ffffffff16565b600487015490611b8b565b600486018190556002850154855460009261210592916108af9164e8d4a51000916108b591612364565b9050801561212457601254612124906001600160a01b03168883613451565b84546121309089611b19565b855560058601546121419089611b19565b6005870155855461215c906001600160a01b0316888a613451565b5050505b6003830154825461217b9164e8d4a51000916108b591612364565b60018301556004830154825461219b9164e8d4a51000916108b591612364565b600283015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020015b60405180910390a3505050505050565b6000600984815481106121fe576121fe613ccb565b60009182526020808320878452600a825260408085206001600160a01b038816865290925292208054600690920290920192508411156122805760405162461bcd60e51b815260206004820152601660248201527f7769746864726177436f696e3a206e6f7420676f6f6400000000000000000000604482015260640161096d565b61228985610cbd565b60006122b782600101546108af64e8d4a510006108b58760030154876000015461236490919063ffffffff16565b905080156122c9576122c98482613447565b84156123075781546122db9086611b19565b825560058301546122ec9086611b19565b60058401558254612307906001600160a01b03168587613451565b600383015482546123229164e8d4a51000916108b591612364565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020016121d9565b60006112738284613e84565b60006009838154811061238557612385613ccb565b60009182526020808320868452600a825260408085206001600160a01b0388811687529352808520805460125492517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526006969096029093019650949193919216906370a0823190602401602060405180830381865afa158015612415573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124399190613cfa565b6011546000888152600b6020526040908190205490517f441a3e700000000000000000000000000000000000000000000000000000000081526004810191909152602481018590529192506001600160a01b03169063441a3e7090604401600060405180830381600087803b1580156124b157600080fd5b505af11580156124c5573d6000803e3d6000fd5b50506012546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa15801561252d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125519190613cfa565b905061257a6120d086600501546108b564e8d4a5100061113b8787611b1990919063ffffffff16565b600486015560008085556001850155845461259f906001600160a01b03168785613451565b60058501546125ae9084611b19565b600586015560405183815287906001600160a01b038816907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a350505050505050565b60006009838154811061261157612611613ccb565b60009182526020808320868452600a825260408085206001600160a01b0380891687529352842080548582556001820195909555600690930201805490945091929161265f91168583613451565b600583015461266e9082611b19565b600584015560405181815285906001600160a01b038616907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595906020015b60405180910390a35050505050565b6000611273836001600160a01b038416613518565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811660009081526001830160205260408120541515611273565b6000611273836001600160a01b038416613567565b60006009848154811061278457612784613ccb565b60009182526020808320878452600a825260408085206001600160a01b03881686529092529220600690910290910191506127be85610cbd565b805415612a1a5760006127f382600101546108af64e8d4a510006108b58760030154876000015461236490919063ffffffff16565b90508015612805576128058482613447565b6012546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061288b9190613cfa565b6011546000898152600b60205260408082205490517fe2bbb158000000000000000000000000000000000000000000000000000000008152600481019190915260248101919091529192506001600160a01b03169063e2bbb15890604401600060405180830381600087803b15801561290357600080fd5b505af1158015612917573d6000803e3d6000fd5b50506012546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa15801561297f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a39190613cfa565b90506129cc6120d086600501546108b564e8d4a5100061113b8787611b1990919063ffffffff16565b60048601819055600285015485546000926129f692916108af9164e8d4a51000916108b591612364565b90508015612a1557601254612a15906001600160a01b03168883613451565b505050505b8315612cfb578154612a37906001600160a01b031684308761365a565b8160050154600003612aff576011546000868152600b6020526040908190205490517fe2bbb1580000000000000000000000000000000000000000000000000000000081526001600160a01b039092169163e2bbb15891612aa5918890600401918252602082015260400190565b600060405180830381600087803b158015612abf57600080fd5b505af1158015612ad3573d6000803e3d6000fd5b50508254612ae49250905085611b8b565b81556005820154612af59085611b8b565b6005830155612cfb565b6012546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b859190613cfa565b6011546000888152600b6020526040908190205490517fe2bbb1580000000000000000000000000000000000000000000000000000000081526004810191909152602481018890529192506001600160a01b03169063e2bbb15890604401600060405180830381600087803b158015612bfd57600080fd5b505af1158015612c11573d6000803e3d6000fd5b50506012546040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600093506001600160a01b0390911691506370a0823190602401602060405180830381865afa158015612c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9d9190613cfa565b9050612cd1612cc685600501546108b564e8d4a5100061113b8787611b1990919063ffffffff16565b600486015490611b8b565b60048501558254612ce29087611b8b565b83556005840154612cf39087611b8b565b600585015550505b60038201548154612d169164e8d4a51000916108b591612364565b600182015560048201548154612d369164e8d4a51000916108b591612364565b600282015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15906020016126ac565b600060098481548110612d8d57612d8d613ccb565b60009182526020808320878452600a825260408085206001600160a01b0388168652909252922060069091029091019150612dc785610cbd565b805415612e10576000612dfc82600101546108af64e8d4a510006108b58760030154876000015461236490919063ffffffff16565b90508015612e0e57612e0e8482613447565b505b8315612e50578154612e2d906001600160a01b031684308761365a565b8054612e399085611b8b565b81556005820154612e4a9085611b8b565b60058301555b60038201548154612e6b9164e8d4a51000916108b591612364565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15906020016126ac565b600080600060098581548110612ec557612ec5613ccb565b60009182526020808320888452600a825260408085206001600160a01b038a16865290925292206003600690920290920190810154600482015483549294509091156130ea576011546000898152600b60205260408082205490517f1175a1dd000000000000000000000000000000000000000000000000000000008152600481019190915230602482015290916001600160a01b031690631175a1dd90604401602060405180830381865afa158015612f83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa79190613cfa565b9050612fd3612fcc86600501546108b564e8d4a510008561236490919063ffffffff16565b8390611b8b565b91506000612fff85600201546108af64e8d4a510006108b5878a6000015461236490919063ffffffff16565b905085600201544311156130a557600061301c87600201546110d1565b9050600061303d600e546108b58a600101548561236490919063ffffffff16565b905061306961306289600501546108b564e8d4a510008561236490919063ffffffff16565b8790611b8b565b955061309387600101546108af64e8d4a510006108b58a8c6000015461236490919063ffffffff16565b839950995050505050505050506116ba565b856002015443036130e7576130d885600101546108af64e8d4a510006108b5888a6000015461236490919063ffffffff16565b975095506116ba945050505050565b50505b5060009788975095505050505050565b6000806009848154811061311057613110613ccb565b60009182526020808320878452600a825260408085206001600160a01b03898116875293528085206006949094029091016003810154815492517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015291965093949291909116906370a0823190602401602060405180830381865afa1580156131a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c89190613cfa565b83549091501561329b57836002015443111561325d5760006131ed85600201546110d1565b9050600061320e600e546108b588600101548561236490919063ffffffff16565b9050613226611141846108b58464e8d4a51000612364565b935061325085600101546108af64e8d4a510006108b5888a6000015461236490919063ffffffff16565b965050505050505061086b565b8360020154430361329b5761329083600101546108af64e8d4a510006108b586886000015461236490919063ffffffff16565b94505050505061086b565b5060009695505050505050565b600061086b825490565b6001600160a01b03821661332e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b038216600090815260016020526040902054818110156133bd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161096d565b6001600160a01b03831660008181526001602090815260408083208686039055600380548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b600082600001828154811061343457613434613ccb565b9060005260206000200154905092915050565b610edc82826136ab565b6040516001600160a01b038316602482015260448101829052610cad9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261376c565b600081815260018301602052604081205461355f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561086b565b50600061086b565b6000818152600183016020526040812054801561365057600061358b600183613ca5565b855490915060009061359f90600190613ca5565b90508181146136045760008660000182815481106135bf576135bf613ccb565b90600052602060002001549050808760000184815481106135e2576135e2613ccb565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061361557613615613e9b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061086b565b600091505061086b565b6040516001600160a01b03808516602483015283166044820152606481018290526116399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401613496565b6001600160a01b0382166137015760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161096d565b80600360008282546137139190613cb8565b90915550506001600160a01b0382166000818152600160209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60006137c1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166138519092919063ffffffff16565b805190915015610cad57808060200190518101906137df9190613d13565b610cad5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161096d565b60606138608484600085613868565b949350505050565b6060824710156138e05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161096d565b600080866001600160a01b031685876040516138fc9190613eca565b60006040518083038185875af1925050503d8060008114613939576040519150601f19603f3d011682016040523d82523d6000602084013e61393e565b606091505b509150915061394f8783838761395a565b979650505050505050565b606083156139c95782516000036139c2576001600160a01b0385163b6139c25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161096d565b5081613860565b61386083838151156139de5781518083602001fd5b8060405162461bcd60e51b815260040161096d9190613a1c565b60005b83811015613a135781810151838201526020016139fb565b50506000910152565b6020815260008251806020840152613a3b8160408501602087016139f8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6001600160a01b038116811461181957600080fd5b60008060408385031215613a9557600080fd5b8235613aa081613a6d565b946020939093013593505050565b600060208284031215613ac057600080fd5b5035919050565b801515811461181957600080fd5b600080600060608486031215613aea57600080fd5b833592506020840135613afc81613a6d565b91506040840135613b0c81613ac7565b809150509250925092565b600080600060608486031215613b2c57600080fd5b8335613b3781613a6d565b92506020840135613b4781613a6d565b929592945050506040919091013590565b60008060408385031215613b6b57600080fd5b50508035926020909101359150565b600060208284031215613b8c57600080fd5b813561127381613a6d565b600080600060608486031215613bac57600080fd5b83359250602084013591506040840135613b0c81613ac7565b60008060408385031215613bd857600080fd5b823591506020830135613bea81613a6d565b809150509250929050565b60008060408385031215613c0857600080fd5b8235613c1381613a6d565b91506020830135613bea81613a6d565b600181811c90821680613c3757607f821691505b602082108103613c70577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561086b5761086b613c76565b8082018082111561086b5761086b613c76565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215613d0c57600080fd5b5051919050565b600060208284031215613d2557600080fd5b815161127381613ac7565b60006000198203613d4357613d43613c76565b5060010190565b600181815b808511156116b8578160001904821115613d6b57613d6b613c76565b80851615613d7857918102915b93841c9390800290613d4f565b600082613d945750600161086b565b81613da15750600061086b565b8160018114613db75760028114613dc157613ddd565b600191505061086b565b60ff841115613dd257613dd2613c76565b50506001821b61086b565b5060208310610133831016604e8410600b8410161715613e00575081810a61086b565b613e0a8383613d4a565b8060001904821115613e1e57613e1e613c76565b029392505050565b60006112738383613d85565b600081613e4157613e41613c76565b506000190190565b600082613e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761086b5761086b613c76565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251613edc8184602087016139f8565b919091019291505056fea26469706673582212205bd89e0e2878a2b6e95eff8bbc6ec985a2874655ee1d45b097cfdbbf487dfce664736f6c63430008130033

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

00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001042f47000000000000000000000000000000000000000000000000000000000115221d000000000000000000000000a58eb817dda3415fb68cb040021f5049350deb450000000000000000000000000000000000000000000000000000000000001af400000000000000000000000000000000000000000000000000000000000000155370696e6674205370616365506920506c616e6574000000000000000000000000000000000000000000000000000000000000000000000000000000000000035353500000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): Spinft SpacePi Planet
Arg [1] : symbol_ (string): SSP
Arg [2] : _startBlock (uint256): 17051463
Arg [3] : _endBlock (uint256): 18162205
Arg [4] : _nft (address): 0xa58Eb817Dda3415FB68cB040021f5049350dEb45
Arg [5] : _quota (uint256): 6900

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000000000000000000000000000000000000001042f47
Arg [3] : 000000000000000000000000000000000000000000000000000000000115221d
Arg [4] : 000000000000000000000000a58eb817dda3415fb68cb040021f5049350deb45
Arg [5] : 0000000000000000000000000000000000000000000000000000000000001af4
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000015
Arg [7] : 5370696e6674205370616365506920506c616e65740000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [9] : 5353500000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

60976:20223:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9479:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64148:93;64218:8;:15;64148:93;;;875:25:1;;;863:2;848:18;64148:93:0;729:177:1;62748:23:0;;;;;;11830:201;;;;;;:::i;:::-;;:::i;:::-;;;1555:14:1;;1548:22;1530:41;;1518:2;1503:18;11830:201:0;1390:187:1;67508:291:0;;;;;;:::i;:::-;;:::i;62137:26::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;2086:55:1;;;2068:74;;2173:2;2158:18;;2151:34;;;;2201:18;;;2194:34;;;;2259:2;2244:18;;2237:34;2302:3;2287:19;;2280:35;2346:3;2331:19;;2324:35;2055:3;2040:19;62137:26:0;1767:598:1;62625:34:0;;;;;;10599:108;10687:12;;10599:108;;62972:42;;;;;;66153:694;;;;;;:::i;:::-;;:::i;:::-;;12611:295;;;;;;:::i;:::-;;:::i;10441:93::-;;;10524:2;3565:36:1;;3553:2;3538:18;10441:93:0;3423:184:1;13315:238:0;;;;;;:::i;:::-;;:::i;63078:24::-;;;;;;64762:199;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3776:55:1;;;3758:74;;3746:2;3731:18;64762:199:0;3612:226:1;76158:315:0;;;;;;:::i;:::-;;:::i;63021:18::-;;;;;-1:-1:-1;;;;;63021:18:0;;;62716:25;;;;;;68917:1009;;;;;;:::i;:::-;;:::i;78887:307::-;;;;;;:::i;:::-;;:::i;64249:257::-;;;;;;:::i;:::-;;:::i;62925:40::-;;;;;;62504:26;;;;;;;;;68661:180;;;:::i;66943:304::-;;;;;;:::i;:::-;;:::i;62857:26::-;;;;;-1:-1:-1;;;;;62857:26:0;;;10770:127;;;;;;:::i;:::-;-1:-1:-1;;;;;10871:18:0;10844:7;10871:18;;;:9;:18;;;;;;;10770:127;2884:103;;;:::i;64514:120::-;;;;;;:::i;:::-;;:::i;64014:128::-;;;;;;:::i;:::-;;:::i;63046:25::-;;;;;;2236:87;2282:7;2309:6;-1:-1:-1;;;;;2309:6:0;2236:87;;62219:64;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5252:25:1;;;5308:2;5293:18;;5286:34;;;;5336:18;;;5329:34;5240:2;5225:18;62219:64:0;5050:319:1;67997:581:0;;;;;;:::i;:::-;;:::i;9698:104::-;;;:::i;14056:436::-;;;;;;:::i;:::-;;:::i;11103:193::-;;;;;;:::i;:::-;;:::i;67807:182::-;;;;;;:::i;:::-;;:::i;65314:670::-;;;;;;:::i;:::-;;:::i;62432:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;67322:178;;;;;;:::i;:::-;;:::i;62342:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;64969:72;;;:::i;62014:44::-;;;;;;11359:151;;;;;;:::i;:::-;-1:-1:-1;;;;;11475:18:0;;;11448:7;11475:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;11359:151;62804:25;;;;;-1:-1:-1;;;;;62804:25:0;;;72764:322;;;;;;:::i;:::-;;:::i;69990:439::-;;;;;;:::i;:::-;;:::i;:::-;;;;5941:25:1;;;5997:2;5982:18;;5975:34;;;;5914:18;69990:439:0;5767:248:1;64642:112:0;;;:::i;65049:257::-;;;;;;:::i;:::-;;:::i;3142:201::-;;;;;;:::i;:::-;;:::i;63654:141::-;;;;;;:::i;:::-;;:::i;80889:307::-;;;;;;:::i;:::-;;:::i;9479:100::-;9533:13;9566:5;9559:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9479:100;:::o;11830:201::-;11913:4;861:10;11969:32;861:10;11985:7;11994:6;11969:8;:32::i;:::-;12019:4;12012:11;;;11830:201;;;;;:::o;67508:291::-;67565:7;67589:13;;67606:1;67589:18;67585:59;;-1:-1:-1;67631:1:0;;67508:291;-1:-1:-1;67508:291:0:o;67585:59::-;67672:10;;67658:11;:24;67654:119;;;67706:55;67747:13;;67707:34;67739:1;67707:27;67723:10;;67707:11;:15;;:27;;;;:::i;:::-;:31;;:34::i;:::-;67706:40;;:55::i;67654:119::-;-1:-1:-1;67790:1:0;;67508:291;-1:-1:-1;67508:291:0:o;62137:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62137:26:0;;;;-1:-1:-1;62137:26:0;;;;;:::o;66153:694::-;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;66258:31:0;::::1;66250:72;;;::::0;-1:-1:-1;;;66250:72:0;;6664:2:1;66250:72:0::1;::::0;::::1;6646:21:1::0;6703:2;6683:18;;;6676:30;6742;6722:18;;;6715:58;6790:18;;66250:72:0::1;;;;;;;;;66337:11;66333:61;;;66365:17;:15;:17::i;:::-;66404:23;66445:10;;66430:12;:25;:53;;66473:10;;66430:53;;;66458:12;66430:53;66512:15;::::0;66404:79;;-1:-1:-1;66512:32:0::1;::::0;66532:11;66512:19:::1;:32::i;:::-;66494:15;:50:::0;66569:213:::1;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;66569:213:0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;-1:-1:-1;66569:213:0;;;;;;;;;;;;;;;;;;66555:8:::1;:228:::0;;::::1;::::0;;::::1;::::0;;;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64218:15;66823:16:::1;;;;:::i;:::-;-1:-1:-1::0;;;;;66794:26:0;;::::1;;::::0;;;:7:::1;:26;::::0;;;;:45;;;;-1:-1:-1;;;66153:694:0:o;12611:295::-;12742:4;861:10;12800:38;12816:4;861:10;12831:6;12800:15;:38::i;:::-;12849:27;12859:4;12865:2;12869:6;12849:9;:27::i;:::-;-1:-1:-1;12894:4:0;;12611:295;-1:-1:-1;;;;12611:295:0:o;13315:238::-;861:10;13403:4;11475:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;11475:27:0;;;;;;;;;;13403:4;;861:10;13459:64;;861:10;;11475:27;;13484:38;;13512:10;;13484:38;:::i;:::-;13459:8;:64::i;64762:199::-;64823:7;64878:1;64858:17;:15;:17::i;:::-;:21;;;;:::i;:::-;64850:4;:29;;64842:62;;;;-1:-1:-1;;;64842:62:0;;7473:2:1;64842:62:0;;;7455:21:1;7512:2;7492:18;;;7485:30;7551:22;7531:18;;;7524:50;7591:18;;64842:62:0;7271:344:1;64842:62:0;64922:31;64939:7;64948:4;64922:16;:31::i;76158:315::-;80719:6;;;;80718:7;80710:45;;;;-1:-1:-1;;;80710:45:0;;7822:2:1;80710:45:0;;;7804:21:1;7861:2;7841:18;;;7834:30;7900:27;7880:18;;;7873:55;7945:18;;80710:45:0;7620:349:1;80710:45:0;76234:21:::1;76258:8;76267:4;76258:14;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;76304:12:::0;;76258:14;;-1:-1:-1;76287:31:0::1;::::0;-1:-1:-1;;;;;76304:12:0::1;76287:8;:31::i;:::-;76283:183;;;76335:47;76356:4;76362:7;76371:10;76335:20;:47::i;:::-;76223:250;76158:315:::0;;:::o;76283:183::-:1;76415:39;76428:4;76434:7;76443:10;76415:12;:39::i;68917:1009::-:0;68969:21;68993:8;69002:4;68993:14;;;;;;;;:::i;:::-;;;;;;;;;;;68969:38;;69038:4;:20;;;69022:12;:36;69018:75;;69075:7;68917:1009;:::o;69018:75::-;69151:12;;69103:16;;69134:31;;-1:-1:-1;;;;;69151:12:0;69134:8;:31::i;:::-;69130:436;;;69186:4;:16;;;69206:1;69186:21;69182:122;;-1:-1:-1;69251:12:0;69228:20;;;;:35;-1:-1:-1;68917:1009:0:o;69182:122::-;-1:-1:-1;69329:16:0;;;;69130:436;;;69389:12;;:37;;;;;69420:4;69389:37;;;3758:74:1;-1:-1:-1;;;;;69389:12:0;;;;:22;;3731:18:1;;69389:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69378:48;;69445:8;69457:1;69445:13;69441:114;;-1:-1:-1;69502:12:0;69479:20;;;;:35;-1:-1:-1;68917:1009:0:o;69441:114::-;69576:19;69598:36;69613:4;:20;;;69598:14;:36::i;:::-;69576:58;;69664:1;69649:11;:16;69645:55;;69682:7;;;68917:1009;:::o;69645:55::-;69710:18;69731:53;69768:15;;69731:32;69747:4;:15;;;69731:11;:15;;:32;;;;:::i;:53::-;69710:74;-1:-1:-1;69816:56:0;69837:34;69862:8;69837:20;69710:74;69852:4;69837:14;:20::i;:34::-;69816:16;;;;;:20;:56::i;:::-;69797:16;;;:75;-1:-1:-1;;69906:12:0;69883:20;;;;:35;;;;-1:-1:-1;;68917:1009:0:o;78887:307::-;80719:6;;;;80718:7;80710:45;;;;-1:-1:-1;;;80710:45:0;;7822:2:1;80710:45:0;;;7804:21:1;7861:2;7841:18;;;7834:30;7900:27;7880:18;;;7873:55;7945:18;;80710:45:0;7620:349:1;80710:45:0;78955:21:::1;78979:8;78988:4;78979:14;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;79025:12:::0;;78979:14;;-1:-1:-1;79008:31:0::1;::::0;-1:-1:-1;;;;;79025:12:0::1;79008:8;:31::i;:::-;79004:183;;;79056:47;79086:4;79092:10;79056:29;:47::i;:::-;78944:250;78887:307:::0;:::o;79004:183::-:1;79136:39;79158:4;79164:10;79136:21;:39::i;64249:257::-:0;64310:4;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;64335:20:0;::::1;64327:55;;;::::0;-1:-1:-1;;;64327:55:0;;8554:2:1;64327:55:0::1;::::0;::::1;8536:21:1::0;8593:2;8573:18;;;8566:30;8632:24;8612:18;;;8605:52;8674:18;;64327:55:0::1;8352:346:1::0;64327:55:0::1;64416:10;::::0;64393:53:::1;::::0;;;;-1:-1:-1;;;;;64416:10:0;;::::1;64393:53;::::0;::::1;8877:74:1::0;-1:-1:-1;;8967:18:1;;;8960:34;64393:22:0;;::::1;::::0;::::1;::::0;8850:18:1;;64393:53:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;64464:34;64482:7;64491:6;64464:17;:34::i;68661:180::-:0;68723:8;:15;68706:14;68749:85;68777:6;68771:3;:12;68749:85;;;68807:15;68818:3;68807:10;:15::i;:::-;68785:5;;;:::i;:::-;;;68749:85;;66943:304;2122:13;:11;:13::i;:::-;67041:11:::1;67037:61;;;67069:17;:15;:17::i;:::-;67126:63;67177:11;67126:46;67146:8;67155:4;67146:14;;;;;;;;:::i;:::-;;;;;;;;;;;:25;;;67126:15;;:19;;:46;;;;:::i;:::-;:50:::0;::::1;:63::i;:::-;67108:15;:81;;;;67228:11;67200:8;67209:4;67200:14;;;;;;;;:::i;:::-;;;;;;;;;;;:25;;:39;;;;66943:304:::0;;;:::o;2884:103::-;2122:13;:11;:13::i;:::-;2949:30:::1;2976:1;2949:18;:30::i;:::-;2884:103::o:0;64514:120::-;64566:4;64590:36;64613:7;64622:3;64590:22;:36::i;64014:128::-;2122:13;:11;:13::i;:::-;64084:17:::1;:15;:17::i;:::-;64112:8;:22:::0;64014:128::o;67997:581::-;68068:7;;;68134:23;68140:16;68134:5;:23::i;:::-;68122:35;;68168:9;68180:19;68186:12;68180:5;:19::i;:::-;68168:31;;68210:228;68221:1;68217;:5;68210:228;;;68239:3;;;;:::i;:::-;;;;68257:9;68269:36;68294:10;;68269:20;68275:13;;68269:1;:5;;:20;;;;:::i;:36::-;68257:48;;68334:57;68350:40;68380:9;68387:1;68380:6;:9::i;:::-;68351:23;:1;68357:16;68351:5;:23::i;:::-;68350:29;;:40::i;:::-;68334:11;;:15;:57::i;:::-;68425:1;;-1:-1:-1;68320:71:0;-1:-1:-1;68210:228:0;;;68462:79;68478:62;68519:20;68526:12;68519:6;:20::i;:::-;68479:34;:12;68496:16;68479;:34::i;68478:62::-;68462:11;;:15;:79::i;:::-;68448:93;67997:581;-1:-1:-1;;;;;67997:581:0:o;9698:104::-;9754:13;9787:7;9780:14;;;;;:::i;14056:436::-;861:10;14149:4;11475:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;11475:27:0;;;;;;;;;;14149:4;;861:10;14296:15;14276:16;:35;;14268:85;;;;-1:-1:-1;;;14268:85:0;;9657:2:1;14268:85:0;;;9639:21:1;9696:2;9676:18;;;9669:30;9735:34;9715:18;;;9708:62;9806:7;9786:18;;;9779:35;9831:19;;14268:85:0;9455:401:1;14268:85:0;14389:60;14398:5;14405:7;14433:15;14414:16;:34;14389:8;:60::i;11103:193::-;11182:4;861:10;11238:28;861:10;11255:2;11259:6;11238:9;:28::i;67807:182::-;67865:7;67885:14;67902:18;67908:11;67902:5;:18::i;:::-;67885:35;;67938:43;67968:12;64218:8;:15;;64148:93;67968:12;67938:25;67951:11;67956:6;67951:1;:11;:::i;:::-;67938:8;;;:12;:25::i;:43::-;67931:50;67807:182;-1:-1:-1;;;67807:182:0:o;65314:670::-;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;65416:26:0;::::1;::::0;;::::1;::::0;:55:::1;;-1:-1:-1::0;;;;;;65446:25:0;::::1;::::0;::::1;65416:55;65408:87;;;::::0;-1:-1:-1;;;65408:87:0;;11557:2:1;65408:87:0::1;::::0;::::1;11539:21:1::0;11596:2;11576:18;;;11569:30;11635:21;11615:18;;;11608:49;11674:18;;65408:87:0::1;11355:343:1::0;65408:87:0::1;65514:6;::::0;::::1;;:14;;:6:::0;:14:::1;65506:47;;;::::0;-1:-1:-1;;;65506:47:0;;11905:2:1;65506:47:0::1;::::0;::::1;11887:21:1::0;11944:2;11924:18;;;11917:30;11983:22;11963:18;;;11956:50;12023:18;;65506:47:0::1;11703:344:1::0;65506:47:0::1;65564:11;:26:::0;;-1:-1:-1;;;;;65564:26:0;;::::1;::::0;;;::::1;;::::0;;;65601:10:::1;:24:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;65564:11:::1;65653:17;:15;:17::i;:::-;65636:34;;65681:296;65688:10:::0;;65681:296:::1;;65715:16;65734:28;65751:7;65760:1;65734:16;:28::i;:::-;-1:-1:-1::0;;;;;65791:17:0;;::::1;65777:11;65791:17:::0;;;:7:::1;:17;::::0;;;;;;;;65838:10:::1;::::0;65868:19;;;:14:::1;:19:::0;;;;;;;;65823:65;;;;;65715:47;;-1:-1:-1;65791:17:0;;65838:10;::::1;::::0;65823:44:::1;::::0;:65:::1;::::0;::::1;;875:25:1::0;;;863:2;848:18;;729:177;65823:65:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;65903:39;65924:7;65933:8;65903:20;:39::i;:::-;-1:-1:-1::0;65957:8:0;::::1;::::0;::::1;:::i;:::-;;;;65700:277;;65681:296;;67322:178:::0;2122:13;:11;:13::i;:::-;67430:1:::1;67415:12;64218:8:::0;:15;;64148:93;67415:12:::1;:16;;;;:::i;:::-;67407:4;:24;;67399:55;;;::::0;-1:-1:-1;;;67399:55:0;;12455:2:1;67399:55:0::1;::::0;::::1;12437:21:1::0;12494:2;12474:18;;;12467:30;12533:20;12513:18;;;12506:48;12571:18;;67399:55:0::1;12253:342:1::0;67399:55:0::1;67465:20;::::0;;;:14:::1;:20;::::0;;;;;:27;67322:178::o;64969:72::-;2122:13;:11;:13::i;:::-;65027:6:::1;::::0;;65017:16;;::::1;65027:6;::::0;;::::1;65026:7;65017:16;::::0;;64969:72::o;72764:322::-;80719:6;;;;80718:7;80710:45;;;;-1:-1:-1;;;80710:45:0;;7822:2:1;80710:45:0;;;7804:21:1;7861:2;7841:18;;;7834:30;7900:27;7880:18;;;7873:55;7945:18;;80710:45:0;7620:349:1;80710:45:0;63876:10:::1;::::0;63845:12:::1;::::0;63876:15;-1:-1:-1;63876:15:0;::::1;::::0;:32:::1;;;63900:8;;63895:1;:13;;63876:32;63868:66;;;::::0;-1:-1:-1;;;63868:66:0;;12802:2:1;63868:66:0::1;::::0;::::1;12784:21:1::0;12841:2;12821:18;;;12814:30;12880:23;12860:18;;;12853:51;12921:18;;63868:66:0::1;12600:345:1::0;63868:66:0::1;72849:21:::2;72873:8;72882:4;72873:14;;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;72919:12:::0;;72873:14;;-1:-1:-1;72902:31:0::2;::::0;-1:-1:-1;;;;;72919:12:0::2;72902:8;:31::i;:::-;72898:181;;;72950:46;72970:4;72976:7;72985:10;72950:19;:46::i;:::-;72898:181;;;73029:38;73041:4;73047:7;73056:10;73029:11;:38::i;:::-;72838:248;63822:132:::1;72764:322:::0;;:::o;69990:439::-;70059:7;70068;70087:21;70111:8;70120:4;70111:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;70157:12;;70111:14;;-1:-1:-1;70140:31:0;;-1:-1:-1;;;;;70157:12:0;70140:8;:31::i;:::-;70136:286;;;70189:14;70205:19;70228:32;70248:4;70254:5;70228:19;:32::i;:::-;70188:72;;-1:-1:-1;70188:72:0;-1:-1:-1;70275:28:0;;-1:-1:-1;;;70275:28:0;70136:286;70336:14;70353:24;70365:4;70371:5;70353:11;:24::i;:::-;70336:41;-1:-1:-1;70408:1:0;;-1:-1:-1;70392:18:0;;-1:-1:-1;;70392:18:0;70136:286;70076:353;69990:439;;;;;;:::o;64642:112::-;64690:7;64717:29;64738:7;64717:20;:29::i;:::-;64710:36;;64642:112;:::o;65049:257::-;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;65147:26:0;::::1;::::0;;::::1;::::0;:55:::1;;-1:-1:-1::0;;;;;;65177:25:0;::::1;::::0;::::1;65147:55;65139:87;;;::::0;-1:-1:-1;;;65139:87:0;;11557:2:1;65139:87:0::1;::::0;::::1;11539:21:1::0;11596:2;11576:18;;;11569:30;11635:21;11615:18;;;11608:49;11674:18;;65139:87:0::1;11355:343:1::0;65139:87:0::1;65237:11;:26:::0;;-1:-1:-1;;;;;65237:26:0;;::::1;::::0;;;::::1;;::::0;;;65274:10:::1;:24:::0;;;;;::::1;::::0;::::1;;::::0;;65049:257::o;3142:201::-;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;3231:22:0;::::1;3223:73;;;::::0;-1:-1:-1;;;3223:73:0;;13152:2:1;3223:73:0::1;::::0;::::1;13134:21:1::0;13191:2;13171:18;;;13164:30;13230:34;13210:18;;;13203:62;13301:8;13281:18;;;13274:36;13327:19;;3223:73:0::1;12950:402:1::0;3223:73:0::1;3307:28;3326:8;3307:18;:28::i;:::-;3142:201:::0;:::o;63654:141::-;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;63720:18:0;::::1;63712:54;;;::::0;-1:-1:-1;;;63712:54:0;;13559:2:1;63712:54:0::1;::::0;::::1;13541:21:1::0;13598:2;13578:18;;;13571:30;13637:25;13617:18;;;13610:53;13680:18;;63712:54:0::1;13357:347:1::0;63712:54:0::1;63777:3;:10:::0;;;::::1;-1:-1:-1::0;;;;;63777:10:0;;;::::1;::::0;;;::::1;::::0;;63654:141::o;80889:307::-;80832:10;;80820:9;;:22;80812:51;;;;-1:-1:-1;;;80812:51:0;;13911:2:1;80812:51:0;;;13893:21:1;13950:2;13930:18;;;13923:30;13989:18;13969;;;13962:46;14025:18;;80812:51:0;13709:340:1;80812:51:0;80960:33:::1;80973:4;80979:1;80982:10;80960:12;:33::i;:::-;81033:10;::::0;81018::::1;10844:7:::0;10871:18;;;:9;:18;;;;;;81008:35:::1;81004:185;;81060:29;81066:10;81078;;81060:5;:29::i;:::-;81116:9;::::0;:16:::1;::::0;81130:1:::1;81116:13;:16::i;:::-;81104:9;:28:::0;81156:3:::1;::::0;81147:30:::1;::::0;;;;81166:10:::1;81147:30;::::0;::::1;3758:74:1::0;-1:-1:-1;;;;;81156:3:0;;::::1;::::0;81147:18:::1;::::0;3731::1;;81147:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;80889:307:::0;:::o;18083:380::-;-1:-1:-1;;;;;18219:19:0;;18211:68;;;;-1:-1:-1;;;18211:68:0;;14256:2:1;18211:68:0;;;14238:21:1;14295:2;14275:18;;;14268:30;14334:34;14314:18;;;14307:62;14405:6;14385:18;;;14378:34;14429:19;;18211:68:0;14054:400:1;18211:68:0;-1:-1:-1;;;;;18298:21:0;;18290:68;;;;-1:-1:-1;;;18290:68:0;;14661:2:1;18290:68:0;;;14643:21:1;14700:2;14680:18;;;14673:30;14739:34;14719:18;;;14712:62;14810:4;14790:18;;;14783:32;14832:19;;18290:68:0;14459:398:1;18290:68:0;-1:-1:-1;;;;;18371:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;18423:32;;875:25:1;;;18423:32:0;;848:18:1;18423:32:0;;;;;;;18083:380;;;:::o;43205:98::-;43263:7;43290:5;43294:1;43290;:5;:::i;43961:98::-;44019:7;44046:5;44050:1;44046;:5;:::i;2401:132::-;2282:7;2309:6;-1:-1:-1;;;;;2309:6:0;861:10;2465:23;2457:68;;;;-1:-1:-1;;;2457:68:0;;15343:2:1;2457:68:0;;;15325:21:1;;;15362:18;;;15355:30;15421:34;15401:18;;;15394:62;15473:18;;2457:68:0;15141:356:1;42824:98:0;42882:7;42909:5;42913:1;42909;:5;:::i;18754:453::-;-1:-1:-1;;;;;11475:18:0;;;18889:24;11475:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;18956:37:0;;18952:248;;19038:6;19018:16;:26;;19010:68;;;;-1:-1:-1;;;19010:68:0;;15704:2:1;19010:68:0;;;15686:21:1;15743:2;15723:18;;;15716:30;15782:31;15762:18;;;15755:59;15831:18;;19010:68:0;15502:353:1;19010:68:0;19122:51;19131:5;19138:7;19166:6;19147:16;:25;19122:8;:51::i;14962:840::-;-1:-1:-1;;;;;15093:18:0;;15085:68;;;;-1:-1:-1;;;15085:68:0;;16062:2:1;15085:68:0;;;16044:21:1;16101:2;16081:18;;;16074:30;16140:34;16120:18;;;16113:62;16211:7;16191:18;;;16184:35;16236:19;;15085:68:0;15860:401:1;15085:68:0;-1:-1:-1;;;;;15172:16:0;;15164:64;;;;-1:-1:-1;;;15164:64:0;;16468:2:1;15164:64:0;;;16450:21:1;16507:2;16487:18;;;16480:30;16546:34;16526:18;;;16519:62;16617:5;16597:18;;;16590:33;16640:19;;15164:64:0;16266:399:1;15164:64:0;-1:-1:-1;;;;;15314:15:0;;15292:19;15314:15;;;:9;:15;;;;;;15348:21;;;;15340:72;;;;-1:-1:-1;;;15340:72:0;;16872:2:1;15340:72:0;;;16854:21:1;16911:2;16891:18;;;16884:30;16950:34;16930:18;;;16923:62;17021:8;17001:18;;;16994:36;17047:19;;15340:72:0;16670:402:1;15340:72:0;-1:-1:-1;;;;;15448:15:0;;;;;;;:9;:15;;;;;;15466:20;;;15448:38;;15666:13;;;;;;;;;;:23;;;;;;15718:26;;;;;;15480:6;875:25:1;;863:2;848:18;;729:177;15718:26:0;;;;;;;;15757:37;76158:315;56869:158;56943:7;56994:22;56998:3;57010:5;56994:3;:22::i;76481:1517::-;76576:21;76600:8;76609:4;76600:14;;;;;;;;:::i;:::-;;;;;;;;;76649;;;:8;:14;;;;;;-1:-1:-1;;;;;76649:21:0;;;;;;;;;76689:11;;76600:14;;;;;;;;-1:-1:-1;76689:22:0;-1:-1:-1;76689:22:0;76681:65;;;;-1:-1:-1;;;76681:65:0;;17279:2:1;76681:65:0;;;17261:21:1;17318:2;17298:18;;;17291:30;17357:32;17337:18;;;17330:60;17407:18;;76681:65:0;17077:354:1;76681:65:0;76757:16;76768:4;76757:10;:16::i;:::-;76784:21;76808:64;76856:4;:15;;;76808:43;76846:4;76808:33;76824:4;:16;;;76808:4;:11;;;:15;;:33;;;;:::i;:64::-;76784:88;-1:-1:-1;76887:17:0;;76883:88;;76921:38;76938:5;76945:13;76921:16;:38::i;:::-;76985:11;;76981:808;;77042:11;;77035:44;;;;;77073:4;77035:44;;;3758:74:1;77013:19:0;;-1:-1:-1;;;;;77042:11:0;;77035:29;;3731:18:1;;77035:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77109:10;;;77130:20;;;:14;:20;;;;;;;;77094:66;;;;;;;;5941:25:1;;;;5982:18;;;5975:34;;;77013:66:0;;-1:-1:-1;;;;;;77109:10:0;;77094:35;;5914:18:1;;77094:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;77203:11:0;;77196:44;;;;;77234:4;77196:44;;;3758:74:1;77175:18:0;;-1:-1:-1;;;;;;77203:11:0;;;;-1:-1:-1;77196:29:0;;3731:18:1;;77196:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77175:65;;77280:87;77307:59;77349:4;:16;;;77307:37;77339:4;77307:27;77322:11;77307:10;:14;;:27;;;;:::i;:59::-;77280:22;;;;;:26;:87::i;:::-;77255:22;;;:112;;;77459:21;;;;77405:11;;77382:20;;77405:76;;77459:21;77405:49;;77449:4;;77405:39;;:15;:39::i;:76::-;77382:99;-1:-1:-1;77500:16:0;;77496:110;;77544:11;;77537:53;;-1:-1:-1;;;;;77544:11:0;77570:5;77577:12;77537:32;:53::i;:::-;77634:11;;:24;;77650:7;77634:15;:24::i;:::-;77620:38;;77692:16;;;;:29;;77713:7;77692:20;:29::i;:::-;77673:16;;;:48;77736:12;;:41;;-1:-1:-1;;;;;77736:12:0;77762:5;77769:7;77736:25;:41::i;:::-;76998:791;;;76981:808;77833:16;;;;77817:11;;:43;;77855:4;;77817:33;;:15;:33::i;:43::-;77799:15;;;:61;77911:22;;;;77895:11;;:49;;77939:4;;77895:39;;:15;:39::i;:49::-;77871:21;;;:73;77960:30;;875:25:1;;;77976:4:0;;-1:-1:-1;;;;;77960:30:0;;;;;863:2:1;848:18;77960:30:0;;;;;;;;76565:1433;;;76481:1517;;;:::o;78006:810::-;78093:21;78117:8;78126:4;78117:14;;;;;;;;:::i;:::-;;;;;;;;;78166;;;:8;:14;;;;;;-1:-1:-1;;;;;78166:21:0;;;;;;;;;78206:11;;78117:14;;;;;;;;-1:-1:-1;78206:22:0;-1:-1:-1;78206:22:0;78198:57;;;;-1:-1:-1;;;78198:57:0;;17638:2:1;78198:57:0;;;17620:21:1;17677:2;17657:18;;;17650:30;17716:24;17696:18;;;17689:52;17758:18;;78198:57:0;17436:346:1;78198:57:0;78266:16;78277:4;78266:10;:16::i;:::-;78293:21;78317:64;78365:4;:15;;;78317:43;78355:4;78317:33;78333:4;:16;;;78317:4;:11;;;:15;;:33;;;;:::i;:64::-;78293:88;-1:-1:-1;78396:17:0;;78392:88;;78430:38;78447:5;78454:13;78430:16;:38::i;:::-;78494:11;;78490:201;;78536:11;;:24;;78552:7;78536:15;:24::i;:::-;78522:38;;78594:16;;;;:29;;78615:7;78594:20;:29::i;:::-;78575:16;;;:48;78638:12;;:41;;-1:-1:-1;;;;;78638:12:0;78664:5;78671:7;78638:25;:41::i;:::-;78735:16;;;;78719:11;;:43;;78757:4;;78719:33;;:15;:33::i;:43::-;78701:15;;;:61;78778:30;;875:25:1;;;78794:4:0;;-1:-1:-1;;;;;78778:30:0;;;;;863:2:1;848:18;78778:30:0;729:177:1;43562:98:0;43620:7;43647:5;43651:1;43647;:5;:::i;79202:799::-;79289:21;79313:8;79322:4;79313:14;;;;;;;;:::i;:::-;;;;;;;;;79362;;;:8;:14;;;;;;-1:-1:-1;;;;;79362:21:0;;;;;;;;;;79411:11;;79462;;79455:44;;;;;79493:4;79455:44;;;3758:74:1;79313:14:0;;;;;;;;;-1:-1:-1;79362:21:0;79411:11;;79313:14;;79462:11;;79455:29;;3731:18:1;;79455:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79525:10;;;79546:20;;;:14;:20;;;;;;;;79510:65;;;;;;;;5941:25:1;;;;5982:18;;;5975:34;;;79433:66:0;;-1:-1:-1;;;;;;79525:10:0;;79510:35;;5914:18:1;;79510:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;79614:11:0;;79607:44;;;;;79645:4;79607:44;;;3758:74:1;79586:18:0;;-1:-1:-1;;;;;;79614:11:0;;;;-1:-1:-1;79607:29:0;;3731:18:1;;79607:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79586:65;;79687:87;79714:59;79756:4;:16;;;79714:37;79746:4;79714:27;79729:11;79714:10;:14;;:27;;;;:::i;79687:87::-;79662:22;;;:112;79799:1;79785:15;;;79811;;;:19;79841:12;;:40;;-1:-1:-1;;;;;79841:12:0;79867:5;79874:6;79841:25;:40::i;:::-;79911:16;;;;:28;;79932:6;79911:20;:28::i;:::-;79892:16;;;:47;79955:38;;875:25:1;;;79980:4:0;;-1:-1:-1;;;;;79955:38:0;;;;;863:2:1;848:18;79955:38:0;;;;;;;79278:723;;;;;79202:799;;:::o;80009:439::-;80088:21;80112:8;80121:4;80112:14;;;;;;;;:::i;:::-;;;;;;;;;80161;;;:8;:14;;;;;;-1:-1:-1;;;;;80161:21:0;;;;;;;;;80210:11;;80232:15;;;-1:-1:-1;80258:15:0;;:19;;;;80112:14;;;;;80288:12;;80112:14;;-1:-1:-1;80161:21:0;;80210:11;80288:40;;:12;80176:5;80210:11;80288:25;:40::i;:::-;80358:16;;;;:28;;80379:6;80358:20;:28::i;:::-;80339:16;;;:47;80402:38;;875:25:1;;;80427:4:0;;-1:-1:-1;;;;;80402:38:0;;;;;863:2:1;848:18;80402:38:0;;;;;;;;80077:371;;;80009:439;;:::o;55573:152::-;55643:4;55667:50;55672:3;-1:-1:-1;;;;;55692:23:0;;55667:4;:50::i;3503:191::-;3577:16;3596:6;;-1:-1:-1;;;;;3613:17:0;;;;;;;;;;3646:40;;3596:6;;;;;;;3646:40;;3577:16;3646:40;3566:128;3503:191;:::o;56145:167::-;-1:-1:-1;;;;;56279:23:0;;56225:4;51497:19;;;:12;;;:19;;;;;;:24;;56249:55;51400:129;55901:158;55974:4;55998:53;56006:3;-1:-1:-1;;;;;56026:23:0;;55998:7;:53::i;73094:2189::-;73188:21;73212:8;73221:4;73212:14;;;;;;;;:::i;:::-;;;;;;;;;73261;;;:8;:14;;;;;;-1:-1:-1;;;;;73261:21:0;;;;;;;;;73212:14;;;;;;;;-1:-1:-1;73293:16:0;73270:4;73293:10;:16::i;:::-;73324:11;;:15;73320:846;;73356:21;73380:64;73428:4;:15;;;73380:43;73418:4;73380:33;73396:4;:16;;;73380:4;:11;;;:15;;:33;;;;:::i;:64::-;73356:88;-1:-1:-1;73463:17:0;;73459:96;;73501:38;73518:5;73525:13;73501:16;:38::i;:::-;73598:11;;73591:44;;;;;73629:4;73591:44;;;3758:74:1;73569:19:0;;-1:-1:-1;;;;;73598:11:0;;73591:29;;3731:18:1;;73591:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73665:10;;;73685:20;;;:14;:20;;;;;;;73650:59;;;;;;;;5941:25:1;;;;5982:18;;;5975:34;;;;73569:66:0;;-1:-1:-1;;;;;;73665:10:0;;73650:34;;5914:18:1;;73650:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;73752:11:0;;73745:44;;;;;73783:4;73745:44;;;3758:74:1;73724:18:0;;-1:-1:-1;;;;;;73752:11:0;;;;-1:-1:-1;73745:29:0;;3731:18:1;;73745:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73724:65;;73829:87;73856:59;73898:4;:16;;;73856:37;73888:4;73856:27;73871:11;73856:10;:14;;:27;;;;:::i;73829:87::-;73804:22;;;:112;;;74008:21;;;;73954:11;;73931:20;;73954:76;;74008:21;73954:49;;73998:4;;73954:39;;:15;:39::i;:76::-;73931:99;-1:-1:-1;74049:16:0;;74045:110;;74093:11;;74086:53;;-1:-1:-1;;;;;74093:11:0;74119:5;74126:12;74086:32;:53::i;:::-;73341:825;;;;73320:846;74180:11;;74176:899;;74208:12;;:60;;-1:-1:-1;;;;;74208:12:0;74238:5;74253:4;74260:7;74208:29;:60::i;:::-;74287:4;:16;;;74307:1;74287:21;74283:781;;74344:10;;;74364:20;;;:14;:20;;;;;;;;74329:65;;;;;-1:-1:-1;;;;;74344:10:0;;;;74329:34;;:65;;74386:7;;74329:65;;5941:25:1;;;5997:2;5982:18;;5975:34;5929:2;5914:18;;5767:248;74329:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74427:11:0;;:24;;-1:-1:-1;74427:11:0;-1:-1:-1;74443:7:0;74427:15;:24::i;:::-;74413:38;;74489:16;;;;:29;;74510:7;74489:20;:29::i;:::-;74470:16;;;:48;74283:781;;;74588:11;;74581:44;;;;;74619:4;74581:44;;;3758:74:1;74559:19:0;;-1:-1:-1;;;;;74588:11:0;;74581:29;;3731:18:1;;74581:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74659:10;;;74679:20;;;:14;:20;;;;;;;;74644:65;;;;;;;;5941:25:1;;;;5982:18;;;5975:34;;;74559:66:0;;-1:-1:-1;;;;;;74659:10:0;;74644:34;;5914:18:1;;74644:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74756:11:0;;74749:44;;;;;74787:4;74749:44;;;3758:74:1;74728:18:0;;-1:-1:-1;;;;;;74756:11:0;;;;-1:-1:-1;74749:29:0;;3731:18:1;;74749:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74728:65;;74837:87;74864:59;74906:4;:16;;;74864:37;74896:4;74864:27;74879:11;74864:10;:14;;:27;;;;:::i;:59::-;74837:22;;;;;:26;:87::i;:::-;74812:22;;;:112;74957:11;;:24;;74973:7;74957:15;:24::i;:::-;74943:38;;75019:16;;;;:29;;75040:7;75019:20;:29::i;:::-;75000:16;;;:48;-1:-1:-1;;74283:781:0;75119:16;;;;75103:11;;:43;;75141:4;;75103:33;;:15;:33::i;:43::-;75085:15;;;:61;75197:22;;;;75181:11;;:49;;75225:4;;75181:39;;:15;:39::i;:49::-;75157:21;;;:73;75246:29;;875:25:1;;;75261:4:0;;-1:-1:-1;;;;;75246:29:0;;;;;863:2:1;848:18;75246:29:0;729:177:1;75291:818:0;75377:21;75401:8;75410:4;75401:14;;;;;;;;:::i;:::-;;;;;;;;;75450;;;:8;:14;;;;;;-1:-1:-1;;;;;75450:21:0;;;;;;;;;75401:14;;;;;;;;-1:-1:-1;75482:16:0;75459:4;75482:10;:16::i;:::-;75513:11;;:15;75509:246;;75545:21;75569:64;75617:4;:15;;;75569:43;75607:4;75569:33;75585:4;:16;;;75569:4;:11;;;:15;;:33;;;;:::i;:64::-;75545:88;-1:-1:-1;75652:17:0;;75648:96;;75690:38;75707:5;75714:13;75690:16;:38::i;:::-;75530:225;75509:246;75769:11;;75765:220;;75797:12;;:60;;-1:-1:-1;;;;;75797:12:0;75827:5;75842:4;75849:7;75797:29;:60::i;:::-;75886:11;;:24;;75902:7;75886:15;:24::i;:::-;75872:38;;75944:16;;;;:29;;75965:7;75944:20;:29::i;:::-;75925:16;;;:48;75765:220;76029:16;;;;76013:11;;:43;;76051:4;;76013:33;;:15;:33::i;:43::-;75995:15;;;:61;76072:29;;875:25:1;;;76087:4:0;;-1:-1:-1;;;;;76072:29:0;;;;;863:2:1;848:18;76072:29:0;729:177:1;70437:1315:0;70517:7;70526;70545:21;70569:8;70578:4;70569:14;;;;;;;;:::i;:::-;;;;;;;;;70618;;;:8;:14;;;;;;-1:-1:-1;;;;;70618:21:0;;;;;;;;;70672:16;70569:14;;;;;;;70672:16;;;;70727:22;;;;70764:11;;70569:14;;-1:-1:-1;70672:16:0;;70764:15;70760:961;;70834:10;;70796:20;70858;;;:14;:20;;;;;;;70819:75;;;;;;;;18395:25:1;;;;70888:4:0;18436:18:1;;;18429:83;70796:20:0;;-1:-1:-1;;;;;70834:10:0;;70819:38;;18368:18:1;;70819:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70796:98;;70929:67;70951:44;70978:4;:16;;;70951:22;70968:4;70951:12;:16;;:22;;;;:::i;:44::-;70929:17;;:21;:67::i;:::-;70909:87;;71011:19;71033:71;71082:4;:21;;;71033:44;71072:4;71033:34;71049:17;71033:4;:11;;;:15;;:34;;;;:::i;:71::-;71011:93;;71138:4;:20;;;71123:12;:35;71119:419;;;71179:19;71201:36;71216:4;:20;;;71201:14;:36::i;:::-;71179:58;;71256:18;71277:53;71314:15;;71277:32;71293:4;:15;;;71277:11;:15;;:32;;;;:::i;:53::-;71256:74;;71363:59;71379:42;71404:4;:16;;;71379:20;71394:4;71379:10;:14;;:20;;;;:::i;:42::-;71363:11;;:15;:59::i;:::-;71349:73;;71449:59;71492:4;:15;;;71449:38;71482:4;71449:28;71465:11;71449:4;:11;;;:15;;:28;;;;:::i;:59::-;71510:11;71441:81;;;;;;;;;;;;;;71119:419;71572:4;:20;;;71556:12;:36;71552:158;;71621:59;71664:4;:15;;;71621:38;71654:4;71621:28;71637:11;71621:4;:11;;;:15;;:28;;;;:::i;:59::-;71613:81;-1:-1:-1;71682:11:0;-1:-1:-1;71613:81:0;;-1:-1:-1;;;;;71613:81:0;71552:158;70781:940;;70760:961;-1:-1:-1;71739:1:0;;;;-1:-1:-1;70437:1315:0;-1:-1:-1;;;;;;70437:1315:0:o;71760:938::-;71832:7;71851:21;71875:8;71884:4;71875:14;;;;;;;;:::i;:::-;;;;;;;;;71924;;;:8;:14;;;;;;-1:-1:-1;;;;;71924:21:0;;;;;;;;;;71875:14;;;;;;;;71978:16;;;;72024:12;;:37;;;;;72055:4;72024:37;;;3758:74:1;71875:14:0;;-1:-1:-1;71924:21:0;;71875:14;72024:12;;;;;:22;;3731:18:1;;72024:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72076:11;;72005:56;;-1:-1:-1;72076:15:0;72072:600;;72127:4;:20;;;72112:12;:35;72108:396;;;72168:19;72190:36;72205:4;:20;;;72190:14;:36::i;:::-;72168:58;;72245:18;72266:53;72303:15;;72266:32;72282:4;:15;;;72266:11;:15;;:32;;;;:::i;:53::-;72245:74;-1:-1:-1;72352:51:0;72368:34;72393:8;72368:20;72245:74;72383:4;72368:14;:20::i;72352:51::-;72338:65;;72429:59;72472:4;:15;;;72429:38;72462:4;72429:28;72445:11;72429:4;:11;;;:15;;:28;;;;:::i;:59::-;72422:66;;;;;;;;;;72108:396;72538:4;:20;;;72522:12;:36;72518:143;;72586:59;72629:4;:15;;;72586:38;72619:4;72586:28;72602:11;72586:4;:11;;;:15;;:28;;;;:::i;:59::-;72579:66;;;;;;;;72518:143;-1:-1:-1;72689:1:0;;71760:938;-1:-1:-1;;;;;;71760:938:0:o;56398:117::-;56461:7;56488:19;56496:3;51698:18;;51615:109;16970:675;-1:-1:-1;;;;;17054:21:0;;17046:67;;;;-1:-1:-1;;;17046:67:0;;18725:2:1;17046:67:0;;;18707:21:1;18764:2;18744:18;;;18737:30;18803:34;18783:18;;;18776:62;18874:3;18854:18;;;18847:31;18895:19;;17046:67:0;18523:397:1;17046:67:0;-1:-1:-1;;;;;17213:18:0;;17188:22;17213:18;;;:9;:18;;;;;;17250:24;;;;17242:71;;;;-1:-1:-1;;;17242:71:0;;19127:2:1;17242:71:0;;;19109:21:1;19166:2;19146:18;;;19139:30;19205:34;19185:18;;;19178:62;19276:4;19256:18;;;19249:32;19298:19;;17242:71:0;18925:398:1;17242:71:0;-1:-1:-1;;;;;17349:18:0;;;;;;:9;:18;;;;;;;;17370:23;;;17349:44;;17488:12;:22;;;;;;;17539:37;875:25:1;;;17349:18:0;;;17539:37;;848:18:1;17539:37:0;;;;;;;76223:250:::1;76158:315:::0;;:::o;52078:120::-;52145:7;52172:3;:11;;52184:5;52172:18;;;;;;;;:::i;:::-;;;;;;;;;52165:25;;52078:120;;;;:::o;80562:109::-;80638:25;80650:3;80655:7;80638:11;:25::i;33196:211::-;33340:58;;-1:-1:-1;;;;;8895:55:1;;33340:58:0;;;8877:74:1;8967:18;;;8960:34;;;33313:86:0;;33333:5;;33363:23;;8850:18:1;;33340:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33313:19;:86::i;49304:414::-;49367:4;51497:19;;;:12;;;:19;;;;;;49384:327;;-1:-1:-1;49427:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;49610:18;;49588:19;;;:12;;;:19;;;;;;:40;;;;49643:11;;49384:327;-1:-1:-1;49694:5:0;49687:12;;49894:1420;49960:4;50099:19;;;:12;;;:19;;;;;;50135:15;;50131:1176;;50510:21;50534:14;50547:1;50534:10;:14;:::i;:::-;50583:18;;50510:38;;-1:-1:-1;50563:17:0;;50583:22;;50604:1;;50583:22;:::i;:::-;50563:42;;50639:13;50626:9;:26;50622:405;;50673:17;50693:3;:11;;50705:9;50693:22;;;;;;;;:::i;:::-;;;;;;;;;50673:42;;50847:9;50818:3;:11;;50830:13;50818:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;50932:23;;;:12;;;:23;;;;;:36;;;50622:405;51108:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;51203:3;:12;;:19;51216:5;51203:19;;;;;;;;;;;51196:26;;;51246:4;51239:11;;;;;;;50131:1176;51290:5;51283:12;;;;;33415:248;33586:68;;-1:-1:-1;;;;;19798:15:1;;;33586:68:0;;;19780:34:1;19850:15;;19830:18;;;19823:43;19882:18;;;19875:34;;;33559:96:0;;33579:5;;33609:27;;19692:18:1;;33586:68:0;19517:398:1;16089:548:0;-1:-1:-1;;;;;16173:21:0;;16165:65;;;;-1:-1:-1;;;16165:65:0;;20122:2:1;16165:65:0;;;20104:21:1;20161:2;20141:18;;;20134:30;20200:33;20180:18;;;20173:61;20251:18;;16165:65:0;19920:355:1;16165:65:0;16321:6;16305:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;16476:18:0;;;;;;:9;:18;;;;;;;;:28;;;;;;16531:37;875:25:1;;;16531:37:0;;848:18:1;16531:37:0;;;;;;;78944:250:::1;78887:307:::0;:::o;36263:716::-;36687:23;36713:69;36741:4;36713:69;;;;;;;;;;;;;;;;;36721:5;-1:-1:-1;;;;;36713:27:0;;;:69;;;;;:::i;:::-;36797:17;;36687:95;;-1:-1:-1;36797:21:0;36793:179;;36894:10;36883:30;;;;;;;;;;;;:::i;:::-;36875:85;;;;-1:-1:-1;;;36875:85:0;;20482:2:1;36875:85:0;;;20464:21:1;20521:2;20501:18;;;20494:30;20560:34;20540:18;;;20533:62;20631:12;20611:18;;;20604:40;20661:19;;36875:85:0;20280:406:1;27038:229:0;27175:12;27207:52;27229:6;27237:4;27243:1;27246:12;27207:21;:52::i;:::-;27200:59;27038:229;-1:-1:-1;;;;27038:229:0:o;28158:455::-;28328:12;28386:5;28361:21;:30;;28353:81;;;;-1:-1:-1;;;28353:81:0;;20893:2:1;28353:81:0;;;20875:21:1;20932:2;20912:18;;;20905:30;20971:34;20951:18;;;20944:62;21042:8;21022:18;;;21015:36;21068:19;;28353:81:0;20691:402:1;28353:81:0;28446:12;28460:23;28487:6;-1:-1:-1;;;;;28487:11:0;28506:5;28513:4;28487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28445:73;;;;28536:69;28563:6;28571:7;28580:10;28592:12;28536:26;:69::i;:::-;28529:76;28158:455;-1:-1:-1;;;;;;;28158:455:0:o;30731:644::-;30916:12;30945:7;30941:427;;;30973:10;:17;30994:1;30973:22;30969:290;;-1:-1:-1;;;;;24576:19:0;;;31183:60;;;;-1:-1:-1;;;31183:60:0;;21592:2:1;31183:60:0;;;21574:21:1;21631:2;21611:18;;;21604:30;21670:31;21650:18;;;21643:59;21719:18;;31183:60:0;21390:353:1;31183:60:0;-1:-1:-1;31280:10:0;31273:17;;30941:427;31323:33;31331:10;31343:12;32078:17;;:21;32074:388;;32310:10;32304:17;32367:15;32354:10;32350:2;32346:19;32339:44;32074:388;32437:12;32430:20;;-1:-1:-1;;;32430:20:0;;;;;;;;:::i;14:250:1:-;99:1;109:113;123:6;120:1;117:13;109:113;;;199:11;;;193:18;180:11;;;173:39;145:2;138:10;109:113;;;-1:-1:-1;;256:1:1;238:16;;231:27;14:250::o;269:455::-;418:2;407:9;400:21;381:4;450:6;444:13;493:6;488:2;477:9;473:18;466:34;509:79;581:6;576:2;565:9;561:18;556:2;548:6;544:15;509:79;:::i;:::-;640:2;628:15;645:66;624:88;609:104;;;;715:2;605:113;;269:455;-1:-1:-1;;269:455:1:o;911:154::-;-1:-1:-1;;;;;990:5:1;986:54;979:5;976:65;966:93;;1055:1;1052;1045:12;1070:315;1138:6;1146;1199:2;1187:9;1178:7;1174:23;1170:32;1167:52;;;1215:1;1212;1205:12;1167:52;1254:9;1241:23;1273:31;1298:5;1273:31;:::i;:::-;1323:5;1375:2;1360:18;;;;1347:32;;-1:-1:-1;;;1070:315:1:o;1582:180::-;1641:6;1694:2;1682:9;1673:7;1669:23;1665:32;1662:52;;;1710:1;1707;1700:12;1662:52;-1:-1:-1;1733:23:1;;1582:180;-1:-1:-1;1582:180:1:o;2370:118::-;2456:5;2449:13;2442:21;2435:5;2432:32;2422:60;;2478:1;2475;2468:12;2493:464;2581:6;2589;2597;2650:2;2638:9;2629:7;2625:23;2621:32;2618:52;;;2666:1;2663;2656:12;2618:52;2702:9;2689:23;2679:33;;2762:2;2751:9;2747:18;2734:32;2775:31;2800:5;2775:31;:::i;:::-;2825:5;-1:-1:-1;2882:2:1;2867:18;;2854:32;2895:30;2854:32;2895:30;:::i;:::-;2944:7;2934:17;;;2493:464;;;;;:::o;2962:456::-;3039:6;3047;3055;3108:2;3096:9;3087:7;3083:23;3079:32;3076:52;;;3124:1;3121;3114:12;3076:52;3163:9;3150:23;3182:31;3207:5;3182:31;:::i;:::-;3232:5;-1:-1:-1;3289:2:1;3274:18;;3261:32;3302:33;3261:32;3302:33;:::i;:::-;2962:456;;3354:7;;-1:-1:-1;;;3408:2:1;3393:18;;;;3380:32;;2962:456::o;3843:248::-;3911:6;3919;3972:2;3960:9;3951:7;3947:23;3943:32;3940:52;;;3988:1;3985;3978:12;3940:52;-1:-1:-1;;4011:23:1;;;4081:2;4066:18;;;4053:32;;-1:-1:-1;3843:248:1:o;4096:247::-;4155:6;4208:2;4196:9;4187:7;4183:23;4179:32;4176:52;;;4224:1;4221;4214:12;4176:52;4263:9;4250:23;4282:31;4307:5;4282:31;:::i;4348:377::-;4422:6;4430;4438;4491:2;4479:9;4470:7;4466:23;4462:32;4459:52;;;4507:1;4504;4497:12;4459:52;4543:9;4530:23;4520:33;;4600:2;4589:9;4585:18;4572:32;4562:42;;4654:2;4643:9;4639:18;4626:32;4667:28;4689:5;4667:28;:::i;4730:315::-;4798:6;4806;4859:2;4847:9;4838:7;4834:23;4830:32;4827:52;;;4875:1;4872;4865:12;4827:52;4911:9;4898:23;4888:33;;4971:2;4960:9;4956:18;4943:32;4984:31;5009:5;4984:31;:::i;:::-;5034:5;5024:15;;;4730:315;;;;;:::o;5374:388::-;5442:6;5450;5503:2;5491:9;5482:7;5478:23;5474:32;5471:52;;;5519:1;5516;5509:12;5471:52;5558:9;5545:23;5577:31;5602:5;5577:31;:::i;:::-;5627:5;-1:-1:-1;5684:2:1;5669:18;;5656:32;5697:33;5656:32;5697:33;:::i;6020:437::-;6099:1;6095:12;;;;6142;;;6163:61;;6217:4;6209:6;6205:17;6195:27;;6163:61;6270:2;6262:6;6259:14;6239:18;6236:38;6233:218;;6307:77;6304:1;6297:88;6408:4;6405:1;6398:15;6436:4;6433:1;6426:15;6233:218;;6020:437;;;:::o;6819:184::-;6871:77;6868:1;6861:88;6968:4;6965:1;6958:15;6992:4;6989:1;6982:15;7008:128;7075:9;;;7096:11;;;7093:37;;;7110:18;;:::i;7141:125::-;7206:9;;;7227:10;;;7224:36;;;7240:18;;:::i;7974:184::-;8026:77;8023:1;8016:88;8123:4;8120:1;8113:15;8147:4;8144:1;8137:15;8163:184;8233:6;8286:2;8274:9;8265:7;8261:23;8257:32;8254:52;;;8302:1;8299;8292:12;8254:52;-1:-1:-1;8325:16:1;;8163:184;-1:-1:-1;8163:184:1:o;9005:245::-;9072:6;9125:2;9113:9;9104:7;9100:23;9096:32;9093:52;;;9141:1;9138;9131:12;9093:52;9173:9;9167:16;9192:28;9214:5;9192:28;:::i;9255:195::-;9294:3;-1:-1:-1;;9318:5:1;9315:77;9312:103;;9395:18;;:::i;:::-;-1:-1:-1;9442:1:1;9431:13;;9255:195::o;9861:482::-;9950:1;9993:5;9950:1;10007:330;10028:7;10018:8;10015:21;10007:330;;;10147:4;-1:-1:-1;;10075:77:1;10069:4;10066:87;10063:113;;;10156:18;;:::i;:::-;10206:7;10196:8;10192:22;10189:55;;;10226:16;;;;10189:55;10305:22;;;;10265:15;;;;10007:330;;10348:866;10397:5;10427:8;10417:80;;-1:-1:-1;10468:1:1;10482:5;;10417:80;10516:4;10506:76;;-1:-1:-1;10553:1:1;10567:5;;10506:76;10598:4;10616:1;10611:59;;;;10684:1;10679:130;;;;10591:218;;10611:59;10641:1;10632:10;;10655:5;;;10679:130;10716:3;10706:8;10703:17;10700:43;;;10723:18;;:::i;:::-;-1:-1:-1;;10779:1:1;10765:16;;10794:5;;10591:218;;10893:2;10883:8;10880:16;10874:3;10868:4;10865:13;10861:36;10855:2;10845:8;10842:16;10837:2;10831:4;10828:12;10824:35;10821:77;10818:159;;;-1:-1:-1;10930:19:1;;;10962:5;;10818:159;11009:34;11034:8;11028:4;11009:34;:::i;:::-;11139:6;-1:-1:-1;;11067:79:1;11058:7;11055:92;11052:118;;;11150:18;;:::i;:::-;11188:20;;10348:866;-1:-1:-1;;;10348:866:1:o;11219:131::-;11279:5;11308:36;11335:8;11329:4;11308:36;:::i;12052:196::-;12091:3;12119:5;12109:39;;12128:18;;:::i;:::-;-1:-1:-1;;;12164:78:1;;12052:196::o;14862:274::-;14902:1;14928;14918:189;;14963:77;14960:1;14953:88;15064:4;15061:1;15054:15;15092:4;15089:1;15082:15;14918:189;-1:-1:-1;15121:9:1;;14862:274::o;17787:168::-;17860:9;;;17891;;17908:15;;;17902:22;;17888:37;17878:71;;17929:18;;:::i;19328:184::-;19380:77;19377:1;19370:88;19477:4;19474:1;19467:15;19501:4;19498:1;19491:15;21098:287;21227:3;21265:6;21259:13;21281:66;21340:6;21335:3;21328:4;21320:6;21316:17;21281:66;:::i;:::-;21363:16;;;;;21098:287;-1:-1:-1;;21098:287:1:o

Swarm Source

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