ETH Price: $3,491.46 (+4.91%)

Token

Pepe NFT (PEPENFT)
 

Overview

Max Total Supply

34 PEPENFT

Holders

33

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 PEPENFT
0x40c3fa73f2a3a0b5c70076254f9c5b5deab4bf7a
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:
PepeNFT

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-05-07
*/

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// 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/IERC20Metadata.sol


// 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/utils/Counters.sol


// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

// File: @openzeppelin/contracts/utils/Context.sol


// 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/token/ERC20/ERC20.sol


// 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/access/Ownable.sol


// 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: contracts/Pepe.sol


pragma solidity ^0.8.9;




contract PepeToken is Ownable, ERC20 {
    bool public limited;
    uint256 public maxHoldingAmount;
    uint256 public minHoldingAmount;
    address public uniswapV2Pair;
    mapping(address => bool) public blacklists;

    constructor(uint256 _totalSupply) ERC20("Pepe", "PEPE") {
        _mint(msg.sender, _totalSupply);
    }

    function blacklist(address _address, bool _isBlacklisting) external onlyOwner {
        blacklists[_address] = _isBlacklisting;
    }

    function setRule(bool _limited, address _uniswapV2Pair, uint256 _maxHoldingAmount, uint256 _minHoldingAmount) external onlyOwner {
        limited = _limited;
        uniswapV2Pair = _uniswapV2Pair;
        maxHoldingAmount = _maxHoldingAmount;
        minHoldingAmount = _minHoldingAmount;
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) override internal virtual {
        require(!blacklists[to] && !blacklists[from], "Blacklisted");

        if (uniswapV2Pair == address(0)) {
            require(from == owner() || to == owner(), "trading is not started");
            return;
        }

        if (limited && from == uniswapV2Pair) {
            require(super.balanceOf(to) + amount <= maxHoldingAmount && super.balanceOf(to) + amount >= minHoldingAmount, "Forbid");
        }
    }

    function burn(uint256 value) external {
        _burn(msg.sender, value);
    }
}
// File: contracts/Dividends.sol


pragma solidity ^0.8.9;


/**
 * Standard SafeMath, stripped down to just add/sub/mul/div
 */
library SafeMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }
}

interface IDEXFactory {
    function createPair(
        address tokenA,
        address tokenB
    ) external returns (address pair);
}

interface IDEXRouter {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);
}

interface IDividendDistributor {
    function setShare(address shareholder, uint256 amount) external;

    function deposit(uint256 amount) external;

    function claimDividend(address shareholder) external;

    function getDividendsClaimedOf(
        address shareholder
    ) external returns (uint256);
}

contract DividendDistributor is IDividendDistributor {
    using SafeMath for uint256;

    address public _token;
    address public _owner;

    address public immutable PEPE =
        address(0x6982508145454Ce325dDbE47a25d4ec3d2311933); //UNI

    struct Share {
        uint256 amount;
        uint256 totalExcluded;
        uint256 totalClaimed;
    }

    address[] private shareholders;
    mapping(address => uint256) private shareholderIndexes;

    mapping(address => Share) public shares;

    uint256 public totalShares;
    uint256 public totalDividends;
    uint256 public totalClaimed;
    uint256 public dividendsPerShare;
    uint256 private dividendsPerShareAccuracyFactor = 10 ** 36;

    modifier onlyToken() {
        require(msg.sender == _token);
        _;
    }

    modifier onlyOwner() {
        require(msg.sender == _owner);
        _;
    }

    constructor(address owner) {
        _token = msg.sender;
        _owner = owner;
    }

    receive() external payable {}

    function setShare(
        address shareholder,
        uint256 amount
    ) external override onlyToken {
        if (shares[shareholder].amount > 0) {
            distributeDividend(shareholder);
        }

        if (amount > 0 && shares[shareholder].amount == 0) {
            addShareholder(shareholder);
        } else if (amount == 0 && shares[shareholder].amount > 0) {
            removeShareholder(shareholder);
        }

        totalShares = totalShares.sub(shares[shareholder].amount).add(amount);
        shares[shareholder].amount = amount;
        shares[shareholder].totalExcluded = getCumulativeDividends(
            shares[shareholder].amount
        );
    }

    function deposit(uint256 amount) external override onlyToken {
        if (amount > 0) {
            totalDividends = totalDividends.add(amount);
            dividendsPerShare = dividendsPerShare.add(
                dividendsPerShareAccuracyFactor.mul(amount).div(totalShares)
            );
        }
    }

    function distributeDividend(address shareholder) internal {
        if (shares[shareholder].amount == 0) {
            return;
        }

        uint256 amount = getClaimableDividendOf(shareholder);
        if (amount > 0) {
            totalClaimed = totalClaimed.add(amount);
            shares[shareholder].totalClaimed = shares[shareholder]
                .totalClaimed
                .add(amount);
            shares[shareholder].totalExcluded = getCumulativeDividends(
                shares[shareholder].amount
            );
            IERC20(PEPE).transfer(shareholder, amount);
        }
    }

    function claimDividend(address shareholder) external override onlyToken {
        distributeDividend(shareholder);
    }

    function getClaimableDividendOf(
        address shareholder
    ) public view returns (uint256) {
        if (shares[shareholder].amount == 0) {
            return 0;
        }

        uint256 shareholderTotalDividends = getCumulativeDividends(
            shares[shareholder].amount
        );
        uint256 shareholderTotalExcluded = shares[shareholder].totalExcluded;

        if (shareholderTotalDividends <= shareholderTotalExcluded) {
            return 0;
        }

        return shareholderTotalDividends.sub(shareholderTotalExcluded);
    }

    function getCumulativeDividends(
        uint256 share
    ) internal view returns (uint256) {
        return
            share.mul(dividendsPerShare).div(dividendsPerShareAccuracyFactor);
    }

    function addShareholder(address shareholder) internal {
        shareholderIndexes[shareholder] = shareholders.length;
        shareholders.push(shareholder);
    }

    function removeShareholder(address shareholder) internal {
        shareholders[shareholderIndexes[shareholder]] = shareholders[
            shareholders.length - 1
        ];
        shareholderIndexes[
            shareholders[shareholders.length - 1]
        ] = shareholderIndexes[shareholder];
        shareholders.pop();
    }

    function manualSend(uint256 amount, address holder) external onlyOwner {
        uint256 contractETHBalance = address(this).balance;
        payable(holder).transfer(amount > 0 ? amount : contractETHBalance);
    }

    function getDividendsClaimedOf(
        address shareholder
    ) external view returns (uint256) {
        require(
            shares[shareholder].amount > 0,
            "You're not a PRINTER shareholder!"
        );
        return shares[shareholder].totalClaimed;
    }
}
// File: @openzeppelin/contracts/utils/Address.sol


// 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/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/interfaces/IERC2981.sol


// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/token/common/ERC2981.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;



/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


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

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner or approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _ownerOf(tokenId) != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId, 1);

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId, 1);

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
     * that `ownerOf(tokenId)` is `a`.
     */
    // solhint-disable-next-line func-name-mixedcase
    function __unsafe_increaseBalance(address account, uint256 amount) internal {
        _balances[account] += amount;
    }
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)

pragma solidity ^0.8.0;


/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev See {ERC721-_burn}. This override additionally checks to see if a
     * token-specific URI was set for the token, and if so, it deletes the token URI from
     * the storage mapping.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: contracts/PepeNFT.sol


pragma solidity ^0.8.9;

// ERC 721 Imports for NFT contract standard




// ERC 2981 Imports for royalty standard


// Counters Imports for token ID management



contract PepeNFT is
    ERC721,
    ERC721Enumerable,
    ERC721URIStorage,
    ERC2981,
    Ownable
{
    using Counters for Counters.Counter;
    using SafeMath for uint256;

    // PEPE dividend contract related
    // -----------------------------------------
    address private WETH;

    mapping(address => bool) private isDividendExempt;

    IDEXRouter public router;
    address public immutable UNISWAPV2_ROUTER_ADDRESS =
        address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);

    DividendDistributor private distributor;

    // -----------------------------------------

    // all related to NFT
    // -----------------------------------------
    Counters.Counter private _tokenIdCounter;

    bool _isMintingActive = false;

    // ipfs uri relared
    string private base;
    string private tokenPrefix;
    string private tokenExtension;

    // price per token is 0.01 ETH
    uint256 public ETH_PRICE = 10000000000000000;

    // price per token is 10M PEPE
    uint256 public PEPE_PRICE = 10000000000000000000000000;

    // max number of tokens to mint
    uint256 public constant MAX_TOKENS = 10000;

    // max number of tokens to mint per transaction
    uint256 public constant MAX_TOKENS_PER_TX = 20;

    // max number of tokens to mint per wallet
    uint256 public constant MAX_TOKENS_PER_WALLET = 100;

    // royalties are 2% of the sale price, denoted in BPS (1/10000)
    uint256 public constant ROYALTY_FEE = 200;

    // address of PEPE token. We will be accepting this token as payment alongside ETH
    address public immutable PEPE_TOKEN_ADDRESS =
        address(0x6982508145454Ce325dDbE47a25d4ec3d2311933);

    IERC20 private pepeContract;

    // -----------------------------------------

    // make sure to have / at the end of base URI
    constructor() ERC721("Pepe NFT", "PEPENFT") {
        base = "ipfs://bafybeicthcikij6lgf32yecyxrfayj222ci3l5bae7hneyhakz64slri7e/";
        tokenPrefix = "pepe_";
        tokenExtension = ".json";

        // this is uniswap v2 router address
        pepeContract = IERC20(PEPE_TOKEN_ADDRESS);
        router = IDEXRouter(UNISWAPV2_ROUTER_ADDRESS);
        WETH = router.WETH();
        distributor = new DividendDistributor(owner());
        isDividendExempt[address(this)] = true;

        _tokenIdCounter.increment();
    }

    function setPrice(uint256 newETHPrice, uint256 newPEPEPrice)
        public
        onlyOwner
    {
        ETH_PRICE = newETHPrice;
        PEPE_PRICE = newPEPEPrice;
    }

    function approve(address to, uint256 tokenId) public virtual override {
        super.approve(to, tokenId);
    }

    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        super.setApprovalForAll(operator, approved);
    }

    // airdrop first 69 tokens to wallets given to the function
    function airdrop(address[] calldata wallets, bool[] calldata allowed)
        public
        onlyOwner
    {
        require(!_isMintingActive && totalSupply() == 0, "Minting is active");

        for (uint256 i = 0; i < wallets.length; i++) {
            mintNFT(wallets[i]);
            if (allowed[i]) {
                setShare(wallets[i], false);
            }
        }
    }

    // helper to flip the minting switch
    function flipMintingState() public onlyOwner {
        _isMintingActive = !_isMintingActive;
    }

    // base URI for token metadata. setter and getter
    function _baseURI() internal view override returns (string memory) {
        return base;
    }

    function mintNFT(address to) private {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        string memory tokenUri = string(
            abi.encodePacked(
                tokenPrefix,
                Strings.toString(tokenId),
                tokenExtension
            )
        );
        _setTokenURI(tokenId, tokenUri);
    }

    function _mintNFTs(address to, uint256 numberOfTokens) private {
        for (uint256 i = 0; i < numberOfTokens; i++) {
            mintNFT(to);
        }
    }

    function getShareMultiplier(uint256 tokenId)
        internal
        pure
        returns (uint256)
    {
        uint256 multiplier = 2;
        if (tokenId > 0 && tokenId < 1001) {
            multiplier = 10;
        } else if (tokenId > 1000 && tokenId < 2001) {
            multiplier = 9;
        } else if (tokenId > 2000 && tokenId < 3001) {
            multiplier = 8;
        } else if (tokenId > 3000 && tokenId < 4001) {
            multiplier = 7;
        } else if (tokenId > 4000 && tokenId < 5001) {
            multiplier = 6;
        } else if (tokenId > 5000 && tokenId < 6001) {
            multiplier = 5;
        } else if (tokenId > 6000 && tokenId < 7001) {
            multiplier = 4;
        } else if (tokenId > 7000 && tokenId < 8001) {
            multiplier = 3;
        }
        return multiplier;
    }

    function getShare(address holder) internal view returns (uint256) {
        uint256 share = 0;
        uint256 balance = balanceOf(holder);
        for (uint256 i = 0; i < balance; i++) {
            uint256 tokenId = tokenOfOwnerByIndex(holder, i);
            uint256 multiplier = getShareMultiplier(tokenId);
            share = share.add(multiplier);
        }
        return share;
    }

    function setShare(address sender, bool callDeposit) internal {
        // set the holder's share to the current balance
        if (!isDividendExempt[sender]) {
            try distributor.setShare(sender, getShare(sender)) {} catch {}
        }
        if (callDeposit) {
            depositDividends();
        }
    }

    function mintNFTs(uint256 numberOfTokens, bool buyWithPepe)
        external
        payable
    {
        require(_isMintingActive, "Minting is not active");
        require(
            numberOfTokens <= MAX_TOKENS_PER_TX,
            "Max tokens per transaction exceeded"
        );
        require(
            balanceOf(msg.sender).add(numberOfTokens) <= MAX_TOKENS_PER_WALLET,
            "Max tokens per wallet exceeded"
        );
        require(
            totalSupply().add(numberOfTokens) <= MAX_TOKENS,
            "Not enough tokens left. Decrease the number of tokens to mint"
        );

        if (buyWithPepe) {
            uint256 pepeAmount = PEPE_PRICE.mul(numberOfTokens);
            require(
                pepeContract.balanceOf(msg.sender) >= pepeAmount,
                "Not enough PEPE sent"
            );

            _mintNFTs(msg.sender, numberOfTokens);

            // send to contract
            pepeContract.transferFrom(
                msg.sender,
                address(this),
                pepeAmount.mul(8000).div(10000)
            );

            // send to owner
            pepeContract.transferFrom(
                msg.sender,
                owner(),
                pepeAmount.mul(2000).div(10000)
            );
        } else {
            require(
                msg.value >= ETH_PRICE.mul(numberOfTokens),
                "Not enough ETH sent"
            );

            _mintNFTs(msg.sender, numberOfTokens);

            // use 30% of the ETH to buy the token
            uint256 ethToSwap = msg.value.mul(7000).div(10000);
            swapETHForPEPE(ethToSwap);

            // send the remaining ETH to the owner
            payable(owner()).transfer(msg.value.sub(ethToSwap));
        }

        setShare(msg.sender, true);
    }

    function royaltyInfo(uint256, uint256 salePrice)
        public
        view
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        return (address(this), (salePrice.mul(ROYALTY_FEE)).div(10000));
    }

    receive() external payable {
        // when we receive ETH, we swap one half for PEPE and deposit the other half to owner
        swapETHForPEPE(msg.value.div(2));
        payable(owner()).transfer(msg.value.div(2));
        depositDividends();
    }

    // The following functions are overrides required by Solidity.

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId,
        uint256 batchSize
    ) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);

        // check if from and to are both not zero address
        if (from != address(0) && to != address(0)) {
            setShare(from, true);
            setShare(to, true);
        }
    }

    function _burn(uint256 tokenId)
        internal
        override(ERC721, ERC721URIStorage)
    {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable, ERC2981)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    // PEPE and distrubutor related functions

    function depositDividends() internal {
        uint256 dividends = pepeContract.balanceOf(address(this));

        bool success = pepeContract.transfer(address(distributor), dividends);

        if (success) {
            distributor.deposit(dividends);
        }
    }

    function swapETHForPEPE(uint256 ethAmount) internal {
        address[] memory path = new address[](2);
        path[0] = WETH;
        path[1] = PEPE_TOKEN_ADDRESS;

        // make the swap
        router.swapExactETHForTokens{value: ethAmount}(
            0,
            path,
            address(this),
            block.timestamp.add(300)
        );
    }

    function setIsDividendExempt(address holder, bool exempt) public onlyOwner {
        require(holder != address(this));
        isDividendExempt[holder] = exempt;
        if (exempt) {
            distributor.setShare(holder, 0);
        } else {
            distributor.setShare(holder, balanceOf(holder));
        }
    }

    function claimDividend() external {
        distributor.claimDividend(msg.sender);
    }

    function claimDividendFor(address holder) external onlyOwner {
        distributor.claimDividend(holder);
    }

    function getClaimableDividendOf(address shareholder)
        public
        view
        returns (uint256)
    {
        return distributor.getClaimableDividendOf(shareholder);
    }

    function getTotalDividends() external view returns (uint256) {
        return distributor.totalDividends();
    }

    function getTotalClaimed() external view returns (uint256) {
        return distributor.totalClaimed();
    }

    function getDividendsClaimedOf(address shareholder)
        external
        view
        returns (uint256)
    {
        return distributor.getDividendsClaimedOf(shareholder);
    }

    function manualSend(address toAddress) external onlyOwner {
        payable(toAddress).transfer(address(this).balance);
        pepeContract.transfer(toAddress, pepeContract.balanceOf(address(this)));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","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":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"ETH_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_PER_TX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_PER_WALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PEPE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PEPE_TOKEN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROYALTY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAPV2_ROUTER_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"wallets","type":"address[]"},{"internalType":"bool[]","name":"allowed","type":"bool[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimDividend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"claimDividendFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipMintingState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"}],"name":"getClaimableDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"}],"name":"getDividendsClaimedOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDividends","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"toAddress","type":"address"}],"name":"manualSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"bool","name":"buyWithPepe","type":"bool"}],"name":"mintNFTs","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IDEXRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"bool","name":"exempt","type":"bool"}],"name":"setIsDividendExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newETHPrice","type":"uint256"},{"internalType":"uint256","name":"newPEPEPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c0604052737a250d5630b4cf539739df2c5dacb4c659f2488d6080526013805460ff19169055662386f26fc100006017556a084595161401484a000000601855736982508145454ce325ddbe47a25d4ec3d231193360a0523480156200006557600080fd5b50604080518082018252600881526714195c194813919560c21b6020808301918252835180850190945260078452661411541153919560ca1b908401528151919291620000b59160009162000331565b508051620000cb90600190602084019062000331565b505050620000e8620000e2620002d260201b60201c565b620002d6565b60405180608001604052806043815260200162004863604391398051620001189160149160209091019062000331565b5060408051808201909152600580825264706570655f60d81b6020909201918252620001479160159162000331565b5060408051808201909152600580825264173539b7b760d91b6020909201918252620001769160169162000331565b5060a051601980546001600160a01b03199081166001600160a01b03938416179091556080516010805490921692169182179055604080516315ab88c960e31b8152905163ad5c464891600480820192602092909190829003018186803b158015620001e157600080fd5b505afa158015620001f6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021c9190620003e5565b600e80546001600160a01b0319166001600160a01b03928316179055600d54166040516200024a90620003c0565b6001600160a01b039091168152602001604051809103906000f08015801562000277573d6000803e3d6000fd5b50601180546001600160a01b0319166001600160a01b0392909216919091179055306000908152600f60209081526040909120805460ff19166001179055620002cc9060129062000328811b6200194e17901c565b62000454565b3390565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80546001019055565b8280546200033f9062000417565b90600052602060002090601f016020900481019282620003635760008555620003ae565b82601f106200037e57805160ff1916838001178555620003ae565b82800160010185558215620003ae579182015b82811115620003ae57825182559160200191906001019062000391565b50620003bc929150620003ce565b5090565b610da88062003abb83390190565b5b80821115620003bc5760008155600101620003cf565b600060208284031215620003f857600080fd5b81516001600160a01b03811681146200041057600080fd5b9392505050565b600181811c908216806200042c57607f821691505b602082108114156200044e57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05161363a62000481600039600081816102fb0152610890015260006105cf015261363a6000f3fe60806040526004361061024a5760003560e01c80638832bc2911610139578063d81049ef116100b6578063f2fde38b1161007a578063f2fde38b14610737578063f47c84c514610757578063f655ff221461076d578063f708a64f14610782578063f7d97577146107a2578063f887ea40146107c257600080fd5b8063d81049ef14610691578063e0c23b94146106a4578063e985e9c5146106b9578063edf3525314610702578063f0fc6bca1461072257600080fd5b8063a22cb465116100fd578063a22cb46514610606578063a85e1dea14610626578063b88d4fde1461063c578063c87b56dd1461065c578063d1bdb1d11461067c57600080fd5b80638832bc29146105695780638da5cb5b1461057f5780638ecc37fb1461059d578063932da039146105bd57806395d89b41146105f157600080fd5b8063335477fc116101c75780636352211e1161018b5780636352211e146104ea57806367ee5f091461050a57806370a082311461051f578063715018a61461053f578063736a83a11461055457600080fd5b8063335477fc1461045557806342842e0e1461046a5780634f6ccce71461048a5780635cc33f74146104aa57806360a6f45a146104ca57600080fd5b806316334de71161020e57806316334de71461039757806318160ddd146103b757806323b872dd146103d65780632a55205a146103f65780632f745c591461043557600080fd5b806301ffc9a7146102b45780630323fd6e146102e957806306fdde0314610335578063081812fc14610357578063095ea7b31461037757600080fd5b366102af5761026261025d3460026107e2565b61082d565b600d546001600160a01b03166108fc61027c3460026107e2565b6040518115909202916000818181858888f193505050501580156102a4573d6000803e3d6000fd5b506102ad61096c565b005b600080fd5b3480156102c057600080fd5b506102d46102cf366004612daa565b610ae2565b60405190151581526020015b60405180910390f35b3480156102f557600080fd5b5061031d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102e0565b34801561034157600080fd5b5061034a610aed565b6040516102e09190612e1f565b34801561036357600080fd5b5061031d610372366004612e32565b610b7f565b34801561038357600080fd5b506102ad610392366004612e67565b610ba6565b3480156103a357600080fd5b506102ad6103b2366004612ed6565b610bb0565b3480156103c357600080fd5b506008545b6040519081526020016102e0565b3480156103e257600080fd5b506102ad6103f1366004612f42565b610cc0565b34801561040257600080fd5b50610416610411366004612f7e565b610cf1565b604080516001600160a01b0390931683526020830191909152016102e0565b34801561044157600080fd5b506103c8610450366004612e67565b610d18565b34801561046157600080fd5b506103c860c881565b34801561047657600080fd5b506102ad610485366004612f42565b610dae565b34801561049657600080fd5b506103c86104a5366004612e32565b610dc9565b3480156104b657600080fd5b506103c86104c5366004612fa0565b610e5c565b3480156104d657600080fd5b506102ad6104e5366004612fa0565b610edb565b3480156104f657600080fd5b5061031d610505366004612e32565b61101c565b34801561051657600080fd5b506103c861107c565b34801561052b57600080fd5b506103c861053a366004612fa0565b6110fe565b34801561054b57600080fd5b506102ad611184565b34801561056057600080fd5b506103c8611198565b34801561057557600080fd5b506103c860175481565b34801561058b57600080fd5b50600d546001600160a01b031661031d565b3480156105a957600080fd5b506103c86105b8366004612fa0565b6111dd565b3480156105c957600080fd5b5061031d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105fd57600080fd5b5061034a611210565b34801561061257600080fd5b506102ad610621366004612fc9565b61121f565b34801561063257600080fd5b506103c860185481565b34801561064857600080fd5b506102ad610657366004613047565b611229565b34801561066857600080fd5b5061034a610677366004612e32565b611261565b34801561068857600080fd5b506103c8606481565b6102ad61069f366004613107565b61126c565b3480156106b057600080fd5b506103c8601481565b3480156106c557600080fd5b506102d46106d436600461312c565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561070e57600080fd5b506102ad61071d366004612fa0565b61171a565b34801561072e57600080fd5b506102ad61177d565b34801561074357600080fd5b506102ad610752366004612fa0565b6117d6565b34801561076357600080fd5b506103c861271081565b34801561077957600080fd5b506102ad61184f565b34801561078e57600080fd5b506102ad61079d366004612fc9565b61186b565b3480156107ae57600080fd5b506102ad6107bd366004612f7e565b61193b565b3480156107ce57600080fd5b5060105461031d906001600160a01b031681565b600061082483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611957565b90505b92915050565b6040805160028082526060820183526000926020830190803683375050600e5482519293506001600160a01b03169183915060009061086e5761086e61315f565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000000000000000000000000000000000000000000000816001815181106108c2576108c261315f565b6001600160a01b03928316602091820292909201015260105416637ff36ab583600084306108f24261012c61198e565b6040518663ffffffff1660e01b81526004016109119493929190613175565b6000604051808303818588803b15801561092a57600080fd5b505af115801561093e573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261096791908101906131df565b505050565b6019546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156109b057600080fd5b505afa1580156109c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e89190613285565b60195460115460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905292935060009291169063a9059cbb90604401602060405180830381600087803b158015610a3e57600080fd5b505af1158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a76919061329e565b90508015610ade5760115460405163b6b55f2560e01b8152600481018490526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015610ac557600080fd5b505af1158015610ad9573d6000803e3d6000fd5b505050505b5050565b6000610827826119ed565b606060008054610afc906132bb565b80601f0160208091040260200160405190810160405280929190818152602001828054610b28906132bb565b8015610b755780601f10610b4a57610100808354040283529160200191610b75565b820191906000526020600020905b815481529060010190602001808311610b5857829003601f168201915b5050505050905090565b6000610b8a82611a12565b506000908152600460205260409020546001600160a01b031690565b610ade8282611a71565b610bb8611b82565b60135460ff16158015610bcb5750600854155b610c105760405162461bcd60e51b81526020600482015260116024820152704d696e74696e672069732061637469766560781b60448201526064015b60405180910390fd5b60005b83811015610cb957610c4a858583818110610c3057610c3061315f565b9050602002016020810190610c459190612fa0565b611bdc565b828282818110610c5c57610c5c61315f565b9050602002016020810190610c7191906132f6565b15610ca757610ca7858583818110610c8b57610c8b61315f565b9050602002016020810190610ca09190612fa0565b6000611c3d565b80610cb181613329565b915050610c13565b5050505050565b610cca3382611cdf565b610ce65760405162461bcd60e51b8152600401610c0790613344565b610967838383611d5e565b60008030610d0c612710610d068660c8611ecf565b906107e2565b915091505b9250929050565b6000610d23836110fe565b8210610d855760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c07565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b61096783838360405180602001604052806000815250611229565b6000610dd460085490565b8210610e375760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c07565b60088281548110610e4a57610e4a61315f565b90600052602060002001549050919050565b601154604051631730cfdd60e21b81526001600160a01b0383811660048301526000921690635cc33f74906024015b60206040518083038186803b158015610ea357600080fd5b505afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108279190613285565b610ee3611b82565b6040516001600160a01b038216904780156108fc02916000818181858888f19350505050158015610f18573d6000803e3d6000fd5b506019546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90839083906370a082319060240160206040518083038186803b158015610f6657600080fd5b505afa158015610f7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9e9190613285565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610fe457600080fd5b505af1158015610ff8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ade919061329e565b6000818152600260205260408120546001600160a01b0316806108275760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c07565b6011546040805163997664d760e01b815290516000926001600160a01b03169163997664d7916004808301926020929190829003018186803b1580156110c157600080fd5b505afa1580156110d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f99190613285565b905090565b60006001600160a01b0382166111685760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c07565b506001600160a01b031660009081526003602052604090205490565b61118c611b82565b6111966000611f4e565b565b6011546040805163d54ad2a160e01b815290516000926001600160a01b03169163d54ad2a1916004808301926020929190829003018186803b1580156110c157600080fd5b601154604051638ecc37fb60e01b81526001600160a01b0383811660048301526000921690638ecc37fb90602401610e8b565b606060018054610afc906132bb565b610ade8282611fa0565b6112333383611cdf565b61124f5760405162461bcd60e51b8152600401610c0790613344565b61125b84848484611fab565b50505050565b606061082782611fde565b60135460ff166112b65760405162461bcd60e51b81526020600482015260156024820152744d696e74696e67206973206e6f742061637469766560581b6044820152606401610c07565b60148211156113135760405162461bcd60e51b815260206004820152602360248201527f4d617820746f6b656e7320706572207472616e73616374696f6e20657863656560448201526219195960ea1b6064820152608401610c07565b606461132883611322336110fe565b9061198e565b11156113765760405162461bcd60e51b815260206004820152601e60248201527f4d617820746f6b656e73207065722077616c6c657420657863656564656400006044820152606401610c07565b6127106113868361132260085490565b11156113fa5760405162461bcd60e51b815260206004820152603d60248201527f4e6f7420656e6f75676820746f6b656e73206c6566742e20446563726561736560448201527f20746865206e756d626572206f6620746f6b656e7320746f206d696e740000006064820152608401610c07565b8015611650576018546000906114109084611ecf565b6019546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a082319060240160206040518083038186803b15801561145857600080fd5b505afa15801561146c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114909190613285565b10156114d55760405162461bcd60e51b8152602060048201526014602482015273139bdd08195b9bdd59da0814115411481cd95b9d60621b6044820152606401610c07565b6114df33846120da565b6019546001600160a01b03166323b872dd3330611504612710610d0687611f40611ecf565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561155357600080fd5b505af1158015611567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158b919061329e565b506019546001600160a01b03166323b872dd336115b0600d546001600160a01b031690565b6115c2612710610d06876107d0611ecf565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561161157600080fd5b505af1158015611625573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611649919061329e565b505061170f565b60175461165d9083611ecf565b3410156116a25760405162461bcd60e51b8152602060048201526013602482015272139bdd08195b9bdd59da08115512081cd95b9d606a1b6044820152606401610c07565b6116ac33836120da565b60006116c0612710610d0634611b58611ecf565b90506116cb8161082d565b600d546001600160a01b03166108fc6116e43484612100565b6040518115909202916000818181858888f1935050505015801561170c573d6000803e3d6000fd5b50505b610ade336001611c3d565b611722611b82565b601154604051630afbf02f60e11b81526001600160a01b038381166004830152909116906315f7e05e90602401600060405180830381600087803b15801561176957600080fd5b505af1158015610cb9573d6000803e3d6000fd5b601154604051630afbf02f60e11b81523360048201526001600160a01b03909116906315f7e05e90602401600060405180830381600087803b1580156117c257600080fd5b505af115801561125b573d6000803e3d6000fd5b6117de611b82565b6001600160a01b0381166118435760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c07565b61184c81611f4e565b50565b611857611b82565b6013805460ff19811660ff90911615179055565b611873611b82565b6001600160a01b03821630141561188957600080fd5b6001600160a01b0382166000908152600f60205260409020805460ff191682158015919091179091556118ef57601154604051630a5b654b60e11b81526001600160a01b03848116600483015260006024830152909116906314b6ca9690604401610aab565b6011546001600160a01b03166314b6ca968361190a816110fe565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401610aab565b611943611b82565b601791909155601855565b80546001019055565b600081836119785760405162461bcd60e51b8152600401610c079190612e1f565b5060006119858486613391565b95945050505050565b60008061199b83856133b3565b9050838110156108245760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610c07565b60006001600160e01b0319821663152a902d60e11b1480610827575061082782612142565b6000818152600260205260409020546001600160a01b031661184c5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c07565b6000611a7c8261101c565b9050806001600160a01b0316836001600160a01b03161415611aea5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c07565b336001600160a01b0382161480611b065750611b0681336106d4565b611b785760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c07565b6109678383612167565b600d546001600160a01b031633146111965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c07565b6000611be760125490565b9050611bf7601280546001019055565b611c0182826121d5565b60006015611c0e836121ef565b6016604051602001611c2293929190613465565b6040516020818303038152906040529050610967828261228c565b6001600160a01b0382166000908152600f602052604090205460ff16611cd1576011546001600160a01b03166314b6ca9683611c7881612326565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611cbe57600080fd5b505af1925050508015611ccf575060015b505b8015610ade57610ade61096c565b600080611ceb8361101c565b9050806001600160a01b0316846001600160a01b03161480611d3257506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611d565750836001600160a01b0316611d4b84610b7f565b6001600160a01b0316145b949350505050565b826001600160a01b0316611d718261101c565b6001600160a01b031614611d975760405162461bcd60e51b8152600401610c0790613498565b6001600160a01b038216611df95760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c07565b611e068383836001612385565b826001600160a01b0316611e198261101c565b6001600160a01b031614611e3f5760405162461bcd60e51b8152600401610c0790613498565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600082611ede57506000610827565b6000611eea83856134dd565b905082611ef78583613391565b146108245760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610c07565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610ade3383836123cc565b611fb6848484611d5e565b611fc28484848461249b565b61125b5760405162461bcd60e51b8152600401610c07906134fc565b6060611fe982611a12565b6000828152600a602052604081208054612002906132bb565b80601f016020809104026020016040519081016040528092919081815260200182805461202e906132bb565b801561207b5780601f106120505761010080835404028352916020019161207b565b820191906000526020600020905b81548152906001019060200180831161205e57829003601f168201915b50505050509050600061208c6125a8565b905080516000141561209f575092915050565b8151156120d15780826040516020016120b992919061354e565b60405160208183030381529060405292505050919050565b611d56846125b7565b60005b81811015610967576120ee83611bdc565b806120f881613329565b9150506120dd565b600061082483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061261e565b60006001600160e01b0319821663780e9d6360e01b148061082757506108278261264f565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061219c8261101c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b610ade82826040518060200160405280600081525061269f565b606060006121fc836126d2565b600101905060008167ffffffffffffffff81111561221c5761221c613000565b6040519080825280601f01601f191660200182016040528015612246576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461227f57612284565b612250565b509392505050565b6000828152600260205260409020546001600160a01b03166123075760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610c07565b6000828152600a60209081526040909120825161096792840190612cfb565b60008080612333846110fe565b905060005b8181101561237c57600061234c8683610d18565b90506000612359826127aa565b9050612365858261198e565b94505050808061237490613329565b915050612338565b50909392505050565b612391848484846128a5565b6001600160a01b038416158015906123b157506001600160a01b03831615155b1561125b576123c1846001611c3d565b61125b836001611c3d565b816001600160a01b0316836001600160a01b0316141561242e5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c07565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006001600160a01b0384163b1561259d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906124df90339089908890889060040161357d565b602060405180830381600087803b1580156124f957600080fd5b505af1925050508015612529575060408051601f3d908101601f19168201909252612526918101906135ba565b60015b612583573d808015612557576040519150601f19603f3d011682016040523d82523d6000602084013e61255c565b606091505b50805161257b5760405162461bcd60e51b8152600401610c07906134fc565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d56565b506001949350505050565b606060148054610afc906132bb565b60606125c282611a12565b60006125cc6125a8565b905060008151116125ec5760405180602001604052806000815250612617565b806125f6846121ef565b60405160200161260792919061354e565b6040516020818303038152906040525b9392505050565b600081848411156126425760405162461bcd60e51b8152600401610c079190612e1f565b50600061198584866135d7565b60006001600160e01b031982166380ac58cd60e01b148061268057506001600160e01b03198216635b5e139f60e01b145b8061082757506301ffc9a760e01b6001600160e01b0319831614610827565b6126a983836129d2565b6126b6600084848461249b565b6109675760405162461bcd60e51b8152600401610c07906134fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106127115772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061273d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061275b57662386f26fc10000830492506010015b6305f5e1008310612773576305f5e100830492506008015b612710831061278757612710830492506004015b60648310612799576064830492506002015b600a83106108275760010192915050565b6000600282158015906127be57506103e983105b156127cb5750600a610827565b6103e8831180156127dd57506107d183105b156127ea57506009610827565b6107d0831180156127fc5750610bb983105b1561280957506008610827565b610bb88311801561281b5750610fa183105b1561282857506007610827565b610fa08311801561283a575061138983105b1561284757506006610827565b61138883118015612859575061177183105b1561286657506005610827565b611770831180156128785750611b5983105b1561288557506004610827565b611b58831180156128975750611f4183105b156108275750600392915050565b60018111156129145760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610c07565b816001600160a01b0385166129705761296b81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612993565b836001600160a01b0316856001600160a01b031614612993576129938582612b6b565b6001600160a01b0384166129af576129aa81612c08565b610cb9565b846001600160a01b0316846001600160a01b031614610cb957610cb98482612cb7565b6001600160a01b038216612a285760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c07565b6000818152600260205260409020546001600160a01b031615612a8d5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c07565b612a9b600083836001612385565b6000818152600260205260409020546001600160a01b031615612b005760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c07565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001612b78846110fe565b612b8291906135d7565b600083815260076020526040902054909150808214612bd5576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612c1a906001906135d7565b60008381526009602052604081205460088054939450909284908110612c4257612c4261315f565b906000526020600020015490508060088381548110612c6357612c6361315f565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612c9b57612c9b6135ee565b6001900381819060005260206000200160009055905550505050565b6000612cc2836110fe565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b828054612d07906132bb565b90600052602060002090601f016020900481019282612d295760008555612d6f565b82601f10612d4257805160ff1916838001178555612d6f565b82800160010185558215612d6f579182015b82811115612d6f578251825591602001919060010190612d54565b50612d7b929150612d7f565b5090565b5b80821115612d7b5760008155600101612d80565b6001600160e01b03198116811461184c57600080fd5b600060208284031215612dbc57600080fd5b813561082481612d94565b60005b83811015612de2578181015183820152602001612dca565b8381111561125b5750506000910152565b60008151808452612e0b816020860160208601612dc7565b601f01601f19169290920160200192915050565b6020815260006108246020830184612df3565b600060208284031215612e4457600080fd5b5035919050565b80356001600160a01b0381168114612e6257600080fd5b919050565b60008060408385031215612e7a57600080fd5b612e8383612e4b565b946020939093013593505050565b60008083601f840112612ea357600080fd5b50813567ffffffffffffffff811115612ebb57600080fd5b6020830191508360208260051b8501011115610d1157600080fd5b60008060008060408587031215612eec57600080fd5b843567ffffffffffffffff80821115612f0457600080fd5b612f1088838901612e91565b90965094506020870135915080821115612f2957600080fd5b50612f3687828801612e91565b95989497509550505050565b600080600060608486031215612f5757600080fd5b612f6084612e4b565b9250612f6e60208501612e4b565b9150604084013590509250925092565b60008060408385031215612f9157600080fd5b50508035926020909101359150565b600060208284031215612fb257600080fd5b61082482612e4b565b801515811461184c57600080fd5b60008060408385031215612fdc57600080fd5b612fe583612e4b565b91506020830135612ff581612fbb565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561303f5761303f613000565b604052919050565b6000806000806080858703121561305d57600080fd5b61306685612e4b565b93506020613075818701612e4b565b935060408601359250606086013567ffffffffffffffff8082111561309957600080fd5b818801915088601f8301126130ad57600080fd5b8135818111156130bf576130bf613000565b6130d1601f8201601f19168501613016565b915080825289848285010111156130e757600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000806040838503121561311a57600080fd5b823591506020830135612ff581612fbb565b6000806040838503121561313f57600080fd5b61314883612e4b565b915061315660208401612e4b565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b600060808201868352602060808185015281875180845260a086019150828901935060005b818110156131bf5784516001600160a01b03168352938301939183019160010161319a565b50506001600160a01b039690961660408501525050506060015292915050565b600060208083850312156131f257600080fd5b825167ffffffffffffffff8082111561320a57600080fd5b818501915085601f83011261321e57600080fd5b81518181111561323057613230613000565b8060051b9150613241848301613016565b818152918301840191848101908884111561325b57600080fd5b938501935b8385101561327957845182529385019390850190613260565b98975050505050505050565b60006020828403121561329757600080fd5b5051919050565b6000602082840312156132b057600080fd5b815161082481612fbb565b600181811c908216806132cf57607f821691505b602082108114156132f057634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561330857600080fd5b813561082481612fbb565b634e487b7160e01b600052601160045260246000fd5b600060001982141561333d5761333d613313565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6000826133ae57634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156133c6576133c6613313565b500190565b8054600090600181811c90808316806133e557607f831692505b602080841082141561340757634e487b7160e01b600052602260045260246000fd5b81801561341b576001811461342c57613459565b60ff19861689528489019650613459565b60008881526020902060005b868110156134515781548b820152908501908301613438565b505084890196505b50505050505092915050565b600061347182866133cb565b8451613481818360208901612dc7565b61348d818301866133cb565b979650505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60008160001904831182151516156134f7576134f7613313565b500290565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351613560818460208801612dc7565b835190830190613574818360208801612dc7565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906135b090830184612df3565b9695505050505050565b6000602082840312156135cc57600080fd5b815161082481612d94565b6000828210156135e9576135e9613313565b500390565b634e487b7160e01b600052603160045260246000fdfea26469706673582212200a9933e4cfb0939a917e059b5428fd5464d9ba03ae52920bb3d2e9a2bff4b13c64736f6c6343000809003360a0604052736982508145454ce325ddbe47a25d4ec3d23119336080526ec097ce7bc90715b34b9f100000000060095534801561003b57600080fd5b50604051610da8380380610da883398101604081905261005a9161008d565b60008054336001600160a01b031991821617909155600180549091166001600160a01b03929092169190911790556100bd565b60006020828403121561009f57600080fd5b81516001600160a01b03811681146100b657600080fd5b9392505050565b608051610cc96100df600039600081816102bb015261073d0152610cc96000f3fe6080604052600436106100e15760003560e01c8063b2bdfa7b1161007f578063d54ad2a111610059578063d54ad2a11461027d578063e2d2e21914610293578063e4fbaecb146102a9578063ecd0c0c3146102dd57600080fd5b8063b2bdfa7b146101ce578063b6b55f2514610206578063ce7c2ac21461022657600080fd5b80633a98ef39116100bb5780633a98ef391461014f5780635cc33f74146101785780638ecc37fb14610198578063997664d7146101b857600080fd5b80631014edf5146100ed57806314b6ca961461010f57806315f7e05e1461012f57600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010d610108366004610ae0565b6102fd565b005b34801561011b57600080fd5b5061010d61012a366004610b0c565b61035d565b34801561013b57600080fd5b5061010d61014a366004610b36565b6104d5565b34801561015b57600080fd5b5061016560055481565b6040519081526020015b60405180910390f35b34801561018457600080fd5b50610165610193366004610b36565b6104f8565b3480156101a457600080fd5b506101656101b3366004610b36565b61058b565b3480156101c457600080fd5b5061016560065481565b3480156101da57600080fd5b506001546101ee906001600160a01b031681565b6040516001600160a01b03909116815260200161016f565b34801561021257600080fd5b5061010d610221366004610b51565b610614565b34801561023257600080fd5b50610262610241366004610b36565b60046020526000908152604090208054600182015460029092015490919083565b6040805193845260208401929092529082015260600161016f565b34801561028957600080fd5b5061016560075481565b34801561029f57600080fd5b5061016560085481565b3480156102b557600080fd5b506101ee7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e957600080fd5b506000546101ee906001600160a01b031681565b6001546001600160a01b0316331461031457600080fd5b476001600160a01b0382166108fc8461032d578261032f565b845b6040518115909202916000818181858888f19350505050158015610357573d6000803e3d6000fd5b50505050565b6000546001600160a01b0316331461037457600080fd5b6001600160a01b0382166000908152600460205260409020541561039b5761039b8261066e565b6000811180156103c157506001600160a01b038216600090815260046020526040902054155b1561042757600280546001600160a01b0384166000818152600360205260408120839055600183018455929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b031916909117905561045a565b8015801561044c57506001600160a01b03821660009081526004602052604090205415155b1561045a5761045a826107bf565b6001600160a01b03821660009081526004602052604090205460055461048b918391610485916108d4565b9061091f565b6005556001600160a01b03821660009081526004602052604090208190556104b28161097e565b6001600160a01b0390921660009081526004602052604090206001019190915550565b6000546001600160a01b031633146104ec57600080fd5b6104f58161066e565b50565b6001600160a01b03811660009081526004602052604081205461056c5760405162461bcd60e51b815260206004820152602160248201527f596f75277265206e6f742061205052494e544552207368617265686f6c6465726044820152602160f81b60648201526084015b60405180910390fd5b506001600160a01b031660009081526004602052604090206002015490565b6001600160a01b0381166000908152600460205260408120546105b057506000919050565b6001600160a01b0382166000908152600460205260408120546105d29061097e565b6001600160a01b038416600090815260046020526040902060010154909150808211610602575060009392505050565b61060c82826108d4565b949350505050565b6000546001600160a01b0316331461062b57600080fd5b80156104f55760065461063e908261091f565b6006556005546009546106689161065f91610659908561099b565b90610a1a565b6008549061091f565b60085550565b6001600160a01b03811660009081526004602052604090205461068e5750565b60006106998261058b565b905080156107bb576007546106ae908261091f565b6007556001600160a01b0382166000908152600460205260409020600201546106d7908261091f565b6001600160a01b03831660009081526004602052604090206002810191909155546107019061097e565b6001600160a01b03838116600081815260046020819052604091829020600101949094555163a9059cbb60e01b815292830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b15801561078157600080fd5b505af1158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190610b6a565b505b5050565b600280546107cf90600190610ba2565b815481106107df576107df610bb9565b60009182526020808320909101546001600160a01b038481168452600390925260409092205460028054929093169291811061081d5761081d610bb9565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591831681526003918290526040812054600280549193929161086990600190610ba2565b8154811061087957610879610bb9565b60009182526020808320909101546001600160a01b0316835282019290925260400190205560028054806108af576108af610bcf565b600082815260209020810160001990810180546001600160a01b031916905501905550565b600061091683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610a5c565b90505b92915050565b60008061092c8385610be5565b9050838110156109165760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610563565b60006109196009546106596008548561099b90919063ffffffff16565b6000826109aa57506000610919565b60006109b68385610bfd565b9050826109c38583610c1c565b146109165760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610563565b600061091683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610a96565b60008184841115610a805760405162461bcd60e51b81526004016105639190610c3e565b506000610a8d8486610ba2565b95945050505050565b60008183610ab75760405162461bcd60e51b81526004016105639190610c3e565b506000610a8d8486610c1c565b80356001600160a01b0381168114610adb57600080fd5b919050565b60008060408385031215610af357600080fd5b82359150610b0360208401610ac4565b90509250929050565b60008060408385031215610b1f57600080fd5b610b2883610ac4565b946020939093013593505050565b600060208284031215610b4857600080fd5b61091682610ac4565b600060208284031215610b6357600080fd5b5035919050565b600060208284031215610b7c57600080fd5b8151801515811461091657600080fd5b634e487b7160e01b600052601160045260246000fd5b600082821015610bb457610bb4610b8c565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60008219821115610bf857610bf8610b8c565b500190565b6000816000190483118215151615610c1757610c17610b8c565b500290565b600082610c3957634e487b7160e01b600052601260045260246000fd5b500490565b600060208083528351808285015260005b81811015610c6b57858101830151858201604001528201610c4f565b81811115610c7d576000604083870101525b50601f01601f191692909201604001939250505056fea2646970667358221220c818e5374217cd773b73bece1cad159ee66df6de3eabfe3f4c6369317132d5c264736f6c63430008090033697066733a2f2f6261667962656963746863696b696a366c676633327965637978726661796a3232326369336c3562616537686e657968616b7a3634736c726937652f

Deployed Bytecode

0x60806040526004361061024a5760003560e01c80638832bc2911610139578063d81049ef116100b6578063f2fde38b1161007a578063f2fde38b14610737578063f47c84c514610757578063f655ff221461076d578063f708a64f14610782578063f7d97577146107a2578063f887ea40146107c257600080fd5b8063d81049ef14610691578063e0c23b94146106a4578063e985e9c5146106b9578063edf3525314610702578063f0fc6bca1461072257600080fd5b8063a22cb465116100fd578063a22cb46514610606578063a85e1dea14610626578063b88d4fde1461063c578063c87b56dd1461065c578063d1bdb1d11461067c57600080fd5b80638832bc29146105695780638da5cb5b1461057f5780638ecc37fb1461059d578063932da039146105bd57806395d89b41146105f157600080fd5b8063335477fc116101c75780636352211e1161018b5780636352211e146104ea57806367ee5f091461050a57806370a082311461051f578063715018a61461053f578063736a83a11461055457600080fd5b8063335477fc1461045557806342842e0e1461046a5780634f6ccce71461048a5780635cc33f74146104aa57806360a6f45a146104ca57600080fd5b806316334de71161020e57806316334de71461039757806318160ddd146103b757806323b872dd146103d65780632a55205a146103f65780632f745c591461043557600080fd5b806301ffc9a7146102b45780630323fd6e146102e957806306fdde0314610335578063081812fc14610357578063095ea7b31461037757600080fd5b366102af5761026261025d3460026107e2565b61082d565b600d546001600160a01b03166108fc61027c3460026107e2565b6040518115909202916000818181858888f193505050501580156102a4573d6000803e3d6000fd5b506102ad61096c565b005b600080fd5b3480156102c057600080fd5b506102d46102cf366004612daa565b610ae2565b60405190151581526020015b60405180910390f35b3480156102f557600080fd5b5061031d7f0000000000000000000000006982508145454ce325ddbe47a25d4ec3d231193381565b6040516001600160a01b0390911681526020016102e0565b34801561034157600080fd5b5061034a610aed565b6040516102e09190612e1f565b34801561036357600080fd5b5061031d610372366004612e32565b610b7f565b34801561038357600080fd5b506102ad610392366004612e67565b610ba6565b3480156103a357600080fd5b506102ad6103b2366004612ed6565b610bb0565b3480156103c357600080fd5b506008545b6040519081526020016102e0565b3480156103e257600080fd5b506102ad6103f1366004612f42565b610cc0565b34801561040257600080fd5b50610416610411366004612f7e565b610cf1565b604080516001600160a01b0390931683526020830191909152016102e0565b34801561044157600080fd5b506103c8610450366004612e67565b610d18565b34801561046157600080fd5b506103c860c881565b34801561047657600080fd5b506102ad610485366004612f42565b610dae565b34801561049657600080fd5b506103c86104a5366004612e32565b610dc9565b3480156104b657600080fd5b506103c86104c5366004612fa0565b610e5c565b3480156104d657600080fd5b506102ad6104e5366004612fa0565b610edb565b3480156104f657600080fd5b5061031d610505366004612e32565b61101c565b34801561051657600080fd5b506103c861107c565b34801561052b57600080fd5b506103c861053a366004612fa0565b6110fe565b34801561054b57600080fd5b506102ad611184565b34801561056057600080fd5b506103c8611198565b34801561057557600080fd5b506103c860175481565b34801561058b57600080fd5b50600d546001600160a01b031661031d565b3480156105a957600080fd5b506103c86105b8366004612fa0565b6111dd565b3480156105c957600080fd5b5061031d7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b3480156105fd57600080fd5b5061034a611210565b34801561061257600080fd5b506102ad610621366004612fc9565b61121f565b34801561063257600080fd5b506103c860185481565b34801561064857600080fd5b506102ad610657366004613047565b611229565b34801561066857600080fd5b5061034a610677366004612e32565b611261565b34801561068857600080fd5b506103c8606481565b6102ad61069f366004613107565b61126c565b3480156106b057600080fd5b506103c8601481565b3480156106c557600080fd5b506102d46106d436600461312c565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561070e57600080fd5b506102ad61071d366004612fa0565b61171a565b34801561072e57600080fd5b506102ad61177d565b34801561074357600080fd5b506102ad610752366004612fa0565b6117d6565b34801561076357600080fd5b506103c861271081565b34801561077957600080fd5b506102ad61184f565b34801561078e57600080fd5b506102ad61079d366004612fc9565b61186b565b3480156107ae57600080fd5b506102ad6107bd366004612f7e565b61193b565b3480156107ce57600080fd5b5060105461031d906001600160a01b031681565b600061082483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611957565b90505b92915050565b6040805160028082526060820183526000926020830190803683375050600e5482519293506001600160a01b03169183915060009061086e5761086e61315f565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000006982508145454ce325ddbe47a25d4ec3d2311933816001815181106108c2576108c261315f565b6001600160a01b03928316602091820292909201015260105416637ff36ab583600084306108f24261012c61198e565b6040518663ffffffff1660e01b81526004016109119493929190613175565b6000604051808303818588803b15801561092a57600080fd5b505af115801561093e573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261096791908101906131df565b505050565b6019546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156109b057600080fd5b505afa1580156109c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e89190613285565b60195460115460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905292935060009291169063a9059cbb90604401602060405180830381600087803b158015610a3e57600080fd5b505af1158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a76919061329e565b90508015610ade5760115460405163b6b55f2560e01b8152600481018490526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015610ac557600080fd5b505af1158015610ad9573d6000803e3d6000fd5b505050505b5050565b6000610827826119ed565b606060008054610afc906132bb565b80601f0160208091040260200160405190810160405280929190818152602001828054610b28906132bb565b8015610b755780601f10610b4a57610100808354040283529160200191610b75565b820191906000526020600020905b815481529060010190602001808311610b5857829003601f168201915b5050505050905090565b6000610b8a82611a12565b506000908152600460205260409020546001600160a01b031690565b610ade8282611a71565b610bb8611b82565b60135460ff16158015610bcb5750600854155b610c105760405162461bcd60e51b81526020600482015260116024820152704d696e74696e672069732061637469766560781b60448201526064015b60405180910390fd5b60005b83811015610cb957610c4a858583818110610c3057610c3061315f565b9050602002016020810190610c459190612fa0565b611bdc565b828282818110610c5c57610c5c61315f565b9050602002016020810190610c7191906132f6565b15610ca757610ca7858583818110610c8b57610c8b61315f565b9050602002016020810190610ca09190612fa0565b6000611c3d565b80610cb181613329565b915050610c13565b5050505050565b610cca3382611cdf565b610ce65760405162461bcd60e51b8152600401610c0790613344565b610967838383611d5e565b60008030610d0c612710610d068660c8611ecf565b906107e2565b915091505b9250929050565b6000610d23836110fe565b8210610d855760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c07565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b61096783838360405180602001604052806000815250611229565b6000610dd460085490565b8210610e375760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c07565b60088281548110610e4a57610e4a61315f565b90600052602060002001549050919050565b601154604051631730cfdd60e21b81526001600160a01b0383811660048301526000921690635cc33f74906024015b60206040518083038186803b158015610ea357600080fd5b505afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108279190613285565b610ee3611b82565b6040516001600160a01b038216904780156108fc02916000818181858888f19350505050158015610f18573d6000803e3d6000fd5b506019546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90839083906370a082319060240160206040518083038186803b158015610f6657600080fd5b505afa158015610f7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9e9190613285565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610fe457600080fd5b505af1158015610ff8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ade919061329e565b6000818152600260205260408120546001600160a01b0316806108275760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c07565b6011546040805163997664d760e01b815290516000926001600160a01b03169163997664d7916004808301926020929190829003018186803b1580156110c157600080fd5b505afa1580156110d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f99190613285565b905090565b60006001600160a01b0382166111685760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c07565b506001600160a01b031660009081526003602052604090205490565b61118c611b82565b6111966000611f4e565b565b6011546040805163d54ad2a160e01b815290516000926001600160a01b03169163d54ad2a1916004808301926020929190829003018186803b1580156110c157600080fd5b601154604051638ecc37fb60e01b81526001600160a01b0383811660048301526000921690638ecc37fb90602401610e8b565b606060018054610afc906132bb565b610ade8282611fa0565b6112333383611cdf565b61124f5760405162461bcd60e51b8152600401610c0790613344565b61125b84848484611fab565b50505050565b606061082782611fde565b60135460ff166112b65760405162461bcd60e51b81526020600482015260156024820152744d696e74696e67206973206e6f742061637469766560581b6044820152606401610c07565b60148211156113135760405162461bcd60e51b815260206004820152602360248201527f4d617820746f6b656e7320706572207472616e73616374696f6e20657863656560448201526219195960ea1b6064820152608401610c07565b606461132883611322336110fe565b9061198e565b11156113765760405162461bcd60e51b815260206004820152601e60248201527f4d617820746f6b656e73207065722077616c6c657420657863656564656400006044820152606401610c07565b6127106113868361132260085490565b11156113fa5760405162461bcd60e51b815260206004820152603d60248201527f4e6f7420656e6f75676820746f6b656e73206c6566742e20446563726561736560448201527f20746865206e756d626572206f6620746f6b656e7320746f206d696e740000006064820152608401610c07565b8015611650576018546000906114109084611ecf565b6019546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a082319060240160206040518083038186803b15801561145857600080fd5b505afa15801561146c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114909190613285565b10156114d55760405162461bcd60e51b8152602060048201526014602482015273139bdd08195b9bdd59da0814115411481cd95b9d60621b6044820152606401610c07565b6114df33846120da565b6019546001600160a01b03166323b872dd3330611504612710610d0687611f40611ecf565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561155357600080fd5b505af1158015611567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158b919061329e565b506019546001600160a01b03166323b872dd336115b0600d546001600160a01b031690565b6115c2612710610d06876107d0611ecf565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561161157600080fd5b505af1158015611625573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611649919061329e565b505061170f565b60175461165d9083611ecf565b3410156116a25760405162461bcd60e51b8152602060048201526013602482015272139bdd08195b9bdd59da08115512081cd95b9d606a1b6044820152606401610c07565b6116ac33836120da565b60006116c0612710610d0634611b58611ecf565b90506116cb8161082d565b600d546001600160a01b03166108fc6116e43484612100565b6040518115909202916000818181858888f1935050505015801561170c573d6000803e3d6000fd5b50505b610ade336001611c3d565b611722611b82565b601154604051630afbf02f60e11b81526001600160a01b038381166004830152909116906315f7e05e90602401600060405180830381600087803b15801561176957600080fd5b505af1158015610cb9573d6000803e3d6000fd5b601154604051630afbf02f60e11b81523360048201526001600160a01b03909116906315f7e05e90602401600060405180830381600087803b1580156117c257600080fd5b505af115801561125b573d6000803e3d6000fd5b6117de611b82565b6001600160a01b0381166118435760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c07565b61184c81611f4e565b50565b611857611b82565b6013805460ff19811660ff90911615179055565b611873611b82565b6001600160a01b03821630141561188957600080fd5b6001600160a01b0382166000908152600f60205260409020805460ff191682158015919091179091556118ef57601154604051630a5b654b60e11b81526001600160a01b03848116600483015260006024830152909116906314b6ca9690604401610aab565b6011546001600160a01b03166314b6ca968361190a816110fe565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401610aab565b611943611b82565b601791909155601855565b80546001019055565b600081836119785760405162461bcd60e51b8152600401610c079190612e1f565b5060006119858486613391565b95945050505050565b60008061199b83856133b3565b9050838110156108245760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610c07565b60006001600160e01b0319821663152a902d60e11b1480610827575061082782612142565b6000818152600260205260409020546001600160a01b031661184c5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c07565b6000611a7c8261101c565b9050806001600160a01b0316836001600160a01b03161415611aea5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c07565b336001600160a01b0382161480611b065750611b0681336106d4565b611b785760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c07565b6109678383612167565b600d546001600160a01b031633146111965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c07565b6000611be760125490565b9050611bf7601280546001019055565b611c0182826121d5565b60006015611c0e836121ef565b6016604051602001611c2293929190613465565b6040516020818303038152906040529050610967828261228c565b6001600160a01b0382166000908152600f602052604090205460ff16611cd1576011546001600160a01b03166314b6ca9683611c7881612326565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611cbe57600080fd5b505af1925050508015611ccf575060015b505b8015610ade57610ade61096c565b600080611ceb8361101c565b9050806001600160a01b0316846001600160a01b03161480611d3257506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611d565750836001600160a01b0316611d4b84610b7f565b6001600160a01b0316145b949350505050565b826001600160a01b0316611d718261101c565b6001600160a01b031614611d975760405162461bcd60e51b8152600401610c0790613498565b6001600160a01b038216611df95760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c07565b611e068383836001612385565b826001600160a01b0316611e198261101c565b6001600160a01b031614611e3f5760405162461bcd60e51b8152600401610c0790613498565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600082611ede57506000610827565b6000611eea83856134dd565b905082611ef78583613391565b146108245760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610c07565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610ade3383836123cc565b611fb6848484611d5e565b611fc28484848461249b565b61125b5760405162461bcd60e51b8152600401610c07906134fc565b6060611fe982611a12565b6000828152600a602052604081208054612002906132bb565b80601f016020809104026020016040519081016040528092919081815260200182805461202e906132bb565b801561207b5780601f106120505761010080835404028352916020019161207b565b820191906000526020600020905b81548152906001019060200180831161205e57829003601f168201915b50505050509050600061208c6125a8565b905080516000141561209f575092915050565b8151156120d15780826040516020016120b992919061354e565b60405160208183030381529060405292505050919050565b611d56846125b7565b60005b81811015610967576120ee83611bdc565b806120f881613329565b9150506120dd565b600061082483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061261e565b60006001600160e01b0319821663780e9d6360e01b148061082757506108278261264f565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061219c8261101c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b610ade82826040518060200160405280600081525061269f565b606060006121fc836126d2565b600101905060008167ffffffffffffffff81111561221c5761221c613000565b6040519080825280601f01601f191660200182016040528015612246576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461227f57612284565b612250565b509392505050565b6000828152600260205260409020546001600160a01b03166123075760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610c07565b6000828152600a60209081526040909120825161096792840190612cfb565b60008080612333846110fe565b905060005b8181101561237c57600061234c8683610d18565b90506000612359826127aa565b9050612365858261198e565b94505050808061237490613329565b915050612338565b50909392505050565b612391848484846128a5565b6001600160a01b038416158015906123b157506001600160a01b03831615155b1561125b576123c1846001611c3d565b61125b836001611c3d565b816001600160a01b0316836001600160a01b0316141561242e5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c07565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006001600160a01b0384163b1561259d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906124df90339089908890889060040161357d565b602060405180830381600087803b1580156124f957600080fd5b505af1925050508015612529575060408051601f3d908101601f19168201909252612526918101906135ba565b60015b612583573d808015612557576040519150601f19603f3d011682016040523d82523d6000602084013e61255c565b606091505b50805161257b5760405162461bcd60e51b8152600401610c07906134fc565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d56565b506001949350505050565b606060148054610afc906132bb565b60606125c282611a12565b60006125cc6125a8565b905060008151116125ec5760405180602001604052806000815250612617565b806125f6846121ef565b60405160200161260792919061354e565b6040516020818303038152906040525b9392505050565b600081848411156126425760405162461bcd60e51b8152600401610c079190612e1f565b50600061198584866135d7565b60006001600160e01b031982166380ac58cd60e01b148061268057506001600160e01b03198216635b5e139f60e01b145b8061082757506301ffc9a760e01b6001600160e01b0319831614610827565b6126a983836129d2565b6126b6600084848461249b565b6109675760405162461bcd60e51b8152600401610c07906134fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106127115772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061273d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061275b57662386f26fc10000830492506010015b6305f5e1008310612773576305f5e100830492506008015b612710831061278757612710830492506004015b60648310612799576064830492506002015b600a83106108275760010192915050565b6000600282158015906127be57506103e983105b156127cb5750600a610827565b6103e8831180156127dd57506107d183105b156127ea57506009610827565b6107d0831180156127fc5750610bb983105b1561280957506008610827565b610bb88311801561281b5750610fa183105b1561282857506007610827565b610fa08311801561283a575061138983105b1561284757506006610827565b61138883118015612859575061177183105b1561286657506005610827565b611770831180156128785750611b5983105b1561288557506004610827565b611b58831180156128975750611f4183105b156108275750600392915050565b60018111156129145760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610c07565b816001600160a01b0385166129705761296b81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612993565b836001600160a01b0316856001600160a01b031614612993576129938582612b6b565b6001600160a01b0384166129af576129aa81612c08565b610cb9565b846001600160a01b0316846001600160a01b031614610cb957610cb98482612cb7565b6001600160a01b038216612a285760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c07565b6000818152600260205260409020546001600160a01b031615612a8d5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c07565b612a9b600083836001612385565b6000818152600260205260409020546001600160a01b031615612b005760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c07565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001612b78846110fe565b612b8291906135d7565b600083815260076020526040902054909150808214612bd5576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612c1a906001906135d7565b60008381526009602052604081205460088054939450909284908110612c4257612c4261315f565b906000526020600020015490508060088381548110612c6357612c6361315f565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612c9b57612c9b6135ee565b6001900381819060005260206000200160009055905550505050565b6000612cc2836110fe565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b828054612d07906132bb565b90600052602060002090601f016020900481019282612d295760008555612d6f565b82601f10612d4257805160ff1916838001178555612d6f565b82800160010185558215612d6f579182015b82811115612d6f578251825591602001919060010190612d54565b50612d7b929150612d7f565b5090565b5b80821115612d7b5760008155600101612d80565b6001600160e01b03198116811461184c57600080fd5b600060208284031215612dbc57600080fd5b813561082481612d94565b60005b83811015612de2578181015183820152602001612dca565b8381111561125b5750506000910152565b60008151808452612e0b816020860160208601612dc7565b601f01601f19169290920160200192915050565b6020815260006108246020830184612df3565b600060208284031215612e4457600080fd5b5035919050565b80356001600160a01b0381168114612e6257600080fd5b919050565b60008060408385031215612e7a57600080fd5b612e8383612e4b565b946020939093013593505050565b60008083601f840112612ea357600080fd5b50813567ffffffffffffffff811115612ebb57600080fd5b6020830191508360208260051b8501011115610d1157600080fd5b60008060008060408587031215612eec57600080fd5b843567ffffffffffffffff80821115612f0457600080fd5b612f1088838901612e91565b90965094506020870135915080821115612f2957600080fd5b50612f3687828801612e91565b95989497509550505050565b600080600060608486031215612f5757600080fd5b612f6084612e4b565b9250612f6e60208501612e4b565b9150604084013590509250925092565b60008060408385031215612f9157600080fd5b50508035926020909101359150565b600060208284031215612fb257600080fd5b61082482612e4b565b801515811461184c57600080fd5b60008060408385031215612fdc57600080fd5b612fe583612e4b565b91506020830135612ff581612fbb565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561303f5761303f613000565b604052919050565b6000806000806080858703121561305d57600080fd5b61306685612e4b565b93506020613075818701612e4b565b935060408601359250606086013567ffffffffffffffff8082111561309957600080fd5b818801915088601f8301126130ad57600080fd5b8135818111156130bf576130bf613000565b6130d1601f8201601f19168501613016565b915080825289848285010111156130e757600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000806040838503121561311a57600080fd5b823591506020830135612ff581612fbb565b6000806040838503121561313f57600080fd5b61314883612e4b565b915061315660208401612e4b565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b600060808201868352602060808185015281875180845260a086019150828901935060005b818110156131bf5784516001600160a01b03168352938301939183019160010161319a565b50506001600160a01b039690961660408501525050506060015292915050565b600060208083850312156131f257600080fd5b825167ffffffffffffffff8082111561320a57600080fd5b818501915085601f83011261321e57600080fd5b81518181111561323057613230613000565b8060051b9150613241848301613016565b818152918301840191848101908884111561325b57600080fd5b938501935b8385101561327957845182529385019390850190613260565b98975050505050505050565b60006020828403121561329757600080fd5b5051919050565b6000602082840312156132b057600080fd5b815161082481612fbb565b600181811c908216806132cf57607f821691505b602082108114156132f057634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561330857600080fd5b813561082481612fbb565b634e487b7160e01b600052601160045260246000fd5b600060001982141561333d5761333d613313565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6000826133ae57634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156133c6576133c6613313565b500190565b8054600090600181811c90808316806133e557607f831692505b602080841082141561340757634e487b7160e01b600052602260045260246000fd5b81801561341b576001811461342c57613459565b60ff19861689528489019650613459565b60008881526020902060005b868110156134515781548b820152908501908301613438565b505084890196505b50505050505092915050565b600061347182866133cb565b8451613481818360208901612dc7565b61348d818301866133cb565b979650505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60008160001904831182151516156134f7576134f7613313565b500290565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351613560818460208801612dc7565b835190830190613574818360208801612dc7565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906135b090830184612df3565b9695505050505050565b6000602082840312156135cc57600080fd5b815161082481612d94565b6000828210156135e9576135e9613313565b500390565b634e487b7160e01b600052603160045260246000fdfea26469706673582212200a9933e4cfb0939a917e059b5428fd5464d9ba03ae52920bb3d2e9a2bff4b13c64736f6c63430008090033

Deployed Bytecode Sourcemap

96937:11488:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105070:32;105085:16;:9;105099:1;105085:13;:16::i;:::-;105070:14;:32::i;:::-;35811:6;;-1:-1:-1;;;;;35811:6:0;105113:43;105139:16;:9;105153:1;105139:13;:16::i;:::-;105113:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105167:18;:16;:18::i;:::-;96937:11488;;;;;106078:221;;;;;;;;;;-1:-1:-1;106078:221:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;106078:221:0;;;;;;;;98541:106;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;98541:106:0;592:203:1;72534:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;74046:171::-;;;;;;;;;;-1:-1:-1;74046:171:0;;;;;:::i;:::-;;:::i;99529:115::-;;;;;;;;;;-1:-1:-1;99529:115:0;;;;;:::i;:::-;;:::i;99903:393::-;;;;;;;;;;-1:-1:-1;99903:393:0;;;;;:::i;:::-;;:::i;91428:113::-;;;;;;;;;;-1:-1:-1;91516:10:0;:17;91428:113;;;3466:25:1;;;3454:2;3439:18;91428:113:0;3320:177:1;74746:335:0;;;;;;;;;;-1:-1:-1;74746:335:0;;;;;:::i;:::-;;:::i;104686:243::-;;;;;;;;;;-1:-1:-1;104686:243:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4280:32:1;;;4262:51;;4344:2;4329:18;;4322:34;;;;4235:18;104686:243:0;4088:274:1;91096:256:0;;;;;;;;;;-1:-1:-1;91096:256:0;;;;;:::i;:::-;;:::i;98403:41::-;;;;;;;;;;;;98441:3;98403:41;;75152:185;;;;;;;;;;-1:-1:-1;75152:185:0;;;;;:::i;:::-;;:::i;91618:233::-;;;;;;;;;;-1:-1:-1;91618:233:0;;;;;:::i;:::-;;:::i;108017:188::-;;;;;;;;;;-1:-1:-1;108017:188:0;;;;;:::i;:::-;;:::i;108213:209::-;;;;;;;;;;-1:-1:-1;108213:209:0;;;;;:::i;:::-;;:::i;72244:223::-;;;;;;;;;;-1:-1:-1;72244:223:0;;;;;:::i;:::-;;:::i;107775:115::-;;;;;;;;;;;;;:::i;71975:207::-;;;;;;;;;;-1:-1:-1;71975:207:0;;;;;:::i;:::-;;:::i;36386:103::-;;;;;;;;;;;;;:::i;107898:111::-;;;;;;;;;;;;;:::i;97878:44::-;;;;;;;;;;;;;;;;35738:87;;;;;;;;;;-1:-1:-1;35811:6:0;;-1:-1:-1;;;;;35811:6:0;35738:87;;107579:188;;;;;;;;;;-1:-1:-1;107579:188:0;;;;;:::i;:::-;;:::i;97335:112::-;;;;;;;;;;;;;;;72703:104;;;;;;;;;;;;;:::i;99652:178::-;;;;;;;;;;-1:-1:-1;99652:178:0;;;;;:::i;:::-;;:::i;97967:54::-;;;;;;;;;;;;;;;;75408:322;;;;;;;;;;-1:-1:-1;75408:322:0;;;;;:::i;:::-;;:::i;105874:196::-;;;;;;;;;;-1:-1:-1;105874:196:0;;;;;:::i;:::-;;:::i;98274:51::-;;;;;;;;;;;;98322:3;98274:51;;102825:1853;;;;;;:::i;:::-;;:::i;98171:46::-;;;;;;;;;;;;98215:2;98171:46;;74515:164;;;;;;;;;;-1:-1:-1;74515:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;74636:25:0;;;74612:4;74636:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;74515:164;107458:113;;;;;;;;;;-1:-1:-1;107458:113:0;;;;;:::i;:::-;;:::i;107360:90::-;;;;;;;;;;;;;:::i;36644:201::-;;;;;;;;;;-1:-1:-1;36644:201:0;;;;;:::i;:::-;;:::i;98067:42::-;;;;;;;;;;;;98104:5;98067:42;;100346:100;;;;;;;;;;;;;:::i;107022:330::-;;;;;;;;;;-1:-1:-1;107022:330:0;;;;;:::i;:::-;;:::i;99342:179::-;;;;;;;;;;-1:-1:-1;99342:179:0;;;;;:::i;:::-;;:::i;97304:24::-;;;;;;;;;;-1:-1:-1;97304:24:0;;;;-1:-1:-1;;;;;97304:24:0;;;39715:132;39773:7;39800:39;39804:1;39807;39800:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;39793:46;;39715:132;;;;;:::o;106641:373::-;106728:16;;;106742:1;106728:16;;;;;;;;106704:21;;106728:16;;;;;;;;-1:-1:-1;;106765:4:0;;106755:7;;;;-1:-1:-1;;;;;;106765:4:0;;106755:7;;-1:-1:-1;106765:4:0;;106755:7;;;;:::i;:::-;;;;;;:14;-1:-1:-1;;;;;106755:14:0;;;-1:-1:-1;;;;;106755:14:0;;;;;106790:18;106780:4;106785:1;106780:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;106780:28:0;;;:7;;;;;;;;;:28;106847:6;;;:28;106883:9;106847:6;106924:4;106951;106971:24;:15;106991:3;106971:19;:24::i;:::-;106847:159;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;106847:159:0;;;;;;;;;;;;:::i;:::-;;106693:321;106641:373;:::o;106356:277::-;106424:12;;:37;;-1:-1:-1;;;106424:37:0;;106455:4;106424:37;;;738:51:1;106404:17:0;;-1:-1:-1;;;;;106424:12:0;;:22;;711:18:1;;106424:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;106489:12;;106519:11;;106489:54;;-1:-1:-1;;;106489:54:0;;-1:-1:-1;;;;;106519:11:0;;;106489:54;;;4262:51:1;4329:18;;;4322:34;;;106404:57:0;;-1:-1:-1;106474:12:0;;106489;;;:21;;4235:18:1;;106489:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;106474:69;;106560:7;106556:70;;;106584:11;;:30;;-1:-1:-1;;;106584:30:0;;;;;3466:25:1;;;-1:-1:-1;;;;;106584:11:0;;;;:19;;3439:18:1;;106584:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106556:70;106393:240;;106356:277::o;106078:221::-;106226:4;106255:36;106279:11;106255:23;:36::i;72534:100::-;72588:13;72621:5;72614:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72534:100;:::o;74046:171::-;74122:7;74142:23;74157:7;74142:14;:23::i;:::-;-1:-1:-1;74185:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;74185:24:0;;74046:171::o;99529:115::-;99610:26;99624:2;99628:7;99610:13;:26::i;99903:393::-;35624:13;:11;:13::i;:::-;100033:16:::1;::::0;::::1;;100032:17;:39:::0;::::1;;;-1:-1:-1::0;91516:10:0;:17;100053:18;100032:39:::1;100024:69;;;::::0;-1:-1:-1;;;100024:69:0;;10216:2:1;100024:69:0::1;::::0;::::1;10198:21:1::0;10255:2;10235:18;;;10228:30;-1:-1:-1;;;10274:18:1;;;10267:47;10331:18;;100024:69:0::1;;;;;;;;;100111:9;100106:183;100126:18:::0;;::::1;100106:183;;;100166:19;100174:7;;100182:1;100174:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;100166:7;:19::i;:::-;100204:7;;100212:1;100204:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;100200:78;;;100235:27;100244:7;;100252:1;100244:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;100256:5;100235:8;:27::i;:::-;100146:3:::0;::::1;::::0;::::1;:::i;:::-;;;;100106:183;;;;99903:393:::0;;;;:::o;74746:335::-;74941:41;21037:10;74974:7;74941:18;:41::i;:::-;74933:99;;;;-1:-1:-1;;;74933:99:0;;;;;;;:::i;:::-;75045:28;75055:4;75061:2;75065:7;75045:9;:28::i;104686:243::-;104801:16;;104874:4;104881:39;104914:5;104882:26;:9;98441:3;104882:13;:26::i;:::-;104881:32;;:39::i;:::-;104858:63;;;;104686:243;;;;;;:::o;91096:256::-;91193:7;91229:23;91246:5;91229:16;:23::i;:::-;91221:5;:31;91213:87;;;;-1:-1:-1;;;91213:87:0;;11494:2:1;91213:87:0;;;11476:21:1;11533:2;11513:18;;;11506:30;11572:34;11552:18;;;11545:62;-1:-1:-1;;;11623:18:1;;;11616:41;11674:19;;91213:87:0;11292:407:1;91213:87:0;-1:-1:-1;;;;;;91318:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;91096:256::o;75152:185::-;75290:39;75307:4;75313:2;75317:7;75290:39;;;;;;;;;;;;:16;:39::i;91618:233::-;91693:7;91729:30;91516:10;:17;;91428:113;91729:30;91721:5;:38;91713:95;;;;-1:-1:-1;;;91713:95:0;;11906:2:1;91713:95:0;;;11888:21:1;11945:2;11925:18;;;11918:30;11984:34;11964:18;;;11957:62;-1:-1:-1;;;12035:18:1;;;12028:42;12087:19;;91713:95:0;11704:408:1;91713:95:0;91826:10;91837:5;91826:17;;;;;;;;:::i;:::-;;;;;;;;;91819:24;;91618:233;;;:::o;108017:188::-;108151:11;;:46;;-1:-1:-1;;;108151:46:0;;-1:-1:-1;;;;;756:32:1;;;108151:46:0;;;738:51:1;108119:7:0;;108151:11;;:33;;711:18:1;;108151:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;108213:209::-;35624:13;:11;:13::i;:::-;108282:50:::1;::::0;-1:-1:-1;;;;;108282:27:0;::::1;::::0;108310:21:::1;108282:50:::0;::::1;;;::::0;::::1;::::0;;;108310:21;108282:27;:50;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;108343:12:0::1;::::0;108376:37:::1;::::0;-1:-1:-1;;;108376:37:0;;108407:4:::1;108376:37;::::0;::::1;738:51:1::0;-1:-1:-1;;;;;108343:12:0;;::::1;::::0;:21:::1;::::0;108365:9;;108343:12;;108376:22:::1;::::0;711:18:1;;108376:37:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108343:71;::::0;-1:-1:-1;;;;;;108343:71:0::1;::::0;;;;;;-1:-1:-1;;;;;4280:32:1;;;108343:71:0::1;::::0;::::1;4262:51:1::0;4329:18;;;4322:34;4235:18;;108343:71:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;72244:223::-:0;72316:7;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;;72380:56;;;;-1:-1:-1;;;72380:56:0;;12319:2:1;72380:56:0;;;12301:21:1;12358:2;12338:18;;;12331:30;-1:-1:-1;;;12377:18:1;;;12370:54;12441:18;;72380:56:0;12117:348:1;107775:115:0;107854:11;;:28;;;-1:-1:-1;;;107854:28:0;;;;107827:7;;-1:-1:-1;;;;;107854:11:0;;:26;;:28;;;;;;;;;;;;;;:11;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107847:35;;107775:115;:::o;71975:207::-;72047:7;-1:-1:-1;;;;;72075:19:0;;72067:73;;;;-1:-1:-1;;;72067:73:0;;12672:2:1;72067:73:0;;;12654:21:1;12711:2;12691:18;;;12684:30;12750:34;12730:18;;;12723:62;-1:-1:-1;;;12801:18:1;;;12794:39;12850:19;;72067:73:0;12470:405:1;72067:73:0;-1:-1:-1;;;;;;72158:16:0;;;;;:9;:16;;;;;;;71975:207::o;36386:103::-;35624:13;:11;:13::i;:::-;36451:30:::1;36478:1;36451:18;:30::i;:::-;36386:103::o:0;107898:111::-;107975:11;;:26;;;-1:-1:-1;;;107975:26:0;;;;107948:7;;-1:-1:-1;;;;;107975:11:0;;:24;;:26;;;;;;;;;;;;;;:11;:26;;;;;;;;;;107579:188;107712:11;;:47;;-1:-1:-1;;;107712:47:0;;-1:-1:-1;;;;;756:32:1;;;107712:47:0;;;738:51:1;107680:7:0;;107712:11;;:34;;711:18:1;;107712:47:0;592:203:1;72703:104:0;72759:13;72792:7;72785:14;;;;;:::i;99652:178::-;99779:43;99803:8;99813;99779:23;:43::i;75408:322::-;75582:41;21037:10;75615:7;75582:18;:41::i;:::-;75574:99;;;;-1:-1:-1;;;75574:99:0;;;;;;;:::i;:::-;75684:38;75698:4;75704:2;75708:7;75717:4;75684:13;:38::i;:::-;75408:322;;;;:::o;105874:196::-;106001:13;106039:23;106054:7;106039:14;:23::i;102825:1853::-;102944:16;;;;102936:50;;;;-1:-1:-1;;;102936:50:0;;13082:2:1;102936:50:0;;;13064:21:1;13121:2;13101:18;;;13094:30;-1:-1:-1;;;13140:18:1;;;13133:51;13201:18;;102936:50:0;12880:345:1;102936:50:0;98215:2;103019:14;:35;;102997:120;;;;-1:-1:-1;;;102997:120:0;;13432:2:1;102997:120:0;;;13414:21:1;13471:2;13451:18;;;13444:30;13510:34;13490:18;;;13483:62;-1:-1:-1;;;13561:18:1;;;13554:33;13604:19;;102997:120:0;13230:399:1;102997:120:0;98322:3;103150:41;103176:14;103150:21;103160:10;103150:9;:21::i;:::-;:25;;:41::i;:::-;:66;;103128:146;;;;-1:-1:-1;;;103128:146:0;;13836:2:1;103128:146:0;;;13818:21:1;13875:2;13855:18;;;13848:30;13914:32;13894:18;;;13887:60;13964:18;;103128:146:0;13634:354:1;103128:146:0;98104:5;103307:33;103325:14;103307:13;91516:10;:17;;91428:113;103307:33;:47;;103285:158;;;;-1:-1:-1;;;103285:158:0;;14195:2:1;103285:158:0;;;14177:21:1;14234:2;14214:18;;;14207:30;14273:34;14253:18;;;14246:62;14344:31;14324:18;;;14317:59;14393:19;;103285:158:0;13993:425:1;103285:158:0;103460:11;103456:1176;;;103509:10;;103488:18;;103509:30;;103524:14;103509;:30::i;:::-;103580:12;;:34;;-1:-1:-1;;;103580:34:0;;103603:10;103580:34;;;738:51:1;103488::0;;-1:-1:-1;103488:51:0;;-1:-1:-1;;;;;103580:12:0;;;;:22;;711:18:1;;103580:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;;103554:130;;;;-1:-1:-1;;;103554:130:0;;14625:2:1;103554:130:0;;;14607:21:1;14664:2;14644:18;;;14637:30;-1:-1:-1;;;14683:18:1;;;14676:50;14743:18;;103554:130:0;14423:344:1;103554:130:0;103701:37;103711:10;103723:14;103701:9;:37::i;:::-;103788:12;;-1:-1:-1;;;;;103788:12:0;:25;103832:10;103869:4;103893:31;103918:5;103893:20;:10;103908:4;103893:14;:20::i;:31::-;103788:151;;-1:-1:-1;;;;;;103788:151:0;;;;;;;-1:-1:-1;;;;;15030:15:1;;;103788:151:0;;;15012:34:1;15082:15;;;;15062:18;;;15055:43;15114:18;;;15107:34;14947:18;;103788:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;103986:12:0;;-1:-1:-1;;;;;103986:12:0;:25;104030:10;104059:7;35811:6;;-1:-1:-1;;;;;35811:6:0;;35738:87;104059:7;104085:31;104110:5;104085:20;:10;104100:4;104085:14;:20::i;:31::-;103986:145;;-1:-1:-1;;;;;;103986:145:0;;;;;;;-1:-1:-1;;;;;15030:15:1;;;103986:145:0;;;15012:34:1;15082:15;;;;15062:18;;;15055:43;15114:18;;;15107:34;14947:18;;103986:145:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;103473:670;103456:1176;;;104203:9;;:29;;104217:14;104203:13;:29::i;:::-;104190:9;:42;;104164:123;;;;-1:-1:-1;;;104164:123:0;;15354:2:1;104164:123:0;;;15336:21:1;15393:2;15373:18;;;15366:30;-1:-1:-1;;;15412:18:1;;;15405:49;15471:18;;104164:123:0;15152:343:1;104164:123:0;104304:37;104314:10;104326:14;104304:9;:37::i;:::-;104410:17;104430:30;104454:5;104430:19;:9;104444:4;104430:13;:19::i;:30::-;104410:50;;104475:25;104490:9;104475:14;:25::i;:::-;35811:6;;-1:-1:-1;;;;;35811:6:0;104569:51;104595:24;:9;104609;104595:13;:24::i;:::-;104569:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104149:483;103456:1176;104644:26;104653:10;104665:4;104644:8;:26::i;107458:113::-;35624:13;:11;:13::i;:::-;107530:11:::1;::::0;:33:::1;::::0;-1:-1:-1;;;107530:33:0;;-1:-1:-1;;;;;756:32:1;;;107530:33:0::1;::::0;::::1;738:51:1::0;107530:11:0;;::::1;::::0;:25:::1;::::0;711:18:1;;107530:33:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;107360:90:::0;107405:11;;:37;;-1:-1:-1;;;107405:37:0;;107431:10;107405:37;;;738:51:1;-1:-1:-1;;;;;107405:11:0;;;;:25;;711:18:1;;107405:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36644:201;35624:13;:11;:13::i;:::-;-1:-1:-1;;;;;36733:22:0;::::1;36725:73;;;::::0;-1:-1:-1;;;36725:73:0;;15702:2:1;36725:73:0::1;::::0;::::1;15684:21:1::0;15741:2;15721:18;;;15714:30;15780:34;15760:18;;;15753:62;-1:-1:-1;;;15831:18:1;;;15824:36;15877:19;;36725:73:0::1;15500:402:1::0;36725:73:0::1;36809:28;36828:8;36809:18;:28::i;:::-;36644:201:::0;:::o;100346:100::-;35624:13;:11;:13::i;:::-;100422:16:::1;::::0;;-1:-1:-1;;100402:36:0;::::1;100422:16;::::0;;::::1;100421:17;100402:36;::::0;;100346:100::o;107022:330::-;35624:13;:11;:13::i;:::-;-1:-1:-1;;;;;107116:23:0;::::1;107134:4;107116:23;;107108:32;;;::::0;::::1;;-1:-1:-1::0;;;;;107151:24:0;::::1;;::::0;;;:16:::1;:24;::::0;;;;:33;;-1:-1:-1;;107151:33:0::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;;;107195:150:::1;;107222:11;::::0;:31:::1;::::0;-1:-1:-1;;;107222:31:0;;-1:-1:-1;;;;;4280:32:1;;;107222:31:0::1;::::0;::::1;4262:51:1::0;107222:11:0::1;4329:18:1::0;;;4322:34;107222:11:0;;::::1;::::0;:20:::1;::::0;4235:18:1;;107222:31:0::1;4088:274:1::0;107195:150:0::1;107286:11;::::0;-1:-1:-1;;;;;107286:11:0::1;:20;107307:6:::0;107315:17:::1;107307:6:::0;107315:9:::1;:17::i;:::-;107286:47;::::0;-1:-1:-1;;;;;;107286:47:0::1;::::0;;;;;;-1:-1:-1;;;;;4280:32:1;;;107286:47:0::1;::::0;::::1;4262:51:1::0;4329:18;;;4322:34;4235:18;;107286:47:0::1;4088:274:1::0;99342:179:0;35624:13;:11;:13::i;:::-;99454:9:::1;:23:::0;;;;99488:10:::1;:25:::0;99342:179::o;4608:127::-;4697:19;;4715:1;4697:19;;;4608:127::o;39855:379::-;39975:7;40077:12;40070:5;40062:28;;;;-1:-1:-1;;;40062:28:0;;;;;;;;:::i;:::-;-1:-1:-1;40101:9:0;40113:5;40117:1;40113;:5;:::i;:::-;40101:17;39855:379;-1:-1:-1;;;;;39855:379:0:o;38890:181::-;38948:7;;38980:5;38984:1;38980;:5;:::i;:::-;38968:17;;39009:1;39004;:6;;38996:46;;;;-1:-1:-1;;;38996:46:0;;16883:2:1;38996:46:0;;;16865:21:1;16922:2;16902:18;;;16895:30;16961:29;16941:18;;;16934:57;17008:18;;38996:46:0;16681:351:1;60435:215:0;60537:4;-1:-1:-1;;;;;;60561:41:0;;-1:-1:-1;;;60561:41:0;;:81;;;60606:36;60630:11;60606:23;:36::i;83865:135::-;77533:4;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;83939:53;;;;-1:-1:-1;;;83939:53:0;;12319:2:1;83939:53:0;;;12301:21:1;12358:2;12338:18;;;12331:30;-1:-1:-1;;;12377:18:1;;;12370:54;12441:18;;83939:53:0;12117:348:1;73564:416:0;73645:13;73661:23;73676:7;73661:14;:23::i;:::-;73645:39;;73709:5;-1:-1:-1;;;;;73703:11:0;:2;-1:-1:-1;;;;;73703:11:0;;;73695:57;;;;-1:-1:-1;;;73695:57:0;;17239:2:1;73695:57:0;;;17221:21:1;17278:2;17258:18;;;17251:30;17317:34;17297:18;;;17290:62;-1:-1:-1;;;17368:18:1;;;17361:31;17409:19;;73695:57:0;17037:397:1;73695:57:0;21037:10;-1:-1:-1;;;;;73787:21:0;;;;:62;;-1:-1:-1;73812:37:0;73829:5;21037:10;74515:164;:::i;73812:37::-;73765:173;;;;-1:-1:-1;;;73765:173:0;;17641:2:1;73765:173:0;;;17623:21:1;17680:2;17660:18;;;17653:30;17719:34;17699:18;;;17692:62;17790:31;17770:18;;;17763:59;17839:19;;73765:173:0;17439:425:1;73765:173:0;73951:21;73960:2;73964:7;73951:8;:21::i;35903:132::-;35811:6;;-1:-1:-1;;;;;35811:6:0;21037:10;35967:23;35959:68;;;;-1:-1:-1;;;35959:68:0;;18071:2:1;35959:68:0;;;18053:21:1;;;18090:18;;;18083:30;18149:34;18129:18;;;18122:62;18201:18;;35959:68:0;17869:356:1;100614:418:0;100662:15;100680:25;:15;4578:14;;4486:114;100680:25;100662:43;;100716:27;:15;4697:19;;4715:1;4697:19;;;4608:127;100716:27;100754:22;100764:2;100768:7;100754:9;:22::i;:::-;100787;100868:11;100898:25;100915:7;100898:16;:25::i;:::-;100942:14;100833:138;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;100787:195;;100993:31;101006:7;101015:8;100993:12;:31::i;102489:328::-;-1:-1:-1;;;;;102624:24:0;;;;;;:16;:24;;;;;;;;102619:119;;102669:11;;-1:-1:-1;;;;;102669:11:0;:20;102690:6;102698:16;102690:6;102698:8;:16::i;:::-;102669:46;;-1:-1:-1;;;;;;102669:46:0;;;;;;;-1:-1:-1;;;;;4280:32:1;;;102669:46:0;;;4262:51:1;4329:18;;;4322:34;4235:18;;102669:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102665:62;;102752:11;102748:62;;;102780:18;:16;:18::i;77763:264::-;77856:4;77873:13;77889:23;77904:7;77889:14;:23::i;:::-;77873:39;;77942:5;-1:-1:-1;;;;;77931:16:0;:7;-1:-1:-1;;;;;77931:16:0;;:52;;;-1:-1:-1;;;;;;74636:25:0;;;74612:4;74636:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;77951:32;77931:87;;;;78011:7;-1:-1:-1;;;;;77987:31:0;:20;77999:7;77987:11;:20::i;:::-;-1:-1:-1;;;;;77987:31:0;;77931:87;77923:96;77763:264;-1:-1:-1;;;;77763:264:0:o;81762:1263::-;81921:4;-1:-1:-1;;;;;81894:31:0;:23;81909:7;81894:14;:23::i;:::-;-1:-1:-1;;;;;81894:31:0;;81886:81;;;;-1:-1:-1;;;81886:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;81986:16:0;;81978:65;;;;-1:-1:-1;;;81978:65:0;;20403:2:1;81978:65:0;;;20385:21:1;20442:2;20422:18;;;20415:30;20481:34;20461:18;;;20454:62;-1:-1:-1;;;20532:18:1;;;20525:34;20576:19;;81978:65:0;20201:400:1;81978:65:0;82056:42;82077:4;82083:2;82087:7;82096:1;82056:20;:42::i;:::-;82228:4;-1:-1:-1;;;;;82201:31:0;:23;82216:7;82201:14;:23::i;:::-;-1:-1:-1;;;;;82201:31:0;;82193:81;;;;-1:-1:-1;;;82193:81:0;;;;;;;:::i;:::-;82346:24;;;;:15;:24;;;;;;;;82339:31;;-1:-1:-1;;;;;;82339:31:0;;;;;;-1:-1:-1;;;;;82822:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;82822:20:0;;;82857:13;;;;;;;;;:18;;82339:31;82857:18;;;82897:16;;;:7;:16;;;;;;:21;;;;;;;;;;82936:27;;82362:7;;82936:27;;;106847:159;106693:321;106641:373;:::o;39457:250::-;39515:7;39539:6;39535:47;;-1:-1:-1;39569:1:0;39562:8;;39535:47;39594:9;39606:5;39610:1;39606;:5;:::i;:::-;39594:17;-1:-1:-1;39639:1:0;39630:5;39634:1;39594:17;39630:5;:::i;:::-;:10;39622:56;;;;-1:-1:-1;;;39622:56:0;;20981:2:1;39622:56:0;;;20963:21:1;21020:2;21000:18;;;20993:30;21059:34;21039:18;;;21032:62;-1:-1:-1;;;21110:18:1;;;21103:31;21151:19;;39622:56:0;20779:397:1;37005:191:0;37098:6;;;-1:-1:-1;;;;;37115:17:0;;;-1:-1:-1;;;;;;37115:17:0;;;;;;;37148:40;;37098:6;;;37115:17;37098:6;;37148:40;;37079:16;;37148:40;37068:128;37005:191;:::o;74289:155::-;74384:52;21037:10;74417:8;74427;74384:18;:52::i;76611:313::-;76767:28;76777:4;76783:2;76787:7;76767:9;:28::i;:::-;76814:47;76837:4;76843:2;76847:7;76856:4;76814:22;:47::i;:::-;76806:110;;;;-1:-1:-1;;;76806:110:0;;;;;;;:::i;88327:624::-;88400:13;88426:23;88441:7;88426:14;:23::i;:::-;88462;88488:19;;;:10;:19;;;;;88462:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88518:18;88539:10;:8;:10::i;:::-;88518:31;;88631:4;88625:18;88647:1;88625:23;88621:72;;;-1:-1:-1;88672:9:0;88327:624;-1:-1:-1;;88327:624:0:o;88621:72::-;88797:23;;:27;88793:108;;88872:4;88878:9;88855:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;88841:48;;;;88327:624;;;:::o;88793:108::-;88920:23;88935:7;88920:14;:23::i;101040:164::-;101119:9;101114:83;101138:14;101134:1;:18;101114:83;;;101174:11;101182:2;101174:7;:11::i;:::-;101154:3;;;;:::i;:::-;;;;101114:83;;39079:136;39137:7;39164:43;39168:1;39171;39164:43;;;;;;;;;;;;;;;;;:3;:43::i;90788:224::-;90890:4;-1:-1:-1;;;;;;90914:50:0;;-1:-1:-1;;;90914:50:0;;:90;;;90968:36;90992:11;90968:23;:36::i;83144:174::-;83219:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;83219:29:0;-1:-1:-1;;;;;83219:29:0;;;;;;;;:24;;83273:23;83219:24;83273:14;:23::i;:::-;-1:-1:-1;;;;;83264:46:0;;;;;;;;;;;83144:174;;:::o;78369:110::-;78445:26;78455:2;78459:7;78445:26;;;;;;;;;;;;:9;:26::i;18384:716::-;18440:13;18491:14;18508:17;18519:5;18508:10;:17::i;:::-;18528:1;18508:21;18491:38;;18544:20;18578:6;18567:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18567:18:0;-1:-1:-1;18544:41:0;-1:-1:-1;18709:28:0;;;18725:2;18709:28;18766:288;-1:-1:-1;;18798:5:0;-1:-1:-1;;;18935:2:0;18924:14;;18919:30;18798:5;18906:44;18996:2;18987:11;;;-1:-1:-1;19021:10:0;19017:21;;19033:5;;19017:21;18766:288;;;-1:-1:-1;19075:6:0;18384:716;-1:-1:-1;;;18384:716:0:o;89107:217::-;77533:4;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;89199:75;;;;-1:-1:-1;;;89199:75:0;;22277:2:1;89199:75:0;;;22259:21:1;22316:2;22296:18;;;22289:30;22355:34;22335:18;;;22328:62;-1:-1:-1;;;22406:18:1;;;22399:44;22460:19;;89199:75:0;22075:410:1;89199:75:0;89285:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;102080:401::-;102137:7;;;102203:17;102213:6;102203:9;:17::i;:::-;102185:35;;102236:9;102231:220;102255:7;102251:1;:11;102231:220;;;102284:15;102302:30;102322:6;102330:1;102302:19;:30::i;:::-;102284:48;;102347:18;102368:27;102387:7;102368:18;:27::i;:::-;102347:48;-1:-1:-1;102418:21:0;:5;102347:48;102418:9;:21::i;:::-;102410:29;;102269:182;;102264:3;;;;;:::i;:::-;;;;102231:220;;;-1:-1:-1;102468:5:0;;102080:401;-1:-1:-1;;;102080:401:0:o;105271:449::-;105461:56;105488:4;105494:2;105498:7;105507:9;105461:26;:56::i;:::-;-1:-1:-1;;;;;105593:18:0;;;;;;:38;;-1:-1:-1;;;;;;105615:16:0;;;;105593:38;105589:124;;;105648:20;105657:4;105663;105648:8;:20::i;:::-;105683:18;105692:2;105696:4;105683:8;:18::i;83461:315::-;83616:8;-1:-1:-1;;;;;83607:17:0;:5;-1:-1:-1;;;;;83607:17:0;;;83599:55;;;;-1:-1:-1;;;83599:55:0;;22692:2:1;83599:55:0;;;22674:21:1;22731:2;22711:18;;;22704:30;22770:27;22750:18;;;22743:55;22815:18;;83599:55:0;22490:349:1;83599:55:0;-1:-1:-1;;;;;83665:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;83665:46:0;;;;;;;;;;83727:41;;540::1;;;83727::0;;513:18:1;83727:41:0;;;;;;;83461:315;;;:::o;84564:853::-;84718:4;-1:-1:-1;;;;;84739:13:0;;47251:19;:23;84735:675;;84775:71;;-1:-1:-1;;;84775:71:0;;-1:-1:-1;;;;;84775:36:0;;;;;:71;;21037:10;;84826:4;;84832:7;;84841:4;;84775:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84775:71:0;;;;;;;;-1:-1:-1;;84775:71:0;;;;;;;;;;;;:::i;:::-;;;84771:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;85016:13:0;;85012:328;;85059:60;;-1:-1:-1;;;85059:60:0;;;;;;;:::i;85012:328::-;85290:6;85284:13;85275:6;85271:2;85267:15;85260:38;84771:584;-1:-1:-1;;;;;;84897:51:0;-1:-1:-1;;;84897:51:0;;-1:-1:-1;84890:58:0;;84735:675;-1:-1:-1;85394:4:0;84564:853;;;;;;:::o;100509:97::-;100561:13;100594:4;100587:11;;;;;:::i;72878:281::-;72951:13;72977:23;72992:7;72977:14;:23::i;:::-;73013:21;73037:10;:8;:10::i;:::-;73013:34;;73089:1;73071:7;73065:21;:25;:86;;;;;;;;;;;;;;;;;73117:7;73126:18;:7;:16;:18::i;:::-;73100:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73065:86;73058:93;72878:281;-1:-1:-1;;;72878:281:0:o;39223:226::-;39343:7;39379:12;39371:6;;;;39363:29;;;;-1:-1:-1;;;39363:29:0;;;;;;;;:::i;:::-;-1:-1:-1;39403:9:0;39415:5;39419:1;39415;:5;:::i;71606:305::-;71708:4;-1:-1:-1;;;;;;71745:40:0;;-1:-1:-1;;;71745:40:0;;:105;;-1:-1:-1;;;;;;;71802:48:0;;-1:-1:-1;;;71802:48:0;71745:105;:158;;;-1:-1:-1;;;;;;;;;;58994:40:0;;;71867:36;58885:157;78706:319;78835:18;78841:2;78845:7;78835:5;:18::i;:::-;78886:53;78917:1;78921:2;78925:7;78934:4;78886:22;:53::i;:::-;78864:153;;;;-1:-1:-1;;;78864:153:0;;;;;;;:::i;15250:922::-;15303:7;;-1:-1:-1;;;15381:15:0;;15377:102;;-1:-1:-1;;;15417:15:0;;;-1:-1:-1;15461:2:0;15451:12;15377:102;15506:6;15497:5;:15;15493:102;;15542:6;15533:15;;;-1:-1:-1;15577:2:0;15567:12;15493:102;15622:6;15613:5;:15;15609:102;;15658:6;15649:15;;;-1:-1:-1;15693:2:0;15683:12;15609:102;15738:5;15729;:14;15725:99;;15773:5;15764:14;;;-1:-1:-1;15807:1:0;15797:11;15725:99;15851:5;15842;:14;15838:99;;15886:5;15877:14;;;-1:-1:-1;15920:1:0;15910:11;15838:99;15964:5;15955;:14;15951:99;;15999:5;15990:14;;;-1:-1:-1;16033:1:0;16023:11;15951:99;16077:5;16068;:14;16064:66;;16113:1;16103:11;16158:6;15250:922;-1:-1:-1;;15250:922:0:o;101212:860::-;101307:7;101353:1;101369:11;;;;;:29;;;101394:4;101384:7;:14;101369:29;101365:672;;;-1:-1:-1;101428:2:0;101365:672;;;101462:4;101452:7;:14;:32;;;;;101480:4;101470:7;:14;101452:32;101448:589;;;-1:-1:-1;101514:1:0;101448:589;;;101547:4;101537:7;:14;:32;;;;;101565:4;101555:7;:14;101537:32;101533:504;;;-1:-1:-1;101599:1:0;101533:504;;;101632:4;101622:7;:14;:32;;;;;101650:4;101640:7;:14;101622:32;101618:419;;;-1:-1:-1;101684:1:0;101618:419;;;101717:4;101707:7;:14;:32;;;;;101735:4;101725:7;:14;101707:32;101703:334;;;-1:-1:-1;101769:1:0;101703:334;;;101802:4;101792:7;:14;:32;;;;;101820:4;101810:7;:14;101792:32;101788:249;;;-1:-1:-1;101854:1:0;101788:249;;;101887:4;101877:7;:14;:32;;;;;101905:4;101895:7;:14;101877:32;101873:164;;;-1:-1:-1;101939:1:0;101873:164;;;101972:4;101962:7;:14;:32;;;;;101990:4;101980:7;:14;101962:32;101958:79;;;-1:-1:-1;102024:1:0;102054:10;101212:860;-1:-1:-1;;101212:860:0:o;91925:915::-;92192:1;92180:9;:13;92176:222;;;92323:63;;-1:-1:-1;;;92323:63:0;;23924:2:1;92323:63:0;;;23906:21:1;23963:2;23943:18;;;23936:30;24002:34;23982:18;;;23975:62;-1:-1:-1;;;24053:18:1;;;24046:51;24114:19;;92323:63:0;23722:417:1;92176:222:0;92428:12;-1:-1:-1;;;;;92457:18:0;;92453:187;;92492:40;92524:7;93667:10;:17;;93640:24;;;;:15;:24;;;;;:44;;;93695:24;;;;;;;;;;;;93563:164;92492:40;92453:187;;;92562:2;-1:-1:-1;;;;;92554:10:0;:4;-1:-1:-1;;;;;92554:10:0;;92550:90;;92581:47;92614:4;92620:7;92581:32;:47::i;:::-;-1:-1:-1;;;;;92654:16:0;;92650:183;;92687:45;92724:7;92687:36;:45::i;:::-;92650:183;;;92760:4;-1:-1:-1;;;;;92754:10:0;:2;-1:-1:-1;;;;;92754:10:0;;92750:83;;92781:40;92809:2;92813:7;92781:27;:40::i;79361:942::-;-1:-1:-1;;;;;79441:16:0;;79433:61;;;;-1:-1:-1;;;79433:61:0;;24346:2:1;79433:61:0;;;24328:21:1;;;24365:18;;;24358:30;24424:34;24404:18;;;24397:62;24476:18;;79433:61:0;24144:356:1;79433:61:0;77533:4;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;77557:31;79505:58;;;;-1:-1:-1;;;79505:58:0;;24707:2:1;79505:58:0;;;24689:21:1;24746:2;24726:18;;;24719:30;24785;24765:18;;;24758:58;24833:18;;79505:58:0;24505:352:1;79505:58:0;79576:48;79605:1;79609:2;79613:7;79622:1;79576:20;:48::i;:::-;77533:4;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;77557:31;79714:58;;;;-1:-1:-1;;;79714:58:0;;24707:2:1;79714:58:0;;;24689:21:1;24746:2;24726:18;;;24719:30;24785;24765:18;;;24758:58;24833:18;;79714:58:0;24505:352:1;79714:58:0;-1:-1:-1;;;;;80121:13:0;;;;;;:9;:13;;;;;;;;:18;;80138:1;80121:18;;;80163:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;80163:21:0;;;;;80202:33;80171:7;;80121:13;;80202:33;;80121:13;;80202:33;106393:240;;106356:277::o;94354:988::-;94620:22;94670:1;94645:22;94662:4;94645:16;:22::i;:::-;:26;;;;:::i;:::-;94682:18;94703:26;;;:17;:26;;;;;;94620:51;;-1:-1:-1;94836:28:0;;;94832:328;;-1:-1:-1;;;;;94903:18:0;;94881:19;94903:18;;;:12;:18;;;;;;;;:34;;;;;;;;;94954:30;;;;;;:44;;;95071:30;;:17;:30;;;;;:43;;;94832:328;-1:-1:-1;95256:26:0;;;;:17;:26;;;;;;;;95249:33;;;-1:-1:-1;;;;;95300:18:0;;;;;:12;:18;;;;;:34;;;;;;;95293:41;94354:988::o;95637:1079::-;95915:10;:17;95890:22;;95915:21;;95935:1;;95915:21;:::i;:::-;95947:18;95968:24;;;:15;:24;;;;;;96341:10;:26;;95890:46;;-1:-1:-1;95968:24:0;;95890:46;;96341:26;;;;;;:::i;:::-;;;;;;;;;96319:48;;96405:11;96380:10;96391;96380:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;96485:28;;;:15;:28;;;;;;;:41;;;96657:24;;;;;96650:31;96692:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;95708:1008;;;95637:1079;:::o;93141:221::-;93226:14;93243:20;93260:2;93243:16;:20::i;:::-;-1:-1:-1;;;;;93274:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;93319:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;93141:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;800:258::-;872:1;882:113;896:6;893:1;890:13;882:113;;;972:11;;;966:18;953:11;;;946:39;918:2;911:10;882:113;;;1013:6;1010:1;1007:13;1004:48;;;-1:-1:-1;;1048:1:1;1030:16;;1023:27;800:258::o;1063:::-;1105:3;1143:5;1137:12;1170:6;1165:3;1158:19;1186:63;1242:6;1235:4;1230:3;1226:14;1219:4;1212:5;1208:16;1186:63;:::i;:::-;1303:2;1282:15;-1:-1:-1;;1278:29:1;1269:39;;;;1310:4;1265:50;;1063:258;-1:-1:-1;;1063:258:1:o;1326:220::-;1475:2;1464:9;1457:21;1438:4;1495:45;1536:2;1525:9;1521:18;1513:6;1495:45;:::i;1551:180::-;1610:6;1663:2;1651:9;1642:7;1638:23;1634:32;1631:52;;;1679:1;1676;1669:12;1631:52;-1:-1:-1;1702:23:1;;1551:180;-1:-1:-1;1551:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2173:367::-;2236:8;2246:6;2300:3;2293:4;2285:6;2281:17;2277:27;2267:55;;2318:1;2315;2308:12;2267:55;-1:-1:-1;2341:20:1;;2384:18;2373:30;;2370:50;;;2416:1;2413;2406:12;2370:50;2453:4;2445:6;2441:17;2429:29;;2513:3;2506:4;2496:6;2493:1;2489:14;2481:6;2477:27;2473:38;2470:47;2467:67;;;2530:1;2527;2520:12;2545:770;2664:6;2672;2680;2688;2741:2;2729:9;2720:7;2716:23;2712:32;2709:52;;;2757:1;2754;2747:12;2709:52;2797:9;2784:23;2826:18;2867:2;2859:6;2856:14;2853:34;;;2883:1;2880;2873:12;2853:34;2922:70;2984:7;2975:6;2964:9;2960:22;2922:70;:::i;:::-;3011:8;;-1:-1:-1;2896:96:1;-1:-1:-1;3099:2:1;3084:18;;3071:32;;-1:-1:-1;3115:16:1;;;3112:36;;;3144:1;3141;3134:12;3112:36;;3183:72;3247:7;3236:8;3225:9;3221:24;3183:72;:::i;:::-;2545:770;;;;-1:-1:-1;3274:8:1;-1:-1:-1;;;;2545:770:1:o;3502:328::-;3579:6;3587;3595;3648:2;3636:9;3627:7;3623:23;3619:32;3616:52;;;3664:1;3661;3654:12;3616:52;3687:29;3706:9;3687:29;:::i;:::-;3677:39;;3735:38;3769:2;3758:9;3754:18;3735:38;:::i;:::-;3725:48;;3820:2;3809:9;3805:18;3792:32;3782:42;;3502:328;;;;;:::o;3835:248::-;3903:6;3911;3964:2;3952:9;3943:7;3939:23;3935:32;3932:52;;;3980:1;3977;3970:12;3932:52;-1:-1:-1;;4003:23:1;;;4073:2;4058:18;;;4045:32;;-1:-1:-1;3835:248:1:o;4367:186::-;4426:6;4479:2;4467:9;4458:7;4454:23;4450:32;4447:52;;;4495:1;4492;4485:12;4447:52;4518:29;4537:9;4518:29;:::i;4558:118::-;4644:5;4637:13;4630:21;4623:5;4620:32;4610:60;;4666:1;4663;4656:12;4681:315;4746:6;4754;4807:2;4795:9;4786:7;4782:23;4778:32;4775:52;;;4823:1;4820;4813:12;4775:52;4846:29;4865:9;4846:29;:::i;:::-;4836:39;;4925:2;4914:9;4910:18;4897:32;4938:28;4960:5;4938:28;:::i;:::-;4985:5;4975:15;;;4681:315;;;;;:::o;5001:127::-;5062:10;5057:3;5053:20;5050:1;5043:31;5093:4;5090:1;5083:15;5117:4;5114:1;5107:15;5133:275;5204:2;5198:9;5269:2;5250:13;;-1:-1:-1;;5246:27:1;5234:40;;5304:18;5289:34;;5325:22;;;5286:62;5283:88;;;5351:18;;:::i;:::-;5387:2;5380:22;5133:275;;-1:-1:-1;5133:275:1:o;5413:980::-;5508:6;5516;5524;5532;5585:3;5573:9;5564:7;5560:23;5556:33;5553:53;;;5602:1;5599;5592:12;5553:53;5625:29;5644:9;5625:29;:::i;:::-;5615:39;;5673:2;5694:38;5728:2;5717:9;5713:18;5694:38;:::i;:::-;5684:48;;5779:2;5768:9;5764:18;5751:32;5741:42;;5834:2;5823:9;5819:18;5806:32;5857:18;5898:2;5890:6;5887:14;5884:34;;;5914:1;5911;5904:12;5884:34;5952:6;5941:9;5937:22;5927:32;;5997:7;5990:4;5986:2;5982:13;5978:27;5968:55;;6019:1;6016;6009:12;5968:55;6055:2;6042:16;6077:2;6073;6070:10;6067:36;;;6083:18;;:::i;:::-;6125:53;6168:2;6149:13;;-1:-1:-1;;6145:27:1;6141:36;;6125:53;:::i;:::-;6112:66;;6201:2;6194:5;6187:17;6241:7;6236:2;6231;6227;6223:11;6219:20;6216:33;6213:53;;;6262:1;6259;6252:12;6213:53;6317:2;6312;6308;6304:11;6299:2;6292:5;6288:14;6275:45;6361:1;6356:2;6351;6344:5;6340:14;6336:23;6329:34;;6382:5;6372:15;;;;;5413:980;;;;;;;:::o;6398:309::-;6463:6;6471;6524:2;6512:9;6503:7;6499:23;6495:32;6492:52;;;6540:1;6537;6530:12;6492:52;6576:9;6563:23;6553:33;;6636:2;6625:9;6621:18;6608:32;6649:28;6671:5;6649:28;:::i;6712:260::-;6780:6;6788;6841:2;6829:9;6820:7;6816:23;6812:32;6809:52;;;6857:1;6854;6847:12;6809:52;6880:29;6899:9;6880:29;:::i;:::-;6870:39;;6928:38;6962:2;6951:9;6947:18;6928:38;:::i;:::-;6918:48;;6712:260;;;;;:::o;7204:127::-;7265:10;7260:3;7256:20;7253:1;7246:31;7296:4;7293:1;7286:15;7320:4;7317:1;7310:15;7336:908;7570:4;7618:3;7607:9;7603:19;7649:6;7638:9;7631:25;7675:2;7713:3;7708:2;7697:9;7693:18;7686:31;7737:6;7772;7766:13;7803:6;7795;7788:22;7841:3;7830:9;7826:19;7819:26;;7880:2;7872:6;7868:15;7854:29;;7901:1;7911:195;7925:6;7922:1;7919:13;7911:195;;;7990:13;;-1:-1:-1;;;;;7986:39:1;7974:52;;8081:15;;;;8046:12;;;;8022:1;7940:9;7911:195;;;-1:-1:-1;;;;;;;8162:32:1;;;;8157:2;8142:18;;8135:60;-1:-1:-1;;;8226:2:1;8211:18;8204:34;8123:3;7336:908;-1:-1:-1;;7336:908:1:o;8249:936::-;8344:6;8375:2;8418;8406:9;8397:7;8393:23;8389:32;8386:52;;;8434:1;8431;8424:12;8386:52;8467:9;8461:16;8496:18;8537:2;8529:6;8526:14;8523:34;;;8553:1;8550;8543:12;8523:34;8591:6;8580:9;8576:22;8566:32;;8636:7;8629:4;8625:2;8621:13;8617:27;8607:55;;8658:1;8655;8648:12;8607:55;8687:2;8681:9;8709:2;8705;8702:10;8699:36;;;8715:18;;:::i;:::-;8761:2;8758:1;8754:10;8744:20;;8784:28;8808:2;8804;8800:11;8784:28;:::i;:::-;8846:15;;;8916:11;;;8912:20;;;8877:12;;;;8944:19;;;8941:39;;;8976:1;8973;8966:12;8941:39;9000:11;;;;9020:135;9036:6;9031:3;9028:15;9020:135;;;9102:10;;9090:23;;9053:12;;;;9133;;;;9020:135;;;9174:5;8249:936;-1:-1:-1;;;;;;;;8249:936:1:o;9190:184::-;9260:6;9313:2;9301:9;9292:7;9288:23;9284:32;9281:52;;;9329:1;9326;9319:12;9281:52;-1:-1:-1;9352:16:1;;9190:184;-1:-1:-1;9190:184:1:o;9379:245::-;9446:6;9499:2;9487:9;9478:7;9474:23;9470:32;9467:52;;;9515:1;9512;9505:12;9467:52;9547:9;9541:16;9566:28;9588:5;9566:28;:::i;9629:380::-;9708:1;9704:12;;;;9751;;;9772:61;;9826:4;9818:6;9814:17;9804:27;;9772:61;9879:2;9871:6;9868:14;9848:18;9845:38;9842:161;;;9925:10;9920:3;9916:20;9913:1;9906:31;9960:4;9957:1;9950:15;9988:4;9985:1;9978:15;9842:161;;9629:380;;;:::o;10360:241::-;10416:6;10469:2;10457:9;10448:7;10444:23;10440:32;10437:52;;;10485:1;10482;10475:12;10437:52;10524:9;10511:23;10543:28;10565:5;10543:28;:::i;10606:127::-;10667:10;10662:3;10658:20;10655:1;10648:31;10698:4;10695:1;10688:15;10722:4;10719:1;10712:15;10738:135;10777:3;-1:-1:-1;;10798:17:1;;10795:43;;;10818:18;;:::i;:::-;-1:-1:-1;10865:1:1;10854:13;;10738:135::o;10878:409::-;11080:2;11062:21;;;11119:2;11099:18;;;11092:30;11158:34;11153:2;11138:18;;11131:62;-1:-1:-1;;;11224:2:1;11209:18;;11202:43;11277:3;11262:19;;10878:409::o;16326:217::-;16366:1;16392;16382:132;;16436:10;16431:3;16427:20;16424:1;16417:31;16471:4;16468:1;16461:15;16499:4;16496:1;16489:15;16382:132;-1:-1:-1;16528:9:1;;16326:217::o;16548:128::-;16588:3;16619:1;16615:6;16612:1;16609:13;16606:39;;;16625:18;;:::i;:::-;-1:-1:-1;16661:9:1;;16548:128::o;18356:973::-;18441:12;;18406:3;;18496:1;18516:18;;;;18569;;;;18596:61;;18650:4;18642:6;18638:17;18628:27;;18596:61;18676:2;18724;18716:6;18713:14;18693:18;18690:38;18687:161;;;18770:10;18765:3;18761:20;18758:1;18751:31;18805:4;18802:1;18795:15;18833:4;18830:1;18823:15;18687:161;18864:18;18891:104;;;;19009:1;19004:319;;;;18857:466;;18891:104;-1:-1:-1;;18924:24:1;;18912:37;;18969:16;;;;-1:-1:-1;18891:104:1;;19004:319;18303:1;18296:14;;;18340:4;18327:18;;19098:1;19112:165;19126:6;19123:1;19120:13;19112:165;;;19204:14;;19191:11;;;19184:35;19247:16;;;;19141:10;;19112:165;;;19116:3;;19306:6;19301:3;19297:16;19290:23;;18857:466;;;;;;;18356:973;;;;:::o;19334:456::-;19555:3;19583:38;19617:3;19609:6;19583:38;:::i;:::-;19650:6;19644:13;19666:52;19711:6;19707:2;19700:4;19692:6;19688:17;19666:52;:::i;:::-;19734:50;19776:6;19772:2;19768:15;19760:6;19734:50;:::i;:::-;19727:57;19334:456;-1:-1:-1;;;;;;;19334:456:1:o;19795:401::-;19997:2;19979:21;;;20036:2;20016:18;;;20009:30;20075:34;20070:2;20055:18;;20048:62;-1:-1:-1;;;20141:2:1;20126:18;;20119:35;20186:3;20171:19;;19795:401::o;20606:168::-;20646:7;20712:1;20708;20704:6;20700:14;20697:1;20694:21;20689:1;20682:9;20675:17;20671:45;20668:71;;;20719:18;;:::i;:::-;-1:-1:-1;20759:9:1;;20606:168::o;21181:414::-;21383:2;21365:21;;;21422:2;21402:18;;;21395:30;21461:34;21456:2;21441:18;;21434:62;-1:-1:-1;;;21527:2:1;21512:18;;21505:48;21585:3;21570:19;;21181:414::o;21600:470::-;21779:3;21817:6;21811:13;21833:53;21879:6;21874:3;21867:4;21859:6;21855:17;21833:53;:::i;:::-;21949:13;;21908:16;;;;21971:57;21949:13;21908:16;22005:4;21993:17;;21971:57;:::i;:::-;22044:20;;21600:470;-1:-1:-1;;;;21600:470:1:o;22844:489::-;-1:-1:-1;;;;;23113:15:1;;;23095:34;;23165:15;;23160:2;23145:18;;23138:43;23212:2;23197:18;;23190:34;;;23260:3;23255:2;23240:18;;23233:31;;;23038:4;;23281:46;;23307:19;;23299:6;23281:46;:::i;:::-;23273:54;22844:489;-1:-1:-1;;;;;;22844:489:1:o;23338:249::-;23407:6;23460:2;23448:9;23439:7;23435:23;23431:32;23428:52;;;23476:1;23473;23466:12;23428:52;23508:9;23502:16;23527:30;23551:5;23527:30;:::i;23592:125::-;23632:4;23660:1;23657;23654:8;23651:34;;;23665:18;;:::i;:::-;-1:-1:-1;23702:9:1;;23592:125::o;24862:127::-;24923:10;24918:3;24914:20;24911:1;24904:31;24954:4;24951:1;24944:15;24978:4;24975:1;24968:15

Swarm Source

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