ETH Price: $3,458.03 (+2.07%)
Gas: 8 Gwei

Token

Matsuri (Matsuri)
 

Overview

Max Total Supply

222 Matsuri

Holders

102

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3 Matsuri
0xf5dcb2a47f738d8ba39f9fa2ddc7592f268a262a
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:
Matsuri

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-01-17
*/

/**
 *Submitted for verification at Etherscan.io on 2023-01-17
*/

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

/**
 *Submitted for verification at Etherscan.io on 2023-01-14
*/

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

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

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

// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721 token receiver.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721A.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the
     * ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    // =============================================================
    //                            IERC721
    // =============================================================

    /**
     * @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`,
     * 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 be 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,
        bytes calldata data
    ) external payable;

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom}
     * whenever possible.
     *
     * 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 payable;

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

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

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

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

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

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

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant _BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant _BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant _BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant _BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See {_packedOwnershipOf} implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view virtual returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        // Counter underflow is impossible as `_currentIndex` does not decrement,
        // and it is initialized to `_startTokenId()`.
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view virtual returns (uint256) {
        return _burnCounter;
    }

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal virtual {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

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

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

    /**
     * @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, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @dev Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around over time.
     */
    function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal virtual {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

    /**
     * @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) public payable virtual override {
        address owner = ownerOf(tokenId);

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId].value = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom}
     * for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @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 memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token IDs
     * are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token IDs
     * have been transferred. This includes minting.
     * And also called after one token has been burned.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns whether the call correctly returned the expected magic value.
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, quantity, '');
    }

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value) internal pure virtual returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.4;

contract Matsuri is ERC721A, Ownable, ReentrancyGuard {
    using Strings for uint256;

    string private _baseTokenURI;
    string public prerevealURL = 'ipfs://bafybeigdldl5ex2j64zqhzc3yg2gr3fzq2pibzi67flse7xw3q5hlkvugq/unrev';
    bool private _addJson = true;

    uint16 constant MAX_NFTS = 1555;

    //max quantity per each wave of sale
    uint16 private _maxQuantityPerWave;
    //price for each group per wave
    uint16 private _pricePerWave;

    //address arrays
    mapping (address => bool) private _WLaddress;
    bool constant _addressExists = true;

    //bool flags for wave
    bool private _wlSaleActive = false;
    bool private _publicSaleActive = false;

    mapping(address => uint) private _mintedPerAddress;

    mapping(uint => address) private _tokenToAddress;

    address private _withdrawalAddress;


    constructor() ERC721A("Matsuri", "Matsuri") Ownable() ReentrancyGuard() { }
    
    function mint(uint16 quantity) public payable nonReentrant {
        
        require(_totalMinted() + quantity <= MAX_NFTS, "Maximum amount of nfts reached");
    
        if (msg.sender != owner()) {

            require(quantity > 0 && quantity <= 10 && balanceOf(msg.sender) + quantity <= 10, "Your amount of nfts is limited to max.");

            MintInfo memory info = getMintInfo(msg.sender, quantity);

            require(info.publicSale || info.wlSale, "Sale is not active");
            
            require(info.priceToPay <= msg.value, "Ether value sent is not correct");

            _mintedPerAddress[msg.sender] += quantity;
        }

        _safeMint(msg.sender, quantity);

    }

	function tokenURI(uint256 tokenId) public override view returns (string memory)
    {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

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

    function getMintInfo(address buyer, uint16 quantity) public view returns (MintInfo memory) {

        uint16 freeMintsAllowed = 0;

        uint256 _price = 0.059 ether;

        if (_wlSaleActive == true) {
            _price = 0.039 ether;
        }

        uint16 quantityToPay = quantity;

        if(_mintedPerAddress[buyer] == 0) {
            quantityToPay = quantity - freeMintsAllowed;
        }

        return MintInfo(
            /* unitPrice */ _price,
            /* undiscountedPrice */ _price * quantity,
            /* priceToPay */ _price * quantityToPay,
            /* publicSale */ _publicSaleActive,
            /* wlSale */ _wlSaleActive,
            /* totalMints */ quantity,
            /* mintsToPay */ quantityToPay);
    }

	function _startTokenId() internal pure override returns (uint) {
		return 1;
	}

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

    function setBaseURI(string calldata baseURI) external onlyOwner {
        _baseTokenURI = baseURI;
    }

    function mintedCount(address addressToCheck) external view returns (uint) {
        return _mintedPerAddress[addressToCheck];
    }

    function setPublicSale(bool publicSaleActive) external onlyOwner {
        _wlSaleActive = false;
        _publicSaleActive = publicSaleActive;
    }

    function isPublicSale() public view returns (bool) {
        return _publicSaleActive;
    }   

    function setWLSale(bool wlSale) external onlyOwner {
        _wlSaleActive = wlSale;
    }
    
    function isWlSale() public view returns (bool) {
        return _wlSaleActive;
    }

    function addWLaddress(address wlAddress) external onlyOwner {
        _WLaddress[wlAddress] = _addressExists;
    }

    function addWLaddresses(address[] memory wlAddress) external onlyOwner {
        for (uint i=0; i<wlAddress.length; i++) {
            _WLaddress[wlAddress[i]] = true;
        }
    }

    function shouldAddJson(bool value) external onlyOwner {
        _addJson = value;
    }

    // addition function to airdrop for team
	function airdrop(address to, uint16 quantity) external onlyOwner {
        require(_totalMinted() + quantity <= MAX_NFTS, "Maximum amount of mints reached");
		_safeMint(to, quantity);
	}

    // function to withdraw to external
    function withdraw() external onlyOwner {
        uint balance = address(this).balance;
        payable(_withdrawalAddress).transfer(balance);
    }

    function setWithdrawalAddress(address addr) external onlyOwner {
        _withdrawalAddress = addr;
    }

    function setPrerevealUri(string calldata uri) external onlyOwner {
        prerevealURL = uri;
    }

    function getQuantity() public pure returns (uint256)
    {
        return 10;
    }

    function saleStarted() public view returns (bool) {
        if (_publicSaleActive || _wlSaleActive) {
            return true;
        }
        return false;
    }

    function allowedToMintGirl(address sender) public view returns (bool) {
        if (_mintedPerAddress[sender] > 2) {
            return true;
        } else {
            return false;
        }
    } 

    function isWlAddress(address sender) public view returns (bool) {
        if (_WLaddress[sender] == true) {
            return true;
        } else {
            return false;
        }
    }
}

struct MintInfo {
    uint256 unitPrice;
    uint256 undiscountedPrice;
    uint256 priceToPay;
    bool publicSale;
    bool wlSale;
    uint16 totalMints;
    uint16 mintsToPay;
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","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":"wlAddress","type":"address"}],"name":"addWLaddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"wlAddress","type":"address[]"}],"name":"addWLaddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint16","name":"quantity","type":"uint16"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"allowedToMintGirl","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"buyer","type":"address"},{"internalType":"uint16","name":"quantity","type":"uint16"}],"name":"getMintInfo","outputs":[{"components":[{"internalType":"uint256","name":"unitPrice","type":"uint256"},{"internalType":"uint256","name":"undiscountedPrice","type":"uint256"},{"internalType":"uint256","name":"priceToPay","type":"uint256"},{"internalType":"bool","name":"publicSale","type":"bool"},{"internalType":"bool","name":"wlSale","type":"bool"},{"internalType":"uint16","name":"totalMints","type":"uint16"},{"internalType":"uint16","name":"mintsToPay","type":"uint16"}],"internalType":"struct MintInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQuantity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","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":[],"name":"isPublicSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"isWlAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWlSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"quantity","type":"uint16"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addressToCheck","type":"address"}],"name":"mintedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"prerevealURL","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"payable","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":"payable","type":"function"},{"inputs":[],"name":"saleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"string","name":"uri","type":"string"}],"name":"setPrerevealUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"publicSaleActive","type":"bool"}],"name":"setPublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"wlSale","type":"bool"}],"name":"setWLSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setWithdrawalAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"shouldAddJson","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":"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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060800160405280604881526020016200407060489139600b90816200002e9190620004b5565b506001600c60006101000a81548160ff0219169083151502179055506000600e60006101000a81548160ff0219169083151502179055506000600e60016101000a81548160ff0219169083151502179055503480156200008d57600080fd5b506040518060400160405280600781526020017f4d617473757269000000000000000000000000000000000000000000000000008152506040518060400160405280600781526020017f4d6174737572690000000000000000000000000000000000000000000000000081525081600290816200010b9190620004b5565b5080600390816200011d9190620004b5565b506200012e6200016460201b60201c565b6000819055505050620001566200014a6200016d60201b60201c565b6200017560201b60201c565b60016009819055506200059c565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620002bd57607f821691505b602082108103620002d357620002d262000275565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200033d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002fe565b620003498683620002fe565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000396620003906200038a8462000361565b6200036b565b62000361565b9050919050565b6000819050919050565b620003b28362000375565b620003ca620003c1826200039d565b8484546200030b565b825550505050565b600090565b620003e1620003d2565b620003ee818484620003a7565b505050565b5b8181101562000416576200040a600082620003d7565b600181019050620003f4565b5050565b601f82111562000465576200042f81620002d9565b6200043a84620002ee565b810160208510156200044a578190505b620004626200045985620002ee565b830182620003f3565b50505b505050565b600082821c905092915050565b60006200048a600019846008026200046a565b1980831691505092915050565b6000620004a5838362000477565b9150826002028217905092915050565b620004c0826200023b565b67ffffffffffffffff811115620004dc57620004db62000246565b5b620004e88254620002a4565b620004f58282856200041a565b600060209050601f8311600181146200052d576000841562000518578287015190505b62000524858262000497565b86555062000594565b601f1984166200053d86620002d9565b60005b82811015620005675784890151825560018201915060208501945060208101905062000540565b8683101562000587578489015162000583601f89168262000477565b8355505b6001600288020188555050505b505050505050565b613ac480620005ac6000396000f3fe60806040526004361061021a5760003560e01c80635da0a46711610123578063bc52330f116100ab578063e61b68141161006f578063e61b68141461078c578063e985e9c5146107b5578063ec8d130b146107f2578063f2fde38b1461081b578063fddcb5ea146108445761021a565b8063bc52330f14610693578063c23374bc146106bc578063c87b56dd146106e7578063ccc0944e14610724578063d8210482146107615761021a565b80638da5cb5b116100f25780638da5cb5b146105cd57806395d89b41146105f8578063a22cb46514610623578063a5a865dc1461064c578063b88d4fde146106775761021a565b80635da0a467146104ff5780636352211e1461053c57806370a0823114610579578063715018a6146105b65761021a565b806323cf0a22116101a657806342842e0e1161017557806342842e0e1461043d57806355f804b31461045957806357ff9622146104825780635aca1bb6146104ab5780635c474f9e146104d45761021a565b806323cf0a22146103a45780632822a5a8146103c05780633ba0b551146103e95780633ccfd60b146104265761021a565b8063095ea7b3116101ed578063095ea7b3146102ef57806317bf6e031461030b57806318160ddd1461033457806321b8092e1461035f57806323b872dd146103885761021a565b80630115949c1461021f57806301ffc9a71461024a57806306fdde0314610287578063081812fc146102b2575b600080fd5b34801561022b57600080fd5b50610234610881565b6040516102419190612794565b60405180910390f35b34801561025657600080fd5b50610271600480360381019061026c919061281b565b61088a565b60405161027e9190612863565b60405180910390f35b34801561029357600080fd5b5061029c61091c565b6040516102a9919061290e565b60405180910390f35b3480156102be57600080fd5b506102d960048036038101906102d4919061295c565b6109ae565b6040516102e691906129ca565b60405180910390f35b61030960048036038101906103049190612a11565b610a2d565b005b34801561031757600080fd5b50610332600480360381019061032d9190612a51565b610b71565b005b34801561034057600080fd5b50610349610bd4565b6040516103569190612794565b60405180910390f35b34801561036b57600080fd5b5061038660048036038101906103819190612a51565b610beb565b005b6103a2600480360381019061039d9190612a7e565b610c37565b005b6103be60048036038101906103b99190612b0b565b610f59565b005b3480156103cc57600080fd5b506103e760048036038101906103e29190612b9d565b611190565b005b3480156103f557600080fd5b50610410600480360381019061040b9190612a51565b6111ae565b60405161041d9190612863565b60405180910390f35b34801561043257600080fd5b5061043b61120b565b005b61045760048036038101906104529190612a7e565b611284565b005b34801561046557600080fd5b50610480600480360381019061047b9190612b9d565b6112a4565b005b34801561048e57600080fd5b506104a960048036038101906104a49190612c16565b6112c2565b005b3480156104b757600080fd5b506104d260048036038101906104cd9190612c16565b6112e7565b005b3480156104e057600080fd5b506104e9611327565b6040516104f69190612863565b60405180910390f35b34801561050b57600080fd5b5061052660048036038101906105219190612a51565b611366565b6040516105339190612863565b60405180910390f35b34801561054857600080fd5b50610563600480360381019061055e919061295c565b6113d3565b60405161057091906129ca565b60405180910390f35b34801561058557600080fd5b506105a0600480360381019061059b9190612a51565b6113e5565b6040516105ad9190612794565b60405180910390f35b3480156105c257600080fd5b506105cb61149d565b005b3480156105d957600080fd5b506105e26114b1565b6040516105ef91906129ca565b60405180910390f35b34801561060457600080fd5b5061060d6114db565b60405161061a919061290e565b60405180910390f35b34801561062f57600080fd5b5061064a60048036038101906106459190612c43565b61156d565b005b34801561065857600080fd5b50610661611678565b60405161066e9190612863565b60405180910390f35b610691600480360381019061068c9190612db3565b61168f565b005b34801561069f57600080fd5b506106ba60048036038101906106b59190612c16565b611702565b005b3480156106c857600080fd5b506106d1611727565b6040516106de9190612863565b60405180910390f35b3480156106f357600080fd5b5061070e6004803603810190610709919061295c565b61173e565b60405161071b919061290e565b60405180910390f35b34801561073057600080fd5b5061074b60048036038101906107469190612e36565b6118c2565b6040516107589190612f31565b60405180910390f35b34801561076d57600080fd5b506107766119de565b604051610783919061290e565b60405180910390f35b34801561079857600080fd5b506107b360048036038101906107ae919061300f565b611a6c565b005b3480156107c157600080fd5b506107dc60048036038101906107d79190613058565b611b09565b6040516107e99190612863565b60405180910390f35b3480156107fe57600080fd5b5061081960048036038101906108149190612e36565b611b9d565b005b34801561082757600080fd5b50610842600480360381019061083d9190612a51565b611c16565b005b34801561085057600080fd5b5061086b60048036038101906108669190612a51565b611c99565b6040516108789190612794565b60405180910390f35b6000600a905090565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108e557506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109155750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461092b906130c7565b80601f0160208091040260200160405190810160405280929190818152602001828054610957906130c7565b80156109a45780601f10610979576101008083540402835291602001916109a4565b820191906000526020600020905b81548152906001019060200180831161098757829003601f168201915b5050505050905090565b60006109b982611ce2565b6109ef576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a38826113d3565b90508073ffffffffffffffffffffffffffffffffffffffff16610a59611d41565b73ffffffffffffffffffffffffffffffffffffffff1614610abc57610a8581610a80611d41565b611b09565b610abb576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b610b79611d49565b6001600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000610bde611dc7565b6001546000540303905090565b610bf3611d49565b80601160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610c4282611dd0565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ca9576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610cb584611e9c565b91509150610ccb8187610cc6611d41565b611ec3565b610d1757610ce086610cdb611d41565b611b09565b610d16576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610d7d576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d8a8686866001611f07565b8015610d9557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e6385610e3f888887611f0d565b7c020000000000000000000000000000000000000000000000000000000017611f35565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610ee95760006001850190506000600460008381526020019081526020016000205403610ee7576000548114610ee6578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610f518686866001611f60565b505050505050565b610f61611f66565b61061361ffff168161ffff16610f75611fb5565b610f7f9190613127565b1115610fc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb7906131a7565b60405180910390fd5b610fc86114b1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111775760008161ffff161180156110135750600a8161ffff1611155b80156110375750600a8161ffff1661102a336113e5565b6110349190613127565b11155b611076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106d90613239565b60405180910390fd5b600061108233836118c2565b9050806060015180611095575080608001515b6110d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110cb906132a5565b60405180910390fd5b348160400151111561111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111290613311565b60405180910390fd5b8161ffff16600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461116e9190613127565b92505081905550505b611185338261ffff16611fc8565b61118d611fe6565b50565b611198611d49565b8181600b91826111a99291906134e8565b505050565b60006002600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411156112015760019050611206565b600090505b919050565b611213611d49565b6000479050601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611280573d6000803e3d6000fd5b5050565b61129f8383836040518060200160405280600081525061168f565b505050565b6112ac611d49565b8181600a91826112bd9291906134e8565b505050565b6112ca611d49565b80600e60006101000a81548160ff02191690831515021790555050565b6112ef611d49565b6000600e60006101000a81548160ff02191690831515021790555080600e60016101000a81548160ff02191690831515021790555050565b6000600e60019054906101000a900460ff16806113505750600e60009054906101000a900460ff165b1561135e5760019050611363565b600090505b90565b600060011515600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515036113c957600190506113ce565b600090505b919050565b60006113de82611dd0565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361144c576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6114a5611d49565b6114af6000611ff0565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546114ea906130c7565b80601f0160208091040260200160405190810160405280929190818152602001828054611516906130c7565b80156115635780601f1061153857610100808354040283529160200191611563565b820191906000526020600020905b81548152906001019060200180831161154657829003601f168201915b5050505050905090565b806007600061157a611d41565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611627611d41565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161166c9190612863565b60405180910390a35050565b6000600e60019054906101000a900460ff16905090565b61169a848484610c37565b60008373ffffffffffffffffffffffffffffffffffffffff163b146116fc576116c5848484846120b6565b6116fb576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b61170a611d49565b80600c60006101000a81548160ff02191690831515021790555050565b6000600e60009054906101000a900460ff16905090565b606061174982611ce2565b611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177f9061362a565b60405180910390fd5b6000611792612206565b511161182857600b80546117a5906130c7565b80601f01602080910402602001604051908101604052809291908181526020018280546117d1906130c7565b801561181e5780601f106117f35761010080835404028352916020019161181e565b820191906000526020600020905b81548152906001019060200180831161180157829003601f168201915b50505050506118bb565b611830612206565b61183983612298565b600c60009054906101000a900460ff166118625760405180602001604052806000815250611899565b6040518060400160405280600581526020017f2e6a736f6e0000000000000000000000000000000000000000000000000000008152505b6040516020016118ab93929190613686565b6040516020818303038152906040525b9050919050565b6118ca612732565b60008066d19c2ff9bf8000905060011515600e60009054906101000a900460ff161515036118fd57668a8e4b1a3d800090505b60008490506000600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540361195857828561195591906136b7565b90505b6040518060e001604052808381526020018661ffff168461197991906136ed565b81526020018261ffff168461198e91906136ed565b8152602001600e60019054906101000a900460ff1615158152602001600e60009054906101000a900460ff16151581526020018661ffff1681526020018261ffff16815250935050505092915050565b600b80546119eb906130c7565b80601f0160208091040260200160405190810160405280929190818152602001828054611a17906130c7565b8015611a645780601f10611a3957610100808354040283529160200191611a64565b820191906000526020600020905b815481529060010190602001808311611a4757829003601f168201915b505050505081565b611a74611d49565b60005b8151811015611b05576001600d6000848481518110611a9957611a9861372f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611afd9061375e565b915050611a77565b5050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ba5611d49565b61061361ffff168161ffff16611bb9611fb5565b611bc39190613127565b1115611c04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfb906137f2565b60405180910390fd5b611c12828261ffff16611fc8565b5050565b611c1e611d49565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8490613884565b60405180910390fd5b611c9681611ff0565b50565b6000600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600081611ced611dc7565b11158015611cfc575060005482105b8015611d3a575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b611d51612366565b73ffffffffffffffffffffffffffffffffffffffff16611d6f6114b1565b73ffffffffffffffffffffffffffffffffffffffff1614611dc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dbc906138f0565b60405180910390fd5b565b60006001905090565b60008082905080611ddf611dc7565b11611e6557600054811015611e645760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611e62575b60008103611e58576004600083600190039350838152602001908152602001600020549050611e2e565b8092505050611e97565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611f2486868461236e565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600260095403611fab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa29061395c565b60405180910390fd5b6002600981905550565b6000611fbf611dc7565b60005403905090565b611fe2828260405180602001604052806000815250612377565b5050565b6001600981905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026120dc611d41565b8786866040518563ffffffff1660e01b81526004016120fe94939291906139d1565b6020604051808303816000875af192505050801561213a57506040513d601f19601f820116820180604052508101906121379190613a32565b60015b6121b3573d806000811461216a576040519150601f19603f3d011682016040523d82523d6000602084013e61216f565b606091505b5060008151036121ab576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600a8054612215906130c7565b80601f0160208091040260200160405190810160405280929190818152602001828054612241906130c7565b801561228e5780601f106122635761010080835404028352916020019161228e565b820191906000526020600020905b81548152906001019060200180831161227157829003601f168201915b5050505050905090565b6060600060016122a784612414565b01905060008167ffffffffffffffff8111156122c6576122c5612c88565b5b6040519080825280601f01601f1916602001820160405280156122f85781602001600182028036833780820191505090505b509050600082602001820190505b60011561235b578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161234f5761234e613a5f565b5b04945060008503612306575b819350505050919050565b600033905090565b60009392505050565b6123818383612567565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461240f57600080549050600083820390505b6123c160008683806001019450866120b6565b6123f7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106123ae57816000541461240c57600080fd5b50505b505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612472577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161246857612467613a5f565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106124af576d04ee2d6d415b85acef810000000083816124a5576124a4613a5f565b5b0492506020810190505b662386f26fc1000083106124de57662386f26fc1000083816124d4576124d3613a5f565b5b0492506010810190505b6305f5e1008310612507576305f5e10083816124fd576124fc613a5f565b5b0492506008810190505b612710831061252c57612710838161252257612521613a5f565b5b0492506004810190505b6064831061254f576064838161254557612544613a5f565b5b0492506002810190505b600a831061255e576001810190505b80915050919050565b600080549050600082036125a7576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125b46000848385611f07565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061262b8361261c6000866000611f0d565b61262585612722565b17611f35565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146126cc57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612691565b5060008203612707576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061271d6000848385611f60565b505050565b60006001821460e11b9050919050565b6040518060e00160405280600081526020016000815260200160008152602001600015158152602001600015158152602001600061ffff168152602001600061ffff1681525090565b6000819050919050565b61278e8161277b565b82525050565b60006020820190506127a96000830184612785565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6127f8816127c3565b811461280357600080fd5b50565b600081359050612815816127ef565b92915050565b600060208284031215612831576128306127b9565b5b600061283f84828501612806565b91505092915050565b60008115159050919050565b61285d81612848565b82525050565b60006020820190506128786000830184612854565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156128b857808201518184015260208101905061289d565b60008484015250505050565b6000601f19601f8301169050919050565b60006128e08261287e565b6128ea8185612889565b93506128fa81856020860161289a565b612903816128c4565b840191505092915050565b6000602082019050818103600083015261292881846128d5565b905092915050565b6129398161277b565b811461294457600080fd5b50565b60008135905061295681612930565b92915050565b600060208284031215612972576129716127b9565b5b600061298084828501612947565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006129b482612989565b9050919050565b6129c4816129a9565b82525050565b60006020820190506129df60008301846129bb565b92915050565b6129ee816129a9565b81146129f957600080fd5b50565b600081359050612a0b816129e5565b92915050565b60008060408385031215612a2857612a276127b9565b5b6000612a36858286016129fc565b9250506020612a4785828601612947565b9150509250929050565b600060208284031215612a6757612a666127b9565b5b6000612a75848285016129fc565b91505092915050565b600080600060608486031215612a9757612a966127b9565b5b6000612aa5868287016129fc565b9350506020612ab6868287016129fc565b9250506040612ac786828701612947565b9150509250925092565b600061ffff82169050919050565b612ae881612ad1565b8114612af357600080fd5b50565b600081359050612b0581612adf565b92915050565b600060208284031215612b2157612b206127b9565b5b6000612b2f84828501612af6565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612b5d57612b5c612b38565b5b8235905067ffffffffffffffff811115612b7a57612b79612b3d565b5b602083019150836001820283011115612b9657612b95612b42565b5b9250929050565b60008060208385031215612bb457612bb36127b9565b5b600083013567ffffffffffffffff811115612bd257612bd16127be565b5b612bde85828601612b47565b92509250509250929050565b612bf381612848565b8114612bfe57600080fd5b50565b600081359050612c1081612bea565b92915050565b600060208284031215612c2c57612c2b6127b9565b5b6000612c3a84828501612c01565b91505092915050565b60008060408385031215612c5a57612c596127b9565b5b6000612c68858286016129fc565b9250506020612c7985828601612c01565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cc0826128c4565b810181811067ffffffffffffffff82111715612cdf57612cde612c88565b5b80604052505050565b6000612cf26127af565b9050612cfe8282612cb7565b919050565b600067ffffffffffffffff821115612d1e57612d1d612c88565b5b612d27826128c4565b9050602081019050919050565b82818337600083830152505050565b6000612d56612d5184612d03565b612ce8565b905082815260208101848484011115612d7257612d71612c83565b5b612d7d848285612d34565b509392505050565b600082601f830112612d9a57612d99612b38565b5b8135612daa848260208601612d43565b91505092915050565b60008060008060808587031215612dcd57612dcc6127b9565b5b6000612ddb878288016129fc565b9450506020612dec878288016129fc565b9350506040612dfd87828801612947565b925050606085013567ffffffffffffffff811115612e1e57612e1d6127be565b5b612e2a87828801612d85565b91505092959194509250565b60008060408385031215612e4d57612e4c6127b9565b5b6000612e5b858286016129fc565b9250506020612e6c85828601612af6565b9150509250929050565b612e7f8161277b565b82525050565b612e8e81612848565b82525050565b612e9d81612ad1565b82525050565b60e082016000820151612eb96000850182612e76565b506020820151612ecc6020850182612e76565b506040820151612edf6040850182612e76565b506060820151612ef26060850182612e85565b506080820151612f056080850182612e85565b5060a0820151612f1860a0850182612e94565b5060c0820151612f2b60c0850182612e94565b50505050565b600060e082019050612f466000830184612ea3565b92915050565b600067ffffffffffffffff821115612f6757612f66612c88565b5b602082029050602081019050919050565b6000612f8b612f8684612f4c565b612ce8565b90508083825260208201905060208402830185811115612fae57612fad612b42565b5b835b81811015612fd75780612fc388826129fc565b845260208401935050602081019050612fb0565b5050509392505050565b600082601f830112612ff657612ff5612b38565b5b8135613006848260208601612f78565b91505092915050565b600060208284031215613025576130246127b9565b5b600082013567ffffffffffffffff811115613043576130426127be565b5b61304f84828501612fe1565b91505092915050565b6000806040838503121561306f5761306e6127b9565b5b600061307d858286016129fc565b925050602061308e858286016129fc565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806130df57607f821691505b6020821081036130f2576130f1613098565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006131328261277b565b915061313d8361277b565b9250828201905080821115613155576131546130f8565b5b92915050565b7f4d6178696d756d20616d6f756e74206f66206e66747320726561636865640000600082015250565b6000613191601e83612889565b915061319c8261315b565b602082019050919050565b600060208201905081810360008301526131c081613184565b9050919050565b7f596f757220616d6f756e74206f66206e667473206973206c696d69746564207460008201527f6f206d61782e0000000000000000000000000000000000000000000000000000602082015250565b6000613223602683612889565b915061322e826131c7565b604082019050919050565b6000602082019050818103600083015261325281613216565b9050919050565b7f53616c65206973206e6f74206163746976650000000000000000000000000000600082015250565b600061328f601283612889565b915061329a82613259565b602082019050919050565b600060208201905081810360008301526132be81613282565b9050919050565b7f45746865722076616c75652073656e74206973206e6f7420636f727265637400600082015250565b60006132fb601f83612889565b9150613306826132c5565b602082019050919050565b6000602082019050818103600083015261332a816132ee565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261339e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613361565b6133a88683613361565b95508019841693508086168417925050509392505050565b6000819050919050565b60006133e56133e06133db8461277b565b6133c0565b61277b565b9050919050565b6000819050919050565b6133ff836133ca565b61341361340b826133ec565b84845461336e565b825550505050565b600090565b61342861341b565b6134338184846133f6565b505050565b5b818110156134575761344c600082613420565b600181019050613439565b5050565b601f82111561349c5761346d8161333c565b61347684613351565b81016020851015613485578190505b61349961349185613351565b830182613438565b50505b505050565b600082821c905092915050565b60006134bf600019846008026134a1565b1980831691505092915050565b60006134d883836134ae565b9150826002028217905092915050565b6134f28383613331565b67ffffffffffffffff81111561350b5761350a612c88565b5b61351582546130c7565b61352082828561345b565b6000601f83116001811461354f576000841561353d578287013590505b61354785826134cc565b8655506135af565b601f19841661355d8661333c565b60005b8281101561358557848901358255600182019150602085019450602081019050613560565b868310156135a2578489013561359e601f8916826134ae565b8355505b6001600288020188555050505b50505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613614602f83612889565b915061361f826135b8565b604082019050919050565b6000602082019050818103600083015261364381613607565b9050919050565b600081905092915050565b60006136608261287e565b61366a818561364a565b935061367a81856020860161289a565b80840191505092915050565b60006136928286613655565b915061369e8285613655565b91506136aa8284613655565b9150819050949350505050565b60006136c282612ad1565b91506136cd83612ad1565b9250828203905061ffff8111156136e7576136e66130f8565b5b92915050565b60006136f88261277b565b91506137038361277b565b92508282026137118161277b565b91508282048414831517613728576137276130f8565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006137698261277b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361379b5761379a6130f8565b5b600182019050919050565b7f4d6178696d756d20616d6f756e74206f66206d696e7473207265616368656400600082015250565b60006137dc601f83612889565b91506137e7826137a6565b602082019050919050565b6000602082019050818103600083015261380b816137cf565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061386e602683612889565b915061387982613812565b604082019050919050565b6000602082019050818103600083015261389d81613861565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006138da602083612889565b91506138e5826138a4565b602082019050919050565b60006020820190508181036000830152613909816138cd565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613946601f83612889565b915061395182613910565b602082019050919050565b6000602082019050818103600083015261397581613939565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006139a38261397c565b6139ad8185613987565b93506139bd81856020860161289a565b6139c6816128c4565b840191505092915050565b60006080820190506139e660008301876129bb565b6139f360208301866129bb565b613a006040830185612785565b8181036060830152613a128184613998565b905095945050505050565b600081519050613a2c816127ef565b92915050565b600060208284031215613a4857613a476127b9565b5b6000613a5684828501613a1d565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea2646970667358221220a0cb31990f9bbf176af10b68ffd3aff15481e96064118671d0e72afc0341436b64736f6c63430008110033697066733a2f2f6261667962656967646c646c356578326a36347a71687a6333796732677233667a71327069627a693637666c7365377877337135686c6b767567712f756e726576

Deployed Bytecode

0x60806040526004361061021a5760003560e01c80635da0a46711610123578063bc52330f116100ab578063e61b68141161006f578063e61b68141461078c578063e985e9c5146107b5578063ec8d130b146107f2578063f2fde38b1461081b578063fddcb5ea146108445761021a565b8063bc52330f14610693578063c23374bc146106bc578063c87b56dd146106e7578063ccc0944e14610724578063d8210482146107615761021a565b80638da5cb5b116100f25780638da5cb5b146105cd57806395d89b41146105f8578063a22cb46514610623578063a5a865dc1461064c578063b88d4fde146106775761021a565b80635da0a467146104ff5780636352211e1461053c57806370a0823114610579578063715018a6146105b65761021a565b806323cf0a22116101a657806342842e0e1161017557806342842e0e1461043d57806355f804b31461045957806357ff9622146104825780635aca1bb6146104ab5780635c474f9e146104d45761021a565b806323cf0a22146103a45780632822a5a8146103c05780633ba0b551146103e95780633ccfd60b146104265761021a565b8063095ea7b3116101ed578063095ea7b3146102ef57806317bf6e031461030b57806318160ddd1461033457806321b8092e1461035f57806323b872dd146103885761021a565b80630115949c1461021f57806301ffc9a71461024a57806306fdde0314610287578063081812fc146102b2575b600080fd5b34801561022b57600080fd5b50610234610881565b6040516102419190612794565b60405180910390f35b34801561025657600080fd5b50610271600480360381019061026c919061281b565b61088a565b60405161027e9190612863565b60405180910390f35b34801561029357600080fd5b5061029c61091c565b6040516102a9919061290e565b60405180910390f35b3480156102be57600080fd5b506102d960048036038101906102d4919061295c565b6109ae565b6040516102e691906129ca565b60405180910390f35b61030960048036038101906103049190612a11565b610a2d565b005b34801561031757600080fd5b50610332600480360381019061032d9190612a51565b610b71565b005b34801561034057600080fd5b50610349610bd4565b6040516103569190612794565b60405180910390f35b34801561036b57600080fd5b5061038660048036038101906103819190612a51565b610beb565b005b6103a2600480360381019061039d9190612a7e565b610c37565b005b6103be60048036038101906103b99190612b0b565b610f59565b005b3480156103cc57600080fd5b506103e760048036038101906103e29190612b9d565b611190565b005b3480156103f557600080fd5b50610410600480360381019061040b9190612a51565b6111ae565b60405161041d9190612863565b60405180910390f35b34801561043257600080fd5b5061043b61120b565b005b61045760048036038101906104529190612a7e565b611284565b005b34801561046557600080fd5b50610480600480360381019061047b9190612b9d565b6112a4565b005b34801561048e57600080fd5b506104a960048036038101906104a49190612c16565b6112c2565b005b3480156104b757600080fd5b506104d260048036038101906104cd9190612c16565b6112e7565b005b3480156104e057600080fd5b506104e9611327565b6040516104f69190612863565b60405180910390f35b34801561050b57600080fd5b5061052660048036038101906105219190612a51565b611366565b6040516105339190612863565b60405180910390f35b34801561054857600080fd5b50610563600480360381019061055e919061295c565b6113d3565b60405161057091906129ca565b60405180910390f35b34801561058557600080fd5b506105a0600480360381019061059b9190612a51565b6113e5565b6040516105ad9190612794565b60405180910390f35b3480156105c257600080fd5b506105cb61149d565b005b3480156105d957600080fd5b506105e26114b1565b6040516105ef91906129ca565b60405180910390f35b34801561060457600080fd5b5061060d6114db565b60405161061a919061290e565b60405180910390f35b34801561062f57600080fd5b5061064a60048036038101906106459190612c43565b61156d565b005b34801561065857600080fd5b50610661611678565b60405161066e9190612863565b60405180910390f35b610691600480360381019061068c9190612db3565b61168f565b005b34801561069f57600080fd5b506106ba60048036038101906106b59190612c16565b611702565b005b3480156106c857600080fd5b506106d1611727565b6040516106de9190612863565b60405180910390f35b3480156106f357600080fd5b5061070e6004803603810190610709919061295c565b61173e565b60405161071b919061290e565b60405180910390f35b34801561073057600080fd5b5061074b60048036038101906107469190612e36565b6118c2565b6040516107589190612f31565b60405180910390f35b34801561076d57600080fd5b506107766119de565b604051610783919061290e565b60405180910390f35b34801561079857600080fd5b506107b360048036038101906107ae919061300f565b611a6c565b005b3480156107c157600080fd5b506107dc60048036038101906107d79190613058565b611b09565b6040516107e99190612863565b60405180910390f35b3480156107fe57600080fd5b5061081960048036038101906108149190612e36565b611b9d565b005b34801561082757600080fd5b50610842600480360381019061083d9190612a51565b611c16565b005b34801561085057600080fd5b5061086b60048036038101906108669190612a51565b611c99565b6040516108789190612794565b60405180910390f35b6000600a905090565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108e557506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109155750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461092b906130c7565b80601f0160208091040260200160405190810160405280929190818152602001828054610957906130c7565b80156109a45780601f10610979576101008083540402835291602001916109a4565b820191906000526020600020905b81548152906001019060200180831161098757829003601f168201915b5050505050905090565b60006109b982611ce2565b6109ef576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a38826113d3565b90508073ffffffffffffffffffffffffffffffffffffffff16610a59611d41565b73ffffffffffffffffffffffffffffffffffffffff1614610abc57610a8581610a80611d41565b611b09565b610abb576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b610b79611d49565b6001600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000610bde611dc7565b6001546000540303905090565b610bf3611d49565b80601160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610c4282611dd0565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ca9576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610cb584611e9c565b91509150610ccb8187610cc6611d41565b611ec3565b610d1757610ce086610cdb611d41565b611b09565b610d16576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610d7d576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d8a8686866001611f07565b8015610d9557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e6385610e3f888887611f0d565b7c020000000000000000000000000000000000000000000000000000000017611f35565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610ee95760006001850190506000600460008381526020019081526020016000205403610ee7576000548114610ee6578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610f518686866001611f60565b505050505050565b610f61611f66565b61061361ffff168161ffff16610f75611fb5565b610f7f9190613127565b1115610fc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb7906131a7565b60405180910390fd5b610fc86114b1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111775760008161ffff161180156110135750600a8161ffff1611155b80156110375750600a8161ffff1661102a336113e5565b6110349190613127565b11155b611076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106d90613239565b60405180910390fd5b600061108233836118c2565b9050806060015180611095575080608001515b6110d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110cb906132a5565b60405180910390fd5b348160400151111561111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111290613311565b60405180910390fd5b8161ffff16600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461116e9190613127565b92505081905550505b611185338261ffff16611fc8565b61118d611fe6565b50565b611198611d49565b8181600b91826111a99291906134e8565b505050565b60006002600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411156112015760019050611206565b600090505b919050565b611213611d49565b6000479050601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611280573d6000803e3d6000fd5b5050565b61129f8383836040518060200160405280600081525061168f565b505050565b6112ac611d49565b8181600a91826112bd9291906134e8565b505050565b6112ca611d49565b80600e60006101000a81548160ff02191690831515021790555050565b6112ef611d49565b6000600e60006101000a81548160ff02191690831515021790555080600e60016101000a81548160ff02191690831515021790555050565b6000600e60019054906101000a900460ff16806113505750600e60009054906101000a900460ff165b1561135e5760019050611363565b600090505b90565b600060011515600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515036113c957600190506113ce565b600090505b919050565b60006113de82611dd0565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361144c576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6114a5611d49565b6114af6000611ff0565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546114ea906130c7565b80601f0160208091040260200160405190810160405280929190818152602001828054611516906130c7565b80156115635780601f1061153857610100808354040283529160200191611563565b820191906000526020600020905b81548152906001019060200180831161154657829003601f168201915b5050505050905090565b806007600061157a611d41565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611627611d41565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161166c9190612863565b60405180910390a35050565b6000600e60019054906101000a900460ff16905090565b61169a848484610c37565b60008373ffffffffffffffffffffffffffffffffffffffff163b146116fc576116c5848484846120b6565b6116fb576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b61170a611d49565b80600c60006101000a81548160ff02191690831515021790555050565b6000600e60009054906101000a900460ff16905090565b606061174982611ce2565b611788576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177f9061362a565b60405180910390fd5b6000611792612206565b511161182857600b80546117a5906130c7565b80601f01602080910402602001604051908101604052809291908181526020018280546117d1906130c7565b801561181e5780601f106117f35761010080835404028352916020019161181e565b820191906000526020600020905b81548152906001019060200180831161180157829003601f168201915b50505050506118bb565b611830612206565b61183983612298565b600c60009054906101000a900460ff166118625760405180602001604052806000815250611899565b6040518060400160405280600581526020017f2e6a736f6e0000000000000000000000000000000000000000000000000000008152505b6040516020016118ab93929190613686565b6040516020818303038152906040525b9050919050565b6118ca612732565b60008066d19c2ff9bf8000905060011515600e60009054906101000a900460ff161515036118fd57668a8e4b1a3d800090505b60008490506000600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540361195857828561195591906136b7565b90505b6040518060e001604052808381526020018661ffff168461197991906136ed565b81526020018261ffff168461198e91906136ed565b8152602001600e60019054906101000a900460ff1615158152602001600e60009054906101000a900460ff16151581526020018661ffff1681526020018261ffff16815250935050505092915050565b600b80546119eb906130c7565b80601f0160208091040260200160405190810160405280929190818152602001828054611a17906130c7565b8015611a645780601f10611a3957610100808354040283529160200191611a64565b820191906000526020600020905b815481529060010190602001808311611a4757829003601f168201915b505050505081565b611a74611d49565b60005b8151811015611b05576001600d6000848481518110611a9957611a9861372f565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611afd9061375e565b915050611a77565b5050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ba5611d49565b61061361ffff168161ffff16611bb9611fb5565b611bc39190613127565b1115611c04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfb906137f2565b60405180910390fd5b611c12828261ffff16611fc8565b5050565b611c1e611d49565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8490613884565b60405180910390fd5b611c9681611ff0565b50565b6000600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600081611ced611dc7565b11158015611cfc575060005482105b8015611d3a575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b611d51612366565b73ffffffffffffffffffffffffffffffffffffffff16611d6f6114b1565b73ffffffffffffffffffffffffffffffffffffffff1614611dc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dbc906138f0565b60405180910390fd5b565b60006001905090565b60008082905080611ddf611dc7565b11611e6557600054811015611e645760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611e62575b60008103611e58576004600083600190039350838152602001908152602001600020549050611e2e565b8092505050611e97565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611f2486868461236e565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600260095403611fab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa29061395c565b60405180910390fd5b6002600981905550565b6000611fbf611dc7565b60005403905090565b611fe2828260405180602001604052806000815250612377565b5050565b6001600981905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026120dc611d41565b8786866040518563ffffffff1660e01b81526004016120fe94939291906139d1565b6020604051808303816000875af192505050801561213a57506040513d601f19601f820116820180604052508101906121379190613a32565b60015b6121b3573d806000811461216a576040519150601f19603f3d011682016040523d82523d6000602084013e61216f565b606091505b5060008151036121ab576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600a8054612215906130c7565b80601f0160208091040260200160405190810160405280929190818152602001828054612241906130c7565b801561228e5780601f106122635761010080835404028352916020019161228e565b820191906000526020600020905b81548152906001019060200180831161227157829003601f168201915b5050505050905090565b6060600060016122a784612414565b01905060008167ffffffffffffffff8111156122c6576122c5612c88565b5b6040519080825280601f01601f1916602001820160405280156122f85781602001600182028036833780820191505090505b509050600082602001820190505b60011561235b578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161234f5761234e613a5f565b5b04945060008503612306575b819350505050919050565b600033905090565b60009392505050565b6123818383612567565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461240f57600080549050600083820390505b6123c160008683806001019450866120b6565b6123f7576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106123ae57816000541461240c57600080fd5b50505b505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612472577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161246857612467613a5f565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106124af576d04ee2d6d415b85acef810000000083816124a5576124a4613a5f565b5b0492506020810190505b662386f26fc1000083106124de57662386f26fc1000083816124d4576124d3613a5f565b5b0492506010810190505b6305f5e1008310612507576305f5e10083816124fd576124fc613a5f565b5b0492506008810190505b612710831061252c57612710838161252257612521613a5f565b5b0492506004810190505b6064831061254f576064838161254557612544613a5f565b5b0492506002810190505b600a831061255e576001810190505b80915050919050565b600080549050600082036125a7576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125b46000848385611f07565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061262b8361261c6000866000611f0d565b61262585612722565b17611f35565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146126cc57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612691565b5060008203612707576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061271d6000848385611f60565b505050565b60006001821460e11b9050919050565b6040518060e00160405280600081526020016000815260200160008152602001600015158152602001600015158152602001600061ffff168152602001600061ffff1681525090565b6000819050919050565b61278e8161277b565b82525050565b60006020820190506127a96000830184612785565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6127f8816127c3565b811461280357600080fd5b50565b600081359050612815816127ef565b92915050565b600060208284031215612831576128306127b9565b5b600061283f84828501612806565b91505092915050565b60008115159050919050565b61285d81612848565b82525050565b60006020820190506128786000830184612854565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156128b857808201518184015260208101905061289d565b60008484015250505050565b6000601f19601f8301169050919050565b60006128e08261287e565b6128ea8185612889565b93506128fa81856020860161289a565b612903816128c4565b840191505092915050565b6000602082019050818103600083015261292881846128d5565b905092915050565b6129398161277b565b811461294457600080fd5b50565b60008135905061295681612930565b92915050565b600060208284031215612972576129716127b9565b5b600061298084828501612947565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006129b482612989565b9050919050565b6129c4816129a9565b82525050565b60006020820190506129df60008301846129bb565b92915050565b6129ee816129a9565b81146129f957600080fd5b50565b600081359050612a0b816129e5565b92915050565b60008060408385031215612a2857612a276127b9565b5b6000612a36858286016129fc565b9250506020612a4785828601612947565b9150509250929050565b600060208284031215612a6757612a666127b9565b5b6000612a75848285016129fc565b91505092915050565b600080600060608486031215612a9757612a966127b9565b5b6000612aa5868287016129fc565b9350506020612ab6868287016129fc565b9250506040612ac786828701612947565b9150509250925092565b600061ffff82169050919050565b612ae881612ad1565b8114612af357600080fd5b50565b600081359050612b0581612adf565b92915050565b600060208284031215612b2157612b206127b9565b5b6000612b2f84828501612af6565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612b5d57612b5c612b38565b5b8235905067ffffffffffffffff811115612b7a57612b79612b3d565b5b602083019150836001820283011115612b9657612b95612b42565b5b9250929050565b60008060208385031215612bb457612bb36127b9565b5b600083013567ffffffffffffffff811115612bd257612bd16127be565b5b612bde85828601612b47565b92509250509250929050565b612bf381612848565b8114612bfe57600080fd5b50565b600081359050612c1081612bea565b92915050565b600060208284031215612c2c57612c2b6127b9565b5b6000612c3a84828501612c01565b91505092915050565b60008060408385031215612c5a57612c596127b9565b5b6000612c68858286016129fc565b9250506020612c7985828601612c01565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cc0826128c4565b810181811067ffffffffffffffff82111715612cdf57612cde612c88565b5b80604052505050565b6000612cf26127af565b9050612cfe8282612cb7565b919050565b600067ffffffffffffffff821115612d1e57612d1d612c88565b5b612d27826128c4565b9050602081019050919050565b82818337600083830152505050565b6000612d56612d5184612d03565b612ce8565b905082815260208101848484011115612d7257612d71612c83565b5b612d7d848285612d34565b509392505050565b600082601f830112612d9a57612d99612b38565b5b8135612daa848260208601612d43565b91505092915050565b60008060008060808587031215612dcd57612dcc6127b9565b5b6000612ddb878288016129fc565b9450506020612dec878288016129fc565b9350506040612dfd87828801612947565b925050606085013567ffffffffffffffff811115612e1e57612e1d6127be565b5b612e2a87828801612d85565b91505092959194509250565b60008060408385031215612e4d57612e4c6127b9565b5b6000612e5b858286016129fc565b9250506020612e6c85828601612af6565b9150509250929050565b612e7f8161277b565b82525050565b612e8e81612848565b82525050565b612e9d81612ad1565b82525050565b60e082016000820151612eb96000850182612e76565b506020820151612ecc6020850182612e76565b506040820151612edf6040850182612e76565b506060820151612ef26060850182612e85565b506080820151612f056080850182612e85565b5060a0820151612f1860a0850182612e94565b5060c0820151612f2b60c0850182612e94565b50505050565b600060e082019050612f466000830184612ea3565b92915050565b600067ffffffffffffffff821115612f6757612f66612c88565b5b602082029050602081019050919050565b6000612f8b612f8684612f4c565b612ce8565b90508083825260208201905060208402830185811115612fae57612fad612b42565b5b835b81811015612fd75780612fc388826129fc565b845260208401935050602081019050612fb0565b5050509392505050565b600082601f830112612ff657612ff5612b38565b5b8135613006848260208601612f78565b91505092915050565b600060208284031215613025576130246127b9565b5b600082013567ffffffffffffffff811115613043576130426127be565b5b61304f84828501612fe1565b91505092915050565b6000806040838503121561306f5761306e6127b9565b5b600061307d858286016129fc565b925050602061308e858286016129fc565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806130df57607f821691505b6020821081036130f2576130f1613098565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006131328261277b565b915061313d8361277b565b9250828201905080821115613155576131546130f8565b5b92915050565b7f4d6178696d756d20616d6f756e74206f66206e66747320726561636865640000600082015250565b6000613191601e83612889565b915061319c8261315b565b602082019050919050565b600060208201905081810360008301526131c081613184565b9050919050565b7f596f757220616d6f756e74206f66206e667473206973206c696d69746564207460008201527f6f206d61782e0000000000000000000000000000000000000000000000000000602082015250565b6000613223602683612889565b915061322e826131c7565b604082019050919050565b6000602082019050818103600083015261325281613216565b9050919050565b7f53616c65206973206e6f74206163746976650000000000000000000000000000600082015250565b600061328f601283612889565b915061329a82613259565b602082019050919050565b600060208201905081810360008301526132be81613282565b9050919050565b7f45746865722076616c75652073656e74206973206e6f7420636f727265637400600082015250565b60006132fb601f83612889565b9150613306826132c5565b602082019050919050565b6000602082019050818103600083015261332a816132ee565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261339e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613361565b6133a88683613361565b95508019841693508086168417925050509392505050565b6000819050919050565b60006133e56133e06133db8461277b565b6133c0565b61277b565b9050919050565b6000819050919050565b6133ff836133ca565b61341361340b826133ec565b84845461336e565b825550505050565b600090565b61342861341b565b6134338184846133f6565b505050565b5b818110156134575761344c600082613420565b600181019050613439565b5050565b601f82111561349c5761346d8161333c565b61347684613351565b81016020851015613485578190505b61349961349185613351565b830182613438565b50505b505050565b600082821c905092915050565b60006134bf600019846008026134a1565b1980831691505092915050565b60006134d883836134ae565b9150826002028217905092915050565b6134f28383613331565b67ffffffffffffffff81111561350b5761350a612c88565b5b61351582546130c7565b61352082828561345b565b6000601f83116001811461354f576000841561353d578287013590505b61354785826134cc565b8655506135af565b601f19841661355d8661333c565b60005b8281101561358557848901358255600182019150602085019450602081019050613560565b868310156135a2578489013561359e601f8916826134ae565b8355505b6001600288020188555050505b50505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613614602f83612889565b915061361f826135b8565b604082019050919050565b6000602082019050818103600083015261364381613607565b9050919050565b600081905092915050565b60006136608261287e565b61366a818561364a565b935061367a81856020860161289a565b80840191505092915050565b60006136928286613655565b915061369e8285613655565b91506136aa8284613655565b9150819050949350505050565b60006136c282612ad1565b91506136cd83612ad1565b9250828203905061ffff8111156136e7576136e66130f8565b5b92915050565b60006136f88261277b565b91506137038361277b565b92508282026137118161277b565b91508282048414831517613728576137276130f8565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006137698261277b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361379b5761379a6130f8565b5b600182019050919050565b7f4d6178696d756d20616d6f756e74206f66206d696e7473207265616368656400600082015250565b60006137dc601f83612889565b91506137e7826137a6565b602082019050919050565b6000602082019050818103600083015261380b816137cf565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061386e602683612889565b915061387982613812565b604082019050919050565b6000602082019050818103600083015261389d81613861565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006138da602083612889565b91506138e5826138a4565b602082019050919050565b60006020820190508181036000830152613909816138cd565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613946601f83612889565b915061395182613910565b602082019050919050565b6000602082019050818103600083015261397581613939565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006139a38261397c565b6139ad8185613987565b93506139bd81856020860161289a565b6139c6816128c4565b840191505092915050565b60006080820190506139e660008301876129bb565b6139f360208301866129bb565b613a006040830185612785565b8181036060830152613a128184613998565b905095945050505050565b600081519050613a2c816127ef565b92915050565b600060208284031215613a4857613a476127b9565b5b6000613a5684828501613a1d565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea2646970667358221220a0cb31990f9bbf176af10b68ffd3aff15481e96064118671d0e72afc0341436b64736f6c63430008110033

Deployed Bytecode Sourcemap

73057:5518:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77889:86;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35094:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35996:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42487:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41920:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76807:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31747:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77664:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46126:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74011:719;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77779:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78160:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77506:150;;;;;;;;;;;;;:::i;:::-;;49047:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76089:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76609:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76344:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77983:169;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78375:197;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37389:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32931:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72213:103;;;;;;;;;;;;;:::i;:::-;;71565:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36172:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43045:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76504:94;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49838:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77127:89;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76713:86;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74735:353;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75096:777;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73187:103;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76932:187;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43436:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77267:190;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72471:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76203:133;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77889:86;77933:7;77965:2;77958:9;;77889:86;:::o;35094:639::-;35179:4;35518:10;35503:25;;:11;:25;;;;:102;;;;35595:10;35580:25;;:11;:25;;;;35503:102;:179;;;;35672:10;35657:25;;:11;:25;;;;35503:179;35483:199;;35094:639;;;:::o;35996:100::-;36050:13;36083:5;36076:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35996:100;:::o;42487:218::-;42563:7;42588:16;42596:7;42588;:16::i;:::-;42583:64;;42613:34;;;;;;;;;;;;;;42583:64;42667:15;:24;42683:7;42667:24;;;;;;;;;;;:30;;;;;;;;;;;;42660:37;;42487:218;;;:::o;41920:408::-;42009:13;42025:16;42033:7;42025;:16::i;:::-;42009:32;;42081:5;42058:28;;:19;:17;:19::i;:::-;:28;;;42054:175;;42106:44;42123:5;42130:19;:17;:19::i;:::-;42106:16;:44::i;:::-;42101:128;;42178:35;;;;;;;;;;;;;;42101:128;42054:175;42274:2;42241:15;:24;42257:7;42241:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;42312:7;42308:2;42292:28;;42301:5;42292:28;;;;;;;;;;;;41998:330;41920:408;;:::o;76807:117::-;71451:13;:11;:13::i;:::-;73635:4:::1;76878:10;:21;76889:9;76878:21;;;;;;;;;;;;;;;;:38;;;;;;;;;;;;;;;;;;76807:117:::0;:::o;31747:323::-;31808:7;32036:15;:13;:15::i;:::-;32021:12;;32005:13;;:28;:46;31998:53;;31747:323;:::o;77664:107::-;71451:13;:11;:13::i;:::-;77759:4:::1;77738:18;;:25;;;;;;;;;;;;;;;;;;77664:107:::0;:::o;46126:2825::-;46268:27;46298;46317:7;46298:18;:27::i;:::-;46268:57;;46383:4;46342:45;;46358:19;46342:45;;;46338:86;;46396:28;;;;;;;;;;;;;;46338:86;46438:27;46467:23;46494:35;46521:7;46494:26;:35::i;:::-;46437:92;;;;46629:68;46654:15;46671:4;46677:19;:17;:19::i;:::-;46629:24;:68::i;:::-;46624:180;;46717:43;46734:4;46740:19;:17;:19::i;:::-;46717:16;:43::i;:::-;46712:92;;46769:35;;;;;;;;;;;;;;46712:92;46624:180;46835:1;46821:16;;:2;:16;;;46817:52;;46846:23;;;;;;;;;;;;;;46817:52;46882:43;46904:4;46910:2;46914:7;46923:1;46882:21;:43::i;:::-;47018:15;47015:160;;;47158:1;47137:19;47130:30;47015:160;47555:18;:24;47574:4;47555:24;;;;;;;;;;;;;;;;47553:26;;;;;;;;;;;;47624:18;:22;47643:2;47624:22;;;;;;;;;;;;;;;;47622:24;;;;;;;;;;;47946:146;47983:2;48032:45;48047:4;48053:2;48057:19;48032:14;:45::i;:::-;28146:8;48004:73;47946:18;:146::i;:::-;47917:17;:26;47935:7;47917:26;;;;;;;;;;;:175;;;;48263:1;28146:8;48212:19;:47;:52;48208:627;;48285:19;48317:1;48307:7;:11;48285:33;;48474:1;48440:17;:30;48458:11;48440:30;;;;;;;;;;;;:35;48436:384;;48578:13;;48563:11;:28;48559:242;;48758:19;48725:17;:30;48743:11;48725:30;;;;;;;;;;;:52;;;;48559:242;48436:384;48266:569;48208:627;48882:7;48878:2;48863:27;;48872:4;48863:27;;;;;;;;;;;;48901:42;48922:4;48928:2;48932:7;48941:1;48901:20;:42::i;:::-;46257:2694;;;46126:2825;;;:::o;74011:719::-;2524:21;:19;:21::i;:::-;73361:4:::1;74099:37;;74116:8;74099:25;;:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:37;;74091:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;74206:7;:5;:7::i;:::-;74192:21;;:10;:21;;;74188:489;;74251:1;74240:8;:12;;;:30;;;;;74268:2;74256:8;:14;;;;74240:30;:72;;;;;74310:2;74298:8;74274:32;;:21;74284:10;74274:9;:21::i;:::-;:32;;;;:::i;:::-;:38;;74240:72;74232:123;;;;;;;;;;;;:::i;:::-;;;;;;;;;74372:20;74395:33;74407:10;74419:8;74395:11;:33::i;:::-;74372:56;;74453:4;:15;;;:30;;;;74472:4;:11;;;74453:30;74445:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;74562:9;74543:4;:15;;;:28;;74535:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;74657:8;74624:41;;:17;:29;74642:10;74624:29;;;;;;;;;;;;;;;;:41;;;;;;;:::i;:::-;;;;;;;;74215:462;74188:489;74689:31;74699:10;74711:8;74689:31;;:9;:31::i;:::-;2568:20:::0;:18;:20::i;:::-;74011:719;:::o;77779:102::-;71451:13;:11;:13::i;:::-;77870:3:::1;;77855:12;:18;;;;;;;:::i;:::-;;77779:102:::0;;:::o;78160:206::-;78224:4;78273:1;78245:17;:25;78263:6;78245:25;;;;;;;;;;;;;;;;:29;78241:118;;;78298:4;78291:11;;;;78241:118;78342:5;78335:12;;78160:206;;;;:::o;77506:150::-;71451:13;:11;:13::i;:::-;77556:12:::1;77571:21;77556:36;;77611:18;;;;;;;;;;;77603:36;;:45;77640:7;77603:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;77545:111;77506:150::o:0;49047:193::-;49193:39;49210:4;49216:2;49220:7;49193:39;;;;;;;;;;;;:16;:39::i;:::-;49047:193;;;:::o;76089:106::-;71451:13;:11;:13::i;:::-;76180:7:::1;;76164:13;:23;;;;;;;:::i;:::-;;76089:106:::0;;:::o;76609:92::-;71451:13;:11;:13::i;:::-;76687:6:::1;76671:13;;:22;;;;;;;;;;;;;;;;;;76609:92:::0;:::o;76344:152::-;71451:13;:11;:13::i;:::-;76436:5:::1;76420:13;;:21;;;;;;;;;;;;;;;;;;76472:16;76452:17;;:36;;;;;;;;;;;;;;;;;;76344:152:::0;:::o;77983:169::-;78027:4;78048:17;;;;;;;;;;;:34;;;;78069:13;;;;;;;;;;;78048:34;78044:78;;;78106:4;78099:11;;;;78044:78;78139:5;78132:12;;77983:169;;:::o;78375:197::-;78433:4;78476;78454:26;;:10;:18;78465:6;78454:18;;;;;;;;;;;;;;;;;;;;;;;;;:26;;;78450:115;;78504:4;78497:11;;;;78450:115;78548:5;78541:12;;78375:197;;;;:::o;37389:152::-;37461:7;37504:27;37523:7;37504:18;:27::i;:::-;37481:52;;37389:152;;;:::o;32931:233::-;33003:7;33044:1;33027:19;;:5;:19;;;33023:60;;33055:28;;;;;;;;;;;;;;33023:60;27090:13;33101:18;:25;33120:5;33101:25;;;;;;;;;;;;;;;;:55;33094:62;;32931:233;;;:::o;72213:103::-;71451:13;:11;:13::i;:::-;72278:30:::1;72305:1;72278:18;:30::i;:::-;72213:103::o:0;71565:87::-;71611:7;71638:6;;;;;;;;;;;71631:13;;71565:87;:::o;36172:104::-;36228:13;36261:7;36254:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36172:104;:::o;43045:234::-;43192:8;43140:18;:39;43159:19;:17;:19::i;:::-;43140:39;;;;;;;;;;;;;;;:49;43180:8;43140:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;43252:8;43216:55;;43231:19;:17;:19::i;:::-;43216:55;;;43262:8;43216:55;;;;;;:::i;:::-;;;;;;;;43045:234;;:::o;76504:94::-;76549:4;76573:17;;;;;;;;;;;76566:24;;76504:94;:::o;49838:407::-;50013:31;50026:4;50032:2;50036:7;50013:12;:31::i;:::-;50077:1;50059:2;:14;;;:19;50055:183;;50098:56;50129:4;50135:2;50139:7;50148:5;50098:30;:56::i;:::-;50093:145;;50182:40;;;;;;;;;;;;;;50093:145;50055:183;49838:407;;;;:::o;77127:89::-;71451:13;:11;:13::i;:::-;77203:5:::1;77192:8;;:16;;;;;;;;;;;;;;;;;;77127:89:::0;:::o;76713:86::-;76754:4;76778:13;;;;;;;;;;;76771:20;;76713:86;:::o;74735:353::-;74800:13;74839:16;74847:7;74839;:16::i;:::-;74831:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;74954:1;74933:10;:8;:10::i;:::-;74927:24;:28;:156;;75071:12;74927:156;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74996:10;:8;:10::i;:::-;75008:18;:7;:16;:18::i;:::-;75029:8;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74979:75;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;74927:156;74920:163;;74735:353;;;:::o;75096:777::-;75170:15;;:::i;:::-;75200:23;75240:14;75257:11;75240:28;;75302:4;75285:21;;:13;;;;;;;;;;;:21;;;75281:74;;75332:11;75323:20;;75281:74;75367:20;75390:8;75367:31;;75442:1;75414:17;:24;75432:5;75414:24;;;;;;;;;;;;;;;;:29;75411:104;;75487:16;75476:8;:27;;;;:::i;:::-;75460:43;;75411:104;75534:331;;;;;;;;75573:6;75534:331;;;;75627:8;75618:17;;:6;:17;;;;:::i;:::-;75534:331;;;;75676:13;75667:22;;:6;:22;;;;:::i;:::-;75534:331;;;;75721:17;;;;;;;;;;;75534:331;;;;;;75766:13;;;;;;;;;;;75534:331;;;;;;75811:8;75534:331;;;;;;75851:13;75534:331;;;;;75527:338;;;;;75096:777;;;;:::o;73187:103::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;76932:187::-;71451:13;:11;:13::i;:::-;77019:6:::1;77014:98;77031:9;:16;77029:1;:18;77014:98;;;77096:4;77069:10;:24;77080:9;77090:1;77080:12;;;;;;;;:::i;:::-;;;;;;;;77069:24;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;77049:3;;;;;:::i;:::-;;;;77014:98;;;;76932:187:::0;:::o;43436:164::-;43533:4;43557:18;:25;43576:5;43557:25;;;;;;;;;;;;;;;:35;43583:8;43557:35;;;;;;;;;;;;;;;;;;;;;;;;;43550:42;;43436:164;;;;:::o;77267:190::-;71451:13;:11;:13::i;:::-;73361:4:::1;77351:37;;77368:8;77351:25;;:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:37;;77343:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;77429:23;77439:2;77443:8;77429:23;;:9;:23::i;:::-;77267:190:::0;;:::o;72471:201::-;71451:13;:11;:13::i;:::-;72580:1:::1;72560:22;;:8;:22;;::::0;72552:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;72636:28;72655:8;72636:18;:28::i;:::-;72471:201:::0;:::o;76203:133::-;76271:4;76295:17;:33;76313:14;76295:33;;;;;;;;;;;;;;;;76288:40;;76203:133;;;:::o;43858:282::-;43923:4;43979:7;43960:15;:13;:15::i;:::-;:26;;:66;;;;;44013:13;;44003:7;:23;43960:66;:153;;;;;44112:1;27866:8;44064:17;:26;44082:7;44064:26;;;;;;;;;;;;:44;:49;43960:153;43940:173;;43858:282;;;:::o;66166:105::-;66226:7;66253:10;66246:17;;66166:105;:::o;71730:132::-;71805:12;:10;:12::i;:::-;71794:23;;:7;:5;:7::i;:::-;:23;;;71786:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71730:132::o;75878:81::-;75935:4;75953:1;75946:8;;75878:81;:::o;38544:1275::-;38611:7;38631:12;38646:7;38631:22;;38714:4;38695:15;:13;:15::i;:::-;:23;38691:1061;;38748:13;;38741:4;:20;38737:1015;;;38786:14;38803:17;:23;38821:4;38803:23;;;;;;;;;;;;38786:40;;38920:1;27866:8;38892:6;:24;:29;38888:845;;39557:113;39574:1;39564:6;:11;39557:113;;39617:17;:25;39635:6;;;;;;;39617:25;;;;;;;;;;;;39608:34;;39557:113;;;39703:6;39696:13;;;;;;38888:845;38763:989;38737:1015;38691:1061;39780:31;;;;;;;;;;;;;;38544:1275;;;;:::o;45021:485::-;45123:27;45152:23;45193:38;45234:15;:24;45250:7;45234:24;;;;;;;;;;;45193:65;;45411:18;45388:41;;45468:19;45462:26;45443:45;;45373:126;45021:485;;;:::o;44249:659::-;44398:11;44563:16;44556:5;44552:28;44543:37;;44723:16;44712:9;44708:32;44695:45;;44873:15;44862:9;44859:30;44851:5;44840:9;44837:20;44834:56;44824:66;;44249:659;;;;;:::o;50907:159::-;;;;;:::o;65475:311::-;65610:7;65630:16;28270:3;65656:19;:41;;65630:68;;28270:3;65724:31;65735:4;65741:2;65745:9;65724:10;:31::i;:::-;65716:40;;:62;;65709:69;;;65475:311;;;;;:::o;40367:450::-;40447:14;40615:16;40608:5;40604:28;40595:37;;40792:5;40778:11;40753:23;40749:41;40746:52;40739:5;40736:63;40726:73;;40367:450;;;;:::o;51731:158::-;;;;;:::o;2604:293::-;2006:1;2738:7;;:19;2730:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;2006:1;2871:7;:18;;;;2604:293::o;32168:296::-;32223:7;32430:15;:13;:15::i;:::-;32414:13;;:31;32407:38;;32168:296;:::o;59998:112::-;60075:27;60085:2;60089:8;60075:27;;;;;;;;;;;;:9;:27::i;:::-;59998:112;;:::o;2905:213::-;1962:1;3088:7;:22;;;;2905:213::o;72832:191::-;72906:16;72925:6;;;;;;;;;;;72906:25;;72951:8;72942:6;;:17;;;;;;;;;;;;;;;;;;73006:8;72975:40;;72996:8;72975:40;;;;;;;;;;;;72895:128;72832:191;:::o;52329:716::-;52492:4;52538:2;52513:45;;;52559:19;:17;:19::i;:::-;52580:4;52586:7;52595:5;52513:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;52509:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52813:1;52796:6;:13;:18;52792:235;;52842:40;;;;;;;;;;;;;;52792:235;52985:6;52979:13;52970:6;52966:2;52962:15;52955:38;52509:529;52682:54;;;52672:64;;;:6;:64;;;;52665:71;;;52329:716;;;;;;:::o;75967:114::-;76027:13;76060;76053:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75967:114;:::o;68495:716::-;68551:13;68602:14;68639:1;68619:17;68630:5;68619:10;:17::i;:::-;:21;68602:38;;68655:20;68689:6;68678:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68655:41;;68711:11;68840:6;68836:2;68832:15;68824:6;68820:28;68813:35;;68877:288;68884:4;68877:288;;;68909:5;;;;;;;;69051:8;69046:2;69039:5;69035:14;69030:30;69025:3;69017:44;69107:2;69098:11;;;;;;:::i;:::-;;;;;69141:1;69132:5;:10;68877:288;69128:21;68877:288;69186:6;69179:13;;;;;68495:716;;;:::o;25882:98::-;25935:7;25962:10;25955:17;;25882:98;:::o;65176:147::-;65313:6;65176:147;;;;;:::o;59225:689::-;59356:19;59362:2;59366:8;59356:5;:19::i;:::-;59435:1;59417:2;:14;;;:19;59413:483;;59457:11;59471:13;;59457:27;;59503:13;59525:8;59519:3;:14;59503:30;;59552:233;59583:62;59622:1;59626:2;59630:7;;;;;;59639:5;59583:30;:62::i;:::-;59578:167;;59681:40;;;;;;;;;;;;;;59578:167;59780:3;59772:5;:11;59552:233;;59867:3;59850:13;;:20;59846:34;;59872:8;;;59846:34;59438:458;;59413:483;59225:689;;;:::o;22553:922::-;22606:7;22626:14;22643:1;22626:18;;22693:6;22684:5;:15;22680:102;;22729:6;22720:15;;;;;;:::i;:::-;;;;;22764:2;22754:12;;;;22680:102;22809:6;22800:5;:15;22796:102;;22845:6;22836:15;;;;;;:::i;:::-;;;;;22880:2;22870:12;;;;22796:102;22925:6;22916:5;:15;22912:102;;22961:6;22952:15;;;;;;:::i;:::-;;;;;22996:2;22986:12;;;;22912:102;23041:5;23032;:14;23028:99;;23076:5;23067:14;;;;;;:::i;:::-;;;;;23110:1;23100:11;;;;23028:99;23154:5;23145;:14;23141:99;;23189:5;23180:14;;;;;;:::i;:::-;;;;;23223:1;23213:11;;;;23141:99;23267:5;23258;:14;23254:99;;23302:5;23293:14;;;;;;:::i;:::-;;;;;23336:1;23326:11;;;;23254:99;23380:5;23371;:14;23367:66;;23416:1;23406:11;;;;23367:66;23461:6;23454:13;;;22553:922;;;:::o;53507:2966::-;53580:20;53603:13;;53580:36;;53643:1;53631:8;:13;53627:44;;53653:18;;;;;;;;;;;;;;53627:44;53684:61;53714:1;53718:2;53722:12;53736:8;53684:21;:61::i;:::-;54228:1;27228:2;54198:1;:26;;54197:32;54185:8;:45;54159:18;:22;54178:2;54159:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;54507:139;54544:2;54598:33;54621:1;54625:2;54629:1;54598:14;:33::i;:::-;54565:30;54586:8;54565:20;:30::i;:::-;:66;54507:18;:139::i;:::-;54473:17;:31;54491:12;54473:31;;;;;;;;;;;:173;;;;54663:16;54694:11;54723:8;54708:12;:23;54694:37;;55244:16;55240:2;55236:25;55224:37;;55616:12;55576:8;55535:1;55473:25;55414:1;55353;55326:335;55987:1;55973:12;55969:20;55927:346;56028:3;56019:7;56016:16;55927:346;;56246:7;56236:8;56233:1;56206:25;56203:1;56200;56195:59;56081:1;56072:7;56068:15;56057:26;;55927:346;;;55931:77;56318:1;56306:8;:13;56302:45;;56328:19;;;;;;;;;;;;;;56302:45;56380:3;56364:13;:19;;;;53933:2462;;56405:60;56434:1;56438:2;56442:12;56456:8;56405:20;:60::i;:::-;53569:2904;53507:2966;;:::o;40919:324::-;40989:14;41222:1;41212:8;41209:15;41183:24;41179:46;41169:56;;40919:324;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:75::-;475:6;508:2;502:9;492:19;;442:75;:::o;523:117::-;632:1;629;622:12;646:117;755:1;752;745:12;769:149;805:7;845:66;838:5;834:78;823:89;;769:149;;;:::o;924:120::-;996:23;1013:5;996:23;:::i;:::-;989:5;986:34;976:62;;1034:1;1031;1024:12;976:62;924:120;:::o;1050:137::-;1095:5;1133:6;1120:20;1111:29;;1149:32;1175:5;1149:32;:::i;:::-;1050:137;;;;:::o;1193:327::-;1251:6;1300:2;1288:9;1279:7;1275:23;1271:32;1268:119;;;1306:79;;:::i;:::-;1268:119;1426:1;1451:52;1495:7;1486:6;1475:9;1471:22;1451:52;:::i;:::-;1441:62;;1397:116;1193:327;;;;:::o;1526:90::-;1560:7;1603:5;1596:13;1589:21;1578:32;;1526:90;;;:::o;1622:109::-;1703:21;1718:5;1703:21;:::i;:::-;1698:3;1691:34;1622:109;;:::o;1737:210::-;1824:4;1862:2;1851:9;1847:18;1839:26;;1875:65;1937:1;1926:9;1922:17;1913:6;1875:65;:::i;:::-;1737:210;;;;:::o;1953:99::-;2005:6;2039:5;2033:12;2023:22;;1953:99;;;:::o;2058:169::-;2142:11;2176:6;2171:3;2164:19;2216:4;2211:3;2207:14;2192:29;;2058:169;;;;:::o;2233:246::-;2314:1;2324:113;2338:6;2335:1;2332:13;2324:113;;;2423:1;2418:3;2414:11;2408:18;2404:1;2399:3;2395:11;2388:39;2360:2;2357:1;2353:10;2348:15;;2324:113;;;2471:1;2462:6;2457:3;2453:16;2446:27;2295:184;2233:246;;;:::o;2485:102::-;2526:6;2577:2;2573:7;2568:2;2561:5;2557:14;2553:28;2543:38;;2485:102;;;:::o;2593:377::-;2681:3;2709:39;2742:5;2709:39;:::i;:::-;2764:71;2828:6;2823:3;2764:71;:::i;:::-;2757:78;;2844:65;2902:6;2897:3;2890:4;2883:5;2879:16;2844:65;:::i;:::-;2934:29;2956:6;2934:29;:::i;:::-;2929:3;2925:39;2918:46;;2685:285;2593:377;;;;:::o;2976:313::-;3089:4;3127:2;3116:9;3112:18;3104:26;;3176:9;3170:4;3166:20;3162:1;3151:9;3147:17;3140:47;3204:78;3277:4;3268:6;3204:78;:::i;:::-;3196:86;;2976:313;;;;:::o;3295:122::-;3368:24;3386:5;3368:24;:::i;:::-;3361:5;3358:35;3348:63;;3407:1;3404;3397:12;3348:63;3295:122;:::o;3423:139::-;3469:5;3507:6;3494:20;3485:29;;3523:33;3550:5;3523:33;:::i;:::-;3423:139;;;;:::o;3568:329::-;3627:6;3676:2;3664:9;3655:7;3651:23;3647:32;3644:119;;;3682:79;;:::i;:::-;3644:119;3802:1;3827:53;3872:7;3863:6;3852:9;3848:22;3827:53;:::i;:::-;3817:63;;3773:117;3568:329;;;;:::o;3903:126::-;3940:7;3980:42;3973:5;3969:54;3958:65;;3903:126;;;:::o;4035:96::-;4072:7;4101:24;4119:5;4101:24;:::i;:::-;4090:35;;4035:96;;;:::o;4137:118::-;4224:24;4242:5;4224:24;:::i;:::-;4219:3;4212:37;4137:118;;:::o;4261:222::-;4354:4;4392:2;4381:9;4377:18;4369:26;;4405:71;4473:1;4462:9;4458:17;4449:6;4405:71;:::i;:::-;4261:222;;;;:::o;4489:122::-;4562:24;4580:5;4562:24;:::i;:::-;4555:5;4552:35;4542:63;;4601:1;4598;4591:12;4542:63;4489:122;:::o;4617:139::-;4663:5;4701:6;4688:20;4679:29;;4717:33;4744:5;4717:33;:::i;:::-;4617:139;;;;:::o;4762:474::-;4830:6;4838;4887:2;4875:9;4866:7;4862:23;4858:32;4855:119;;;4893:79;;:::i;:::-;4855:119;5013:1;5038:53;5083:7;5074:6;5063:9;5059:22;5038:53;:::i;:::-;5028:63;;4984:117;5140:2;5166:53;5211:7;5202:6;5191:9;5187:22;5166:53;:::i;:::-;5156:63;;5111:118;4762:474;;;;;:::o;5242:329::-;5301:6;5350:2;5338:9;5329:7;5325:23;5321:32;5318:119;;;5356:79;;:::i;:::-;5318:119;5476:1;5501:53;5546:7;5537:6;5526:9;5522:22;5501:53;:::i;:::-;5491:63;;5447:117;5242:329;;;;:::o;5577:619::-;5654:6;5662;5670;5719:2;5707:9;5698:7;5694:23;5690:32;5687:119;;;5725:79;;:::i;:::-;5687:119;5845:1;5870:53;5915:7;5906:6;5895:9;5891:22;5870:53;:::i;:::-;5860:63;;5816:117;5972:2;5998:53;6043:7;6034:6;6023:9;6019:22;5998:53;:::i;:::-;5988:63;;5943:118;6100:2;6126:53;6171:7;6162:6;6151:9;6147:22;6126:53;:::i;:::-;6116:63;;6071:118;5577:619;;;;;:::o;6202:89::-;6238:7;6278:6;6271:5;6267:18;6256:29;;6202:89;;;:::o;6297:120::-;6369:23;6386:5;6369:23;:::i;:::-;6362:5;6359:34;6349:62;;6407:1;6404;6397:12;6349:62;6297:120;:::o;6423:137::-;6468:5;6506:6;6493:20;6484:29;;6522:32;6548:5;6522:32;:::i;:::-;6423:137;;;;:::o;6566:327::-;6624:6;6673:2;6661:9;6652:7;6648:23;6644:32;6641:119;;;6679:79;;:::i;:::-;6641:119;6799:1;6824:52;6868:7;6859:6;6848:9;6844:22;6824:52;:::i;:::-;6814:62;;6770:116;6566:327;;;;:::o;6899:117::-;7008:1;7005;6998:12;7022:117;7131:1;7128;7121:12;7145:117;7254:1;7251;7244:12;7282:553;7340:8;7350:6;7400:3;7393:4;7385:6;7381:17;7377:27;7367:122;;7408:79;;:::i;:::-;7367:122;7521:6;7508:20;7498:30;;7551:18;7543:6;7540:30;7537:117;;;7573:79;;:::i;:::-;7537:117;7687:4;7679:6;7675:17;7663:29;;7741:3;7733:4;7725:6;7721:17;7711:8;7707:32;7704:41;7701:128;;;7748:79;;:::i;:::-;7701:128;7282:553;;;;;:::o;7841:529::-;7912:6;7920;7969:2;7957:9;7948:7;7944:23;7940:32;7937:119;;;7975:79;;:::i;:::-;7937:119;8123:1;8112:9;8108:17;8095:31;8153:18;8145:6;8142:30;8139:117;;;8175:79;;:::i;:::-;8139:117;8288:65;8345:7;8336:6;8325:9;8321:22;8288:65;:::i;:::-;8270:83;;;;8066:297;7841:529;;;;;:::o;8376:116::-;8446:21;8461:5;8446:21;:::i;:::-;8439:5;8436:32;8426:60;;8482:1;8479;8472:12;8426:60;8376:116;:::o;8498:133::-;8541:5;8579:6;8566:20;8557:29;;8595:30;8619:5;8595:30;:::i;:::-;8498:133;;;;:::o;8637:323::-;8693:6;8742:2;8730:9;8721:7;8717:23;8713:32;8710:119;;;8748:79;;:::i;:::-;8710:119;8868:1;8893:50;8935:7;8926:6;8915:9;8911:22;8893:50;:::i;:::-;8883:60;;8839:114;8637:323;;;;:::o;8966:468::-;9031:6;9039;9088:2;9076:9;9067:7;9063:23;9059:32;9056:119;;;9094:79;;:::i;:::-;9056:119;9214:1;9239:53;9284:7;9275:6;9264:9;9260:22;9239:53;:::i;:::-;9229:63;;9185:117;9341:2;9367:50;9409:7;9400:6;9389:9;9385:22;9367:50;:::i;:::-;9357:60;;9312:115;8966:468;;;;;:::o;9440:117::-;9549:1;9546;9539:12;9563:180;9611:77;9608:1;9601:88;9708:4;9705:1;9698:15;9732:4;9729:1;9722:15;9749:281;9832:27;9854:4;9832:27;:::i;:::-;9824:6;9820:40;9962:6;9950:10;9947:22;9926:18;9914:10;9911:34;9908:62;9905:88;;;9973:18;;:::i;:::-;9905:88;10013:10;10009:2;10002:22;9792:238;9749:281;;:::o;10036:129::-;10070:6;10097:20;;:::i;:::-;10087:30;;10126:33;10154:4;10146:6;10126:33;:::i;:::-;10036:129;;;:::o;10171:307::-;10232:4;10322:18;10314:6;10311:30;10308:56;;;10344:18;;:::i;:::-;10308:56;10382:29;10404:6;10382:29;:::i;:::-;10374:37;;10466:4;10460;10456:15;10448:23;;10171:307;;;:::o;10484:146::-;10581:6;10576:3;10571;10558:30;10622:1;10613:6;10608:3;10604:16;10597:27;10484:146;;;:::o;10636:423::-;10713:5;10738:65;10754:48;10795:6;10754:48;:::i;:::-;10738:65;:::i;:::-;10729:74;;10826:6;10819:5;10812:21;10864:4;10857:5;10853:16;10902:3;10893:6;10888:3;10884:16;10881:25;10878:112;;;10909:79;;:::i;:::-;10878:112;10999:54;11046:6;11041:3;11036;10999:54;:::i;:::-;10719:340;10636:423;;;;;:::o;11078:338::-;11133:5;11182:3;11175:4;11167:6;11163:17;11159:27;11149:122;;11190:79;;:::i;:::-;11149:122;11307:6;11294:20;11332:78;11406:3;11398:6;11391:4;11383:6;11379:17;11332:78;:::i;:::-;11323:87;;11139:277;11078:338;;;;:::o;11422:943::-;11517:6;11525;11533;11541;11590:3;11578:9;11569:7;11565:23;11561:33;11558:120;;;11597:79;;:::i;:::-;11558:120;11717:1;11742:53;11787:7;11778:6;11767:9;11763:22;11742:53;:::i;:::-;11732:63;;11688:117;11844:2;11870:53;11915:7;11906:6;11895:9;11891:22;11870:53;:::i;:::-;11860:63;;11815:118;11972:2;11998:53;12043:7;12034:6;12023:9;12019:22;11998:53;:::i;:::-;11988:63;;11943:118;12128:2;12117:9;12113:18;12100:32;12159:18;12151:6;12148:30;12145:117;;;12181:79;;:::i;:::-;12145:117;12286:62;12340:7;12331:6;12320:9;12316:22;12286:62;:::i;:::-;12276:72;;12071:287;11422:943;;;;;;;:::o;12371:472::-;12438:6;12446;12495:2;12483:9;12474:7;12470:23;12466:32;12463:119;;;12501:79;;:::i;:::-;12463:119;12621:1;12646:53;12691:7;12682:6;12671:9;12667:22;12646:53;:::i;:::-;12636:63;;12592:117;12748:2;12774:52;12818:7;12809:6;12798:9;12794:22;12774:52;:::i;:::-;12764:62;;12719:117;12371:472;;;;;:::o;12849:108::-;12926:24;12944:5;12926:24;:::i;:::-;12921:3;12914:37;12849:108;;:::o;12963:99::-;13034:21;13049:5;13034:21;:::i;:::-;13029:3;13022:34;12963:99;;:::o;13068:105::-;13143:23;13160:5;13143:23;:::i;:::-;13138:3;13131:36;13068:105;;:::o;13221:1407::-;13370:4;13365:3;13361:14;13462:4;13455:5;13451:16;13445:23;13481:63;13538:4;13533:3;13529:14;13515:12;13481:63;:::i;:::-;13385:169;13649:4;13642:5;13638:16;13632:23;13668:63;13725:4;13720:3;13716:14;13702:12;13668:63;:::i;:::-;13564:177;13829:4;13822:5;13818:16;13812:23;13848:63;13905:4;13900:3;13896:14;13882:12;13848:63;:::i;:::-;13751:170;14009:4;14002:5;13998:16;13992:23;14028:57;14079:4;14074:3;14070:14;14056:12;14028:57;:::i;:::-;13931:164;14179:4;14172:5;14168:16;14162:23;14198:57;14249:4;14244:3;14240:14;14226:12;14198:57;:::i;:::-;14105:160;14353:4;14346:5;14342:16;14336:23;14372:61;14427:4;14422:3;14418:14;14404:12;14372:61;:::i;:::-;14275:168;14531:4;14524:5;14520:16;14514:23;14550:61;14605:4;14600:3;14596:14;14582:12;14550:61;:::i;:::-;14453:168;13339:1289;13221:1407;;:::o;14634:327::-;14779:4;14817:3;14806:9;14802:19;14794:27;;14831:123;14951:1;14940:9;14936:17;14927:6;14831:123;:::i;:::-;14634:327;;;;:::o;14967:311::-;15044:4;15134:18;15126:6;15123:30;15120:56;;;15156:18;;:::i;:::-;15120:56;15206:4;15198:6;15194:17;15186:25;;15266:4;15260;15256:15;15248:23;;14967:311;;;:::o;15301:710::-;15397:5;15422:81;15438:64;15495:6;15438:64;:::i;:::-;15422:81;:::i;:::-;15413:90;;15523:5;15552:6;15545:5;15538:21;15586:4;15579:5;15575:16;15568:23;;15639:4;15631:6;15627:17;15619:6;15615:30;15668:3;15660:6;15657:15;15654:122;;;15687:79;;:::i;:::-;15654:122;15802:6;15785:220;15819:6;15814:3;15811:15;15785:220;;;15894:3;15923:37;15956:3;15944:10;15923:37;:::i;:::-;15918:3;15911:50;15990:4;15985:3;15981:14;15974:21;;15861:144;15845:4;15840:3;15836:14;15829:21;;15785:220;;;15789:21;15403:608;;15301:710;;;;;:::o;16034:370::-;16105:5;16154:3;16147:4;16139:6;16135:17;16131:27;16121:122;;16162:79;;:::i;:::-;16121:122;16279:6;16266:20;16304:94;16394:3;16386:6;16379:4;16371:6;16367:17;16304:94;:::i;:::-;16295:103;;16111:293;16034:370;;;;:::o;16410:539::-;16494:6;16543:2;16531:9;16522:7;16518:23;16514:32;16511:119;;;16549:79;;:::i;:::-;16511:119;16697:1;16686:9;16682:17;16669:31;16727:18;16719:6;16716:30;16713:117;;;16749:79;;:::i;:::-;16713:117;16854:78;16924:7;16915:6;16904:9;16900:22;16854:78;:::i;:::-;16844:88;;16640:302;16410:539;;;;:::o;16955:474::-;17023:6;17031;17080:2;17068:9;17059:7;17055:23;17051:32;17048:119;;;17086:79;;:::i;:::-;17048:119;17206:1;17231:53;17276:7;17267:6;17256:9;17252:22;17231:53;:::i;:::-;17221:63;;17177:117;17333:2;17359:53;17404:7;17395:6;17384:9;17380:22;17359:53;:::i;:::-;17349:63;;17304:118;16955:474;;;;;:::o;17435:180::-;17483:77;17480:1;17473:88;17580:4;17577:1;17570:15;17604:4;17601:1;17594:15;17621:320;17665:6;17702:1;17696:4;17692:12;17682:22;;17749:1;17743:4;17739:12;17770:18;17760:81;;17826:4;17818:6;17814:17;17804:27;;17760:81;17888:2;17880:6;17877:14;17857:18;17854:38;17851:84;;17907:18;;:::i;:::-;17851:84;17672:269;17621:320;;;:::o;17947:180::-;17995:77;17992:1;17985:88;18092:4;18089:1;18082:15;18116:4;18113:1;18106:15;18133:191;18173:3;18192:20;18210:1;18192:20;:::i;:::-;18187:25;;18226:20;18244:1;18226:20;:::i;:::-;18221:25;;18269:1;18266;18262:9;18255:16;;18290:3;18287:1;18284:10;18281:36;;;18297:18;;:::i;:::-;18281:36;18133:191;;;;:::o;18330:180::-;18470:32;18466:1;18458:6;18454:14;18447:56;18330:180;:::o;18516:366::-;18658:3;18679:67;18743:2;18738:3;18679:67;:::i;:::-;18672:74;;18755:93;18844:3;18755:93;:::i;:::-;18873:2;18868:3;18864:12;18857:19;;18516:366;;;:::o;18888:419::-;19054:4;19092:2;19081:9;19077:18;19069:26;;19141:9;19135:4;19131:20;19127:1;19116:9;19112:17;19105:47;19169:131;19295:4;19169:131;:::i;:::-;19161:139;;18888:419;;;:::o;19313:225::-;19453:34;19449:1;19441:6;19437:14;19430:58;19522:8;19517:2;19509:6;19505:15;19498:33;19313:225;:::o;19544:366::-;19686:3;19707:67;19771:2;19766:3;19707:67;:::i;:::-;19700:74;;19783:93;19872:3;19783:93;:::i;:::-;19901:2;19896:3;19892:12;19885:19;;19544:366;;;:::o;19916:419::-;20082:4;20120:2;20109:9;20105:18;20097:26;;20169:9;20163:4;20159:20;20155:1;20144:9;20140:17;20133:47;20197:131;20323:4;20197:131;:::i;:::-;20189:139;;19916:419;;;:::o;20341:168::-;20481:20;20477:1;20469:6;20465:14;20458:44;20341:168;:::o;20515:366::-;20657:3;20678:67;20742:2;20737:3;20678:67;:::i;:::-;20671:74;;20754:93;20843:3;20754:93;:::i;:::-;20872:2;20867:3;20863:12;20856:19;;20515:366;;;:::o;20887:419::-;21053:4;21091:2;21080:9;21076:18;21068:26;;21140:9;21134:4;21130:20;21126:1;21115:9;21111:17;21104:47;21168:131;21294:4;21168:131;:::i;:::-;21160:139;;20887:419;;;:::o;21312:181::-;21452:33;21448:1;21440:6;21436:14;21429:57;21312:181;:::o;21499:366::-;21641:3;21662:67;21726:2;21721:3;21662:67;:::i;:::-;21655:74;;21738:93;21827:3;21738:93;:::i;:::-;21856:2;21851:3;21847:12;21840:19;;21499:366;;;:::o;21871:419::-;22037:4;22075:2;22064:9;22060:18;22052:26;;22124:9;22118:4;22114:20;22110:1;22099:9;22095:17;22088:47;22152:131;22278:4;22152:131;:::i;:::-;22144:139;;21871:419;;;:::o;22296:97::-;22355:6;22383:3;22373:13;;22296:97;;;;:::o;22399:141::-;22448:4;22471:3;22463:11;;22494:3;22491:1;22484:14;22528:4;22525:1;22515:18;22507:26;;22399:141;;;:::o;22546:93::-;22583:6;22630:2;22625;22618:5;22614:14;22610:23;22600:33;;22546:93;;;:::o;22645:107::-;22689:8;22739:5;22733:4;22729:16;22708:37;;22645:107;;;;:::o;22758:393::-;22827:6;22877:1;22865:10;22861:18;22900:97;22930:66;22919:9;22900:97;:::i;:::-;23018:39;23048:8;23037:9;23018:39;:::i;:::-;23006:51;;23090:4;23086:9;23079:5;23075:21;23066:30;;23139:4;23129:8;23125:19;23118:5;23115:30;23105:40;;22834:317;;22758:393;;;;;:::o;23157:60::-;23185:3;23206:5;23199:12;;23157:60;;;:::o;23223:142::-;23273:9;23306:53;23324:34;23333:24;23351:5;23333:24;:::i;:::-;23324:34;:::i;:::-;23306:53;:::i;:::-;23293:66;;23223:142;;;:::o;23371:75::-;23414:3;23435:5;23428:12;;23371:75;;;:::o;23452:269::-;23562:39;23593:7;23562:39;:::i;:::-;23623:91;23672:41;23696:16;23672:41;:::i;:::-;23664:6;23657:4;23651:11;23623:91;:::i;:::-;23617:4;23610:105;23528:193;23452:269;;;:::o;23727:73::-;23772:3;23727:73;:::o;23806:189::-;23883:32;;:::i;:::-;23924:65;23982:6;23974;23968:4;23924:65;:::i;:::-;23859:136;23806:189;;:::o;24001:186::-;24061:120;24078:3;24071:5;24068:14;24061:120;;;24132:39;24169:1;24162:5;24132:39;:::i;:::-;24105:1;24098:5;24094:13;24085:22;;24061:120;;;24001:186;;:::o;24193:543::-;24294:2;24289:3;24286:11;24283:446;;;24328:38;24360:5;24328:38;:::i;:::-;24412:29;24430:10;24412:29;:::i;:::-;24402:8;24398:44;24595:2;24583:10;24580:18;24577:49;;;24616:8;24601:23;;24577:49;24639:80;24695:22;24713:3;24695:22;:::i;:::-;24685:8;24681:37;24668:11;24639:80;:::i;:::-;24298:431;;24283:446;24193:543;;;:::o;24742:117::-;24796:8;24846:5;24840:4;24836:16;24815:37;;24742:117;;;;:::o;24865:169::-;24909:6;24942:51;24990:1;24986:6;24978:5;24975:1;24971:13;24942:51;:::i;:::-;24938:56;25023:4;25017;25013:15;25003:25;;24916:118;24865:169;;;;:::o;25039:295::-;25115:4;25261:29;25286:3;25280:4;25261:29;:::i;:::-;25253:37;;25323:3;25320:1;25316:11;25310:4;25307:21;25299:29;;25039:295;;;;:::o;25339:1403::-;25463:44;25503:3;25498;25463:44;:::i;:::-;25572:18;25564:6;25561:30;25558:56;;;25594:18;;:::i;:::-;25558:56;25638:38;25670:4;25664:11;25638:38;:::i;:::-;25723:67;25783:6;25775;25769:4;25723:67;:::i;:::-;25817:1;25846:2;25838:6;25835:14;25863:1;25858:632;;;;26534:1;26551:6;26548:84;;;26607:9;26602:3;26598:19;26585:33;26576:42;;26548:84;26658:67;26718:6;26711:5;26658:67;:::i;:::-;26652:4;26645:81;26507:229;25828:908;;25858:632;25910:4;25906:9;25898:6;25894:22;25944:37;25976:4;25944:37;:::i;:::-;26003:1;26017:215;26031:7;26028:1;26025:14;26017:215;;;26117:9;26112:3;26108:19;26095:33;26087:6;26080:49;26168:1;26160:6;26156:14;26146:24;;26215:2;26204:9;26200:18;26187:31;;26054:4;26051:1;26047:12;26042:17;;26017:215;;;26260:6;26251:7;26248:19;26245:186;;;26325:9;26320:3;26316:19;26303:33;26368:48;26410:4;26402:6;26398:17;26387:9;26368:48;:::i;:::-;26360:6;26353:64;26268:163;26245:186;26477:1;26473;26465:6;26461:14;26457:22;26451:4;26444:36;25865:625;;;25828:908;;25438:1304;;;25339:1403;;;:::o;26748:234::-;26888:34;26884:1;26876:6;26872:14;26865:58;26957:17;26952:2;26944:6;26940:15;26933:42;26748:234;:::o;26988:366::-;27130:3;27151:67;27215:2;27210:3;27151:67;:::i;:::-;27144:74;;27227:93;27316:3;27227:93;:::i;:::-;27345:2;27340:3;27336:12;27329:19;;26988:366;;;:::o;27360:419::-;27526:4;27564:2;27553:9;27549:18;27541:26;;27613:9;27607:4;27603:20;27599:1;27588:9;27584:17;27577:47;27641:131;27767:4;27641:131;:::i;:::-;27633:139;;27360:419;;;:::o;27785:148::-;27887:11;27924:3;27909:18;;27785:148;;;;:::o;27939:390::-;28045:3;28073:39;28106:5;28073:39;:::i;:::-;28128:89;28210:6;28205:3;28128:89;:::i;:::-;28121:96;;28226:65;28284:6;28279:3;28272:4;28265:5;28261:16;28226:65;:::i;:::-;28316:6;28311:3;28307:16;28300:23;;28049:280;27939:390;;;;:::o;28335:595::-;28563:3;28585:95;28676:3;28667:6;28585:95;:::i;:::-;28578:102;;28697:95;28788:3;28779:6;28697:95;:::i;:::-;28690:102;;28809:95;28900:3;28891:6;28809:95;:::i;:::-;28802:102;;28921:3;28914:10;;28335:595;;;;;;:::o;28936:196::-;28975:4;28995:19;29012:1;28995:19;:::i;:::-;28990:24;;29028:19;29045:1;29028:19;:::i;:::-;29023:24;;29071:1;29068;29064:9;29056:17;;29095:6;29089:4;29086:16;29083:42;;;29105:18;;:::i;:::-;29083:42;28936:196;;;;:::o;29138:410::-;29178:7;29201:20;29219:1;29201:20;:::i;:::-;29196:25;;29235:20;29253:1;29235:20;:::i;:::-;29230:25;;29290:1;29287;29283:9;29312:30;29330:11;29312:30;:::i;:::-;29301:41;;29491:1;29482:7;29478:15;29475:1;29472:22;29452:1;29445:9;29425:83;29402:139;;29521:18;;:::i;:::-;29402:139;29186:362;29138:410;;;;:::o;29554:180::-;29602:77;29599:1;29592:88;29699:4;29696:1;29689:15;29723:4;29720:1;29713:15;29740:233;29779:3;29802:24;29820:5;29802:24;:::i;:::-;29793:33;;29848:66;29841:5;29838:77;29835:103;;29918:18;;:::i;:::-;29835:103;29965:1;29958:5;29954:13;29947:20;;29740:233;;;:::o;29979:181::-;30119:33;30115:1;30107:6;30103:14;30096:57;29979:181;:::o;30166:366::-;30308:3;30329:67;30393:2;30388:3;30329:67;:::i;:::-;30322:74;;30405:93;30494:3;30405:93;:::i;:::-;30523:2;30518:3;30514:12;30507:19;;30166:366;;;:::o;30538:419::-;30704:4;30742:2;30731:9;30727:18;30719:26;;30791:9;30785:4;30781:20;30777:1;30766:9;30762:17;30755:47;30819:131;30945:4;30819:131;:::i;:::-;30811:139;;30538:419;;;:::o;30963:225::-;31103:34;31099:1;31091:6;31087:14;31080:58;31172:8;31167:2;31159:6;31155:15;31148:33;30963:225;:::o;31194:366::-;31336:3;31357:67;31421:2;31416:3;31357:67;:::i;:::-;31350:74;;31433:93;31522:3;31433:93;:::i;:::-;31551:2;31546:3;31542:12;31535:19;;31194:366;;;:::o;31566:419::-;31732:4;31770:2;31759:9;31755:18;31747:26;;31819:9;31813:4;31809:20;31805:1;31794:9;31790:17;31783:47;31847:131;31973:4;31847:131;:::i;:::-;31839:139;;31566:419;;;:::o;31991:182::-;32131:34;32127:1;32119:6;32115:14;32108:58;31991:182;:::o;32179:366::-;32321:3;32342:67;32406:2;32401:3;32342:67;:::i;:::-;32335:74;;32418:93;32507:3;32418:93;:::i;:::-;32536:2;32531:3;32527:12;32520:19;;32179:366;;;:::o;32551:419::-;32717:4;32755:2;32744:9;32740:18;32732:26;;32804:9;32798:4;32794:20;32790:1;32779:9;32775:17;32768:47;32832:131;32958:4;32832:131;:::i;:::-;32824:139;;32551:419;;;:::o;32976:181::-;33116:33;33112:1;33104:6;33100:14;33093:57;32976:181;:::o;33163:366::-;33305:3;33326:67;33390:2;33385:3;33326:67;:::i;:::-;33319:74;;33402:93;33491:3;33402:93;:::i;:::-;33520:2;33515:3;33511:12;33504:19;;33163:366;;;:::o;33535:419::-;33701:4;33739:2;33728:9;33724:18;33716:26;;33788:9;33782:4;33778:20;33774:1;33763:9;33759:17;33752:47;33816:131;33942:4;33816:131;:::i;:::-;33808:139;;33535:419;;;:::o;33960:98::-;34011:6;34045:5;34039:12;34029:22;;33960:98;;;:::o;34064:168::-;34147:11;34181:6;34176:3;34169:19;34221:4;34216:3;34212:14;34197:29;;34064:168;;;;:::o;34238:373::-;34324:3;34352:38;34384:5;34352:38;:::i;:::-;34406:70;34469:6;34464:3;34406:70;:::i;:::-;34399:77;;34485:65;34543:6;34538:3;34531:4;34524:5;34520:16;34485:65;:::i;:::-;34575:29;34597:6;34575:29;:::i;:::-;34570:3;34566:39;34559:46;;34328:283;34238:373;;;;:::o;34617:640::-;34812:4;34850:3;34839:9;34835:19;34827:27;;34864:71;34932:1;34921:9;34917:17;34908:6;34864:71;:::i;:::-;34945:72;35013:2;35002:9;34998:18;34989:6;34945:72;:::i;:::-;35027;35095:2;35084:9;35080:18;35071:6;35027:72;:::i;:::-;35146:9;35140:4;35136:20;35131:2;35120:9;35116:18;35109:48;35174:76;35245:4;35236:6;35174:76;:::i;:::-;35166:84;;34617:640;;;;;;;:::o;35263:141::-;35319:5;35350:6;35344:13;35335:22;;35366:32;35392:5;35366:32;:::i;:::-;35263:141;;;;:::o;35410:349::-;35479:6;35528:2;35516:9;35507:7;35503:23;35499:32;35496:119;;;35534:79;;:::i;:::-;35496:119;35654:1;35679:63;35734:7;35725:6;35714:9;35710:22;35679:63;:::i;:::-;35669:73;;35625:127;35410:349;;;;:::o;35765:180::-;35813:77;35810:1;35803:88;35910:4;35907:1;35900:15;35934:4;35931:1;35924:15

Swarm Source

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