ETH Price: $2,642.91 (+1.04%)

Token

TheGurus (THEGURUS)
 

Overview

Max Total Supply

7,769 THEGURUS

Holders

4,130

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 THEGURUS
0x9953d1fc0cb4f0e117d8ee7c675d9d4277f075c4
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:
Gurus3D

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-06-05
*/

// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.20;

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

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

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

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

    /**
     * @dev Returns the 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 towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (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 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

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

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

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

            uint256 twos = denominator & (0 - denominator);
            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 (unsignedRoundsUp(rounding) && 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
     * towards zero.
     *
     * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

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

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

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)

pragma solidity ^0.8.20;



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

    /**
     * @dev The `value` string doesn't fit in the specified `length`.
     */
    error StringsInsufficientHexLength(uint256 value, uint256 length);

    /**
     * @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), HEX_DIGITS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

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

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        uint256 localValue = value;
        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] = HEX_DIGITS[localValue & 0xf];
            localValue >>= 4;
        }
        if (localValue != 0) {
            revert StringsInsufficientHexLength(value, length);
        }
        return string(buffer);
    }

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

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

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


// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


/**
 * @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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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 {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.20;

/**
 * @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 (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @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/utils/introspection/ERC165.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;


/**
 * @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);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;


/**
 * @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 address zero.
     *
     * 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 v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.20;


/**
 * @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 (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.20;


/**
 * @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 v5.0.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.20;








/**
 * @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}.
 */
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    mapping(uint256 tokenId => address) private _owners;

    mapping(address owner => uint256) private _balances;

    mapping(uint256 tokenId => address) private _tokenApprovals;

    mapping(address owner => mapping(address operator => 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 returns (uint256) {
        if (owner == address(0)) {
            revert ERC721InvalidOwner(address(0));
        }
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual returns (address) {
        return _requireOwned(tokenId);
    }

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

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

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

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string.concat(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 {
        _approve(to, tokenId, _msgSender());
    }

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

        return _getApproved(tokenId);
    }

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists
        // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.
        address previousOwner = _update(to, tokenId, _msgSender());
        if (previousOwner != from) {
            revert ERC721IncorrectOwner(from, tokenId, previousOwner);
        }
    }

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
        transferFrom(from, to, tokenId);
        _checkOnERC721Received(from, to, tokenId, data);
    }

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     *
     * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
     * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances
     * consistent with ownership. The invariant to preserve is 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`.
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.
     */
    function _getApproved(uint256 tokenId) internal view virtual returns (address) {
        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in
     * particular (ignoring whether it is owned by `owner`).
     *
     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
     * assumption.
     */
    function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
        return
            spender != address(0) &&
            (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
    }

    /**
     * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.
     * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets
     * the `spender` for the specific `tokenId`.
     *
     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
     * assumption.
     */
    function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
        if (!_isAuthorized(owner, spender, tokenId)) {
            if (owner == address(0)) {
                revert ERC721NonexistentToken(tokenId);
            } else {
                revert ERC721InsufficientApproval(spender, tokenId);
            }
        }
    }

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that
     * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.
     *
     * WARNING: Increasing an account's balance using this function tends to be paired with an override of the
     * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership
     * remain consistent with one another.
     */
    function _increaseBalance(address account, uint128 value) internal virtual {
        unchecked {
            _balances[account] += value;
        }
    }

    /**
     * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner
     * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.
     *
     * The `auth` argument is optional. If the value passed is non 0, then this function will check that
     * `auth` is either the owner of the token, or approved to operate on the token (by the owner).
     *
     * Emits a {Transfer} event.
     *
     * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.
     */
    function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
        address from = _ownerOf(tokenId);

        // Perform (optional) operator check
        if (auth != address(0)) {
            _checkAuthorized(from, auth, tokenId);
        }

        // Execute the update
        if (from != address(0)) {
            // Clear approval. No need to re-authorize or emit the Approval event
            _approve(address(0), tokenId, address(0), false);

            unchecked {
                _balances[from] -= 1;
            }
        }

        if (to != address(0)) {
            unchecked {
                _balances[to] += 1;
            }
        }

        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        return from;
    }

    /**
     * @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 {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        address previousOwner = _update(to, tokenId, address(0));
        if (previousOwner != address(0)) {
            revert ERC721InvalidSender(address(0));
        }
    }

    /**
     * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.
     *
     * 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 {
        _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);
        _checkOnERC721Received(address(0), to, tokenId, data);
    }

    /**
     * @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 {
        address previousOwner = _update(address(0), tokenId, address(0));
        if (previousOwner == address(0)) {
            revert ERC721NonexistentToken(tokenId);
        }
    }

    /**
     * @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 {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        address previousOwner = _update(to, tokenId, address(0));
        if (previousOwner == address(0)) {
            revert ERC721NonexistentToken(tokenId);
        } else if (previousOwner != from) {
            revert ERC721IncorrectOwner(from, tokenId, previousOwner);
        }
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients
     * are aware of the ERC721 standard 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 like {safeTransferFrom} in the sense that it invokes
     * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `tokenId` token must exist and be owned by `from`.
     * - `to` cannot be the zero address.
     * - `from` cannot be the zero address.
     * - 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) internal {
        _safeTransfer(from, to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
        _transfer(from, to, tokenId);
        _checkOnERC721Received(from, to, tokenId, data);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is
     * either the owner of the token, or approved to operate on all tokens held by this owner.
     *
     * Emits an {Approval} event.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address to, uint256 tokenId, address auth) internal {
        _approve(to, tokenId, auth, true);
    }

    /**
     * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not
     * emitted in the context of transfers.
     */
    function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {
        // Avoid reading the owner unless necessary
        if (emitEvent || auth != address(0)) {
            address owner = _requireOwned(tokenId);

            // We do not use _isAuthorized because single-token approvals should not be able to call approve
            if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
                revert ERC721InvalidApprover(auth);
            }

            if (emitEvent) {
                emit Approval(owner, to, tokenId);
            }
        }

        _tokenApprovals[tokenId] = to;
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Requirements:
     * - operator can't be the address zero.
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
        if (operator == address(0)) {
            revert ERC721InvalidOperator(operator);
        }
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).
     * Returns the owner.
     *
     * Overrides to ownership logic should be done to {_ownerOf}.
     */
    function _requireOwned(uint256 tokenId) internal view returns (address) {
        address owner = _ownerOf(tokenId);
        if (owner == address(0)) {
            revert ERC721NonexistentToken(tokenId);
        }
        return owner;
    }

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the
     * recipient doesn't accept the token transfer. 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
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
        if (to.code.length > 0) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                if (retval != IERC721Receiver.onERC721Received.selector) {
                    revert ERC721InvalidReceiver(to);
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert ERC721InvalidReceiver(to);
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.20;




/**
 * @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.
 *
 * CAUTION: `ERC721` extensions that implement custom `balanceOf` logic, such as `ERC721Consecutive`,
 * interfere with enumerability and should not be used together with `ERC721Enumerable`.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    mapping(address owner => mapping(uint256 index => uint256)) private _ownedTokens;
    mapping(uint256 tokenId => uint256) private _ownedTokensIndex;

    uint256[] private _allTokens;
    mapping(uint256 tokenId => uint256) private _allTokensIndex;

    /**
     * @dev An `owner`'s token query was out of bounds for `index`.
     *
     * NOTE: The owner being `address(0)` indicates a global out of bounds index.
     */
    error ERC721OutOfBoundsIndex(address owner, uint256 index);

    /**
     * @dev Batch mint is not allowed.
     */
    error ERC721EnumerableForbiddenBatchMint();

    /**
     * @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 returns (uint256) {
        if (index >= balanceOf(owner)) {
            revert ERC721OutOfBoundsIndex(owner, index);
        }
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual returns (uint256) {
        if (index >= totalSupply()) {
            revert ERC721OutOfBoundsIndex(address(0), index);
        }
        return _allTokens[index];
    }

    /**
     * @dev See {ERC721-_update}.
     */
    function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {
        address previousOwner = super._update(to, tokenId, auth);

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

        return previousOwner;
    }

    /**
     * @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 = balanceOf(to) - 1;
        _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 = balanceOf(from);
        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();
    }

    /**
     * See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch
     */
    function _increaseBalance(address account, uint128 amount) internal virtual override {
        if (amount > 0) {
            revert ERC721EnumerableForbiddenBatchMint();
        }
        super._increaseBalance(account, amount);
    }
}

// File: contracts/TheGurus.sol


pragma solidity ^0.8.2;




contract Gurus3D is ERC721Enumerable, Ownable {

    using Strings for uint256;

    string _baseTokenURI;
    address public fundWallet;

    constructor(string memory baseURI, address _fundWallet) Ownable(_fundWallet) ERC721("TheGurus", "THEGURUS")  {
        require(_fundWallet != address(0), "Zero address error");
        setBaseURI(baseURI);
        fundWallet = _fundWallet;
    }

     function mintBatch(address[] memory to, uint256[] memory tokenIds) public onlyOwner {
        uint256 toLength = to.length;
        require(toLength == tokenIds.length, "Arrays must have the same length");

        for (uint256 i = 0; i < toLength; i++) {
            require(to[i] != address(0), "Zero address error");
            _safeMint(to[i], tokenIds[i]);
        }
    }
    
    function walletOfOwner(address _owner) public view returns(uint256[] memory) {
        uint256 tokenCount = balanceOf(_owner);

        uint256[] memory tokensId = new uint256[](tokenCount);
        for(uint256 i; i < tokenCount; i++){
            tokensId[i] = tokenOfOwnerByIndex(_owner, i);
        }
        return tokensId;
    }

    function setFundWallet(address _fundWallet) public onlyOwner() {
        require(_fundWallet != address(0), "Zero address error");
        fundWallet = _fundWallet;
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return _baseTokenURI;
    }

    function setBaseURI(string memory baseURI) public onlyOwner {
        _baseTokenURI = baseURI;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireOwned(tokenId);

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

    function withdrawAll() public payable onlyOwner {
        require(payable(fundWallet).send(address(this).balance));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"address","name":"_fundWallet","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC721EnumerableForbiddenBatchMint","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ERC721OutOfBoundsIndex","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"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":[{"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":"fundWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"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":"to","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","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":[{"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":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fundWallet","type":"address"}],"name":"setFundWallet","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"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]

608060405234801561000f575f80fd5b50604051613c91380380613c9183398181016040528101906100319190610556565b806040518060400160405280600881526020017f54686547757275730000000000000000000000000000000000000000000000008152506040518060400160405280600881526020017f5448454755525553000000000000000000000000000000000000000000000000815250815f90816100ac91906107bd565b5080600190816100bc91906107bd565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361012f575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610126919061089b565b60405180910390fd5b61013e8161020360201b60201c565b505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a49061090e565b60405180910390fd5b6101bc826102c660201b60201c565b80600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061092c565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6102d46102e760201b60201c565b80600b90816102e391906107bd565b5050565b6102f561038060201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1661031961038760201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161461037e5761034261038060201b60201c565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610375919061089b565b60405180910390fd5b565b5f33905090565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61040e826103c8565b810181811067ffffffffffffffff8211171561042d5761042c6103d8565b5b80604052505050565b5f61043f6103af565b905061044b8282610405565b919050565b5f67ffffffffffffffff82111561046a576104696103d8565b5b610473826103c8565b9050602081019050919050565b8281835e5f83830152505050565b5f6104a061049b84610450565b610436565b9050828152602081018484840111156104bc576104bb6103c4565b5b6104c7848285610480565b509392505050565b5f82601f8301126104e3576104e26103c0565b5b81516104f384826020860161048e565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610525826104fc565b9050919050565b6105358161051b565b811461053f575f80fd5b50565b5f815190506105508161052c565b92915050565b5f806040838503121561056c5761056b6103b8565b5b5f83015167ffffffffffffffff811115610589576105886103bc565b5b610595858286016104cf565b92505060206105a685828601610542565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806105fe57607f821691505b602082108103610611576106106105ba565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026106737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610638565b61067d8683610638565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6106c16106bc6106b784610695565b61069e565b610695565b9050919050565b5f819050919050565b6106da836106a7565b6106ee6106e6826106c8565b848454610644565b825550505050565b5f90565b6107026106f6565b61070d8184846106d1565b505050565b5b81811015610730576107255f826106fa565b600181019050610713565b5050565b601f8211156107755761074681610617565b61074f84610629565b8101602085101561075e578190505b61077261076a85610629565b830182610712565b50505b505050565b5f82821c905092915050565b5f6107955f198460080261077a565b1980831691505092915050565b5f6107ad8383610786565b9150826002028217905092915050565b6107c6826105b0565b67ffffffffffffffff8111156107df576107de6103d8565b5b6107e982546105e7565b6107f4828285610734565b5f60209050601f831160018114610825575f8415610813578287015190505b61081d85826107a2565b865550610884565b601f19841661083386610617565b5f5b8281101561085a57848901518255600182019150602085019450602081019050610835565b868310156108775784890151610873601f891682610786565b8355505b6001600288020188555050505b505050505050565b6108958161051b565b82525050565b5f6020820190506108ae5f83018461088c565b92915050565b5f82825260208201905092915050565b7f5a65726f2061646472657373206572726f7200000000000000000000000000005f82015250565b5f6108f86012836108b4565b9150610903826108c4565b602082019050919050565b5f6020820190508181035f830152610925816108ec565b9050919050565b613358806109395f395ff3fe608060405260043610610165575f3560e01c80636352211e116100d05780638da5cb5b11610089578063b88d4fde11610063578063b88d4fde14610517578063c87b56dd1461053f578063e985e9c51461057b578063f2fde38b146105b757610165565b80638da5cb5b1461049b57806395d89b41146104c5578063a22cb465146104ef57610165565b80636352211e146103b1578063664a1ad6146103ed57806370a0823114610417578063715018a6146104535780637c88e3d914610469578063853828b61461049157610165565b80632f745c59116101225780632f745c591461028557806342842e0e146102c1578063438b6300146102e95780634f6ccce71461032557806355ce3b9a1461036157806355f804b31461038957610165565b806301ffc9a71461016957806306fdde03146101a5578063081812fc146101cf578063095ea7b31461020b57806318160ddd1461023357806323b872dd1461025d575b5f80fd5b348015610174575f80fd5b5061018f600480360381019061018a9190612402565b6105df565b60405161019c9190612447565b60405180910390f35b3480156101b0575f80fd5b506101b9610658565b6040516101c691906124d0565b60405180910390f35b3480156101da575f80fd5b506101f560048036038101906101f09190612523565b6106e7565b604051610202919061258d565b60405180910390f35b348015610216575f80fd5b50610231600480360381019061022c91906125d0565b610702565b005b34801561023e575f80fd5b50610247610718565b604051610254919061261d565b60405180910390f35b348015610268575f80fd5b50610283600480360381019061027e9190612636565b610724565b005b348015610290575f80fd5b506102ab60048036038101906102a691906125d0565b610823565b6040516102b8919061261d565b60405180910390f35b3480156102cc575f80fd5b506102e760048036038101906102e29190612636565b6108c7565b005b3480156102f4575f80fd5b5061030f600480360381019061030a9190612686565b6108e6565b60405161031c9190612768565b60405180910390f35b348015610330575f80fd5b5061034b60048036038101906103469190612523565b61098b565b604051610358919061261d565b60405180910390f35b34801561036c575f80fd5b5061038760048036038101906103829190612686565b6109fd565b005b348015610394575f80fd5b506103af60048036038101906103aa91906128b4565b610ab6565b005b3480156103bc575f80fd5b506103d760048036038101906103d29190612523565b610ad1565b6040516103e4919061258d565b60405180910390f35b3480156103f8575f80fd5b50610401610ae2565b60405161040e919061258d565b60405180910390f35b348015610422575f80fd5b5061043d60048036038101906104389190612686565b610b07565b60405161044a919061261d565b60405180910390f35b34801561045e575f80fd5b50610467610bbd565b005b348015610474575f80fd5b5061048f600480360381019061048a9190612a7f565b610bd0565b005b610499610d03565b005b3480156104a6575f80fd5b506104af610d6a565b6040516104bc919061258d565b60405180910390f35b3480156104d0575f80fd5b506104d9610d92565b6040516104e691906124d0565b60405180910390f35b3480156104fa575f80fd5b5061051560048036038101906105109190612b1f565b610e22565b005b348015610522575f80fd5b5061053d60048036038101906105389190612bfb565b610e38565b005b34801561054a575f80fd5b5061056560048036038101906105609190612523565b610e55565b60405161057291906124d0565b60405180910390f35b348015610586575f80fd5b506105a1600480360381019061059c9190612c7b565b610ebb565b6040516105ae9190612447565b60405180910390f35b3480156105c2575f80fd5b506105dd60048036038101906105d89190612686565b610f49565b005b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610651575061065082610fcd565b5b9050919050565b60605f805461066690612ce6565b80601f016020809104026020016040519081016040528092919081815260200182805461069290612ce6565b80156106dd5780601f106106b4576101008083540402835291602001916106dd565b820191905f5260205f20905b8154815290600101906020018083116106c057829003601f168201915b5050505050905090565b5f6106f1826110ae565b506106fb82611134565b9050919050565b610714828261070f61116d565b611174565b5050565b5f600880549050905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610794575f6040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161078b919061258d565b60405180910390fd5b5f6107a783836107a261116d565b611186565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461081d578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161081493929190612d16565b60405180910390fd5b50505050565b5f61082d83610b07565b82106108725782826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610869929190612d4b565b60405180910390fd5b60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b6108e183838360405180602001604052805f815250610e38565b505050565b60605f6108f283610b07565b90505f8167ffffffffffffffff81111561090f5761090e612790565b5b60405190808252806020026020018201604052801561093d5781602001602082028036833780820191505090505b5090505f5b82811015610980576109548582610823565b82828151811061096757610966612d72565b5b6020026020010181815250508080600101915050610942565b508092505050919050565b5f610994610718565b82106109d9575f826040517fa57d13dc0000000000000000000000000000000000000000000000000000000081526004016109d0929190612d4b565b60405180910390fd5b600882815481106109ed576109ec612d72565b5b905f5260205f2001549050919050565b610a056112a0565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6a90612de9565b60405180910390fd5b80600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610abe6112a0565b80600b9081610acd9190612fa4565b5050565b5f610adb826110ae565b9050919050565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b78575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610b6f919061258d565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610bc56112a0565b610bce5f611327565b565b610bd86112a0565b5f8251905081518114610c20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c17906130bd565b60405180910390fd5b5f5b81811015610cfd575f73ffffffffffffffffffffffffffffffffffffffff16848281518110610c5457610c53612d72565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610cb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca990612de9565b60405180910390fd5b610cf0848281518110610cc857610cc7612d72565b5b6020026020010151848381518110610ce357610ce2612d72565b5b60200260200101516113ea565b8080600101915050610c22565b50505050565b610d0b6112a0565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f19350505050610d68575f80fd5b565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610da190612ce6565b80601f0160208091040260200160405190810160405280929190818152602001828054610dcd90612ce6565b8015610e185780601f10610def57610100808354040283529160200191610e18565b820191905f5260205f20905b815481529060010190602001808311610dfb57829003601f168201915b5050505050905090565b610e34610e2d61116d565b8383611407565b5050565b610e43848484610724565b610e4f84848484611570565b50505050565b6060610e60826110ae565b505f610e6a611722565b90505f815111610e885760405180602001604052805f815250610eb3565b80610e92846117b2565b604051602001610ea392919061315f565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b610f516112a0565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fc1575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610fb8919061258d565b60405180910390fd5b610fca81611327565b50565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061109757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806110a757506110a68261187c565b5b9050919050565b5f806110b9836118e5565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361112b57826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401611122919061261d565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b611181838383600161191e565b505050565b5f80611193858585611add565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111d6576111d184611ce8565b611215565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611214576112138185611d2c565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036112565761125184611e76565b611295565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611294576112938585611f36565b5b5b809150509392505050565b6112a861116d565b73ffffffffffffffffffffffffffffffffffffffff166112c6610d6a565b73ffffffffffffffffffffffffffffffffffffffff1614611325576112e961116d565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161131c919061258d565b60405180910390fd5b565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611403828260405180602001604052805f815250611fba565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361147757816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161146e919061258d565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115639190612447565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b111561171c578273ffffffffffffffffffffffffffffffffffffffff1663150b7a026115b361116d565b8685856040518563ffffffff1660e01b81526004016115d594939291906131df565b6020604051808303815f875af192505050801561161057506040513d601f19601f8201168201806040525081019061160d919061323d565b60015b611691573d805f811461163e576040519150601f19603f3d011682016040523d82523d5f602084013e611643565b606091505b505f81510361168957836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401611680919061258d565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461171a57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401611711919061258d565b60405180910390fd5b505b50505050565b6060600b805461173190612ce6565b80601f016020809104026020016040519081016040528092919081815260200182805461175d90612ce6565b80156117a85780601f1061177f576101008083540402835291602001916117a8565b820191905f5260205f20905b81548152906001019060200180831161178b57829003601f168201915b5050505050905090565b60605f60016117c084611fd5565b0190505f8167ffffffffffffffff8111156117de576117dd612790565b5b6040519080825280601f01601f1916602001820160405280156118105781602001600182028036833780820191505090505b5090505f82602001820190505b600115611871578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161186657611865613268565b5b0494505f850361181d575b819350505050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b808061195657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611a88575f611965846110ae565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156119cf57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156119e257506119e08184610ebb565b155b15611a2457826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401611a1b919061258d565b60405180910390fd5b8115611a8657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f80611ae8846118e5565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611b2957611b28818486612126565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611bb457611b685f855f8061191e565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611c3357600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b60088054905060095f8381526020019081526020015f2081905550600881908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f611d3683610b07565b90505f60075f8481526020019081526020015f20549050818114611e0d575f60065f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205490508060065f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f20819055508160075f8381526020019081526020015f2081905550505b60075f8481526020019081526020015f205f905560065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f905550505050565b5f6001600880549050611e8991906132c2565b90505f60095f8481526020019081526020015f205490505f60088381548110611eb557611eb4612d72565b5b905f5260205f20015490508060088381548110611ed557611ed4612d72565b5b905f5260205f2001819055508160095f8381526020019081526020015f208190555060095f8581526020019081526020015f205f90556008805480611f1d57611f1c6132f5565b5b600190038181905f5260205f20015f9055905550505050565b5f6001611f4284610b07565b611f4c91906132c2565b90508160065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060075f8481526020019081526020015f2081905550505050565b611fc483836121e9565b611fd05f848484611570565b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612031577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161202757612026613268565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061206e576d04ee2d6d415b85acef8100000000838161206457612063613268565b5b0492506020810190505b662386f26fc10000831061209d57662386f26fc10000838161209357612092613268565b5b0492506010810190505b6305f5e10083106120c6576305f5e10083816120bc576120bb613268565b5b0492506008810190505b61271083106120eb5761271083816120e1576120e0613268565b5b0492506004810190505b6064831061210e576064838161210457612103613268565b5b0492506002810190505b600a831061211d576001810190505b80915050919050565b6121318383836122dc565b6121e4575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036121a557806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040161219c919061261d565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016121db929190612d4b565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612259575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401612250919061258d565b60405180910390fd5b5f61226583835f611186565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146122d7575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016122ce919061258d565b60405180910390fd5b505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561239357508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061235457506123538484610ebb565b5b8061239257508273ffffffffffffffffffffffffffffffffffffffff1661237a83611134565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6123e1816123ad565b81146123eb575f80fd5b50565b5f813590506123fc816123d8565b92915050565b5f60208284031215612417576124166123a5565b5b5f612424848285016123ee565b91505092915050565b5f8115159050919050565b6124418161242d565b82525050565b5f60208201905061245a5f830184612438565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6124a282612460565b6124ac818561246a565b93506124bc81856020860161247a565b6124c581612488565b840191505092915050565b5f6020820190508181035f8301526124e88184612498565b905092915050565b5f819050919050565b612502816124f0565b811461250c575f80fd5b50565b5f8135905061251d816124f9565b92915050565b5f60208284031215612538576125376123a5565b5b5f6125458482850161250f565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125778261254e565b9050919050565b6125878161256d565b82525050565b5f6020820190506125a05f83018461257e565b92915050565b6125af8161256d565b81146125b9575f80fd5b50565b5f813590506125ca816125a6565b92915050565b5f80604083850312156125e6576125e56123a5565b5b5f6125f3858286016125bc565b92505060206126048582860161250f565b9150509250929050565b612617816124f0565b82525050565b5f6020820190506126305f83018461260e565b92915050565b5f805f6060848603121561264d5761264c6123a5565b5b5f61265a868287016125bc565b935050602061266b868287016125bc565b925050604061267c8682870161250f565b9150509250925092565b5f6020828403121561269b5761269a6123a5565b5b5f6126a8848285016125bc565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6126e3816124f0565b82525050565b5f6126f483836126da565b60208301905092915050565b5f602082019050919050565b5f612716826126b1565b61272081856126bb565b935061272b836126cb565b805f5b8381101561275b57815161274288826126e9565b975061274d83612700565b92505060018101905061272e565b5085935050505092915050565b5f6020820190508181035f830152612780818461270c565b905092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6127c682612488565b810181811067ffffffffffffffff821117156127e5576127e4612790565b5b80604052505050565b5f6127f761239c565b905061280382826127bd565b919050565b5f67ffffffffffffffff82111561282257612821612790565b5b61282b82612488565b9050602081019050919050565b828183375f83830152505050565b5f61285861285384612808565b6127ee565b9050828152602081018484840111156128745761287361278c565b5b61287f848285612838565b509392505050565b5f82601f83011261289b5761289a612788565b5b81356128ab848260208601612846565b91505092915050565b5f602082840312156128c9576128c86123a5565b5b5f82013567ffffffffffffffff8111156128e6576128e56123a9565b5b6128f284828501612887565b91505092915050565b5f67ffffffffffffffff82111561291557612914612790565b5b602082029050602081019050919050565b5f80fd5b5f61293c612937846128fb565b6127ee565b9050808382526020820190506020840283018581111561295f5761295e612926565b5b835b81811015612988578061297488826125bc565b845260208401935050602081019050612961565b5050509392505050565b5f82601f8301126129a6576129a5612788565b5b81356129b684826020860161292a565b91505092915050565b5f67ffffffffffffffff8211156129d9576129d8612790565b5b602082029050602081019050919050565b5f6129fc6129f7846129bf565b6127ee565b90508083825260208201905060208402830185811115612a1f57612a1e612926565b5b835b81811015612a485780612a34888261250f565b845260208401935050602081019050612a21565b5050509392505050565b5f82601f830112612a6657612a65612788565b5b8135612a768482602086016129ea565b91505092915050565b5f8060408385031215612a9557612a946123a5565b5b5f83013567ffffffffffffffff811115612ab257612ab16123a9565b5b612abe85828601612992565b925050602083013567ffffffffffffffff811115612adf57612ade6123a9565b5b612aeb85828601612a52565b9150509250929050565b612afe8161242d565b8114612b08575f80fd5b50565b5f81359050612b1981612af5565b92915050565b5f8060408385031215612b3557612b346123a5565b5b5f612b42858286016125bc565b9250506020612b5385828601612b0b565b9150509250929050565b5f67ffffffffffffffff821115612b7757612b76612790565b5b612b8082612488565b9050602081019050919050565b5f612b9f612b9a84612b5d565b6127ee565b905082815260208101848484011115612bbb57612bba61278c565b5b612bc6848285612838565b509392505050565b5f82601f830112612be257612be1612788565b5b8135612bf2848260208601612b8d565b91505092915050565b5f805f8060808587031215612c1357612c126123a5565b5b5f612c20878288016125bc565b9450506020612c31878288016125bc565b9350506040612c428782880161250f565b925050606085013567ffffffffffffffff811115612c6357612c626123a9565b5b612c6f87828801612bce565b91505092959194509250565b5f8060408385031215612c9157612c906123a5565b5b5f612c9e858286016125bc565b9250506020612caf858286016125bc565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612cfd57607f821691505b602082108103612d1057612d0f612cb9565b5b50919050565b5f606082019050612d295f83018661257e565b612d36602083018561260e565b612d43604083018461257e565b949350505050565b5f604082019050612d5e5f83018561257e565b612d6b602083018461260e565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f5a65726f2061646472657373206572726f7200000000000000000000000000005f82015250565b5f612dd360128361246a565b9150612dde82612d9f565b602082019050919050565b5f6020820190508181035f830152612e0081612dc7565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612e637fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612e28565b612e6d8683612e28565b95508019841693508086168417925050509392505050565b5f819050919050565b5f612ea8612ea3612e9e846124f0565b612e85565b6124f0565b9050919050565b5f819050919050565b612ec183612e8e565b612ed5612ecd82612eaf565b848454612e34565b825550505050565b5f90565b612ee9612edd565b612ef4818484612eb8565b505050565b5b81811015612f1757612f0c5f82612ee1565b600181019050612efa565b5050565b601f821115612f5c57612f2d81612e07565b612f3684612e19565b81016020851015612f45578190505b612f59612f5185612e19565b830182612ef9565b50505b505050565b5f82821c905092915050565b5f612f7c5f1984600802612f61565b1980831691505092915050565b5f612f948383612f6d565b9150826002028217905092915050565b612fad82612460565b67ffffffffffffffff811115612fc657612fc5612790565b5b612fd08254612ce6565b612fdb828285612f1b565b5f60209050601f83116001811461300c575f8415612ffa578287015190505b6130048582612f89565b86555061306b565b601f19841661301a86612e07565b5f5b828110156130415784890151825560018201915060208501945060208101905061301c565b8683101561305e578489015161305a601f891682612f6d565b8355505b6001600288020188555050505b505050505050565b7f417272617973206d7573742068617665207468652073616d65206c656e6774685f82015250565b5f6130a760208361246a565b91506130b282613073565b602082019050919050565b5f6020820190508181035f8301526130d48161309b565b9050919050565b5f81905092915050565b5f6130ef82612460565b6130f981856130db565b935061310981856020860161247a565b80840191505092915050565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000005f82015250565b5f6131496005836130db565b915061315482613115565b600582019050919050565b5f61316a82856130e5565b915061317682846130e5565b91506131818261313d565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f6131b18261318d565b6131bb8185613197565b93506131cb81856020860161247a565b6131d481612488565b840191505092915050565b5f6080820190506131f25f83018761257e565b6131ff602083018661257e565b61320c604083018561260e565b818103606083015261321e81846131a7565b905095945050505050565b5f81519050613237816123d8565b92915050565b5f60208284031215613252576132516123a5565b5b5f61325f84828501613229565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6132cc826124f0565b91506132d7836124f0565b92508282039050818111156132ef576132ee613295565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220a8db1c5a4b42baf7570e0419c5cd77aca38cfd4d8f4a71f3f39365946e38f05264736f6c634300081900330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000e608ad1b46c36c0d8d75d856cbe846bcce12a3f8000000000000000000000000000000000000000000000000000000000000006568747470733a2f2f726f73652d666173742d706172726f74666973682d3339312e6d7970696e6174612e636c6f75642f697066732f516d633262757275566e633570626758626464537a5a42784e74786f4a7335474772754d483645353459534751532f2c000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405260043610610165575f3560e01c80636352211e116100d05780638da5cb5b11610089578063b88d4fde11610063578063b88d4fde14610517578063c87b56dd1461053f578063e985e9c51461057b578063f2fde38b146105b757610165565b80638da5cb5b1461049b57806395d89b41146104c5578063a22cb465146104ef57610165565b80636352211e146103b1578063664a1ad6146103ed57806370a0823114610417578063715018a6146104535780637c88e3d914610469578063853828b61461049157610165565b80632f745c59116101225780632f745c591461028557806342842e0e146102c1578063438b6300146102e95780634f6ccce71461032557806355ce3b9a1461036157806355f804b31461038957610165565b806301ffc9a71461016957806306fdde03146101a5578063081812fc146101cf578063095ea7b31461020b57806318160ddd1461023357806323b872dd1461025d575b5f80fd5b348015610174575f80fd5b5061018f600480360381019061018a9190612402565b6105df565b60405161019c9190612447565b60405180910390f35b3480156101b0575f80fd5b506101b9610658565b6040516101c691906124d0565b60405180910390f35b3480156101da575f80fd5b506101f560048036038101906101f09190612523565b6106e7565b604051610202919061258d565b60405180910390f35b348015610216575f80fd5b50610231600480360381019061022c91906125d0565b610702565b005b34801561023e575f80fd5b50610247610718565b604051610254919061261d565b60405180910390f35b348015610268575f80fd5b50610283600480360381019061027e9190612636565b610724565b005b348015610290575f80fd5b506102ab60048036038101906102a691906125d0565b610823565b6040516102b8919061261d565b60405180910390f35b3480156102cc575f80fd5b506102e760048036038101906102e29190612636565b6108c7565b005b3480156102f4575f80fd5b5061030f600480360381019061030a9190612686565b6108e6565b60405161031c9190612768565b60405180910390f35b348015610330575f80fd5b5061034b60048036038101906103469190612523565b61098b565b604051610358919061261d565b60405180910390f35b34801561036c575f80fd5b5061038760048036038101906103829190612686565b6109fd565b005b348015610394575f80fd5b506103af60048036038101906103aa91906128b4565b610ab6565b005b3480156103bc575f80fd5b506103d760048036038101906103d29190612523565b610ad1565b6040516103e4919061258d565b60405180910390f35b3480156103f8575f80fd5b50610401610ae2565b60405161040e919061258d565b60405180910390f35b348015610422575f80fd5b5061043d60048036038101906104389190612686565b610b07565b60405161044a919061261d565b60405180910390f35b34801561045e575f80fd5b50610467610bbd565b005b348015610474575f80fd5b5061048f600480360381019061048a9190612a7f565b610bd0565b005b610499610d03565b005b3480156104a6575f80fd5b506104af610d6a565b6040516104bc919061258d565b60405180910390f35b3480156104d0575f80fd5b506104d9610d92565b6040516104e691906124d0565b60405180910390f35b3480156104fa575f80fd5b5061051560048036038101906105109190612b1f565b610e22565b005b348015610522575f80fd5b5061053d60048036038101906105389190612bfb565b610e38565b005b34801561054a575f80fd5b5061056560048036038101906105609190612523565b610e55565b60405161057291906124d0565b60405180910390f35b348015610586575f80fd5b506105a1600480360381019061059c9190612c7b565b610ebb565b6040516105ae9190612447565b60405180910390f35b3480156105c2575f80fd5b506105dd60048036038101906105d89190612686565b610f49565b005b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610651575061065082610fcd565b5b9050919050565b60605f805461066690612ce6565b80601f016020809104026020016040519081016040528092919081815260200182805461069290612ce6565b80156106dd5780601f106106b4576101008083540402835291602001916106dd565b820191905f5260205f20905b8154815290600101906020018083116106c057829003601f168201915b5050505050905090565b5f6106f1826110ae565b506106fb82611134565b9050919050565b610714828261070f61116d565b611174565b5050565b5f600880549050905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610794575f6040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161078b919061258d565b60405180910390fd5b5f6107a783836107a261116d565b611186565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461081d578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161081493929190612d16565b60405180910390fd5b50505050565b5f61082d83610b07565b82106108725782826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610869929190612d4b565b60405180910390fd5b60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b6108e183838360405180602001604052805f815250610e38565b505050565b60605f6108f283610b07565b90505f8167ffffffffffffffff81111561090f5761090e612790565b5b60405190808252806020026020018201604052801561093d5781602001602082028036833780820191505090505b5090505f5b82811015610980576109548582610823565b82828151811061096757610966612d72565b5b6020026020010181815250508080600101915050610942565b508092505050919050565b5f610994610718565b82106109d9575f826040517fa57d13dc0000000000000000000000000000000000000000000000000000000081526004016109d0929190612d4b565b60405180910390fd5b600882815481106109ed576109ec612d72565b5b905f5260205f2001549050919050565b610a056112a0565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6a90612de9565b60405180910390fd5b80600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610abe6112a0565b80600b9081610acd9190612fa4565b5050565b5f610adb826110ae565b9050919050565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b78575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610b6f919061258d565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610bc56112a0565b610bce5f611327565b565b610bd86112a0565b5f8251905081518114610c20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c17906130bd565b60405180910390fd5b5f5b81811015610cfd575f73ffffffffffffffffffffffffffffffffffffffff16848281518110610c5457610c53612d72565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610cb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca990612de9565b60405180910390fd5b610cf0848281518110610cc857610cc7612d72565b5b6020026020010151848381518110610ce357610ce2612d72565b5b60200260200101516113ea565b8080600101915050610c22565b50505050565b610d0b6112a0565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f19350505050610d68575f80fd5b565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610da190612ce6565b80601f0160208091040260200160405190810160405280929190818152602001828054610dcd90612ce6565b8015610e185780601f10610def57610100808354040283529160200191610e18565b820191905f5260205f20905b815481529060010190602001808311610dfb57829003601f168201915b5050505050905090565b610e34610e2d61116d565b8383611407565b5050565b610e43848484610724565b610e4f84848484611570565b50505050565b6060610e60826110ae565b505f610e6a611722565b90505f815111610e885760405180602001604052805f815250610eb3565b80610e92846117b2565b604051602001610ea392919061315f565b6040516020818303038152906040525b915050919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b610f516112a0565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fc1575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610fb8919061258d565b60405180910390fd5b610fca81611327565b50565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061109757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806110a757506110a68261187c565b5b9050919050565b5f806110b9836118e5565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361112b57826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401611122919061261d565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b611181838383600161191e565b505050565b5f80611193858585611add565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111d6576111d184611ce8565b611215565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611214576112138185611d2c565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036112565761125184611e76565b611295565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611294576112938585611f36565b5b5b809150509392505050565b6112a861116d565b73ffffffffffffffffffffffffffffffffffffffff166112c6610d6a565b73ffffffffffffffffffffffffffffffffffffffff1614611325576112e961116d565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161131c919061258d565b60405180910390fd5b565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611403828260405180602001604052805f815250611fba565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361147757816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161146e919061258d565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115639190612447565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b111561171c578273ffffffffffffffffffffffffffffffffffffffff1663150b7a026115b361116d565b8685856040518563ffffffff1660e01b81526004016115d594939291906131df565b6020604051808303815f875af192505050801561161057506040513d601f19601f8201168201806040525081019061160d919061323d565b60015b611691573d805f811461163e576040519150601f19603f3d011682016040523d82523d5f602084013e611643565b606091505b505f81510361168957836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401611680919061258d565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461171a57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401611711919061258d565b60405180910390fd5b505b50505050565b6060600b805461173190612ce6565b80601f016020809104026020016040519081016040528092919081815260200182805461175d90612ce6565b80156117a85780601f1061177f576101008083540402835291602001916117a8565b820191905f5260205f20905b81548152906001019060200180831161178b57829003601f168201915b5050505050905090565b60605f60016117c084611fd5565b0190505f8167ffffffffffffffff8111156117de576117dd612790565b5b6040519080825280601f01601f1916602001820160405280156118105781602001600182028036833780820191505090505b5090505f82602001820190505b600115611871578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161186657611865613268565b5b0494505f850361181d575b819350505050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b808061195657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611a88575f611965846110ae565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156119cf57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156119e257506119e08184610ebb565b155b15611a2457826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401611a1b919061258d565b60405180910390fd5b8115611a8657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f80611ae8846118e5565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611b2957611b28818486612126565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611bb457611b685f855f8061191e565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611c3357600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b60088054905060095f8381526020019081526020015f2081905550600881908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f611d3683610b07565b90505f60075f8481526020019081526020015f20549050818114611e0d575f60065f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205490508060065f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f20819055508160075f8381526020019081526020015f2081905550505b60075f8481526020019081526020015f205f905560065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f905550505050565b5f6001600880549050611e8991906132c2565b90505f60095f8481526020019081526020015f205490505f60088381548110611eb557611eb4612d72565b5b905f5260205f20015490508060088381548110611ed557611ed4612d72565b5b905f5260205f2001819055508160095f8381526020019081526020015f208190555060095f8581526020019081526020015f205f90556008805480611f1d57611f1c6132f5565b5b600190038181905f5260205f20015f9055905550505050565b5f6001611f4284610b07565b611f4c91906132c2565b90508160065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060075f8481526020019081526020015f2081905550505050565b611fc483836121e9565b611fd05f848484611570565b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612031577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161202757612026613268565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061206e576d04ee2d6d415b85acef8100000000838161206457612063613268565b5b0492506020810190505b662386f26fc10000831061209d57662386f26fc10000838161209357612092613268565b5b0492506010810190505b6305f5e10083106120c6576305f5e10083816120bc576120bb613268565b5b0492506008810190505b61271083106120eb5761271083816120e1576120e0613268565b5b0492506004810190505b6064831061210e576064838161210457612103613268565b5b0492506002810190505b600a831061211d576001810190505b80915050919050565b6121318383836122dc565b6121e4575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036121a557806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040161219c919061261d565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016121db929190612d4b565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612259575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401612250919061258d565b60405180910390fd5b5f61226583835f611186565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146122d7575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016122ce919061258d565b60405180910390fd5b505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561239357508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061235457506123538484610ebb565b5b8061239257508273ffffffffffffffffffffffffffffffffffffffff1661237a83611134565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6123e1816123ad565b81146123eb575f80fd5b50565b5f813590506123fc816123d8565b92915050565b5f60208284031215612417576124166123a5565b5b5f612424848285016123ee565b91505092915050565b5f8115159050919050565b6124418161242d565b82525050565b5f60208201905061245a5f830184612438565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6124a282612460565b6124ac818561246a565b93506124bc81856020860161247a565b6124c581612488565b840191505092915050565b5f6020820190508181035f8301526124e88184612498565b905092915050565b5f819050919050565b612502816124f0565b811461250c575f80fd5b50565b5f8135905061251d816124f9565b92915050565b5f60208284031215612538576125376123a5565b5b5f6125458482850161250f565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125778261254e565b9050919050565b6125878161256d565b82525050565b5f6020820190506125a05f83018461257e565b92915050565b6125af8161256d565b81146125b9575f80fd5b50565b5f813590506125ca816125a6565b92915050565b5f80604083850312156125e6576125e56123a5565b5b5f6125f3858286016125bc565b92505060206126048582860161250f565b9150509250929050565b612617816124f0565b82525050565b5f6020820190506126305f83018461260e565b92915050565b5f805f6060848603121561264d5761264c6123a5565b5b5f61265a868287016125bc565b935050602061266b868287016125bc565b925050604061267c8682870161250f565b9150509250925092565b5f6020828403121561269b5761269a6123a5565b5b5f6126a8848285016125bc565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6126e3816124f0565b82525050565b5f6126f483836126da565b60208301905092915050565b5f602082019050919050565b5f612716826126b1565b61272081856126bb565b935061272b836126cb565b805f5b8381101561275b57815161274288826126e9565b975061274d83612700565b92505060018101905061272e565b5085935050505092915050565b5f6020820190508181035f830152612780818461270c565b905092915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6127c682612488565b810181811067ffffffffffffffff821117156127e5576127e4612790565b5b80604052505050565b5f6127f761239c565b905061280382826127bd565b919050565b5f67ffffffffffffffff82111561282257612821612790565b5b61282b82612488565b9050602081019050919050565b828183375f83830152505050565b5f61285861285384612808565b6127ee565b9050828152602081018484840111156128745761287361278c565b5b61287f848285612838565b509392505050565b5f82601f83011261289b5761289a612788565b5b81356128ab848260208601612846565b91505092915050565b5f602082840312156128c9576128c86123a5565b5b5f82013567ffffffffffffffff8111156128e6576128e56123a9565b5b6128f284828501612887565b91505092915050565b5f67ffffffffffffffff82111561291557612914612790565b5b602082029050602081019050919050565b5f80fd5b5f61293c612937846128fb565b6127ee565b9050808382526020820190506020840283018581111561295f5761295e612926565b5b835b81811015612988578061297488826125bc565b845260208401935050602081019050612961565b5050509392505050565b5f82601f8301126129a6576129a5612788565b5b81356129b684826020860161292a565b91505092915050565b5f67ffffffffffffffff8211156129d9576129d8612790565b5b602082029050602081019050919050565b5f6129fc6129f7846129bf565b6127ee565b90508083825260208201905060208402830185811115612a1f57612a1e612926565b5b835b81811015612a485780612a34888261250f565b845260208401935050602081019050612a21565b5050509392505050565b5f82601f830112612a6657612a65612788565b5b8135612a768482602086016129ea565b91505092915050565b5f8060408385031215612a9557612a946123a5565b5b5f83013567ffffffffffffffff811115612ab257612ab16123a9565b5b612abe85828601612992565b925050602083013567ffffffffffffffff811115612adf57612ade6123a9565b5b612aeb85828601612a52565b9150509250929050565b612afe8161242d565b8114612b08575f80fd5b50565b5f81359050612b1981612af5565b92915050565b5f8060408385031215612b3557612b346123a5565b5b5f612b42858286016125bc565b9250506020612b5385828601612b0b565b9150509250929050565b5f67ffffffffffffffff821115612b7757612b76612790565b5b612b8082612488565b9050602081019050919050565b5f612b9f612b9a84612b5d565b6127ee565b905082815260208101848484011115612bbb57612bba61278c565b5b612bc6848285612838565b509392505050565b5f82601f830112612be257612be1612788565b5b8135612bf2848260208601612b8d565b91505092915050565b5f805f8060808587031215612c1357612c126123a5565b5b5f612c20878288016125bc565b9450506020612c31878288016125bc565b9350506040612c428782880161250f565b925050606085013567ffffffffffffffff811115612c6357612c626123a9565b5b612c6f87828801612bce565b91505092959194509250565b5f8060408385031215612c9157612c906123a5565b5b5f612c9e858286016125bc565b9250506020612caf858286016125bc565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612cfd57607f821691505b602082108103612d1057612d0f612cb9565b5b50919050565b5f606082019050612d295f83018661257e565b612d36602083018561260e565b612d43604083018461257e565b949350505050565b5f604082019050612d5e5f83018561257e565b612d6b602083018461260e565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f5a65726f2061646472657373206572726f7200000000000000000000000000005f82015250565b5f612dd360128361246a565b9150612dde82612d9f565b602082019050919050565b5f6020820190508181035f830152612e0081612dc7565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612e637fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612e28565b612e6d8683612e28565b95508019841693508086168417925050509392505050565b5f819050919050565b5f612ea8612ea3612e9e846124f0565b612e85565b6124f0565b9050919050565b5f819050919050565b612ec183612e8e565b612ed5612ecd82612eaf565b848454612e34565b825550505050565b5f90565b612ee9612edd565b612ef4818484612eb8565b505050565b5b81811015612f1757612f0c5f82612ee1565b600181019050612efa565b5050565b601f821115612f5c57612f2d81612e07565b612f3684612e19565b81016020851015612f45578190505b612f59612f5185612e19565b830182612ef9565b50505b505050565b5f82821c905092915050565b5f612f7c5f1984600802612f61565b1980831691505092915050565b5f612f948383612f6d565b9150826002028217905092915050565b612fad82612460565b67ffffffffffffffff811115612fc657612fc5612790565b5b612fd08254612ce6565b612fdb828285612f1b565b5f60209050601f83116001811461300c575f8415612ffa578287015190505b6130048582612f89565b86555061306b565b601f19841661301a86612e07565b5f5b828110156130415784890151825560018201915060208501945060208101905061301c565b8683101561305e578489015161305a601f891682612f6d565b8355505b6001600288020188555050505b505050505050565b7f417272617973206d7573742068617665207468652073616d65206c656e6774685f82015250565b5f6130a760208361246a565b91506130b282613073565b602082019050919050565b5f6020820190508181035f8301526130d48161309b565b9050919050565b5f81905092915050565b5f6130ef82612460565b6130f981856130db565b935061310981856020860161247a565b80840191505092915050565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000005f82015250565b5f6131496005836130db565b915061315482613115565b600582019050919050565b5f61316a82856130e5565b915061317682846130e5565b91506131818261313d565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f6131b18261318d565b6131bb8185613197565b93506131cb81856020860161247a565b6131d481612488565b840191505092915050565b5f6080820190506131f25f83018761257e565b6131ff602083018661257e565b61320c604083018561260e565b818103606083015261321e81846131a7565b905095945050505050565b5f81519050613237816123d8565b92915050565b5f60208284031215613252576132516123a5565b5b5f61325f84828501613229565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6132cc826124f0565b91506132d7836124f0565b92508282039050818111156132ef576132ee613295565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220a8db1c5a4b42baf7570e0419c5cd77aca38cfd4d8f4a71f3f39365946e38f05264736f6c63430008190033

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

0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000e608ad1b46c36c0d8d75d856cbe846bcce12a3f8000000000000000000000000000000000000000000000000000000000000006568747470733a2f2f726f73652d666173742d706172726f74666973682d3339312e6d7970696e6174612e636c6f75642f697066732f516d633262757275566e633570626758626464537a5a42784e74786f4a7335474772754d483645353459534751532f2c000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : baseURI (string): https://rose-fast-parrotfish-391.mypinata.cloud/ipfs/Qmc2buruVnc5pbgXbddSzZBxNtxoJs5GGruMH6E54YSGQS/,
Arg [1] : _fundWallet (address): 0xE608aD1B46c36c0d8d75d856cbE846bCCe12a3f8

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 000000000000000000000000e608ad1b46c36c0d8d75d856cbe846bcce12a3f8
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000065
Arg [3] : 68747470733a2f2f726f73652d666173742d706172726f74666973682d333931
Arg [4] : 2e6d7970696e6174612e636c6f75642f697066732f516d633262757275566e63
Arg [5] : 3570626758626464537a5a42784e74786f4a7335474772754d48364535345953
Arg [6] : 4751532f2c000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

66074:1992:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60017:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42905:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44077:158;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43896:115;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60661:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44746:588;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60325:260;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45405:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66880:342;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60842:231;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67230:173;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67533:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42718:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66190:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42443:213;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30121:103;;;;;;;;;;;;;:::i;:::-;;66482:386;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67940:123;;;:::i;:::-;;29446:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43065:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44307:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45610:211;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67643:289;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44524:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30379:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60017:224;60119:4;60158:35;60143:50;;;:11;:50;;;;:90;;;;60197:36;60221:11;60197:23;:36::i;:::-;60143:90;60136:97;;60017:224;;;:::o;42905:91::-;42950:13;42983:5;42976:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42905:91;:::o;44077:158::-;44144:7;44164:22;44178:7;44164:13;:22::i;:::-;;44206:21;44219:7;44206:12;:21::i;:::-;44199:28;;44077:158;;;:::o;43896:115::-;43968:35;43977:2;43981:7;43990:12;:10;:12::i;:::-;43968:8;:35::i;:::-;43896:115;;:::o;60661:104::-;60713:7;60740:10;:17;;;;60733:24;;60661:104;:::o;44746:588::-;44855:1;44841:16;;:2;:16;;;44837:89;;44911:1;44881:33;;;;;;;;;;;:::i;:::-;;;;;;;;44837:89;45147:21;45171:34;45179:2;45183:7;45192:12;:10;:12::i;:::-;45171:7;:34::i;:::-;45147:58;;45237:4;45220:21;;:13;:21;;;45216:111;;45286:4;45292:7;45301:13;45265:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;45216:111;44826:508;44746:588;;;:::o;60325:260::-;60413:7;60446:16;60456:5;60446:9;:16::i;:::-;60437:5;:25;60433:101;;60509:5;60516;60486:36;;;;;;;;;;;;:::i;:::-;;;;;;;;60433:101;60551:12;:19;60564:5;60551:19;;;;;;;;;;;;;;;:26;60571:5;60551:26;;;;;;;;;;;;60544:33;;60325:260;;;;:::o;45405:134::-;45492:39;45509:4;45515:2;45519:7;45492:39;;;;;;;;;;;;:16;:39::i;:::-;45405:134;;;:::o;66880:342::-;66939:16;66968:18;66989:17;66999:6;66989:9;:17::i;:::-;66968:38;;67019:25;67061:10;67047:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67019:53;;67087:9;67083:106;67102:10;67098:1;:14;67083:106;;;67147:30;67167:6;67175:1;67147:19;:30::i;:::-;67133:8;67142:1;67133:11;;;;;;;;:::i;:::-;;;;;;;:44;;;;;67114:3;;;;;;;67083:106;;;;67206:8;67199:15;;;;66880:342;;;:::o;60842:231::-;60908:7;60941:13;:11;:13::i;:::-;60932:5;:22;60928:103;;61009:1;61013:5;60978:41;;;;;;;;;;;;:::i;:::-;;;;;;;;60928:103;61048:10;61059:5;61048:17;;;;;;;;:::i;:::-;;;;;;;;;;61041:24;;60842:231;;;:::o;67230:173::-;29332:13;:11;:13::i;:::-;67335:1:::1;67312:25;;:11;:25;;::::0;67304:56:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;67384:11;67371:10;;:24;;;;;;;;;;;;;;;;;;67230:173:::0;:::o;67533:102::-;29332:13;:11;:13::i;:::-;67620:7:::1;67604:13;:23;;;;;;:::i;:::-;;67533:102:::0;:::o;42718:120::-;42781:7;42808:22;42822:7;42808:13;:22::i;:::-;42801:29;;42718:120;;;:::o;66190:25::-;;;;;;;;;;;;;:::o;42443:213::-;42506:7;42547:1;42530:19;;:5;:19;;;42526:89;;42600:1;42573:30;;;;;;;;;;;:::i;:::-;;;;;;;;42526:89;42632:9;:16;42642:5;42632:16;;;;;;;;;;;;;;;;42625:23;;42443:213;;;:::o;30121:103::-;29332:13;:11;:13::i;:::-;30186:30:::1;30213:1;30186:18;:30::i;:::-;30121:103::o:0;66482:386::-;29332:13;:11;:13::i;:::-;66577:16:::1;66596:2;:9;66577:28;;66636:8;:15;66624:8;:27;66616:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;66706:9;66701:160;66725:8;66721:1;:12;66701:160;;;66780:1;66763:19;;:2;66766:1;66763:5;;;;;;;;:::i;:::-;;;;;;;;:19;;::::0;66755:50:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;66820:29;66830:2;66833:1;66830:5;;;;;;;;:::i;:::-;;;;;;;;66837:8;66846:1;66837:11;;;;;;;;:::i;:::-;;;;;;;;66820:9;:29::i;:::-;66735:3;;;;;;;66701:160;;;;66566:302;66482:386:::0;;:::o;67940:123::-;29332:13;:11;:13::i;:::-;68015:10:::1;;;;;;;;;;;68007:24;;:47;68032:21;68007:47;;;;;;;;;;;;;;;;;;;;;;;67999:56;;;::::0;::::1;;67940:123::o:0;29446:87::-;29492:7;29519:6;;;;;;;;;;;29512:13;;29446:87;:::o;43065:95::-;43112:13;43145:7;43138:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43065:95;:::o;44307:146::-;44393:52;44412:12;:10;:12::i;:::-;44426:8;44436;44393:18;:52::i;:::-;44307:146;;:::o;45610:211::-;45724:31;45737:4;45743:2;45747:7;45724:12;:31::i;:::-;45766:47;45789:4;45795:2;45799:7;45808:4;45766:22;:47::i;:::-;45610:211;;;;:::o;67643:289::-;67716:13;67742:22;67756:7;67742:13;:22::i;:::-;;67777:21;67801:10;:8;:10::i;:::-;67777:34;;67853:1;67835:7;67829:21;:25;:95;;;;;;;;;;;;;;;;;67881:7;67890:18;:7;:16;:18::i;:::-;67864:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;67829:95;67822:102;;;67643:289;;;:::o;44524:155::-;44612:4;44636:18;:25;44655:5;44636:25;;;;;;;;;;;;;;;:35;44662:8;44636:35;;;;;;;;;;;;;;;;;;;;;;;;;44629:42;;44524:155;;;;:::o;30379:220::-;29332:13;:11;:13::i;:::-;30484:1:::1;30464:22;;:8;:22;;::::0;30460:93:::1;;30538:1;30510:31;;;;;;;;;;;:::i;:::-;;;;;;;;30460:93;30563:28;30582:8;30563:18;:28::i;:::-;30379:220:::0;:::o;42074:305::-;42176:4;42228:25;42213:40;;;:11;:40;;;;:105;;;;42285:33;42270:48;;;:11;:48;;;;42213:105;:158;;;;42335:36;42359:11;42335:23;:36::i;:::-;42213:158;42193:178;;42074:305;;;:::o;57052:247::-;57115:7;57135:13;57151:17;57160:7;57151:8;:17::i;:::-;57135:33;;57200:1;57183:19;;:5;:19;;;57179:90;;57249:7;57226:31;;;;;;;;;;;:::i;:::-;;;;;;;;57179:90;57286:5;57279:12;;;57052:247;;;:::o;46583:129::-;46653:7;46680:15;:24;46696:7;46680:24;;;;;;;;;;;;;;;;;;;;;46673:31;;46583:129;;;:::o;27455:98::-;27508:7;27535:10;27528:17;;27455:98;:::o;55284:122::-;55365:33;55374:2;55378:7;55387:4;55393;55365:8;:33::i;:::-;55284:122;;;:::o;61134:640::-;61229:7;61249:21;61273:32;61287:2;61291:7;61300:4;61273:13;:32::i;:::-;61249:56;;61347:1;61322:27;;:13;:27;;;61318:214;;61366:40;61398:7;61366:31;:40::i;:::-;61318:214;;;61445:2;61428:19;;:13;:19;;;61424:108;;61464:56;61497:13;61512:7;61464:32;:56::i;:::-;61424:108;61318:214;61560:1;61546:16;;:2;:16;;;61542:192;;61579:45;61616:7;61579:36;:45::i;:::-;61542:192;;;61663:2;61646:19;;:13;:19;;;61642:92;;61682:40;61710:2;61714:7;61682:27;:40::i;:::-;61642:92;61542:192;61753:13;61746:20;;;61134:640;;;;;:::o;29611:166::-;29682:12;:10;:12::i;:::-;29671:23;;:7;:5;:7::i;:::-;:23;;;29667:103;;29745:12;:10;:12::i;:::-;29718:40;;;;;;;;;;;:::i;:::-;;;;;;;;29667:103;29611:166::o;30759:191::-;30833:16;30852:6;;;;;;;;;;;30833:25;;30878:8;30869:6;;:17;;;;;;;;;;;;;;;;;;30933:8;30902:40;;30923:8;30902:40;;;;;;;;;;;;30822:128;30759:191;:::o;51403:102::-;51471:26;51481:2;51485:7;51471:26;;;;;;;;;;;;:9;:26::i;:::-;51403:102;;:::o;56491:318::-;56619:1;56599:22;;:8;:22;;;56595:93;;56667:8;56645:31;;;;;;;;;;;:::i;:::-;;;;;;;;56595:93;56736:8;56698:18;:25;56717:5;56698:25;;;;;;;;;;;;;;;:35;56724:8;56698:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;56782:8;56760:41;;56775:5;56760:41;;;56792:8;56760:41;;;;;;:::i;:::-;;;;;;;;56491:318;;;:::o;57849:799::-;57983:1;57966:2;:14;;;:18;57962:679;;;58021:2;58005:36;;;58042:12;:10;:12::i;:::-;58056:4;58062:7;58071:4;58005:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;58001:629;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58336:1;58319:6;:13;:18;58315:300;;58391:2;58369:25;;;;;;;;;;;:::i;:::-;;;;;;;;58315:300;58565:6;58559:13;58550:6;58546:2;58542:15;58535:38;58001:629;58134:41;;;58124:51;;;:6;:51;;;;58120:132;;58229:2;58207:25;;;;;;;;;;;:::i;:::-;;;;;;;;58120:132;58077:190;57962:679;57849:799;;;;:::o;67411:114::-;67471:13;67504;67497:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67411:114;:::o;24225:718::-;24281:13;24332:14;24369:1;24349:17;24360:5;24349:10;:17::i;:::-;:21;24332:38;;24385:20;24419:6;24408:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24385:41;;24441:11;24570:6;24566:2;24562:15;24554:6;24550:28;24543:35;;24607:290;24614:4;24607:290;;;24639:5;;;;;;;;24781:10;24776:2;24769:5;24765:14;24760:32;24755:3;24747:46;24839:2;24830:11;;;;;;:::i;:::-;;;;;24873:1;24864:5;:10;24607:290;24860:21;24607:290;24918:6;24911:13;;;;;24225:718;;;:::o;33734:148::-;33810:4;33849:25;33834:40;;;:11;:40;;;;33827:47;;33734:148;;;:::o;46345:117::-;46411:7;46438;:16;46446:7;46438:16;;;;;;;;;;;;;;;;;;;;;46431:23;;46345:117;;;:::o;55594:678::-;55756:9;:31;;;;55785:1;55769:18;;:4;:18;;;;55756:31;55752:471;;;55804:13;55820:22;55834:7;55820:13;:22::i;:::-;55804:38;;55989:1;55973:18;;:4;:18;;;;:35;;;;;56004:4;55995:13;;:5;:13;;;;55973:35;:69;;;;;56013:29;56030:5;56037:4;56013:16;:29::i;:::-;56012:30;55973:69;55969:144;;;56092:4;56070:27;;;;;;;;;;;:::i;:::-;;;;;;;;55969:144;56133:9;56129:83;;;56188:7;56184:2;56168:28;;56177:5;56168:28;;;;;;;;;;;;56129:83;55789:434;55752:471;56262:2;56235:15;:24;56251:7;56235:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;55594:678;;;;:::o;49545:824::-;49631:7;49651:12;49666:17;49675:7;49666:8;:17::i;:::-;49651:32;;49762:1;49746:18;;:4;:18;;;49742:88;;49781:37;49798:4;49804;49810:7;49781:16;:37::i;:::-;49742:88;49893:1;49877:18;;:4;:18;;;49873:263;;49995:48;50012:1;50016:7;50033:1;50037:5;49995:8;:48::i;:::-;50108:1;50089:9;:15;50099:4;50089:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;49873:263;50166:1;50152:16;;:2;:16;;;50148:111;;50231:1;50214:9;:13;50224:2;50214:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;50148:111;50290:2;50271:7;:16;50279:7;50271:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;50329:7;50325:2;50310:27;;50319:4;50310:27;;;;;;;;;;;;50357:4;50350:11;;;49545:824;;;;;:::o;62494:164::-;62598:10;:17;;;;62571:15;:24;62587:7;62571:24;;;;;;;;;;;:44;;;;62626:10;62642:7;62626:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62494:164;:::o;63285:977::-;63551:22;63576:15;63586:4;63576:9;:15::i;:::-;63551:40;;63602:18;63623:17;:26;63641:7;63623:26;;;;;;;;;;;;63602:47;;63770:14;63756:10;:28;63752:328;;63801:19;63823:12;:18;63836:4;63823:18;;;;;;;;;;;;;;;:34;63842:14;63823:34;;;;;;;;;;;;63801:56;;63907:11;63874:12;:18;63887:4;63874:18;;;;;;;;;;;;;;;:30;63893:10;63874:30;;;;;;;;;;;:44;;;;64024:10;63991:17;:30;64009:11;63991:30;;;;;;;;;;;:43;;;;63786:294;63752:328;64176:17;:26;64194:7;64176:26;;;;;;;;;;;64169:33;;;64220:12;:18;64233:4;64220:18;;;;;;;;;;;;;;;:34;64239:14;64220:34;;;;;;;;;;;64213:41;;;63366:896;;63285:977;;:::o;64557:1079::-;64810:22;64855:1;64835:10;:17;;;;:21;;;;:::i;:::-;64810:46;;64867:18;64888:15;:24;64904:7;64888:24;;;;;;;;;;;;64867:45;;65239:19;65261:10;65272:14;65261:26;;;;;;;;:::i;:::-;;;;;;;;;;65239:48;;65325:11;65300:10;65311;65300:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;65436:10;65405:15;:28;65421:11;65405:28;;;;;;;;;;;:41;;;;65577:15;:24;65593:7;65577:24;;;;;;;;;;;65570:31;;;65612:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;64628:1008;;;64557:1079;:::o;62075:218::-;62160:14;62193:1;62177:13;62187:2;62177:9;:13::i;:::-;:17;;;;:::i;:::-;62160:34;;62232:7;62205:12;:16;62218:2;62205:16;;;;;;;;;;;;;;;:24;62222:6;62205:24;;;;;;;;;;;:34;;;;62279:6;62250:17;:26;62268:7;62250:26;;;;;;;;;;;:35;;;;62149:144;62075:218;;:::o;51732:185::-;51827:18;51833:2;51837:7;51827:5;:18::i;:::-;51856:53;51887:1;51891:2;51895:7;51904:4;51856:22;:53::i;:::-;51732:185;;;:::o;20629:948::-;20682:7;20702:14;20719:1;20702:18;;20769:8;20760:5;:17;20756:106;;20807:8;20798:17;;;;;;:::i;:::-;;;;;20844:2;20834:12;;;;20756:106;20889:8;20880:5;:17;20876:106;;20927:8;20918:17;;;;;;:::i;:::-;;;;;20964:2;20954:12;;;;20876:106;21009:8;21000:5;:17;20996:106;;21047:8;21038:17;;;;;;:::i;:::-;;;;;21084:2;21074:12;;;;20996:106;21129:7;21120:5;:16;21116:103;;21166:7;21157:16;;;;;;:::i;:::-;;;;;21202:1;21192:11;;;;21116:103;21246:7;21237:5;:16;21233:103;;21283:7;21274:16;;;;;;:::i;:::-;;;;;21319:1;21309:11;;;;21233:103;21363:7;21354:5;:16;21350:103;;21400:7;21391:16;;;;;;:::i;:::-;;;;;21436:1;21426:11;;;;21350:103;21480:7;21471:5;:16;21467:68;;21518:1;21508:11;;;;21467:68;21563:6;21556:13;;;20629:948;;;:::o;47752:376::-;47865:38;47879:5;47886:7;47895;47865:13;:38::i;:::-;47860:261;;47941:1;47924:19;;:5;:19;;;47920:190;;47994:7;47971:31;;;;;;;;;;;:::i;:::-;;;;;;;;47920:190;48077:7;48086;48050:44;;;;;;;;;;;;:::i;:::-;;;;;;;;47860:261;47752:376;;;:::o;50705:335::-;50787:1;50773:16;;:2;:16;;;50769:89;;50843:1;50813:33;;;;;;;;;;;:::i;:::-;;;;;;;;50769:89;50868:21;50892:32;50900:2;50904:7;50921:1;50892:7;:32::i;:::-;50868:56;;50964:1;50939:27;;:13;:27;;;50935:98;;51018:1;50990:31;;;;;;;;;;;:::i;:::-;;;;;;;;50935:98;50758:282;50705:335;;:::o;47032:276::-;47135:4;47191:1;47172:21;;:7;:21;;;;:128;;;;;47220:7;47211:16;;:5;:16;;;:52;;;;47231:32;47248:5;47255:7;47231:16;:32::i;:::-;47211:52;:88;;;;47292:7;47267:32;;:21;47280:7;47267:12;:21::i;:::-;:32;;;47211:88;47172:128;47152:148;;47032:276;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:139::-;1887:6;1882:3;1877;1871:23;1928:1;1919:6;1914:3;1910:16;1903:27;1798:139;;;:::o;1943:102::-;1984:6;2035:2;2031:7;2026:2;2019:5;2015:14;2011:28;2001:38;;1943:102;;;:::o;2051:377::-;2139:3;2167:39;2200:5;2167:39;:::i;:::-;2222:71;2286:6;2281:3;2222:71;:::i;:::-;2215:78;;2302:65;2360:6;2355:3;2348:4;2341:5;2337:16;2302:65;:::i;:::-;2392:29;2414:6;2392:29;:::i;:::-;2387:3;2383:39;2376:46;;2143:285;2051:377;;;;:::o;2434:313::-;2547:4;2585:2;2574:9;2570:18;2562:26;;2634:9;2628:4;2624:20;2620:1;2609:9;2605:17;2598:47;2662:78;2735:4;2726:6;2662:78;:::i;:::-;2654:86;;2434:313;;;;:::o;2753:77::-;2790:7;2819:5;2808:16;;2753:77;;;:::o;2836:122::-;2909:24;2927:5;2909:24;:::i;:::-;2902:5;2899:35;2889:63;;2948:1;2945;2938:12;2889:63;2836:122;:::o;2964:139::-;3010:5;3048:6;3035:20;3026:29;;3064:33;3091:5;3064:33;:::i;:::-;2964:139;;;;:::o;3109:329::-;3168:6;3217:2;3205:9;3196:7;3192:23;3188:32;3185:119;;;3223:79;;:::i;:::-;3185:119;3343:1;3368:53;3413:7;3404:6;3393:9;3389:22;3368:53;:::i;:::-;3358:63;;3314:117;3109:329;;;;:::o;3444:126::-;3481:7;3521:42;3514:5;3510:54;3499:65;;3444:126;;;:::o;3576:96::-;3613:7;3642:24;3660:5;3642:24;:::i;:::-;3631:35;;3576:96;;;:::o;3678:118::-;3765:24;3783:5;3765:24;:::i;:::-;3760:3;3753:37;3678:118;;:::o;3802:222::-;3895:4;3933:2;3922:9;3918:18;3910:26;;3946:71;4014:1;4003:9;3999:17;3990:6;3946:71;:::i;:::-;3802:222;;;;:::o;4030:122::-;4103:24;4121:5;4103:24;:::i;:::-;4096:5;4093:35;4083:63;;4142:1;4139;4132:12;4083:63;4030:122;:::o;4158:139::-;4204:5;4242:6;4229:20;4220:29;;4258:33;4285:5;4258:33;:::i;:::-;4158:139;;;;:::o;4303:474::-;4371:6;4379;4428:2;4416:9;4407:7;4403:23;4399:32;4396:119;;;4434:79;;:::i;:::-;4396:119;4554:1;4579:53;4624:7;4615:6;4604:9;4600:22;4579:53;:::i;:::-;4569:63;;4525:117;4681:2;4707:53;4752:7;4743:6;4732:9;4728:22;4707:53;:::i;:::-;4697:63;;4652:118;4303:474;;;;;:::o;4783:118::-;4870:24;4888:5;4870:24;:::i;:::-;4865:3;4858:37;4783:118;;:::o;4907:222::-;5000:4;5038:2;5027:9;5023:18;5015:26;;5051:71;5119:1;5108:9;5104:17;5095:6;5051:71;:::i;:::-;4907:222;;;;:::o;5135:619::-;5212:6;5220;5228;5277:2;5265:9;5256:7;5252:23;5248:32;5245:119;;;5283:79;;:::i;:::-;5245:119;5403:1;5428:53;5473:7;5464:6;5453:9;5449:22;5428:53;:::i;:::-;5418:63;;5374:117;5530:2;5556:53;5601:7;5592:6;5581:9;5577:22;5556:53;:::i;:::-;5546:63;;5501:118;5658:2;5684:53;5729:7;5720:6;5709:9;5705:22;5684:53;:::i;:::-;5674:63;;5629:118;5135:619;;;;;:::o;5760:329::-;5819:6;5868:2;5856:9;5847:7;5843:23;5839:32;5836:119;;;5874:79;;:::i;:::-;5836:119;5994:1;6019:53;6064:7;6055:6;6044:9;6040:22;6019:53;:::i;:::-;6009:63;;5965:117;5760:329;;;;:::o;6095:114::-;6162:6;6196:5;6190:12;6180:22;;6095:114;;;:::o;6215:184::-;6314:11;6348:6;6343:3;6336:19;6388:4;6383:3;6379:14;6364:29;;6215:184;;;;:::o;6405:132::-;6472:4;6495:3;6487:11;;6525:4;6520:3;6516:14;6508:22;;6405:132;;;:::o;6543:108::-;6620:24;6638:5;6620:24;:::i;:::-;6615:3;6608:37;6543:108;;:::o;6657:179::-;6726:10;6747:46;6789:3;6781:6;6747:46;:::i;:::-;6825:4;6820:3;6816:14;6802:28;;6657:179;;;;:::o;6842:113::-;6912:4;6944;6939:3;6935:14;6927:22;;6842:113;;;:::o;6991:732::-;7110:3;7139:54;7187:5;7139:54;:::i;:::-;7209:86;7288:6;7283:3;7209:86;:::i;:::-;7202:93;;7319:56;7369:5;7319:56;:::i;:::-;7398:7;7429:1;7414:284;7439:6;7436:1;7433:13;7414:284;;;7515:6;7509:13;7542:63;7601:3;7586:13;7542:63;:::i;:::-;7535:70;;7628:60;7681:6;7628:60;:::i;:::-;7618:70;;7474:224;7461:1;7458;7454:9;7449:14;;7414:284;;;7418:14;7714:3;7707:10;;7115:608;;;6991:732;;;;:::o;7729:373::-;7872:4;7910:2;7899:9;7895:18;7887:26;;7959:9;7953:4;7949:20;7945:1;7934:9;7930:17;7923:47;7987:108;8090:4;8081:6;7987:108;:::i;:::-;7979:116;;7729:373;;;;:::o;8108:117::-;8217:1;8214;8207:12;8231:117;8340:1;8337;8330:12;8354:180;8402:77;8399:1;8392:88;8499:4;8496:1;8489:15;8523:4;8520:1;8513:15;8540:281;8623:27;8645:4;8623:27;:::i;:::-;8615:6;8611:40;8753:6;8741:10;8738:22;8717:18;8705:10;8702:34;8699:62;8696:88;;;8764:18;;:::i;:::-;8696:88;8804:10;8800:2;8793:22;8583:238;8540:281;;:::o;8827:129::-;8861:6;8888:20;;:::i;:::-;8878:30;;8917:33;8945:4;8937:6;8917:33;:::i;:::-;8827:129;;;:::o;8962:308::-;9024:4;9114:18;9106:6;9103:30;9100:56;;;9136:18;;:::i;:::-;9100:56;9174:29;9196:6;9174:29;:::i;:::-;9166:37;;9258:4;9252;9248:15;9240:23;;8962:308;;;:::o;9276:148::-;9374:6;9369:3;9364;9351:30;9415:1;9406:6;9401:3;9397:16;9390:27;9276:148;;;:::o;9430:425::-;9508:5;9533:66;9549:49;9591:6;9549:49;:::i;:::-;9533:66;:::i;:::-;9524:75;;9622:6;9615:5;9608:21;9660:4;9653:5;9649:16;9698:3;9689:6;9684:3;9680:16;9677:25;9674:112;;;9705:79;;:::i;:::-;9674:112;9795:54;9842:6;9837:3;9832;9795:54;:::i;:::-;9514:341;9430:425;;;;;:::o;9875:340::-;9931:5;9980:3;9973:4;9965:6;9961:17;9957:27;9947:122;;9988:79;;:::i;:::-;9947:122;10105:6;10092:20;10130:79;10205:3;10197:6;10190:4;10182:6;10178:17;10130:79;:::i;:::-;10121:88;;9937:278;9875:340;;;;:::o;10221:509::-;10290:6;10339:2;10327:9;10318:7;10314:23;10310:32;10307:119;;;10345:79;;:::i;:::-;10307:119;10493:1;10482:9;10478:17;10465:31;10523:18;10515:6;10512:30;10509:117;;;10545:79;;:::i;:::-;10509:117;10650:63;10705:7;10696:6;10685:9;10681:22;10650:63;:::i;:::-;10640:73;;10436:287;10221:509;;;;:::o;10736:311::-;10813:4;10903:18;10895:6;10892:30;10889:56;;;10925:18;;:::i;:::-;10889:56;10975:4;10967:6;10963:17;10955:25;;11035:4;11029;11025:15;11017:23;;10736:311;;;:::o;11053:117::-;11162:1;11159;11152:12;11193:710;11289:5;11314:81;11330:64;11387:6;11330:64;:::i;:::-;11314:81;:::i;:::-;11305:90;;11415:5;11444:6;11437:5;11430:21;11478:4;11471:5;11467:16;11460:23;;11531:4;11523:6;11519:17;11511:6;11507:30;11560:3;11552:6;11549:15;11546:122;;;11579:79;;:::i;:::-;11546:122;11694:6;11677:220;11711:6;11706:3;11703:15;11677:220;;;11786:3;11815:37;11848:3;11836:10;11815:37;:::i;:::-;11810:3;11803:50;11882:4;11877:3;11873:14;11866:21;;11753:144;11737:4;11732:3;11728:14;11721:21;;11677:220;;;11681:21;11295:608;;11193:710;;;;;:::o;11926:370::-;11997:5;12046:3;12039:4;12031:6;12027:17;12023:27;12013:122;;12054:79;;:::i;:::-;12013:122;12171:6;12158:20;12196:94;12286:3;12278:6;12271:4;12263:6;12259:17;12196:94;:::i;:::-;12187:103;;12003:293;11926:370;;;;:::o;12302:311::-;12379:4;12469:18;12461:6;12458:30;12455:56;;;12491:18;;:::i;:::-;12455:56;12541:4;12533:6;12529:17;12521:25;;12601:4;12595;12591:15;12583:23;;12302:311;;;:::o;12636:710::-;12732:5;12757:81;12773:64;12830:6;12773:64;:::i;:::-;12757:81;:::i;:::-;12748:90;;12858:5;12887:6;12880:5;12873:21;12921:4;12914:5;12910:16;12903:23;;12974:4;12966:6;12962:17;12954:6;12950:30;13003:3;12995:6;12992:15;12989:122;;;13022:79;;:::i;:::-;12989:122;13137:6;13120:220;13154:6;13149:3;13146:15;13120:220;;;13229:3;13258:37;13291:3;13279:10;13258:37;:::i;:::-;13253:3;13246:50;13325:4;13320:3;13316:14;13309:21;;13196:144;13180:4;13175:3;13171:14;13164:21;;13120:220;;;13124:21;12738:608;;12636:710;;;;;:::o;13369:370::-;13440:5;13489:3;13482:4;13474:6;13470:17;13466:27;13456:122;;13497:79;;:::i;:::-;13456:122;13614:6;13601:20;13639:94;13729:3;13721:6;13714:4;13706:6;13702:17;13639:94;:::i;:::-;13630:103;;13446:293;13369:370;;;;:::o;13745:894::-;13863:6;13871;13920:2;13908:9;13899:7;13895:23;13891:32;13888:119;;;13926:79;;:::i;:::-;13888:119;14074:1;14063:9;14059:17;14046:31;14104:18;14096:6;14093:30;14090:117;;;14126:79;;:::i;:::-;14090:117;14231:78;14301:7;14292:6;14281:9;14277:22;14231:78;:::i;:::-;14221:88;;14017:302;14386:2;14375:9;14371:18;14358:32;14417:18;14409:6;14406:30;14403:117;;;14439:79;;:::i;:::-;14403:117;14544:78;14614:7;14605:6;14594:9;14590:22;14544:78;:::i;:::-;14534:88;;14329:303;13745:894;;;;;:::o;14645:116::-;14715:21;14730:5;14715:21;:::i;:::-;14708:5;14705:32;14695:60;;14751:1;14748;14741:12;14695:60;14645:116;:::o;14767:133::-;14810:5;14848:6;14835:20;14826:29;;14864:30;14888:5;14864:30;:::i;:::-;14767:133;;;;:::o;14906:468::-;14971:6;14979;15028:2;15016:9;15007:7;15003:23;14999:32;14996:119;;;15034:79;;:::i;:::-;14996:119;15154:1;15179:53;15224:7;15215:6;15204:9;15200:22;15179:53;:::i;:::-;15169:63;;15125:117;15281:2;15307:50;15349:7;15340:6;15329:9;15325:22;15307:50;:::i;:::-;15297:60;;15252:115;14906:468;;;;;:::o;15380:307::-;15441:4;15531:18;15523:6;15520:30;15517:56;;;15553:18;;:::i;:::-;15517:56;15591:29;15613:6;15591:29;:::i;:::-;15583:37;;15675:4;15669;15665:15;15657:23;;15380:307;;;:::o;15693:423::-;15770:5;15795:65;15811:48;15852:6;15811:48;:::i;:::-;15795:65;:::i;:::-;15786:74;;15883:6;15876:5;15869:21;15921:4;15914:5;15910:16;15959:3;15950:6;15945:3;15941:16;15938:25;15935:112;;;15966:79;;:::i;:::-;15935:112;16056:54;16103:6;16098:3;16093;16056:54;:::i;:::-;15776:340;15693:423;;;;;:::o;16135:338::-;16190:5;16239:3;16232:4;16224:6;16220:17;16216:27;16206:122;;16247:79;;:::i;:::-;16206:122;16364:6;16351:20;16389:78;16463:3;16455:6;16448:4;16440:6;16436:17;16389:78;:::i;:::-;16380:87;;16196:277;16135:338;;;;:::o;16479:943::-;16574:6;16582;16590;16598;16647:3;16635:9;16626:7;16622:23;16618:33;16615:120;;;16654:79;;:::i;:::-;16615:120;16774:1;16799:53;16844:7;16835:6;16824:9;16820:22;16799:53;:::i;:::-;16789:63;;16745:117;16901:2;16927:53;16972:7;16963:6;16952:9;16948:22;16927:53;:::i;:::-;16917:63;;16872:118;17029:2;17055:53;17100:7;17091:6;17080:9;17076:22;17055:53;:::i;:::-;17045:63;;17000:118;17185:2;17174:9;17170:18;17157:32;17216:18;17208:6;17205:30;17202:117;;;17238:79;;:::i;:::-;17202:117;17343:62;17397:7;17388:6;17377:9;17373:22;17343:62;:::i;:::-;17333:72;;17128:287;16479:943;;;;;;;:::o;17428:474::-;17496:6;17504;17553:2;17541:9;17532:7;17528:23;17524:32;17521:119;;;17559:79;;:::i;:::-;17521:119;17679:1;17704:53;17749:7;17740:6;17729:9;17725:22;17704:53;:::i;:::-;17694:63;;17650:117;17806:2;17832:53;17877:7;17868:6;17857:9;17853:22;17832:53;:::i;:::-;17822:63;;17777:118;17428:474;;;;;:::o;17908:180::-;17956:77;17953:1;17946:88;18053:4;18050:1;18043:15;18077:4;18074:1;18067:15;18094:320;18138:6;18175:1;18169:4;18165:12;18155:22;;18222:1;18216:4;18212:12;18243:18;18233:81;;18299:4;18291:6;18287:17;18277:27;;18233:81;18361:2;18353:6;18350:14;18330:18;18327:38;18324:84;;18380:18;;:::i;:::-;18324:84;18145:269;18094:320;;;:::o;18420:442::-;18569:4;18607:2;18596:9;18592:18;18584:26;;18620:71;18688:1;18677:9;18673:17;18664:6;18620:71;:::i;:::-;18701:72;18769:2;18758:9;18754:18;18745:6;18701:72;:::i;:::-;18783;18851:2;18840:9;18836:18;18827:6;18783:72;:::i;:::-;18420:442;;;;;;:::o;18868:332::-;18989:4;19027:2;19016:9;19012:18;19004:26;;19040:71;19108:1;19097:9;19093:17;19084:6;19040:71;:::i;:::-;19121:72;19189:2;19178:9;19174:18;19165:6;19121:72;:::i;:::-;18868:332;;;;;:::o;19206:180::-;19254:77;19251:1;19244:88;19351:4;19348:1;19341:15;19375:4;19372:1;19365:15;19392:168;19532:20;19528:1;19520:6;19516:14;19509:44;19392:168;:::o;19566:366::-;19708:3;19729:67;19793:2;19788:3;19729:67;:::i;:::-;19722:74;;19805:93;19894:3;19805:93;:::i;:::-;19923:2;19918:3;19914:12;19907:19;;19566:366;;;:::o;19938:419::-;20104:4;20142:2;20131:9;20127:18;20119:26;;20191:9;20185:4;20181:20;20177:1;20166:9;20162:17;20155:47;20219:131;20345:4;20219:131;:::i;:::-;20211:139;;19938:419;;;:::o;20363:141::-;20412:4;20435:3;20427:11;;20458:3;20455:1;20448:14;20492:4;20489:1;20479:18;20471:26;;20363:141;;;:::o;20510:93::-;20547:6;20594:2;20589;20582:5;20578:14;20574:23;20564:33;;20510:93;;;:::o;20609:107::-;20653:8;20703:5;20697:4;20693:16;20672:37;;20609:107;;;;:::o;20722:393::-;20791:6;20841:1;20829:10;20825:18;20864:97;20894:66;20883:9;20864:97;:::i;:::-;20982:39;21012:8;21001:9;20982:39;:::i;:::-;20970:51;;21054:4;21050:9;21043:5;21039:21;21030:30;;21103:4;21093:8;21089:19;21082:5;21079:30;21069:40;;20798:317;;20722:393;;;;;:::o;21121:60::-;21149:3;21170:5;21163:12;;21121:60;;;:::o;21187:142::-;21237:9;21270:53;21288:34;21297:24;21315:5;21297:24;:::i;:::-;21288:34;:::i;:::-;21270:53;:::i;:::-;21257:66;;21187:142;;;:::o;21335:75::-;21378:3;21399:5;21392:12;;21335:75;;;:::o;21416:269::-;21526:39;21557:7;21526:39;:::i;:::-;21587:91;21636:41;21660:16;21636:41;:::i;:::-;21628:6;21621:4;21615:11;21587:91;:::i;:::-;21581:4;21574:105;21492:193;21416:269;;;:::o;21691:73::-;21736:3;21691:73;:::o;21770:189::-;21847:32;;:::i;:::-;21888:65;21946:6;21938;21932:4;21888:65;:::i;:::-;21823:136;21770:189;;:::o;21965:186::-;22025:120;22042:3;22035:5;22032:14;22025:120;;;22096:39;22133:1;22126:5;22096:39;:::i;:::-;22069:1;22062:5;22058:13;22049:22;;22025:120;;;21965:186;;:::o;22157:543::-;22258:2;22253:3;22250:11;22247:446;;;22292:38;22324:5;22292:38;:::i;:::-;22376:29;22394:10;22376:29;:::i;:::-;22366:8;22362:44;22559:2;22547:10;22544:18;22541:49;;;22580:8;22565:23;;22541:49;22603:80;22659:22;22677:3;22659:22;:::i;:::-;22649:8;22645:37;22632:11;22603:80;:::i;:::-;22262:431;;22247:446;22157:543;;;:::o;22706:117::-;22760:8;22810:5;22804:4;22800:16;22779:37;;22706:117;;;;:::o;22829:169::-;22873:6;22906:51;22954:1;22950:6;22942:5;22939:1;22935:13;22906:51;:::i;:::-;22902:56;22987:4;22981;22977:15;22967:25;;22880:118;22829:169;;;;:::o;23003:295::-;23079:4;23225:29;23250:3;23244:4;23225:29;:::i;:::-;23217:37;;23287:3;23284:1;23280:11;23274:4;23271:21;23263:29;;23003:295;;;;:::o;23303:1395::-;23420:37;23453:3;23420:37;:::i;:::-;23522:18;23514:6;23511:30;23508:56;;;23544:18;;:::i;:::-;23508:56;23588:38;23620:4;23614:11;23588:38;:::i;:::-;23673:67;23733:6;23725;23719:4;23673:67;:::i;:::-;23767:1;23791:4;23778:17;;23823:2;23815:6;23812:14;23840:1;23835:618;;;;24497:1;24514:6;24511:77;;;24563:9;24558:3;24554:19;24548:26;24539:35;;24511:77;24614:67;24674:6;24667:5;24614:67;:::i;:::-;24608:4;24601:81;24470:222;23805:887;;23835:618;23887:4;23883:9;23875:6;23871:22;23921:37;23953:4;23921:37;:::i;:::-;23980:1;23994:208;24008:7;24005:1;24002:14;23994:208;;;24087:9;24082:3;24078:19;24072:26;24064:6;24057:42;24138:1;24130:6;24126:14;24116:24;;24185:2;24174:9;24170:18;24157:31;;24031:4;24028:1;24024:12;24019:17;;23994:208;;;24230:6;24221:7;24218:19;24215:179;;;24288:9;24283:3;24279:19;24273:26;24331:48;24373:4;24365:6;24361:17;24350:9;24331:48;:::i;:::-;24323:6;24316:64;24238:156;24215:179;24440:1;24436;24428:6;24424:14;24420:22;24414:4;24407:36;23842:611;;;23805:887;;23395:1303;;;23303:1395;;:::o;24704:182::-;24844:34;24840:1;24832:6;24828:14;24821:58;24704:182;:::o;24892:366::-;25034:3;25055:67;25119:2;25114:3;25055:67;:::i;:::-;25048:74;;25131:93;25220:3;25131:93;:::i;:::-;25249:2;25244:3;25240:12;25233:19;;24892:366;;;:::o;25264:419::-;25430:4;25468:2;25457:9;25453:18;25445:26;;25517:9;25511:4;25507:20;25503:1;25492:9;25488:17;25481:47;25545:131;25671:4;25545:131;:::i;:::-;25537:139;;25264:419;;;:::o;25689:148::-;25791:11;25828:3;25813:18;;25689:148;;;;:::o;25843:390::-;25949:3;25977:39;26010:5;25977:39;:::i;:::-;26032:89;26114:6;26109:3;26032:89;:::i;:::-;26025:96;;26130:65;26188:6;26183:3;26176:4;26169:5;26165:16;26130:65;:::i;:::-;26220:6;26215:3;26211:16;26204:23;;25953:280;25843:390;;;;:::o;26239:155::-;26379:7;26375:1;26367:6;26363:14;26356:31;26239:155;:::o;26400:400::-;26560:3;26581:84;26663:1;26658:3;26581:84;:::i;:::-;26574:91;;26674:93;26763:3;26674:93;:::i;:::-;26792:1;26787:3;26783:11;26776:18;;26400:400;;;:::o;26806:701::-;27087:3;27109:95;27200:3;27191:6;27109:95;:::i;:::-;27102:102;;27221:95;27312:3;27303:6;27221:95;:::i;:::-;27214:102;;27333:148;27477:3;27333:148;:::i;:::-;27326:155;;27498:3;27491:10;;26806:701;;;;;:::o;27513:98::-;27564:6;27598:5;27592:12;27582:22;;27513:98;;;:::o;27617:168::-;27700:11;27734:6;27729:3;27722:19;27774:4;27769:3;27765:14;27750:29;;27617:168;;;;:::o;27791:373::-;27877:3;27905:38;27937:5;27905:38;:::i;:::-;27959:70;28022:6;28017:3;27959:70;:::i;:::-;27952:77;;28038:65;28096:6;28091:3;28084:4;28077:5;28073:16;28038:65;:::i;:::-;28128:29;28150:6;28128:29;:::i;:::-;28123:3;28119:39;28112:46;;27881:283;27791:373;;;;:::o;28170:640::-;28365:4;28403:3;28392:9;28388:19;28380:27;;28417:71;28485:1;28474:9;28470:17;28461:6;28417:71;:::i;:::-;28498:72;28566:2;28555:9;28551:18;28542:6;28498:72;:::i;:::-;28580;28648:2;28637:9;28633:18;28624:6;28580:72;:::i;:::-;28699:9;28693:4;28689:20;28684:2;28673:9;28669:18;28662:48;28727:76;28798:4;28789:6;28727:76;:::i;:::-;28719:84;;28170:640;;;;;;;:::o;28816:141::-;28872:5;28903:6;28897:13;28888:22;;28919:32;28945:5;28919:32;:::i;:::-;28816:141;;;;:::o;28963:349::-;29032:6;29081:2;29069:9;29060:7;29056:23;29052:32;29049:119;;;29087:79;;:::i;:::-;29049:119;29207:1;29232:63;29287:7;29278:6;29267:9;29263:22;29232:63;:::i;:::-;29222:73;;29178:127;28963:349;;;;:::o;29318:180::-;29366:77;29363:1;29356:88;29463:4;29460:1;29453:15;29487:4;29484:1;29477:15;29504:180;29552:77;29549:1;29542:88;29649:4;29646:1;29639:15;29673:4;29670:1;29663:15;29690:194;29730:4;29750:20;29768:1;29750:20;:::i;:::-;29745:25;;29784:20;29802:1;29784:20;:::i;:::-;29779:25;;29828:1;29825;29821:9;29813:17;;29852:1;29846:4;29843:11;29840:37;;;29857:18;;:::i;:::-;29840:37;29690:194;;;;:::o;29890:180::-;29938:77;29935:1;29928:88;30035:4;30032:1;30025:15;30059:4;30056:1;30049:15

Swarm Source

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