ETH Price: $3,432.26 (+0.99%)

Token

KAMITSUBAKIRG (KRG)
 

Overview

Max Total Supply

4,000 KRG

Holders

998

Market

Volume (24H)

0.0657 ETH

Min Price (24H)

$74.95 @ 0.021837 ETH

Max Price (24H)

$75.48 @ 0.021991 ETH
Filtered by Token Holder
miyao1122.eth
Balance
1 KRG
0x957143815f0e1d1b1a31b2bfcded5b416ee675ed
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

KAMITSUBAKI R.G., the proof of residency to KAMITSUBAKI City, a new Web3 entertainment.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
ResidentGenesis

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-03-24
*/

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

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

// License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}


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

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

pragma solidity ^0.8.0;

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

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


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

// License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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


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

// License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

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


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

// License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

// License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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


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

// License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;




/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(account),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * May emit a {RoleGranted} event.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


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

// License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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


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

// License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}


// File erc721a/contracts/[email protected]

// License-Identifier: MIT
// 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);
}


// File erc721a/contracts/[email protected]

// License-Identifier: MIT
// 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);
}

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


// File erc721a/contracts/extensions/[email protected]

// License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721AQueryable.
 */
interface IERC721AQueryable is IERC721A {
    /**
     * Invalid query range (`start` >= `stop`).
     */
    error InvalidQueryRange();

    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) external view returns (uint256[] memory);
}


// File erc721a/contracts/extensions/[email protected]

// License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @title ERC721AQueryable.
 *
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) {
        TokenOwnership memory ownership;
        if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
            return ownership;
        }
        ownership = _ownershipAt(tokenId);
        if (ownership.burned) {
            return ownership;
        }
        return _ownershipOf(tokenId);
    }

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] calldata tokenIds)
        external
        view
        virtual
        override
        returns (TokenOwnership[] memory)
    {
        unchecked {
            uint256 tokenIdsLength = tokenIds.length;
            TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
            for (uint256 i; i != tokenIdsLength; ++i) {
                ownerships[i] = explicitOwnershipOf(tokenIds[i]);
            }
            return ownerships;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view virtual override returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();
            uint256 tokenIdsIdx;
            uint256 stopLimit = _nextTokenId();
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            // Set `stop = min(stop, stopLimit)`.
            if (stop > stopLimit) {
                stop = stopLimit;
            }
            uint256 tokenIdsMaxLength = balanceOf(owner);
            // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
            // to cater for cases where `balanceOf(owner)` is too big.
            if (start < stop) {
                uint256 rangeLength = stop - start;
                if (rangeLength < tokenIdsMaxLength) {
                    tokenIdsMaxLength = rangeLength;
                }
            } else {
                tokenIdsMaxLength = 0;
            }
            uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
            if (tokenIdsMaxLength == 0) {
                return tokenIds;
            }
            // We need to call `explicitOwnershipOf(start)`,
            // because the slot at `start` may not be initialized.
            TokenOwnership memory ownership = explicitOwnershipOf(start);
            address currOwnershipAddr;
            // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
            // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
            if (!ownership.burned) {
                currOwnershipAddr = ownership.addr;
            }
            for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            // Downsize the array to fit.
            assembly {
                mstore(tokenIds, tokenIdsIdx)
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }
}


// File operator-filter-registry/src/lib/[email protected]

// License-Identifier: MIT
pragma solidity ^0.8.17;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;


// File operator-filter-registry/src/[email protected]

// License-Identifier: MIT
pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}


// File operator-filter-registry/src/[email protected]

// License-Identifier: MIT
pragma solidity ^0.8.13;

/**
 * @title  UpdatableOperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the
 *         OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address,
 *         which will bypass registry checks.
 *         Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract UpdatableOperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);
    /// @dev Emitted when someone other than the owner is trying to call an only owner function.
    error OnlyOwner();

    event OperatorFilterRegistryAddressUpdated(address newRegistry);

    IOperatorFilterRegistry public operatorFilterRegistry;

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) {
        IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry);
        operatorFilterRegistry = registry;
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(registry).code.length > 0) {
            if (subscribe) {
                registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    registry.register(address(this));
                }
            }
        }
    }

    /**
     * @dev A helper function to check if the operator is allowed.
     */
    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    /**
     * @dev A helper function to check if the operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be bypassed. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public virtual {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
        emit OperatorFilterRegistryAddressUpdated(newRegistry);
    }

    /**
     * @dev Assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract.
     */
    function owner() public view virtual returns (address);

    /**
     * @dev A helper function to check if the operator is allowed.
     */
    function _checkFilterOperator(address operator) internal view virtual {
        IOperatorFilterRegistry registry = operatorFilterRegistry;
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(registry) != address(0) && address(registry).code.length > 0) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (!registry.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}


// File operator-filter-registry/src/[email protected]

// License-Identifier: MIT
pragma solidity ^0.8.13;


/**
 * @title  RevokableOperatorFilterer
 * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The
 *         Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at
 *         any point. As implemented, this abstract contract allows the contract owner to permanently skip the
 *         OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry
 *         address cannot be further updated.
 *         Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer {
    /// @dev Emitted when the registry has already been revoked.
    error RegistryHasBeenRevoked();
    /// @dev Emitted when the initial registry address is attempted to be set to the zero address.
    error InitialRegistryAddressCannotBeZeroAddress();

    event OperatorFilterRegistryRevoked();

    bool public isOperatorFilterRegistryRevoked;

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe)
        UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe)
    {
        // don't allow creating a contract with a permanently revoked registry
        if (_registry == address(0)) {
            revert InitialRegistryAddressCannotBeZeroAddress();
        }
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public override {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
        emit OperatorFilterRegistryAddressUpdated(newRegistry);
    }

    /**
     * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner.
     */
    function revokeOperatorFilterRegistry() public {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        // set to zero address to bypass checks
        operatorFilterRegistry = IOperatorFilterRegistry(address(0));
        isOperatorFilterRegistryRevoked = true;
        emit OperatorFilterRegistryRevoked();
    }
}


// File operator-filter-registry/src/[email protected]

// License-Identifier: MIT
pragma solidity ^0.8.13;


/**
 * @title  RevokableDefaultOperatorFilterer
 * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription.
 *         Note that OpenSea will disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */

abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor()
        RevokableOperatorFilterer(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS, CANONICAL_CORI_SUBSCRIPTION, true)
    {}
}


// File src/oasis/IApprovalProxy.sol

// License-Identifier: MIT
pragma solidity ^0.8.0;

interface IApprovalProxy {
    function setApprovalForAll(
        address _owner,
        address _spender,
        bool _approved
    ) external;

    function isApprovedForAll(
        address _owner,
        address _spender,
        bool _approved
    ) external view returns (bool);
}


// File src/oasis/INFTOasis.sol

// License-Identifier: MIT
pragma solidity ^0.8.0;

interface INFTOasis {
    function mint(address to, uint256 tokenId) external;

    function mint(
        address[] memory _toList,
        uint256[] memory tokenIdList
    ) external;

    function mintFor(address to, uint256 tokenId) external;

    function exists(uint256 tokenId) external view returns (bool);

    function setBaseURI(string memory __baseURI) external;
}


// File src/oasis/NFTOasisA.sol

// License-Identifier: MIT
pragma solidity ^0.8.4;





contract NFTOasisA is ERC721AQueryable, INFTOasis, AccessControl, Ownable {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    // `_baseURI` は関数で定義されているため、例外的な変数名の `baseURI_` にする.
    string internal baseURI_;
    string internal _tokenURIExtension;

    uint256 internal _totalOwner;
    uint256 internal _totalAirDrop;

    IApprovalProxy public approvalProxy;

    event UpdateApprovalProxy(address _newProxyContract);

    /**
     * @dev コンストラクタ.
     */
    constructor(
        string memory name_,
        string memory symbol_
    ) ERC721A(name_, symbol_) {
        _setRoleAdmin(MINTER_ROLE, MINTER_ROLE);
        _setupRole(MINTER_ROLE, _msgSender());
        _tokenURIExtension = ".json";
    }

    /**
     * @dev `1` からはじめる.
     */
    function _startTokenId() internal view virtual override returns (uint256) {
        return 1;
    }

    /**
     * @dev `to` に対してトークンを1つmintする. `tokenId` は無視される.
     */
    function mint(address to, uint256 /* tokenId */) public virtual {
        // 既存機能との互換性を保つため `tokenId` を受け入れるが、実際の処理では無視します。
        require(
            hasRole(MINTER_ROLE, _msgSender()),
            "ERC721Mintble: must have minter role to mint"
        );

        // `tokenId` を無視して、token を 1つだけmintする
        // (ここで指定する値は、tokenIdではなく発行量になる)
        _mint(to, 1);
        _totalAirDrop += 1;
    }

    /**
     * @dev `receivers` に対してトークンを1つずつmintする. `tokenIds` は無視される.
     */
    function mint(
        address[] memory receivers,
        uint256[] memory /* tokenIds */
    ) external virtual {
        // 既存機能との互換性を保つため `tokenIds` を受け入れるが、実際の処理では無視される
        // 使用しないので `tokenIds` の長さも検査しない
        for (uint256 i = 0; i < receivers.length; i++) {
            mint(receivers[i], 1);
        }
    }

    /**
     * @dev `to` に対してトークンを1つmintする. `tokenId` は無視される.
     */
    function mintFor(address to, uint256 tokenId) public virtual {
        mint(to, tokenId);
    }

    /**
     * @dev airdrop - 主に運営チームの確保用に使用するmint.
     */
    function doAirDrop(
        address receiver,
        uint256 quantity
    ) public virtual onlyOwner {
        _mint(receiver, quantity);
        _totalAirDrop += quantity;
    }

    /**
     * @dev transferの前処理.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 /* startTokenId */,
        uint256 /* quantity */
    ) internal virtual override {
        // 新規保有者が増えた時はカウントアップ
        if (to != address(0) && balanceOf(to) == 0) {
            unchecked {
                _totalOwner++;
            }
        }
        // 既存の保有者の保有数が `0` になる時はカウントダウン
        if (from != address(0) && balanceOf(from) == 1 && _totalOwner > 0) {
            unchecked {
                _totalOwner--;
            }
        }
    }

    /**
     * @dev NFTを保有しているオーナー数を返します.
     */
    function totalOwner() external view virtual returns (uint256) {
        return _totalOwner;
    }

    /**
     * @dev '支払いなし'で配布したNFT数を返します.
     */
    function totalAirDrop() external view virtual returns (uint256) {
        return _totalAirDrop;
    }

    /**
     * @dev `tokenId` に紐づくオーナー情報を返します.
     */
    function ownershipOf(
        uint256 tokenId
    ) external view virtual returns (TokenOwnership memory) {
        return _ownershipOf(tokenId);
    }

    /**
     * @dev `tokenId` が発行されていれば true を返します.
     */
    function exists(uint256 tokenId) external view virtual returns (bool) {
        return _exists(tokenId);
    }

    /**
     * @dev `tokenId` に対応するURIを返します.
     */
    function tokenURI(
        uint256 tokenId
    ) public view virtual override(ERC721A, IERC721A) returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();

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

    /**
     * @dev baseURIを変更する.
     */
    function setBaseURI(string calldata __baseURI) external virtual onlyOwner {
        baseURI_ = __baseURI;
    }

    /**
     * @dev tokenURIに付与する拡張子を変更する.
     */
    function setTokenURIExtension(
        string memory tokenURIExtension_
    ) external virtual onlyOwner {
        _tokenURIExtension = tokenURIExtension_;
    }

    /**
     * @dev `approvalProxy` を変更します.
     */
    function setApprovalProxy(address proxy) external virtual onlyOwner {
        approvalProxy = IApprovalProxy(proxy);
        emit UpdateApprovalProxy(proxy);
    }

    /**
     * @dev `operator` に権限がある場合は true を返します.
     */
    function isApprovedForAll(
        address owner_,
        address operator
    ) public view virtual override(ERC721A, IERC721A) returns (bool) {
        bool approved = super.isApprovedForAll(owner_, operator);
        if (address(approvalProxy) != address(0x0)) {
            return approvalProxy.isApprovedForAll(owner_, operator, approved);
        }
        return approved;
    }

    /**
     * @dev `operator` の権限を設定します.
     */
    function setApprovalForAll(
        address operator,
        bool approved
    ) public virtual override(ERC721A, IERC721A) {
        if (
            address(approvalProxy) != address(0x0) && operator.code.length > 0
        ) {
            approvalProxy.setApprovalForAll(msg.sender, operator, approved);
        }
        super.setApprovalForAll(operator, approved);
    }

    /**
     * @dev `interfaceId` をサポートしている場合は true を返します.
     */
    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        virtual
        override(ERC721A, AccessControl, IERC721A)
        returns (bool)
    {
        return
            AccessControl.supportsInterface(interfaceId) ||
            ERC721A.supportsInterface(interfaceId);
    }

    /**
     * @dev baseURIを返します.
     */
    function _baseURI() internal view virtual override returns (string memory) {
        if (bytes(baseURI_).length > 0) {
            return baseURI_;
        }

        return
            string(
                abi.encodePacked(
                    "https://nft.financie.io/metadata/",
                    symbol(),
                    "/"
                )
            );
    }
}


// File src/Kamitsubaki.sol

// License-Identifier: MIT
pragma solidity ^0.8.17;




contract Kamitsubaki is NFTOasisA, RevokableDefaultOperatorFilterer {
    // -------------------------
    // event
    // -------------------------
    event UpdateSupplyLimit(address sender, uint256 newSupplyLimit);
    event UpdateQuantityLimit(address sender, uint256 newQuantityLimit);
    event UpdateAllowListSalePrice(
        address sender,
        uint256 newAllowListSalePrice
    );
    event UpdatePayoutAddress(address sender, address newPayoutAddress);
    event UpdateSaleState(address sender, uint8 newSaleState);

    // -------------------------
    // error
    // -------------------------
    error MintQuantityExceedsLimitPerAddress();
    error MintSupplyExceedsLimit();
    error MintInvalidBodySigner();
    error MintInvalidHeadSigner();
    error MintInvalidValue();
    error NotOpenPreSaleOrNotOwner();
    error NotOpenPublicSaleOrNotOwner();

    // -------------------------
    // struct
    // -------------------------
    struct MintTicket {
        uint256 quantityLimit;
        bytes uuid;
        bytes headSignature;
        bytes bodySignature;
        address bodySigner;
        address receiver;
    }

    struct State {
        uint256 totalSupply;
        uint256 totalOwner;
        uint256 totalAirDrop;
        uint256 salePrice;
        uint256 supplyLimit;
        uint256 quantityLimit;
        address owner;
        address payoutAddress;
        bool isOpenedPreSale;
        bool isOpenedPublicSale;
        string name;
        string symbol;
    }

    struct AddressProps {
        uint256 balance;
        uint256 mintCount;
        uint256 publicSaleMintCount;
        uint256 allowListSaleMintCount;
    }

    // -------------------------
    // variable
    // -------------------------
    uint256 public salePrice;
    uint256 public supplyLimit;
    uint256 public quantityLimit;
    address payable public payoutAddress;
    uint8 internal _saleState;

    /**
     * @dev コンストラクタ.
     */
    constructor(
        string memory name_,
        string memory symbol_,
        uint256 salePrice_,
        uint256 supplyLimit_,
        uint256 quantityLimit_,
        address payoutAddress_
    ) NFTOasisA(name_, symbol_) {
        salePrice = salePrice_;
        supplyLimit = supplyLimit_;
        quantityLimit = quantityLimit_;
        if (address(0) != payoutAddress_) {
            payoutAddress = payable(payoutAddress_);
        } else {
            payoutAddress = payable(msg.sender);
        }
        _saleState = 0;
    }

    modifier whenOpenPreSaleOrOwner() {
        bool isOpenedPreSale = _saleState == 1 || _saleState == 3;
        if (!isOpenedPreSale && owner() != _msgSender())
            revert NotOpenPreSaleOrNotOwner();
        _;
    }

    modifier whenOpenPublicSaleOrOwner() {
        bool isOpenedPublicSale = _saleState == 2 || _saleState == 3;
        if (!isOpenedPublicSale && owner() != _msgSender())
            revert NotOpenPublicSaleOrNotOwner();
        _;
    }

    /**
     * @dev 供給上限を変更します.
     */
    function setSupplyLimit(uint256 supplyLimit_) external onlyOwner {
        supplyLimit = supplyLimit_;
        emit UpdateSupplyLimit(msg.sender, supplyLimit_);
    }

    /**
     * @dev 公開販売の1アドレスあたりのmint数上限を変更します.
     */
    function setQuantityLimit(uint256 quantityLimit_) external onlyOwner {
        quantityLimit = quantityLimit_;
        emit UpdateQuantityLimit(msg.sender, quantityLimit_);
    }

    /**
     * @dev 価格を変更します.
     */
    function setSalePrice(uint256 salePrice_) external onlyOwner {
        salePrice = salePrice_;
        emit UpdateAllowListSalePrice(msg.sender, salePrice_);
    }

    /**
     * @dev 支払い先アドレスを変更します.
     */
    function setPayoutAddress(address payoutAddress_) external onlyOwner {
        require(payoutAddress_ != address(0));
        payoutAddress = payable(payoutAddress_);
        emit UpdatePayoutAddress(msg.sender, payoutAddress_);
    }

    /**
     * @dev 販売状態を変更します.
     */
    function setSaleState(uint8 saleState_) external onlyOwner {
        // 0 ... close both pre sale and public sale.
        // 1 ... open pre sale (mint for allow list).
        // 2 ... open public sale (mint for public sale).
        // 3 ... open both pre sale and public sale.
        require(
            saleState_ == 0 ||
                saleState_ == 1 ||
                saleState_ == 2 ||
                saleState_ == 3
        );
        _saleState = saleState_;
        emit UpdateSaleState(msg.sender, saleState_);
    }

    /**
     * @dev コントラクトの状態を返します.
     */
    function getState() external view returns (State memory) {
        bool isOpenedPreSale = _saleState == 1 || _saleState == 3;
        bool isOpenedPublicSale = _saleState == 2 || _saleState == 3;
        return
            State(
                totalSupply(),
                _totalOwner,
                _totalAirDrop,
                salePrice,
                supplyLimit,
                quantityLimit,
                owner(),
                payoutAddress,
                isOpenedPreSale,
                isOpenedPublicSale,
                name(),
                symbol()
            );
    }

    function _mint(address to, uint256 quantity) internal override {
        if (totalSupply() + quantity > supplyLimit)
            revert MintSupplyExceedsLimit();

        super._mint(to, quantity);
    }

    /**
     * @dev `owner_` の情報を返します.
     */
    function addressProps(
        address owner_
    ) external view returns (AddressProps memory) {
        return
            AddressProps(
                balanceOf(owner_),
                _numberMinted(owner_),
                mintCountForPublicSale(owner_),
                mintCountForAllowListSale(owner_)
            );
    }

    /**
     * @dev 公開販売用mint.
     */
    function mintForPublicSale(
        uint256 quantity
    ) external payable whenOpenPublicSaleOrOwner {
        uint64 mintCount = mintCountForPublicSale(msg.sender);
        if (mintCount + quantity > quantityLimit)
            revert MintQuantityExceedsLimitPerAddress();
        if (msg.value != (salePrice * quantity)) revert MintInvalidValue();

        _mint(msg.sender, quantity);
        unchecked {
            mintCount += uint64(quantity);
        }
        setMintCountForPublicSale(msg.sender, mintCount);

        (bool success, ) = payoutAddress.call{value: msg.value}("");
        require(success, "Transfer failed.");
    }

    /**
     * @dev AL販売用mint.
     */
    function mintForAllowListSale(
        MintTicket calldata mintTicket,
        uint256 quantity
    ) external payable whenOpenPreSaleOrOwner {
        uint64 mintCount = mintCountForAllowListSale(mintTicket.receiver);
        if (mintCount + quantity > mintTicket.quantityLimit)
            revert MintQuantityExceedsLimitPerAddress();
        if (msg.value != (salePrice * quantity)) revert MintInvalidValue();

        (address headSigner, address bodySigner) = _recoverSigners(mintTicket);
        if (headSigner != owner()) revert MintInvalidHeadSigner();
        if (bodySigner != mintTicket.bodySigner) revert MintInvalidBodySigner();

        _mint(mintTicket.receiver, quantity);
        unchecked {
            mintCount += uint64(quantity);
        }
        setMintCountForAllowListSale(mintTicket.receiver, mintCount);

        (bool success, ) = payoutAddress.call{value: msg.value}("");
        require(success, "Transfer failed.");
    }

    /**
     * @dev ALでmintした数を返す.
     */
    function mintCountForAllowListSale(
        address owner_
    ) public view returns (uint64) {
        // Auxフィールドの前半32bitがALのmint数
        return uint64((_getAux(owner_) & 0x00000000FFFFFFFF));
    }

    /**
     * @dev 公開販売でmintした数を返す.
     */
    function mintCountForPublicSale(
        address owner_
    ) public view returns (uint64) {
        // Auxフィールドの後半32bitが販売のmint数
        return uint64(_getAux(owner_) >> 32);
    }

    /**
     * @dev ALでmintした数を設定する.
     */
    function setMintCountForAllowListSale(
        address owner_,
        uint64 count
    ) internal {
        uint64 countForPublicSale = mintCountForPublicSale(owner_);
        _setAux(owner_, (countForPublicSale << 32) | count);
    }

    /**
     * @dev 公開販売でmintした数を設定する.
     */
    function setMintCountForPublicSale(address owner_, uint64 count) internal {
        uint64 countForAllowListSale = mintCountForAllowListSale(owner_);
        _setAux(owner_, (count << 32) | countForAllowListSale);
    }

    /**
     * @dev 署名者のアドレスをリカバリーして返す.
     */
    function _recoverSigners(
        MintTicket calldata mintTicket
    ) private pure returns (address, address) {
        bytes32 headHash = ECDSA.toEthSignedMessageHash(
            keccak256(abi.encodePacked(mintTicket.bodySigner))
        );
        address headSigner = ECDSA.recover(headHash, mintTicket.headSignature);

        bytes32 bodyHash = ECDSA.toEthSignedMessageHash(
            keccak256(
                abi.encodePacked(
                    mintTicket.receiver,
                    mintTicket.uuid,
                    mintTicket.quantityLimit
                )
            )
        );
        address bodySigner = ECDSA.recover(bodyHash, mintTicket.bodySignature);

        return (headSigner, bodySigner);
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     *      In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry.
     */
    function setApprovalForAll(
        address operator,
        bool approved
    ) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    /**
     * @dev See {IERC721-approve}.
     *      In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry.
     */
    function approve(
        address operator,
        uint256 tokenId
    )
        public
        payable
        override(ERC721A, IERC721A)
        onlyAllowedOperatorApproval(operator)
    {
        super.approve(operator, tokenId);
    }

    /**
     * @dev See {IERC721-transferFrom}.
     *      In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     *      In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     *      In this example the added modifier ensures that the operator is allowed by the OperatorFilterRegistry.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public payable override(ERC721A, IERC721A) onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId, data);
    }

    /**
     * @dev Returns the owner of the ERC721 token contract.
     */
    function owner()
        public
        view
        virtual
        override(Ownable, UpdatableOperatorFilterer)
        returns (address)
    {
        return Ownable.owner();
    }
}


// File src/ResidentGenesis.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract ResidentGenesis is Kamitsubaki {
    constructor()
        Kamitsubaki(
            // name
            "KAMITSUBAKIRG",
            // symbol
            "KRG",
            // allowListSalePrice(unit: wei)
            // 0.1 ETH -> 100000000000000000 wei
            135000000000000000,
            // supplyLimit
            5000,
            // quantityLimit for PublicSale
            2,
            // payoutAddress
            address(0xe8b9110CA629e2222D9503718eB9e7B954827A2D)
        )
    {}
}

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":"InitialRegistryAddressCannotBeZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintInvalidBodySigner","type":"error"},{"inputs":[],"name":"MintInvalidHeadSigner","type":"error"},{"inputs":[],"name":"MintInvalidValue","type":"error"},{"inputs":[],"name":"MintQuantityExceedsLimitPerAddress","type":"error"},{"inputs":[],"name":"MintSupplyExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotOpenPreSaleOrNotOwner","type":"error"},{"inputs":[],"name":"NotOpenPublicSaleOrNotOwner","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"RegistryHasBeenRevoked","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":false,"internalType":"address","name":"newRegistry","type":"address"}],"name":"OperatorFilterRegistryAddressUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"OperatorFilterRegistryRevoked","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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"newAllowListSalePrice","type":"uint256"}],"name":"UpdateAllowListSalePrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newProxyContract","type":"address"}],"name":"UpdateApprovalProxy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"newPayoutAddress","type":"address"}],"name":"UpdatePayoutAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"newQuantityLimit","type":"uint256"}],"name":"UpdateQuantityLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint8","name":"newSaleState","type":"uint8"}],"name":"UpdateSaleState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSupplyLimit","type":"uint256"}],"name":"UpdateSupplyLimit","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"addressProps","outputs":[{"components":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"mintCount","type":"uint256"},{"internalType":"uint256","name":"publicSaleMintCount","type":"uint256"},{"internalType":"uint256","name":"allowListSaleMintCount","type":"uint256"}],"internalType":"struct Kamitsubaki.AddressProps","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalProxy","outputs":[{"internalType":"contract IApprovalProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","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":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"doAirDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"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":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"totalOwner","type":"uint256"},{"internalType":"uint256","name":"totalAirDrop","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"},{"internalType":"uint256","name":"supplyLimit","type":"uint256"},{"internalType":"uint256","name":"quantityLimit","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"payoutAddress","type":"address"},{"internalType":"bool","name":"isOpenedPreSale","type":"bool"},{"internalType":"bool","name":"isOpenedPublicSale","type":"bool"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"internalType":"struct Kamitsubaki.State","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOperatorFilterRegistryRevoked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"mintCountForAllowListSale","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"mintCountForPublicSale","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mintFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"quantityLimit","type":"uint256"},{"internalType":"bytes","name":"uuid","type":"bytes"},{"internalType":"bytes","name":"headSignature","type":"bytes"},{"internalType":"bytes","name":"bodySignature","type":"bytes"},{"internalType":"address","name":"bodySigner","type":"address"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct Kamitsubaki.MintTicket","name":"mintTicket","type":"tuple"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mintForAllowListSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mintForPublicSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilterRegistry","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payoutAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quantityLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeOperatorFilterRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","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":"salePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"address","name":"proxy","type":"address"}],"name":"setApprovalProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"__baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"payoutAddress_","type":"address"}],"name":"setPayoutAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantityLimit_","type":"uint256"}],"name":"setQuantityLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"salePrice_","type":"uint256"}],"name":"setSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"saleState_","type":"uint8"}],"name":"setSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"supplyLimit_","type":"uint256"}],"name":"setSupplyLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"tokenURIExtension_","type":"string"}],"name":"setTokenURIExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAirDrop","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOwner","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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":[{"internalType":"address","name":"newRegistry","type":"address"}],"name":"updateOperatorFilterRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040518060400160405280600d81526020016c4b414d4954535542414b49524760981b815250604051806040016040528060038152602001624b524760e81b8152506701df9dc8e4ad8000611388600273e8b9110ca629e2222d9503718eb9e7b954827a2d6daaeb6d7670e522a718067333cd4e733cc6cdda760b79bafa08df41ecfa224f810dceb660018282828b8b81818160029081620000b5919062000507565b506003620000c4828262000507565b5050600160005550620000d73362000311565b620000f2600080516020620042cf8339815191528062000363565b6200010d600080516020620042cf83398151915233620003ae565b604080518082019091526005815264173539b7b760d91b6020820152600b9062000138908262000507565b5050600f80546001600160a01b0319166001600160a01b0386169081179091558491503b1562000274578115620001d357604051633e9f1edf60e11b81523060048201526001600160a01b038481166024830152821690637d3e3dbe906044015b600060405180830381600087803b158015620001b457600080fd5b505af1158015620001c9573d6000803e3d6000fd5b5050505062000274565b6001600160a01b03831615620002185760405163a0af290360e01b81523060048201526001600160a01b03848116602483015282169063a0af29039060440162000199565b604051632210724360e11b81523060048201526001600160a01b03821690634420e48690602401600060405180830381600087803b1580156200025a57600080fd5b505af11580156200026f573d6000803e3d6000fd5b505050505b5050506001600160a01b0384169050620002a15760405163c49d17ad60e01b815260040160405180910390fd5b5050506010849055601183905560128290556001600160a01b03811615620002e457601380546001600160a01b0319166001600160a01b038316179055620002f7565b601380546001600160a01b031916331790555b50506013805460ff60a01b1916905550620005d392505050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600082815260086020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b620003ba8282620003be565b5050565b60008281526008602090815260408083206001600160a01b038516845290915290205460ff16620003ba5760008281526008602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200041e3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200048d57607f821691505b602082108103620004ae57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200050257600081815260208120601f850160051c81016020861015620004dd5750805b601f850160051c820191505b81811015620004fe57828155600101620004e9565b5050505b505050565b81516001600160401b0381111562000523576200052362000462565b6200053b8162000534845462000478565b84620004b4565b602080601f8311600181146200057357600084156200055a5750858301515b600019600386901b1c1916600185901b178555620004fe565b600085815260208120601f198616915b82811015620005a45788860151825594840194600190910190840162000583565b5085821015620005c35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b613cec80620005e36000396000f3fe60806040526004361061038c5760003560e01c80636352211e116101dc578063b88d4fde11610102578063e467f7e0116100a0578063eecd97e01161006f578063eecd97e014610abd578063f2fde38b14610af6578063f51f96dd14610b16578063fb6b18c014610b2c57600080fd5b8063e467f7e014610a05578063e968703814610a25578063e985e9c514610a7c578063ecba222a14610a9c57600080fd5b8063c87b56dd116100dc578063c87b56dd14610971578063d539139314610991578063d547741f146109c5578063da1919b3146109e557600080fd5b8063b88d4fde1461091e578063b8d1e53214610931578063c23dc68f1461095157600080fd5b8063930b98e11161017a5780639bb5c9c3116101495780639bb5c9c3146108a9578063a217fddf146108c9578063a22cb465146108de578063b0ccc31e146108fe57600080fd5b8063930b98e11461080e57806394ce057f1461086157806395d89b411461087457806399a2557a1461088957600080fd5b8063715018a6116101b6578063715018a6146107975780638462151c146107ac5780638da5cb5b146107d957806391d14854146107ee57600080fd5b80636352211e146107375780636c1599701461075757806370a082311461077757600080fd5b80632f2ff15d116102c157806342842e0e1161025f5780635a67de071161022e5780635a67de07146106b55780635b8d02d7146106d55780635bbb2177146106f55780635ef9432a1461072257600080fd5b806342842e0e146106425780634dd09f33146106555780634f558e791461067557806355f804b31461069557600080fd5b806336568abe1161029b57806336568abe146105cd5780633e9564f7146105ed57806340c10f191461060d578063420b538c1461062d57600080fd5b80632f2ff15d1461056d57806333ea51a81461058d578063361fab25146105ad57600080fd5b806318160ddd1161032e57806319d1997a1161030857806319d1997a146104fe57806323b872dd14610514578063248a9ca31461052757806329cb320b1461055757600080fd5b806318160ddd146104955780631865c57d146104bc5780631919fed7146104de57600080fd5b8063095ea7b31161036a578063095ea7b3146104205780630ff6bceb14610435578063140364a1146104485780631796068a1461047557600080fd5b806301ffc9a71461039157806306fdde03146103c6578063081812fc146103e8575b600080fd5b34801561039d57600080fd5b506103b16103ac366004613047565b610b41565b60405190151581526020015b60405180910390f35b3480156103d257600080fd5b506103db610b61565b6040516103bd91906130b4565b3480156103f457600080fd5b506104086104033660046130c7565b610bf3565b6040516001600160a01b0390911681526020016103bd565b61043361042e3660046130fc565b610c37565b005b610433610443366004613126565b610c50565b34801561045457600080fd5b506104686104633660046130c7565b610e94565b6040516103bd919061319d565b34801561048157600080fd5b506104336104903660046130c7565b610ea5565b3480156104a157600080fd5b5060015460005403600019015b6040519081526020016103bd565b3480156104c857600080fd5b506104d1610eef565b6040516103bd91906131ab565b3480156104ea57600080fd5b506104336104f93660046130c7565b611061565b34801561050a57600080fd5b506104ae60115481565b610433610522366004613291565b6110a4565b34801561053357600080fd5b506104ae6105423660046130c7565b60009081526008602052604090206001015490565b34801561056357600080fd5b506104ae60125481565b34801561057957600080fd5b506104336105883660046132cd565b6110cf565b34801561059957600080fd5b506104336105a83660046132f9565b6110f4565b3480156105b957600080fd5b506104336105c83660046130c7565b611164565b3480156105d957600080fd5b506104336105e83660046132cd565b6111a7565b3480156105f957600080fd5b506104336106083660046133b1565b611225565b34801561061957600080fd5b506104336106283660046130fc565b611239565b34801561063957600080fd5b50600c546104ae565b610433610650366004613291565b6112eb565b34801561066157600080fd5b50600e54610408906001600160a01b031681565b34801561068157600080fd5b506103b16106903660046130c7565b611310565b3480156106a157600080fd5b506104336106b03660046133f9565b61131b565b3480156106c157600080fd5b506104336106d036600461346a565b611330565b3480156106e157600080fd5b50601354610408906001600160a01b031681565b34801561070157600080fd5b5061071561071036600461348d565b6113c5565b6040516103bd91906134ef565b34801561072e57600080fd5b50610433611477565b34801561074357600080fd5b506104086107523660046130c7565b61151c565b34801561076357600080fd5b506104336107723660046130fc565b611527565b34801561078357600080fd5b506104ae6107923660046132f9565b61154b565b3480156107a357600080fd5b50610433611599565b3480156107b857600080fd5b506107cc6107c73660046132f9565b6115ad565b6040516103bd9190613531565b3480156107e557600080fd5b50610408611693565b3480156107fa57600080fd5b506103b16108093660046132cd565b6116ac565b34801561081a57600080fd5b5061082e6108293660046132f9565b6116d7565b6040516103bd91908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b61043361086f3660046130c7565b6117b5565b34801561088057600080fd5b506103db611938565b34801561089557600080fd5b506107cc6108a4366004613569565b611947565b3480156108b557600080fd5b506104336108c43660046132f9565b611ace565b3480156108d557600080fd5b506104ae600081565b3480156108ea57600080fd5b506104336108f93660046135aa565b611b24565b34801561090a57600080fd5b50600f54610408906001600160a01b031681565b61043361092c3660046135e1565b611b38565b34801561093d57600080fd5b5061043361094c3660046132f9565b611b65565b34801561095d57600080fd5b5061046861096c3660046130c7565b611c17565b34801561097d57600080fd5b506103db61098c3660046130c7565b611c67565b34801561099d57600080fd5b506104ae7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b3480156109d157600080fd5b506104336109e03660046132cd565b611ced565b3480156109f157600080fd5b50610433610a003660046130fc565b611d12565b348015610a1157600080fd5b50610433610a203660046136ea565b611d1c565b348015610a3157600080fd5b50610a64610a403660046132f9565b6001600160a01b031660009081526005602052604090205460c01c63ffffffff1690565b6040516001600160401b0390911681526020016103bd565b348015610a8857600080fd5b506103b1610a973660046137a9565b611d5e565b348015610aa857600080fd5b50600f546103b190600160a01b900460ff1681565b348015610ac957600080fd5b50610a64610ad83660046132f9565b6001600160a01b031660009081526005602052604090205460e01c90565b348015610b0257600080fd5b50610433610b113660046132f9565b611e1c565b348015610b2257600080fd5b506104ae60105481565b348015610b3857600080fd5b50600d546104ae565b6000610b4c82611e95565b80610b5b5750610b5b82611eca565b92915050565b606060028054610b70906137d3565b80601f0160208091040260200160405190810160405280929190818152602001828054610b9c906137d3565b8015610be95780601f10610bbe57610100808354040283529160200191610be9565b820191906000526020600020905b815481529060010190602001808311610bcc57829003601f168201915b5050505050905090565b6000610bfe82611f18565b610c1b576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b81610c4181611f4d565b610c4b838361200f565b505050565b601354600090600160a01b900460ff1660011480610c7a5750601354600160a01b900460ff166003145b905080158015610c9a575033610c8e611693565b6001600160a01b031614155b15610cb85760405163726d9d6960e01b815260040160405180910390fd5b6000610ccd610a4060c0860160a087016132f9565b90508335610ce4846001600160401b038416613823565b1115610d0357604051637673930f60e01b815260040160405180910390fd5b82601054610d119190613836565b3414610d305760405163656b1af360e01b815260040160405180910390fd5b600080610d3c866120af565b91509150610d48611693565b6001600160a01b0316826001600160a01b031614610d795760405163f896abaf60e01b815260040160405180910390fd5b610d8960a08701608088016132f9565b6001600160a01b0316816001600160a01b031614610dba576040516304efa49d60e51b815260040160405180910390fd5b610dd3610dcd60c0880160a089016132f9565b866121f9565b91840191610df0610dea60c0880160a089016132f9565b8461223d565b6013546040516000916001600160a01b03169034908381818185875af1925050503d8060008114610e3d576040519150601f19603f3d011682016040523d82523d6000602084013e610e42565b606091505b5050905080610e8b5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064015b60405180910390fd5b50505050505050565b610e9c61300a565b610b5b82612274565b610ead61228d565b601281905560408051338152602081018390527f9074f4c535a222861a631985c506f755c216edda189cb7656116f60322228bad91015b60405180910390a150565b610f6960405180610180016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160001515815260200160001515815260200160608152602001606081525090565b601354600090600160a01b900460ff1660011480610f935750601354600160a01b900460ff166003145b90506000601360149054906101000a900460ff1660ff1660021480610fc45750601354600160a01b900460ff166003145b9050604051806101800160405280610fe56001546000546000199190030190565b8152602001600c548152602001600d54815260200160105481526020016011548152602001601254815260200161101a611693565b6001600160a01b0390811682526013541660208201528315156040820152821515606082015260800161104b610b61565b8152602001611058611938565b90529392505050565b61106961228d565b601081905560408051338152602081018390527ff0e57f2cc3c10647532b9e07271e329734cb12e00ef14333da0d79a9c53d831f9101610ee4565b826001600160a01b03811633146110be576110be33611f4d565b6110c98484846122ec565b50505050565b6000828152600860205260409020600101546110ea81612492565b610c4b838361249c565b6110fc61228d565b6001600160a01b03811661110f57600080fd5b601380546001600160a01b0319166001600160a01b0383169081179091556040805133815260208101929092527f54f1877b9010a3135c68dc2b0b326591d02a8cfbae5443bc11b94af1cafae4029101610ee4565b61116c61228d565b601181905560408051338152602081018390527fd60ff19058ff26897d4ccb9d7ee31a589d1230dc668dfdee26fda0a565bac7349101610ee4565b6001600160a01b03811633146112175760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610e82565b6112218282612522565b5050565b61122d61228d565b600b6112218282613893565b6112637f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336116ac565b6112c45760405162461bcd60e51b815260206004820152602c60248201527f4552433732314d696e74626c653a206d7573742068617665206d696e7465722060448201526b1c9bdb19481d1bc81b5a5b9d60a21b6064820152608401610e82565b6112cf8260016121f9565b6001600d60008282546112e29190613823565b90915550505050565b826001600160a01b03811633146113055761130533611f4d565b6110c9848484612589565b6000610b5b82611f18565b61132361228d565b600a610c4b828483613952565b61133861228d565b60ff8116158061134b57508060ff166001145b8061135957508060ff166002145b8061136757508060ff166003145b61137057600080fd5b6013805460ff60a01b1916600160a01b60ff8416908102919091179091556040805133815260208101929092527fc713b270b8a45c8a69dfb64819d91aed2138afa15cadd92359025e74745847009101610ee4565b6060816000816001600160401b038111156113e2576113e2613314565b60405190808252806020026020018201604052801561141b57816020015b61140861300a565b8152602001906001900390816114005790505b50905060005b82811461146e5761144986868381811061143d5761143d613a11565b90506020020135611c17565b82828151811061145b5761145b613a11565b6020908102919091010152600101611421565b50949350505050565b61147f611693565b6001600160a01b0316336001600160a01b0316146114b057604051635fc483c560e01b815260040160405180910390fd5b600f54600160a01b900460ff16156114db57604051631551a48f60e11b815260040160405180910390fd5b600f80546001600160a81b031916600160a01b1790556040517f51e2d870cc2e10853e38dc06fcdae46ad3c3f588f326608803dac6204541ad1690600090a1565b6000610b5b826125a4565b61152f61228d565b61153982826121f9565b80600d60008282546112e29190613823565b60006001600160a01b038216611574576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6115a161228d565b6115ab6000612613565b565b606060008060006115bd8561154b565b90506000816001600160401b038111156115d9576115d9613314565b604051908082528060200260200182016040528015611602578160200160208202803683370190505b50905061160d61300a565b60015b8386146116875761162081612665565b9150816040015161167f5781516001600160a01b03161561164057815194505b876001600160a01b0316856001600160a01b03160361167f578083878060010198508151811061167257611672613a11565b6020026020010181815250505b600101611610565b50909695505050505050565b60006116a76009546001600160a01b031690565b905090565b60009182526008602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6117026040518060800160405280600081526020016000815260200160008152602001600081525090565b60405180608001604052806117168461154b565b8152602001611747846001600160a01b03166000908152600560205260409081902054901c6001600160401b031690565b815260200161176e846001600160a01b031660009081526005602052604090205460e01c90565b6001600160401b031681526020016117a4846001600160a01b031660009081526005602052604090205460c01c63ffffffff1690565b6001600160401b0316905292915050565b601354600090600160a01b900460ff16600214806117df5750601354600160a01b900460ff166003145b9050801580156117ff5750336117f3611693565b6001600160a01b031614155b1561181c576040516271245160e01b815260040160405180910390fd5b3360009081526005602052604090205460125460e09190911c906118408483613823565b111561185f57604051637673930f60e01b815260040160405180910390fd5b8260105461186d9190613836565b341461188c5760405163656b1af360e01b815260040160405180910390fd5b61189633846121f9565b82016118a23382612685565b6013546040516000916001600160a01b03169034908381818185875af1925050503d80600081146118ef576040519150601f19603f3d011682016040523d82523d6000602084013e6118f4565b606091505b50509050806110c95760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610e82565b606060038054610b70906137d3565b606081831061196957604051631960ccad60e11b815260040160405180910390fd5b60008061197560005490565b9050600185101561198557600194505b80841115611991578093505b600061199c8761154b565b9050848610156119bb57858503818110156119b5578091505b506119bf565b5060005b6000816001600160401b038111156119d9576119d9613314565b604051908082528060200260200182016040528015611a02578160200160208202803683370190505b50905081600003611a18579350611ac792505050565b6000611a2388611c17565b905060008160400151611a34575080515b885b888114158015611a465750848714155b15611abb57611a5481612665565b92508260400151611ab35782516001600160a01b031615611a7457825191505b8a6001600160a01b0316826001600160a01b031603611ab35780848880600101995081518110611aa657611aa6613a11565b6020026020010181815250505b600101611a36565b50505092835250909150505b9392505050565b611ad661228d565b600e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f12be4820d03362d1f48434d870b2fc1549b3a3d16d891eeaac7c3073f3ded8b790602001610ee4565b81611b2e81611f4d565b610c4b83836126ca565b836001600160a01b0381163314611b5257611b5233611f4d565b611b5e8585858561276b565b5050505050565b611b6d611693565b6001600160a01b0316336001600160a01b031614611b9e57604051635fc483c560e01b815260040160405180910390fd5b600f54600160a01b900460ff1615611bc957604051631551a48f60e11b815260040160405180910390fd5b600f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f9f513fe86dc42fdbac355fa4d9b1d5be7b5e6cd2df67e30db8003766568de47690602001610ee4565b611c1f61300a565b611c2761300a565b6001831080611c3857506000548310155b15611c435792915050565b611c4c83612665565b9050806040015115611c5e5792915050565b611ac783612274565b6060611c7282611f18565b611c8f57604051630a14c4b560e41b815260040160405180910390fd5b6000611c996127af565b90508051600003611cb95760405180602001604052806000815250611ac7565b80611cc384612801565b600b604051602001611cd793929190613a27565b6040516020818303038152906040529392505050565b600082815260086020526040902060010154611d0881612492565b610c4b8383612522565b6112218282611239565b60005b8251811015610c4b57611d4c838281518110611d3d57611d3d613a11565b60200260200101516001611239565b80611d5681613ac7565b915050611d1f565b6001600160a01b0382811660009081526007602090815260408083208585168452909152812054600e54919260ff909116911615611ac757600e546040516346e67e2960e11b81526001600160a01b0386811660048301528581166024830152831515604483015290911690638dccfc5290606401602060405180830381865afa158015611df0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e149190613ae0565b915050610b5b565b611e2461228d565b6001600160a01b038116611e895760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610e82565b611e9281612613565b50565b60006001600160e01b03198216637965db0b60e01b1480610b5b57506301ffc9a760e01b6001600160e01b0319831614610b5b565b60006301ffc9a760e01b6001600160e01b031983161480611efb57506380ac58cd60e01b6001600160e01b03198316145b80610b5b5750506001600160e01b031916635b5e139f60e01b1490565b600081600111158015611f2c575060005482105b8015610b5b575050600090815260046020526040902054600160e01b161590565b600f546001600160a01b03168015801590611f7257506000816001600160a01b03163b115b1561122157604051633185c44d60e21b81523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190613ae0565b61122157604051633b79c77360e21b81526001600160a01b0383166004820152602401610e82565b600061201a8261151c565b9050336001600160a01b03821614612053576120368133611d5e565b612053576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000808061214e6120c660a08601608087016132f9565b6040516020016120ee919060609190911b6bffffffffffffffffffffffff1916815260140190565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b9050600061219d826121636040880188613afd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061284592505050565b905060006121d66121b460c0880160a089016132f9565b6121c16020890189613afd565b6040516120ee939291908b3590602001613b43565b905060006121eb8261216360608a018a613afd565b929792965091945050505050565b60115460015460005483919003600019016122149190613823565b111561223357604051633be28bdb60e11b815260040160405180910390fd5b6112218282612869565b6001600160a01b03821660009081526005602052604081205460e01c9050610c4b83836020846001600160401b0316901b17612974565b61227c61300a565b610b5b612288836125a4565b6129a6565b33612296611693565b6001600160a01b0316146115ab5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610e82565b60006122f7826125a4565b9050836001600160a01b0316816001600160a01b03161461232a5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b038816909114176123775761235a8633611d5e565b61237757604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661239e57604051633a954ecd60e21b815260040160405180910390fd5b6123ab86868660016129e9565b80156123b657600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003612448576001840160008181526004602052604081205490036124465760005481146124465760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b611e928133612a59565b6124a682826116ac565b6112215760008281526008602090815260408083206001600160a01b03851684529091529020805460ff191660011790556124de3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61252c82826116ac565b156112215760008281526008602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b610c4b83838360405180602001604052806000815250611b38565b600081806001116125fa576000548110156125fa5760008181526004602052604081205490600160e01b821690036125f8575b80600003611ac75750600019016000818152600460205260409020546125d7565b505b604051636f96cda160e11b815260040160405180910390fd5b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61266d61300a565b600082815260046020526040902054610b5b906129a6565b60006126af836001600160a01b031660009081526005602052604090205460c01c63ffffffff1690565b9050610c4b83826020856001600160401b0316901b17612974565b600e546001600160a01b0316158015906126ee57506000826001600160a01b03163b115b1561276157600e54604051631b3b02e560e11b81523360048201526001600160a01b03848116602483015283151560448301529091169063367605ca90606401600060405180830381600087803b15801561274857600080fd5b505af115801561275c573d6000803e3d6000fd5b505050505b6112218282612ab2565b6127768484846110a4565b6001600160a01b0383163b156110c95761279284848484612b1e565b6110c9576040516368d2bf6b60e11b815260040160405180910390fd5b60606000600a80546127c0906137d3565b905011156127d557600a8054610b70906137d3565b6127dd611938565b6040516020016127ed9190613b70565b604051602081830303815290604052905090565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061281b5750819003601f19909101908152919050565b60008060006128548585612c0a565b9150915061286181612c4f565b509392505050565b600080549082900361288e5760405163b562e8dd60e01b815260040160405180910390fd5b61289b60008483856129e9565b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b81811461294a57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612912565b508160000361296b57604051622e076360e81b815260040160405180910390fd5b60005550505050565b6001600160a01b03909116600090815260056020526040902080546001600160c01b031660c09290921b919091179055565b6129ae61300a565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b6001600160a01b03831615801590612a075750612a058361154b565b155b15612a1657600c805460010190555b6001600160a01b03841615801590612a365750612a328461154b565b6001145b8015612a4457506000600c54115b156110c957600c805460001901905550505050565b612a6382826116ac565b61122157612a7081612d99565b612a7b836020612dab565b604051602001612a8c929190613bc4565b60408051601f198184030181529082905262461bcd60e51b8252610e82916004016130b4565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290612b53903390899088908890600401613c39565b6020604051808303816000875af1925050508015612b8e575060408051601f3d908101601f19168201909252612b8b91810190613c6c565b60015b612bec573d808015612bbc576040519150601f19603f3d011682016040523d82523d6000602084013e612bc1565b606091505b508051600003612be4576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6000808251604103612c405760208301516040840151606085015160001a612c3487828585612f46565b94509450505050612c48565b506000905060025b9250929050565b6000816004811115612c6357612c63613c89565b03612c6b5750565b6001816004811115612c7f57612c7f613c89565b03612ccc5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610e82565b6002816004811115612ce057612ce0613c89565b03612d2d5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610e82565b6003816004811115612d4157612d41613c89565b03611e925760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610e82565b6060610b5b6001600160a01b03831660145b60606000612dba836002613836565b612dc5906002613823565b6001600160401b03811115612ddc57612ddc613314565b6040519080825280601f01601f191660200182016040528015612e06576020820181803683370190505b509050600360fc1b81600081518110612e2157612e21613a11565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612e5057612e50613a11565b60200101906001600160f81b031916908160001a9053506000612e74846002613836565b612e7f906001613823565b90505b6001811115612ef7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612eb357612eb3613a11565b1a60f81b828281518110612ec957612ec9613a11565b60200101906001600160f81b031916908160001a90535060049490941c93612ef081613c9f565b9050612e82565b508315611ac75760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610e82565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f7d5750600090506003613001565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612fd1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612ffa57600060019250925050613001565b9150600090505b94509492505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160e01b031981168114611e9257600080fd5b60006020828403121561305957600080fd5b8135611ac781613031565b60005b8381101561307f578181015183820152602001613067565b50506000910152565b600081518084526130a0816020860160208601613064565b601f01601f19169290920160200192915050565b602081526000611ac76020830184613088565b6000602082840312156130d957600080fd5b5035919050565b80356001600160a01b03811681146130f757600080fd5b919050565b6000806040838503121561310f57600080fd5b613118836130e0565b946020939093013593505050565b6000806040838503121561313957600080fd5b82356001600160401b0381111561314f57600080fd5b830160c0818603121561311857600080fd5b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b60808101610b5b8284613161565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a082015260a082015160c0820152600060c083015161320460e08401826001600160a01b03169052565b5060e0830151610100613221818501836001600160a01b03169052565b84015190506101206132368482018315159052565b840151905061014061324b8482018315159052565b80850151915050610180610160818186015261326b6101a0860184613088565b90860151858203601f1901838701529092506132878382613088565b9695505050505050565b6000806000606084860312156132a657600080fd5b6132af846130e0565b92506132bd602085016130e0565b9150604084013590509250925092565b600080604083850312156132e057600080fd5b823591506132f0602084016130e0565b90509250929050565b60006020828403121561330b57600080fd5b611ac7826130e0565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561335257613352613314565b604052919050565b60006001600160401b0383111561337357613373613314565b613386601f8401601f191660200161332a565b905082815283838301111561339a57600080fd5b828260208301376000602084830101529392505050565b6000602082840312156133c357600080fd5b81356001600160401b038111156133d957600080fd5b8201601f810184136133ea57600080fd5b612c028482356020840161335a565b6000806020838503121561340c57600080fd5b82356001600160401b038082111561342357600080fd5b818501915085601f83011261343757600080fd5b81358181111561344657600080fd5b86602082850101111561345857600080fd5b60209290920196919550909350505050565b60006020828403121561347c57600080fd5b813560ff81168114611ac757600080fd5b600080602083850312156134a057600080fd5b82356001600160401b03808211156134b757600080fd5b818501915085601f8301126134cb57600080fd5b8135818111156134da57600080fd5b8660208260051b850101111561345857600080fd5b6020808252825182820181905260009190848201906040850190845b818110156116875761351e838551613161565b928401926080929092019160010161350b565b6020808252825182820181905260009190848201906040850190845b818110156116875783518352928401929184019160010161354d565b60008060006060848603121561357e57600080fd5b613587846130e0565b95602085013595506040909401359392505050565b8015158114611e9257600080fd5b600080604083850312156135bd57600080fd5b6135c6836130e0565b915060208301356135d68161359c565b809150509250929050565b600080600080608085870312156135f757600080fd5b613600856130e0565b935061360e602086016130e0565b92506040850135915060608501356001600160401b0381111561363057600080fd5b8501601f8101871361364157600080fd5b6136508782356020840161335a565b91505092959194509250565b60006001600160401b0382111561367557613675613314565b5060051b60200190565b600082601f83011261369057600080fd5b813560206136a56136a08361365c565b61332a565b82815260059290921b840181019181810190868411156136c457600080fd5b8286015b848110156136df57803583529183019183016136c8565b509695505050505050565b600080604083850312156136fd57600080fd5b82356001600160401b038082111561371457600080fd5b818501915085601f83011261372857600080fd5b813560206137386136a08361365c565b82815260059290921b8401810191818101908984111561375757600080fd5b948201945b8386101561377c5761376d866130e0565b8252948201949082019061375c565b9650508601359250508082111561379257600080fd5b5061379f8582860161367f565b9150509250929050565b600080604083850312156137bc57600080fd5b6137c5836130e0565b91506132f0602084016130e0565b600181811c908216806137e757607f821691505b60208210810361380757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610b5b57610b5b61380d565b8082028115828204841417610b5b57610b5b61380d565b601f821115610c4b57600081815260208120601f850160051c810160208610156138745750805b601f850160051c820191505b8181101561248a57828155600101613880565b81516001600160401b038111156138ac576138ac613314565b6138c0816138ba84546137d3565b8461384d565b602080601f8311600181146138f557600084156138dd5750858301515b600019600386901b1c1916600185901b17855561248a565b600085815260208120601f198616915b8281101561392457888601518255948401946001909101908401613905565b50858210156139425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160401b0383111561396957613969613314565b61397d8361397783546137d3565b8361384d565b6000601f8411600181146139b157600085156139995750838201355b600019600387901b1c1916600186901b178355611b5e565b600083815260209020601f19861690835b828110156139e257868501358255602094850194600190920191016139c2565b50868210156139ff5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b634e487b7160e01b600052603260045260246000fd5b600084516020613a3a8285838a01613064565b855191840191613a4d8184848a01613064565b8554920191600090613a5e816137d3565b60018281168015613a765760018114613a8b57613ab7565b60ff1984168752821515830287019450613ab7565b896000528560002060005b84811015613aaf57815489820152908301908701613a96565b505082870194505b50929a9950505050505050505050565b600060018201613ad957613ad961380d565b5060010190565b600060208284031215613af257600080fd5b8151611ac78161359c565b6000808335601e19843603018112613b1457600080fd5b8301803591506001600160401b03821115613b2e57600080fd5b602001915036819003821315612c4857600080fd5b6bffffffffffffffffffffffff198560601b16815282846014830137601492019182015260340192915050565b7f68747470733a2f2f6e66742e66696e616e6369652e696f2f6d6574616461746181526000602f60f81b8060208401528351613bb3816021860160208801613064565b602193019283015250602201919050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613bfc816017850160208801613064565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613c2d816028840160208801613064565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061328790830184613088565b600060208284031215613c7e57600080fd5b8151611ac781613031565b634e487b7160e01b600052602160045260246000fd5b600081613cae57613cae61380d565b50600019019056fea2646970667358221220ad83ae1bac39192d8f9c57b5294762f52c9d5cb32af24f51bf1268321725264b64736f6c634300081100339f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6

Deployed Bytecode

0x60806040526004361061038c5760003560e01c80636352211e116101dc578063b88d4fde11610102578063e467f7e0116100a0578063eecd97e01161006f578063eecd97e014610abd578063f2fde38b14610af6578063f51f96dd14610b16578063fb6b18c014610b2c57600080fd5b8063e467f7e014610a05578063e968703814610a25578063e985e9c514610a7c578063ecba222a14610a9c57600080fd5b8063c87b56dd116100dc578063c87b56dd14610971578063d539139314610991578063d547741f146109c5578063da1919b3146109e557600080fd5b8063b88d4fde1461091e578063b8d1e53214610931578063c23dc68f1461095157600080fd5b8063930b98e11161017a5780639bb5c9c3116101495780639bb5c9c3146108a9578063a217fddf146108c9578063a22cb465146108de578063b0ccc31e146108fe57600080fd5b8063930b98e11461080e57806394ce057f1461086157806395d89b411461087457806399a2557a1461088957600080fd5b8063715018a6116101b6578063715018a6146107975780638462151c146107ac5780638da5cb5b146107d957806391d14854146107ee57600080fd5b80636352211e146107375780636c1599701461075757806370a082311461077757600080fd5b80632f2ff15d116102c157806342842e0e1161025f5780635a67de071161022e5780635a67de07146106b55780635b8d02d7146106d55780635bbb2177146106f55780635ef9432a1461072257600080fd5b806342842e0e146106425780634dd09f33146106555780634f558e791461067557806355f804b31461069557600080fd5b806336568abe1161029b57806336568abe146105cd5780633e9564f7146105ed57806340c10f191461060d578063420b538c1461062d57600080fd5b80632f2ff15d1461056d57806333ea51a81461058d578063361fab25146105ad57600080fd5b806318160ddd1161032e57806319d1997a1161030857806319d1997a146104fe57806323b872dd14610514578063248a9ca31461052757806329cb320b1461055757600080fd5b806318160ddd146104955780631865c57d146104bc5780631919fed7146104de57600080fd5b8063095ea7b31161036a578063095ea7b3146104205780630ff6bceb14610435578063140364a1146104485780631796068a1461047557600080fd5b806301ffc9a71461039157806306fdde03146103c6578063081812fc146103e8575b600080fd5b34801561039d57600080fd5b506103b16103ac366004613047565b610b41565b60405190151581526020015b60405180910390f35b3480156103d257600080fd5b506103db610b61565b6040516103bd91906130b4565b3480156103f457600080fd5b506104086104033660046130c7565b610bf3565b6040516001600160a01b0390911681526020016103bd565b61043361042e3660046130fc565b610c37565b005b610433610443366004613126565b610c50565b34801561045457600080fd5b506104686104633660046130c7565b610e94565b6040516103bd919061319d565b34801561048157600080fd5b506104336104903660046130c7565b610ea5565b3480156104a157600080fd5b5060015460005403600019015b6040519081526020016103bd565b3480156104c857600080fd5b506104d1610eef565b6040516103bd91906131ab565b3480156104ea57600080fd5b506104336104f93660046130c7565b611061565b34801561050a57600080fd5b506104ae60115481565b610433610522366004613291565b6110a4565b34801561053357600080fd5b506104ae6105423660046130c7565b60009081526008602052604090206001015490565b34801561056357600080fd5b506104ae60125481565b34801561057957600080fd5b506104336105883660046132cd565b6110cf565b34801561059957600080fd5b506104336105a83660046132f9565b6110f4565b3480156105b957600080fd5b506104336105c83660046130c7565b611164565b3480156105d957600080fd5b506104336105e83660046132cd565b6111a7565b3480156105f957600080fd5b506104336106083660046133b1565b611225565b34801561061957600080fd5b506104336106283660046130fc565b611239565b34801561063957600080fd5b50600c546104ae565b610433610650366004613291565b6112eb565b34801561066157600080fd5b50600e54610408906001600160a01b031681565b34801561068157600080fd5b506103b16106903660046130c7565b611310565b3480156106a157600080fd5b506104336106b03660046133f9565b61131b565b3480156106c157600080fd5b506104336106d036600461346a565b611330565b3480156106e157600080fd5b50601354610408906001600160a01b031681565b34801561070157600080fd5b5061071561071036600461348d565b6113c5565b6040516103bd91906134ef565b34801561072e57600080fd5b50610433611477565b34801561074357600080fd5b506104086107523660046130c7565b61151c565b34801561076357600080fd5b506104336107723660046130fc565b611527565b34801561078357600080fd5b506104ae6107923660046132f9565b61154b565b3480156107a357600080fd5b50610433611599565b3480156107b857600080fd5b506107cc6107c73660046132f9565b6115ad565b6040516103bd9190613531565b3480156107e557600080fd5b50610408611693565b3480156107fa57600080fd5b506103b16108093660046132cd565b6116ac565b34801561081a57600080fd5b5061082e6108293660046132f9565b6116d7565b6040516103bd91908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b61043361086f3660046130c7565b6117b5565b34801561088057600080fd5b506103db611938565b34801561089557600080fd5b506107cc6108a4366004613569565b611947565b3480156108b557600080fd5b506104336108c43660046132f9565b611ace565b3480156108d557600080fd5b506104ae600081565b3480156108ea57600080fd5b506104336108f93660046135aa565b611b24565b34801561090a57600080fd5b50600f54610408906001600160a01b031681565b61043361092c3660046135e1565b611b38565b34801561093d57600080fd5b5061043361094c3660046132f9565b611b65565b34801561095d57600080fd5b5061046861096c3660046130c7565b611c17565b34801561097d57600080fd5b506103db61098c3660046130c7565b611c67565b34801561099d57600080fd5b506104ae7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b3480156109d157600080fd5b506104336109e03660046132cd565b611ced565b3480156109f157600080fd5b50610433610a003660046130fc565b611d12565b348015610a1157600080fd5b50610433610a203660046136ea565b611d1c565b348015610a3157600080fd5b50610a64610a403660046132f9565b6001600160a01b031660009081526005602052604090205460c01c63ffffffff1690565b6040516001600160401b0390911681526020016103bd565b348015610a8857600080fd5b506103b1610a973660046137a9565b611d5e565b348015610aa857600080fd5b50600f546103b190600160a01b900460ff1681565b348015610ac957600080fd5b50610a64610ad83660046132f9565b6001600160a01b031660009081526005602052604090205460e01c90565b348015610b0257600080fd5b50610433610b113660046132f9565b611e1c565b348015610b2257600080fd5b506104ae60105481565b348015610b3857600080fd5b50600d546104ae565b6000610b4c82611e95565b80610b5b5750610b5b82611eca565b92915050565b606060028054610b70906137d3565b80601f0160208091040260200160405190810160405280929190818152602001828054610b9c906137d3565b8015610be95780601f10610bbe57610100808354040283529160200191610be9565b820191906000526020600020905b815481529060010190602001808311610bcc57829003601f168201915b5050505050905090565b6000610bfe82611f18565b610c1b576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b81610c4181611f4d565b610c4b838361200f565b505050565b601354600090600160a01b900460ff1660011480610c7a5750601354600160a01b900460ff166003145b905080158015610c9a575033610c8e611693565b6001600160a01b031614155b15610cb85760405163726d9d6960e01b815260040160405180910390fd5b6000610ccd610a4060c0860160a087016132f9565b90508335610ce4846001600160401b038416613823565b1115610d0357604051637673930f60e01b815260040160405180910390fd5b82601054610d119190613836565b3414610d305760405163656b1af360e01b815260040160405180910390fd5b600080610d3c866120af565b91509150610d48611693565b6001600160a01b0316826001600160a01b031614610d795760405163f896abaf60e01b815260040160405180910390fd5b610d8960a08701608088016132f9565b6001600160a01b0316816001600160a01b031614610dba576040516304efa49d60e51b815260040160405180910390fd5b610dd3610dcd60c0880160a089016132f9565b866121f9565b91840191610df0610dea60c0880160a089016132f9565b8461223d565b6013546040516000916001600160a01b03169034908381818185875af1925050503d8060008114610e3d576040519150601f19603f3d011682016040523d82523d6000602084013e610e42565b606091505b5050905080610e8b5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064015b60405180910390fd5b50505050505050565b610e9c61300a565b610b5b82612274565b610ead61228d565b601281905560408051338152602081018390527f9074f4c535a222861a631985c506f755c216edda189cb7656116f60322228bad91015b60405180910390a150565b610f6960405180610180016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160001515815260200160001515815260200160608152602001606081525090565b601354600090600160a01b900460ff1660011480610f935750601354600160a01b900460ff166003145b90506000601360149054906101000a900460ff1660ff1660021480610fc45750601354600160a01b900460ff166003145b9050604051806101800160405280610fe56001546000546000199190030190565b8152602001600c548152602001600d54815260200160105481526020016011548152602001601254815260200161101a611693565b6001600160a01b0390811682526013541660208201528315156040820152821515606082015260800161104b610b61565b8152602001611058611938565b90529392505050565b61106961228d565b601081905560408051338152602081018390527ff0e57f2cc3c10647532b9e07271e329734cb12e00ef14333da0d79a9c53d831f9101610ee4565b826001600160a01b03811633146110be576110be33611f4d565b6110c98484846122ec565b50505050565b6000828152600860205260409020600101546110ea81612492565b610c4b838361249c565b6110fc61228d565b6001600160a01b03811661110f57600080fd5b601380546001600160a01b0319166001600160a01b0383169081179091556040805133815260208101929092527f54f1877b9010a3135c68dc2b0b326591d02a8cfbae5443bc11b94af1cafae4029101610ee4565b61116c61228d565b601181905560408051338152602081018390527fd60ff19058ff26897d4ccb9d7ee31a589d1230dc668dfdee26fda0a565bac7349101610ee4565b6001600160a01b03811633146112175760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610e82565b6112218282612522565b5050565b61122d61228d565b600b6112218282613893565b6112637f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336116ac565b6112c45760405162461bcd60e51b815260206004820152602c60248201527f4552433732314d696e74626c653a206d7573742068617665206d696e7465722060448201526b1c9bdb19481d1bc81b5a5b9d60a21b6064820152608401610e82565b6112cf8260016121f9565b6001600d60008282546112e29190613823565b90915550505050565b826001600160a01b03811633146113055761130533611f4d565b6110c9848484612589565b6000610b5b82611f18565b61132361228d565b600a610c4b828483613952565b61133861228d565b60ff8116158061134b57508060ff166001145b8061135957508060ff166002145b8061136757508060ff166003145b61137057600080fd5b6013805460ff60a01b1916600160a01b60ff8416908102919091179091556040805133815260208101929092527fc713b270b8a45c8a69dfb64819d91aed2138afa15cadd92359025e74745847009101610ee4565b6060816000816001600160401b038111156113e2576113e2613314565b60405190808252806020026020018201604052801561141b57816020015b61140861300a565b8152602001906001900390816114005790505b50905060005b82811461146e5761144986868381811061143d5761143d613a11565b90506020020135611c17565b82828151811061145b5761145b613a11565b6020908102919091010152600101611421565b50949350505050565b61147f611693565b6001600160a01b0316336001600160a01b0316146114b057604051635fc483c560e01b815260040160405180910390fd5b600f54600160a01b900460ff16156114db57604051631551a48f60e11b815260040160405180910390fd5b600f80546001600160a81b031916600160a01b1790556040517f51e2d870cc2e10853e38dc06fcdae46ad3c3f588f326608803dac6204541ad1690600090a1565b6000610b5b826125a4565b61152f61228d565b61153982826121f9565b80600d60008282546112e29190613823565b60006001600160a01b038216611574576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6115a161228d565b6115ab6000612613565b565b606060008060006115bd8561154b565b90506000816001600160401b038111156115d9576115d9613314565b604051908082528060200260200182016040528015611602578160200160208202803683370190505b50905061160d61300a565b60015b8386146116875761162081612665565b9150816040015161167f5781516001600160a01b03161561164057815194505b876001600160a01b0316856001600160a01b03160361167f578083878060010198508151811061167257611672613a11565b6020026020010181815250505b600101611610565b50909695505050505050565b60006116a76009546001600160a01b031690565b905090565b60009182526008602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6117026040518060800160405280600081526020016000815260200160008152602001600081525090565b60405180608001604052806117168461154b565b8152602001611747846001600160a01b03166000908152600560205260409081902054901c6001600160401b031690565b815260200161176e846001600160a01b031660009081526005602052604090205460e01c90565b6001600160401b031681526020016117a4846001600160a01b031660009081526005602052604090205460c01c63ffffffff1690565b6001600160401b0316905292915050565b601354600090600160a01b900460ff16600214806117df5750601354600160a01b900460ff166003145b9050801580156117ff5750336117f3611693565b6001600160a01b031614155b1561181c576040516271245160e01b815260040160405180910390fd5b3360009081526005602052604090205460125460e09190911c906118408483613823565b111561185f57604051637673930f60e01b815260040160405180910390fd5b8260105461186d9190613836565b341461188c5760405163656b1af360e01b815260040160405180910390fd5b61189633846121f9565b82016118a23382612685565b6013546040516000916001600160a01b03169034908381818185875af1925050503d80600081146118ef576040519150601f19603f3d011682016040523d82523d6000602084013e6118f4565b606091505b50509050806110c95760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610e82565b606060038054610b70906137d3565b606081831061196957604051631960ccad60e11b815260040160405180910390fd5b60008061197560005490565b9050600185101561198557600194505b80841115611991578093505b600061199c8761154b565b9050848610156119bb57858503818110156119b5578091505b506119bf565b5060005b6000816001600160401b038111156119d9576119d9613314565b604051908082528060200260200182016040528015611a02578160200160208202803683370190505b50905081600003611a18579350611ac792505050565b6000611a2388611c17565b905060008160400151611a34575080515b885b888114158015611a465750848714155b15611abb57611a5481612665565b92508260400151611ab35782516001600160a01b031615611a7457825191505b8a6001600160a01b0316826001600160a01b031603611ab35780848880600101995081518110611aa657611aa6613a11565b6020026020010181815250505b600101611a36565b50505092835250909150505b9392505050565b611ad661228d565b600e80546001600160a01b0319166001600160a01b0383169081179091556040519081527f12be4820d03362d1f48434d870b2fc1549b3a3d16d891eeaac7c3073f3ded8b790602001610ee4565b81611b2e81611f4d565b610c4b83836126ca565b836001600160a01b0381163314611b5257611b5233611f4d565b611b5e8585858561276b565b5050505050565b611b6d611693565b6001600160a01b0316336001600160a01b031614611b9e57604051635fc483c560e01b815260040160405180910390fd5b600f54600160a01b900460ff1615611bc957604051631551a48f60e11b815260040160405180910390fd5b600f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f9f513fe86dc42fdbac355fa4d9b1d5be7b5e6cd2df67e30db8003766568de47690602001610ee4565b611c1f61300a565b611c2761300a565b6001831080611c3857506000548310155b15611c435792915050565b611c4c83612665565b9050806040015115611c5e5792915050565b611ac783612274565b6060611c7282611f18565b611c8f57604051630a14c4b560e41b815260040160405180910390fd5b6000611c996127af565b90508051600003611cb95760405180602001604052806000815250611ac7565b80611cc384612801565b600b604051602001611cd793929190613a27565b6040516020818303038152906040529392505050565b600082815260086020526040902060010154611d0881612492565b610c4b8383612522565b6112218282611239565b60005b8251811015610c4b57611d4c838281518110611d3d57611d3d613a11565b60200260200101516001611239565b80611d5681613ac7565b915050611d1f565b6001600160a01b0382811660009081526007602090815260408083208585168452909152812054600e54919260ff909116911615611ac757600e546040516346e67e2960e11b81526001600160a01b0386811660048301528581166024830152831515604483015290911690638dccfc5290606401602060405180830381865afa158015611df0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e149190613ae0565b915050610b5b565b611e2461228d565b6001600160a01b038116611e895760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610e82565b611e9281612613565b50565b60006001600160e01b03198216637965db0b60e01b1480610b5b57506301ffc9a760e01b6001600160e01b0319831614610b5b565b60006301ffc9a760e01b6001600160e01b031983161480611efb57506380ac58cd60e01b6001600160e01b03198316145b80610b5b5750506001600160e01b031916635b5e139f60e01b1490565b600081600111158015611f2c575060005482105b8015610b5b575050600090815260046020526040902054600160e01b161590565b600f546001600160a01b03168015801590611f7257506000816001600160a01b03163b115b1561122157604051633185c44d60e21b81523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190613ae0565b61122157604051633b79c77360e21b81526001600160a01b0383166004820152602401610e82565b600061201a8261151c565b9050336001600160a01b03821614612053576120368133611d5e565b612053576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000808061214e6120c660a08601608087016132f9565b6040516020016120ee919060609190911b6bffffffffffffffffffffffff1916815260140190565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b9050600061219d826121636040880188613afd565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061284592505050565b905060006121d66121b460c0880160a089016132f9565b6121c16020890189613afd565b6040516120ee939291908b3590602001613b43565b905060006121eb8261216360608a018a613afd565b929792965091945050505050565b60115460015460005483919003600019016122149190613823565b111561223357604051633be28bdb60e11b815260040160405180910390fd5b6112218282612869565b6001600160a01b03821660009081526005602052604081205460e01c9050610c4b83836020846001600160401b0316901b17612974565b61227c61300a565b610b5b612288836125a4565b6129a6565b33612296611693565b6001600160a01b0316146115ab5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610e82565b60006122f7826125a4565b9050836001600160a01b0316816001600160a01b03161461232a5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b038816909114176123775761235a8633611d5e565b61237757604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661239e57604051633a954ecd60e21b815260040160405180910390fd5b6123ab86868660016129e9565b80156123b657600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003612448576001840160008181526004602052604081205490036124465760005481146124465760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b611e928133612a59565b6124a682826116ac565b6112215760008281526008602090815260408083206001600160a01b03851684529091529020805460ff191660011790556124de3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61252c82826116ac565b156112215760008281526008602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b610c4b83838360405180602001604052806000815250611b38565b600081806001116125fa576000548110156125fa5760008181526004602052604081205490600160e01b821690036125f8575b80600003611ac75750600019016000818152600460205260409020546125d7565b505b604051636f96cda160e11b815260040160405180910390fd5b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61266d61300a565b600082815260046020526040902054610b5b906129a6565b60006126af836001600160a01b031660009081526005602052604090205460c01c63ffffffff1690565b9050610c4b83826020856001600160401b0316901b17612974565b600e546001600160a01b0316158015906126ee57506000826001600160a01b03163b115b1561276157600e54604051631b3b02e560e11b81523360048201526001600160a01b03848116602483015283151560448301529091169063367605ca90606401600060405180830381600087803b15801561274857600080fd5b505af115801561275c573d6000803e3d6000fd5b505050505b6112218282612ab2565b6127768484846110a4565b6001600160a01b0383163b156110c95761279284848484612b1e565b6110c9576040516368d2bf6b60e11b815260040160405180910390fd5b60606000600a80546127c0906137d3565b905011156127d557600a8054610b70906137d3565b6127dd611938565b6040516020016127ed9190613b70565b604051602081830303815290604052905090565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061281b5750819003601f19909101908152919050565b60008060006128548585612c0a565b9150915061286181612c4f565b509392505050565b600080549082900361288e5760405163b562e8dd60e01b815260040160405180910390fd5b61289b60008483856129e9565b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b81811461294a57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612912565b508160000361296b57604051622e076360e81b815260040160405180910390fd5b60005550505050565b6001600160a01b03909116600090815260056020526040902080546001600160c01b031660c09290921b919091179055565b6129ae61300a565b6001600160a01b03821681526001600160401b0360a083901c166020820152600160e01b82161515604082015260e89190911c606082015290565b6001600160a01b03831615801590612a075750612a058361154b565b155b15612a1657600c805460010190555b6001600160a01b03841615801590612a365750612a328461154b565b6001145b8015612a4457506000600c54115b156110c957600c805460001901905550505050565b612a6382826116ac565b61122157612a7081612d99565b612a7b836020612dab565b604051602001612a8c929190613bc4565b60408051601f198184030181529082905262461bcd60e51b8252610e82916004016130b4565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290612b53903390899088908890600401613c39565b6020604051808303816000875af1925050508015612b8e575060408051601f3d908101601f19168201909252612b8b91810190613c6c565b60015b612bec573d808015612bbc576040519150601f19603f3d011682016040523d82523d6000602084013e612bc1565b606091505b508051600003612be4576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6000808251604103612c405760208301516040840151606085015160001a612c3487828585612f46565b94509450505050612c48565b506000905060025b9250929050565b6000816004811115612c6357612c63613c89565b03612c6b5750565b6001816004811115612c7f57612c7f613c89565b03612ccc5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610e82565b6002816004811115612ce057612ce0613c89565b03612d2d5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610e82565b6003816004811115612d4157612d41613c89565b03611e925760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610e82565b6060610b5b6001600160a01b03831660145b60606000612dba836002613836565b612dc5906002613823565b6001600160401b03811115612ddc57612ddc613314565b6040519080825280601f01601f191660200182016040528015612e06576020820181803683370190505b509050600360fc1b81600081518110612e2157612e21613a11565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612e5057612e50613a11565b60200101906001600160f81b031916908160001a9053506000612e74846002613836565b612e7f906001613823565b90505b6001811115612ef7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612eb357612eb3613a11565b1a60f81b828281518110612ec957612ec9613a11565b60200101906001600160f81b031916908160001a90535060049490941c93612ef081613c9f565b9050612e82565b508315611ac75760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610e82565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f7d5750600090506003613001565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612fd1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612ffa57600060019250925050613001565b9150600090505b94509492505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160e01b031981168114611e9257600080fd5b60006020828403121561305957600080fd5b8135611ac781613031565b60005b8381101561307f578181015183820152602001613067565b50506000910152565b600081518084526130a0816020860160208601613064565b601f01601f19169290920160200192915050565b602081526000611ac76020830184613088565b6000602082840312156130d957600080fd5b5035919050565b80356001600160a01b03811681146130f757600080fd5b919050565b6000806040838503121561310f57600080fd5b613118836130e0565b946020939093013593505050565b6000806040838503121561313957600080fd5b82356001600160401b0381111561314f57600080fd5b830160c0818603121561311857600080fd5b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b60808101610b5b8284613161565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a082015260a082015160c0820152600060c083015161320460e08401826001600160a01b03169052565b5060e0830151610100613221818501836001600160a01b03169052565b84015190506101206132368482018315159052565b840151905061014061324b8482018315159052565b80850151915050610180610160818186015261326b6101a0860184613088565b90860151858203601f1901838701529092506132878382613088565b9695505050505050565b6000806000606084860312156132a657600080fd5b6132af846130e0565b92506132bd602085016130e0565b9150604084013590509250925092565b600080604083850312156132e057600080fd5b823591506132f0602084016130e0565b90509250929050565b60006020828403121561330b57600080fd5b611ac7826130e0565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561335257613352613314565b604052919050565b60006001600160401b0383111561337357613373613314565b613386601f8401601f191660200161332a565b905082815283838301111561339a57600080fd5b828260208301376000602084830101529392505050565b6000602082840312156133c357600080fd5b81356001600160401b038111156133d957600080fd5b8201601f810184136133ea57600080fd5b612c028482356020840161335a565b6000806020838503121561340c57600080fd5b82356001600160401b038082111561342357600080fd5b818501915085601f83011261343757600080fd5b81358181111561344657600080fd5b86602082850101111561345857600080fd5b60209290920196919550909350505050565b60006020828403121561347c57600080fd5b813560ff81168114611ac757600080fd5b600080602083850312156134a057600080fd5b82356001600160401b03808211156134b757600080fd5b818501915085601f8301126134cb57600080fd5b8135818111156134da57600080fd5b8660208260051b850101111561345857600080fd5b6020808252825182820181905260009190848201906040850190845b818110156116875761351e838551613161565b928401926080929092019160010161350b565b6020808252825182820181905260009190848201906040850190845b818110156116875783518352928401929184019160010161354d565b60008060006060848603121561357e57600080fd5b613587846130e0565b95602085013595506040909401359392505050565b8015158114611e9257600080fd5b600080604083850312156135bd57600080fd5b6135c6836130e0565b915060208301356135d68161359c565b809150509250929050565b600080600080608085870312156135f757600080fd5b613600856130e0565b935061360e602086016130e0565b92506040850135915060608501356001600160401b0381111561363057600080fd5b8501601f8101871361364157600080fd5b6136508782356020840161335a565b91505092959194509250565b60006001600160401b0382111561367557613675613314565b5060051b60200190565b600082601f83011261369057600080fd5b813560206136a56136a08361365c565b61332a565b82815260059290921b840181019181810190868411156136c457600080fd5b8286015b848110156136df57803583529183019183016136c8565b509695505050505050565b600080604083850312156136fd57600080fd5b82356001600160401b038082111561371457600080fd5b818501915085601f83011261372857600080fd5b813560206137386136a08361365c565b82815260059290921b8401810191818101908984111561375757600080fd5b948201945b8386101561377c5761376d866130e0565b8252948201949082019061375c565b9650508601359250508082111561379257600080fd5b5061379f8582860161367f565b9150509250929050565b600080604083850312156137bc57600080fd5b6137c5836130e0565b91506132f0602084016130e0565b600181811c908216806137e757607f821691505b60208210810361380757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610b5b57610b5b61380d565b8082028115828204841417610b5b57610b5b61380d565b601f821115610c4b57600081815260208120601f850160051c810160208610156138745750805b601f850160051c820191505b8181101561248a57828155600101613880565b81516001600160401b038111156138ac576138ac613314565b6138c0816138ba84546137d3565b8461384d565b602080601f8311600181146138f557600084156138dd5750858301515b600019600386901b1c1916600185901b17855561248a565b600085815260208120601f198616915b8281101561392457888601518255948401946001909101908401613905565b50858210156139425787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160401b0383111561396957613969613314565b61397d8361397783546137d3565b8361384d565b6000601f8411600181146139b157600085156139995750838201355b600019600387901b1c1916600186901b178355611b5e565b600083815260209020601f19861690835b828110156139e257868501358255602094850194600190920191016139c2565b50868210156139ff5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b634e487b7160e01b600052603260045260246000fd5b600084516020613a3a8285838a01613064565b855191840191613a4d8184848a01613064565b8554920191600090613a5e816137d3565b60018281168015613a765760018114613a8b57613ab7565b60ff1984168752821515830287019450613ab7565b896000528560002060005b84811015613aaf57815489820152908301908701613a96565b505082870194505b50929a9950505050505050505050565b600060018201613ad957613ad961380d565b5060010190565b600060208284031215613af257600080fd5b8151611ac78161359c565b6000808335601e19843603018112613b1457600080fd5b8301803591506001600160401b03821115613b2e57600080fd5b602001915036819003821315612c4857600080fd5b6bffffffffffffffffffffffff198560601b16815282846014830137601492019182015260340192915050565b7f68747470733a2f2f6e66742e66696e616e6369652e696f2f6d6574616461746181526000602f60f81b8060208401528351613bb3816021860160208801613064565b602193019283015250602201919050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613bfc816017850160208801613064565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613c2d816028840160208801613064565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061328790830184613088565b600060208284031215613c7e57600080fd5b8151611ac781613031565b634e487b7160e01b600052602160045260246000fd5b600081613cae57613cae61380d565b50600019019056fea2646970667358221220ad83ae1bac39192d8f9c57b5294762f52c9d5cb32af24f51bf1268321725264b64736f6c63430008110033

Deployed Bytecode Sourcemap

138124:530:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124836:329;;;;;;;;;;-1:-1:-1;124836:329:0;;;;;:::i;:::-;;:::i;:::-;;;661:14:1;;654:22;636:41;;624:2;609:18;124836:329:0;;;;;;;;60517:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;67008:218::-;;;;;;;;;;-1:-1:-1;67008:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1902:32:1;;;1884:51;;1872:2;1857:18;67008:218:0;1738:203:1;136212:250:0;;;;;;:::i;:::-;;:::i;:::-;;132617:974;;;;;;:::i;:::-;;:::i;122084:155::-;;;;;;;;;;-1:-1:-1;122084:155:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;129161:181::-;;;;;;;;;;-1:-1:-1;129161:181:0;;;;;:::i;:::-;;:::i;56268:323::-;;;;;;;;;;-1:-1:-1;119161:1:0;56542:12;56329:7;56526:13;:28;-1:-1:-1;;56526:46:0;56268:323;;;3619:25:1;;;3607:2;3592:18;56268:323:0;3473:177:1;130594:620:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;129407:166::-;;;;;;;;;;-1:-1:-1;129407:166:0;;;;;:::i;:::-;;:::i;127571:26::-;;;;;;;;;;;;;;;;136645:224;;;;;;:::i;:::-;;:::i;25774:131::-;;;;;;;;;;-1:-1:-1;25774:131:0;;;;;:::i;:::-;25848:7;25875:12;;;:6;:12;;;;;:22;;;;25774:131;127604:28;;;;;;;;;;;;;;;;26215:147;;;;;;;;;;-1:-1:-1;26215:147:0;;;;;:::i;:::-;;:::i;129656:238::-;;;;;;;;;;-1:-1:-1;129656:238:0;;;;;:::i;:::-;;:::i;128880:169::-;;;;;;;;;;-1:-1:-1;128880:169:0;;;;;:::i;:::-;;:::i;27359:218::-;;;;;;;;;;-1:-1:-1;27359:218:0;;;;;:::i;:::-;;:::i;123358:165::-;;;;;;;;;;-1:-1:-1;123358:165:0;;;;;:::i;:::-;;:::i;119287:547::-;;;;;;;;;;-1:-1:-1;119287:547:0;;;;;:::i;:::-;;:::i;121692:99::-;;;;;;;;;;-1:-1:-1;121772:11:0;;121692:99;;137056:232;;;;;;:::i;:::-;;:::i;118597:35::-;;;;;;;;;;-1:-1:-1;118597:35:0;;;;-1:-1:-1;;;;;118597:35:0;;;122338:112;;;;;;;;;;-1:-1:-1;122338:112:0;;;;;:::i;:::-;;:::i;123157:113::-;;;;;;;;;;-1:-1:-1;123157:113:0;;;;;:::i;:::-;;:::i;129965:546::-;;;;;;;;;;-1:-1:-1;129965:546:0;;;;;:::i;:::-;;:::i;127639:36::-;;;;;;;;;;-1:-1:-1;127639:36:0;;;;-1:-1:-1;;;;;127639:36:0;;;96902:528;;;;;;;;;;-1:-1:-1;96902:528:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;115849:531::-;;;;;;;;;;;;;:::i;61910:152::-;;;;;;;;;;-1:-1:-1;61910:152:0;;;;;:::i;:::-;;:::i;120712:185::-;;;;;;;;;;-1:-1:-1;120712:185:0;;;;;:::i;:::-;;:::i;57452:233::-;;;;;;;;;;-1:-1:-1;57452:233:0;;;;;:::i;:::-;;:::i;31535:103::-;;;;;;;;;;;;;:::i;100778:900::-;;;;;;;;;;-1:-1:-1;100778:900:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;137828:191::-;;;;;;;;;;;;;:::i;24247:147::-;;;;;;;;;;-1:-1:-1;24247:147:0;;;;;:::i;:::-;;:::i;131504:341::-;;;;;;;;;;-1:-1:-1;131504:341:0;;;;;:::i;:::-;;:::i;:::-;;;;;;11084:13:1;;11066:32;;11154:4;11142:17;;;11136:24;11114:20;;;11107:54;11217:4;11205:17;;;11199:24;11177:20;;;11170:54;11280:4;11268:17;;;11262:24;11240:20;;;11233:54;;;;11053:3;11038:19;;10859:434;131905:656:0;;;;;;:::i;:::-;;:::i;60693:104::-;;;;;;;;;;;;;:::i;97818:2513::-;;;;;;;;;;-1:-1:-1;97818:2513:0;;;;;:::i;:::-;;:::i;123598:166::-;;;;;;;;;;-1:-1:-1;123598:166:0;;;;;:::i;:::-;;:::i;23352:49::-;;;;;;;;;;-1:-1:-1;23352:49:0;23397:4;23352:49;;135833:201;;;;;;;;;;-1:-1:-1;135833:201:0;;;;;:::i;:::-;;:::i;109846:53::-;;;;;;;;;;-1:-1:-1;109846:53:0;;;;-1:-1:-1;;;;;109846:53:0;;;137475:266;;;;;;:::i;:::-;;:::i;115236:487::-;;;;;;;;;;-1:-1:-1;115236:487:0;;;;;:::i;:::-;;:::i;96315:428::-;;;;;;;;;;-1:-1:-1;96315:428:0;;;;;:::i;:::-;;:::i;122534:560::-;;;;;;;;;;-1:-1:-1;122534:560:0;;;;;:::i;:::-;;:::i;118270:62::-;;;;;;;;;;;;118308:24;118270:62;;26655:149;;;;;;;;;;-1:-1:-1;26655:149:0;;;;;:::i;:::-;;:::i;120512:97::-;;;;;;;;;;-1:-1:-1;120512:97:0;;;;;:::i;:::-;;:::i;119965:430::-;;;;;;;;;;-1:-1:-1;119965:430:0;;;;;:::i;:::-;;:::i;133659:228::-;;;;;;;;;;-1:-1:-1;133659:228:0;;;;;:::i;:::-;-1:-1:-1;;;;;58427:25:0;133747:6;58427:25;;;:18;:25;;;;;;51985:3;58427:40;133859:18;133841:36;;133659:228;;;;-1:-1:-1;;;;;15148:31:1;;;15130:50;;15118:2;15103:18;133659:228:0;14986:200:1;123864:395:0;;;;;;;;;;-1:-1:-1;123864:395:0;;;;;:::i;:::-;;:::i;114462:43::-;;;;;;;;;;-1:-1:-1;114462:43:0;;;;-1:-1:-1;;;114462:43:0;;;;;;133965:212;;;;;;;;;;-1:-1:-1;133965:212:0;;;;;:::i;:::-;-1:-1:-1;;;;;58427:25:0;134050:6;58427:25;;;:18;134166:2;58427:25;;;;;134147:21;;;133965:212;31793:201;;;;;;;;;;-1:-1:-1;31793:201:0;;;;;:::i;:::-;;:::i;127540:24::-;;;;;;;;;;;;;;;;121885:103;;;;;;;;;;-1:-1:-1;121967:13:0;;121885:103;;124836:329;125016:4;125058:44;125090:11;125058:31;:44::i;:::-;:99;;;;125119:38;125145:11;125119:25;:38::i;:::-;125038:119;124836:329;-1:-1:-1;;124836:329:0:o;60517:100::-;60571:13;60604:5;60597:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60517:100;:::o;67008:218::-;67084:7;67109:16;67117:7;67109;:16::i;:::-;67104:64;;67134:34;;-1:-1:-1;;;67134:34:0;;;;;;;;;;;67104:64;-1:-1:-1;67188:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;67188:30:0;;67008:218::o;136212:250::-;136396:8;111619:30;111640:8;111619:20;:30::i;:::-;136422:32:::1;136436:8;136446:7;136422:13;:32::i;:::-;136212:250:::0;;;:::o;132617:974::-;128401:10;;128378:20;;-1:-1:-1;;;128401:10:0;;;;128415:1;128401:15;;:34;;-1:-1:-1;128420:10:0;;-1:-1:-1;;;128420:10:0;;;;128434:1;128420:15;128401:34;128378:57;;128451:15;128450:16;:43;;;;-1:-1:-1;3931:10:0;128470:7;:5;:7::i;:::-;-1:-1:-1;;;;;128470:23:0;;;128450:43;128446:95;;;128515:26;;-1:-1:-1;;;128515:26:0;;;;;;;;;;;128446:95;132773:16:::1;132792:46;132818:19;::::0;;;::::1;::::0;::::1;;:::i;132792:46::-;132773:65:::0;-1:-1:-1;132876:24:0;::::1;132853:20;132865:8:::0;-1:-1:-1;;;;;132853:20:0;::::1;;:::i;:::-;:47;132849:109;;;132922:36;;-1:-1:-1::0;;;132922:36:0::1;;;;;;;;;;;132849:109;132999:8;132987:9;;:20;;;;:::i;:::-;132973:9;:35;132969:66;;133017:18;;-1:-1:-1::0;;;133017:18:0::1;;;;;;;;;;;132969:66;133049:18;133069::::0;133091:27:::1;133107:10;133091:15;:27::i;:::-;133048:70;;;;133147:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;133133:21:0::1;:10;-1:-1:-1::0;;;;;133133:21:0::1;;133129:57;;133163:23;;-1:-1:-1::0;;;133163:23:0::1;;;;;;;;;;;133129:57;133215:21;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;133201:35:0::1;:10;-1:-1:-1::0;;;;;133201:35:0::1;;133197:71;;133245:23;;-1:-1:-1::0;;;133245:23:0::1;;;;;;;;;;;133197:71;133281:36;133287:19;::::0;;;::::1;::::0;::::1;;:::i;:::-;133308:8;133281:5;:36::i;:::-;133353:29:::0;;::::1;::::0;133404:60:::1;133433:19;::::0;;;::::1;::::0;::::1;;:::i;:::-;133454:9;133404:28;:60::i;:::-;133496:13;::::0;:40:::1;::::0;133478:12:::1;::::0;-1:-1:-1;;;;;133496:13:0::1;::::0;133522:9:::1;::::0;133478:12;133496:40;133478:12;133496:40;133522:9;133496:13;:40:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;133477:59;;;133555:7;133547:36;;;::::0;-1:-1:-1;;;133547:36:0;;16688:2:1;133547:36:0::1;::::0;::::1;16670:21:1::0;16727:2;16707:18;;;16700:30;-1:-1:-1;;;16746:18:1;;;16739:46;16802:18;;133547:36:0::1;;;;;;;;;132762:829;;;;128367:194:::0;132617:974;;:::o;122084:155::-;122169:21;;:::i;:::-;122210;122223:7;122210:12;:21::i;129161:181::-;30773:13;:11;:13::i;:::-;129241::::1;:30:::0;;;129287:47:::1;::::0;;129307:10:::1;17005:51:1::0;;17087:2;17072:18;;17065:34;;;129287:47:0::1;::::0;16978:18:1;129287:47:0::1;;;;;;;;129161:181:::0;:::o;130594:620::-;130637:12;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;130637:12:0;130685:10;;130662:20;;-1:-1:-1;;;130685:10:0;;;;130699:1;130685:15;;:34;;-1:-1:-1;130704:10:0;;-1:-1:-1;;;130704:10:0;;;;130718:1;130704:15;130685:34;130662:57;;130730:23;130756:10;;;;;;;;;;;:15;;130770:1;130756:15;:34;;;-1:-1:-1;130775:10:0;;-1:-1:-1;;;130775:10:0;;;;130789:1;130775:15;130756:34;130730:60;;130821:385;;;;;;;;130845:13;119161:1;56542:12;56329:7;56526:13;-1:-1:-1;;56526:28:0;;;:46;;56268:323;130845:13;130821:385;;;;130877:11;;130821:385;;;;130907:13;;130821:385;;;;130939:9;;130821:385;;;;130967:11;;130821:385;;;;130997:13;;130821:385;;;;131029:7;:5;:7::i;:::-;-1:-1:-1;;;;;130821:385:0;;;;;131055:13;;;130821:385;;;;;;;;;;;;;;;;;;;;131158:6;:4;:6::i;:::-;130821:385;;;;131183:8;:6;:8::i;:::-;130821:385;;130801:405;130594:620;-1:-1:-1;;;130594:620:0:o;129407:166::-;30773:13;:11;:13::i;:::-;129479:9:::1;:22:::0;;;129517:48:::1;::::0;;129542:10:::1;17005:51:1::0;;17087:2;17072:18;;17065:34;;;129517:48:0::1;::::0;16978:18:1;129517:48:0::1;16831:274:1::0;136645:224:0;136807:4;-1:-1:-1;;;;;111344:18:0;;111352:10;111344:18;111340:83;;111379:32;111400:10;111379:20;:32::i;:::-;136824:37:::1;136843:4;136849:2;136853:7;136824:18;:37::i;:::-;136645:224:::0;;;;:::o;26215:147::-;25848:7;25875:12;;;:6;:12;;;;;:22;;;23843:16;23854:4;23843:10;:16::i;:::-;26329:25:::1;26340:4;26346:7;26329:10;:25::i;129656:238::-:0;30773:13;:11;:13::i;:::-;-1:-1:-1;;;;;129744:28:0;::::1;129736:37;;;::::0;::::1;;129784:13;:39:::0;;-1:-1:-1;;;;;;129784:39:0::1;-1:-1:-1::0;;;;;129784:39:0;::::1;::::0;;::::1;::::0;;;129839:47:::1;::::0;;129859:10:::1;17322:34:1::0;;17387:2;17372:18;;17365:43;;;;129839:47:0::1;::::0;17257:18:1;129839:47:0::1;17110:304:1::0;128880:169:0;30773:13;:11;:13::i;:::-;128956:11:::1;:26:::0;;;128998:43:::1;::::0;;129016:10:::1;17005:51:1::0;;17087:2;17072:18;;17065:34;;;128998:43:0::1;::::0;16978:18:1;128998:43:0::1;16831:274:1::0;27359:218:0;-1:-1:-1;;;;;27455:23:0;;3931:10;27455:23;27447:83;;;;-1:-1:-1;;;27447:83:0;;17621:2:1;27447:83:0;;;17603:21:1;17660:2;17640:18;;;17633:30;17699:34;17679:18;;;17672:62;-1:-1:-1;;;17750:18:1;;;17743:45;17805:19;;27447:83:0;17419:411:1;27447:83:0;27543:26;27555:4;27561:7;27543:11;:26::i;:::-;27359:218;;:::o;123358:165::-;30773:13;:11;:13::i;:::-;123476:18:::1;:39;123497:18:::0;123476;:39:::1;:::i;119287:547::-:0;119513:34;118308:24;3931:10;24247:147;:::i;119513:34::-;119491:128;;;;-1:-1:-1;;;119491:128:0;;20241:2:1;119491:128:0;;;20223:21:1;20280:2;20260:18;;;20253:30;20319:34;20299:18;;;20292:62;-1:-1:-1;;;20370:18:1;;;20363:42;20422:19;;119491:128:0;20039:408:1;119491:128:0;119785:12;119791:2;119795:1;119785:5;:12::i;:::-;119825:1;119808:13;;:18;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;119287:547:0:o;137056:232::-;137222:4;-1:-1:-1;;;;;111344:18:0;;111352:10;111344:18;111340:83;;111379:32;111400:10;111379:20;:32::i;:::-;137239:41:::1;137262:4;137268:2;137272:7;137239:22;:41::i;122338:112::-:0;122402:4;122426:16;122434:7;122426;:16::i;123157:113::-;30773:13;:11;:13::i;:::-;123242:8:::1;:20;123253:9:::0;;123242:8;:20:::1;:::i;129965:546::-:0;30773:13;:11;:13::i;:::-;130280:15:::1;::::0;::::1;::::0;;:51:::1;;;130316:10;:15;;130330:1;130316:15;130280:51;:87;;;;130352:10;:15;;130366:1;130352:15;130280:87;:123;;;;130388:10;:15;;130402:1;130388:15;130280:123;130258:156;;;::::0;::::1;;130425:10;:23:::0;;-1:-1:-1;;;;130425:23:0::1;-1:-1:-1::0;;;130425:23:0::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;130464:39:::1;::::0;;130480:10:::1;21833:51:1::0;;21915:2;21900:18;;21893:45;;;;130464:39:0::1;::::0;21806:18:1;130464:39:0::1;21663:281:1::0;96902:528:0;97046:23;97137:8;97112:22;97137:8;-1:-1:-1;;;;;97204:36:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;97167:73;;97260:9;97255:125;97276:14;97271:1;:19;97255:125;;97332:32;97352:8;;97361:1;97352:11;;;;;;;:::i;:::-;;;;;;;97332:19;:32::i;:::-;97316:10;97327:1;97316:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;97292:3;;97255:125;;;-1:-1:-1;97401:10:0;96902:528;-1:-1:-1;;;;96902:528:0:o;115849:531::-;115925:7;:5;:7::i;:::-;-1:-1:-1;;;;;115911:21:0;:10;-1:-1:-1;;;;;115911:21:0;;115907:72;;115956:11;;-1:-1:-1;;;115956:11:0;;;;;;;;;;;115907:72;116064:31;;-1:-1:-1;;;116064:31:0;;;;116060:95;;;116119:24;;-1:-1:-1;;;116119:24:0;;;;;;;;;;;116060:95;116216:22;:60;;-1:-1:-1;;;;;;116287:38:0;-1:-1:-1;;;116287:38:0;;;116341:31;;;;116273:1;;116341:31;115849:531::o;61910:152::-;61982:7;62025:27;62044:7;62025:18;:27::i;120712:185::-;30773:13;:11;:13::i;:::-;120828:25:::1;120834:8;120844;120828:5;:25::i;:::-;120881:8;120864:13;;:25;;;;;;;:::i;57452:233::-:0;57524:7;-1:-1:-1;;;;;57548:19:0;;57544:60;;57576:28;;-1:-1:-1;;;57576:28:0;;;;;;;;;;;57544:60;-1:-1:-1;;;;;;57622:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;57622:55:0;;57452:233::o;31535:103::-;30773:13;:11;:13::i;:::-;31600:30:::1;31627:1;31600:18;:30::i;:::-;31535:103::o:0;100778:900::-;100856:16;100910:19;100944:25;100984:22;101009:16;101019:5;101009:9;:16::i;:::-;100984:41;;101040:25;101082:14;-1:-1:-1;;;;;101068:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;101068:29:0;;101040:57;;101112:31;;:::i;:::-;119161:1;101158:472;101207:14;101192:11;:29;101158:472;;101259:15;101272:1;101259:12;:15::i;:::-;101247:27;;101297:9;:16;;;101338:8;101293:73;101388:14;;-1:-1:-1;;;;;101388:28:0;;101384:111;;101461:14;;;-1:-1:-1;101384:111:0;101538:5;-1:-1:-1;;;;;101517:26:0;:17;-1:-1:-1;;;;;101517:26:0;;101513:102;;101594:1;101568:8;101577:13;;;;;;101568:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;101513:102;101223:3;;101158:472;;;-1:-1:-1;101651:8:0;;100778:900;-1:-1:-1;;;;;;100778:900:0:o;137828:191::-;137964:7;137996:15;30960:6;;-1:-1:-1;;;;;30960:6:0;;30887:87;137996:15;137989:22;;137828:191;:::o;24247:147::-;24333:4;24357:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;24357:29:0;;;;;;;;;;;;;;;24247:147::o;131504:341::-;131581:19;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;131581:19:0;131633:204;;;;;;;;131664:17;131674:6;131664:9;:17::i;:::-;131633:204;;;;131700:21;131714:6;-1:-1:-1;;;;;57856:25:0;57828:7;57856:25;;;:18;:25;;51749:2;57856:25;;;;;:50;;-1:-1:-1;;;;;57855:82:0;;57767:178;131700:21;131633:204;;;;131740:30;131763:6;-1:-1:-1;;;;;58427:25:0;134050:6;58427:25;;;:18;134166:2;58427:25;;;;;134147:21;;;133965:212;131740:30;-1:-1:-1;;;;;131633:204:0;;;;;131789:33;131815:6;-1:-1:-1;;;;;58427:25:0;133747:6;58427:25;;;:18;:25;;;;;;51985:3;58427:40;133859:18;133841:36;;133659:228;131789:33;-1:-1:-1;;;;;131633:204:0;;;131613:224;131504:341;-1:-1:-1;;131504:341:0:o;131905:656::-;128643:10;;128617:23;;-1:-1:-1;;;128643:10:0;;;;128657:1;128643:15;;:34;;-1:-1:-1;128662:10:0;;-1:-1:-1;;;128662:10:0;;;;128676:1;128662:15;128643:34;128617:60;;128693:18;128692:19;:46;;;;-1:-1:-1;3931:10:0;128715:7;:5;:7::i;:::-;-1:-1:-1;;;;;128715:23:0;;;128692:46;128688:101;;;128760:29;;-1:-1:-1;;;128760:29:0;;;;;;;;;;;128688:101;132062:10:::1;132020:16;58427:25:::0;;;:18;134166:2;58427:25;;;;;132111:13:::1;::::0;134147:21;;;;;;132088:20:::1;132100:8:::0;134147:21;132088:20:::1;:::i;:::-;:36;132084:98;;;132146:36;;-1:-1:-1::0;;;132146:36:0::1;;;;;;;;;;;132084:98;132223:8;132211:9;;:20;;;;:::i;:::-;132197:9;:35;132193:66;;132241:18;;-1:-1:-1::0;;;132241:18:0::1;;;;;;;;;;;132193:66;132272:27;132278:10;132290:8;132272:5;:27::i;:::-;132335:29:::0;::::1;132386:48;132412:10;132335:29:::0;132386:25:::1;:48::i;:::-;132466:13;::::0;:40:::1;::::0;132448:12:::1;::::0;-1:-1:-1;;;;;132466:13:0::1;::::0;132492:9:::1;::::0;132448:12;132466:40;132448:12;132466:40;132492:9;132466:13;:40:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;132447:59;;;132525:7;132517:36;;;::::0;-1:-1:-1;;;132517:36:0;;16688:2:1;132517:36:0::1;::::0;::::1;16670:21:1::0;16727:2;16707:18;;;16700:30;-1:-1:-1;;;16746:18:1;;;16739:46;16802:18;;132517:36:0::1;16486:340:1::0;60693:104:0;60749:13;60782:7;60775:14;;;;;:::i;97818:2513::-;97961:16;98028:4;98019:5;:13;98015:45;;98041:19;;-1:-1:-1;;;98041:19:0;;;;;;;;;;;98015:45;98075:19;98109:17;98129:14;56010:7;56037:13;;55955:103;98129:14;98109:34;-1:-1:-1;119161:1:0;98221:5;:23;98217:87;;;119161:1;98265:23;;98217:87;98380:9;98373:4;:16;98369:73;;;98417:9;98410:16;;98369:73;98456:25;98484:16;98494:5;98484:9;:16::i;:::-;98456:44;;98678:4;98670:5;:12;98666:278;;;98725:12;;;98760:31;;;98756:111;;;98836:11;98816:31;;98756:111;98684:198;98666:278;;;-1:-1:-1;98927:1:0;98666:278;98958:25;99000:17;-1:-1:-1;;;;;98986:32:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;98986:32:0;;98958:60;;99037:17;99058:1;99037:22;99033:78;;99087:8;-1:-1:-1;99080:15:0;;-1:-1:-1;;;99080:15:0;99033:78;99255:31;99289:26;99309:5;99289:19;:26::i;:::-;99255:60;;99330:25;99575:9;:16;;;99570:92;;-1:-1:-1;99632:14:0;;99570:92;99693:5;99676:478;99705:4;99700:1;:9;;:45;;;;;99728:17;99713:11;:32;;99700:45;99676:478;;;99783:15;99796:1;99783:12;:15::i;:::-;99771:27;;99821:9;:16;;;99862:8;99817:73;99912:14;;-1:-1:-1;;;;;99912:28:0;;99908:111;;99985:14;;;-1:-1:-1;99908:111:0;100062:5;-1:-1:-1;;;;;100041:26:0;:17;-1:-1:-1;;;;;100041:26:0;;100037:102;;100118:1;100092:8;100101:13;;;;;;100092:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;100037:102;99747:3;;99676:478;;;-1:-1:-1;;;100239:29:0;;;-1:-1:-1;100246:8:0;;-1:-1:-1;;97818:2513:0;;;;;;:::o;123598:166::-;30773:13;:11;:13::i;:::-;123677::::1;:37:::0;;-1:-1:-1;;;;;;123677:37:0::1;-1:-1:-1::0;;;;;123677:37:0;::::1;::::0;;::::1;::::0;;;123730:26:::1;::::0;1884:51:1;;;123730:26:0::1;::::0;1872:2:1;1857:18;123730:26:0::1;1738:203:1::0;135833:201:0;135962:8;111619:30;111640:8;111619:20;:30::i;:::-;135983:43:::1;136007:8;136017;135983:23;:43::i;137475:266::-:0;137669:4;-1:-1:-1;;;;;111344:18:0;;111352:10;111344:18;111340:83;;111379:32;111400:10;111379:20;:32::i;:::-;137686:47:::1;137709:4;137715:2;137719:7;137728:4;137686:22;:47::i;:::-;137475:266:::0;;;;;:::o;115236:487::-;115347:7;:5;:7::i;:::-;-1:-1:-1;;;;;115333:21:0;:10;-1:-1:-1;;;;;115333:21:0;;115329:72;;115378:11;;-1:-1:-1;;;115378:11:0;;;;;;;;;;;115329:72;115486:31;;-1:-1:-1;;;115486:31:0;;;;115482:95;;;115541:24;;-1:-1:-1;;;115541:24:0;;;;;;;;;;;115482:95;115589:22;:61;;-1:-1:-1;;;;;;115589:61:0;-1:-1:-1;;;;;115589:61:0;;;;;;;;115666:49;;1884:51:1;;;115666:49:0;;1872:2:1;1857:18;115666:49:0;1738:203:1;96315:428:0;96399:21;;:::i;:::-;96433:31;;:::i;:::-;119161:1;96479:7;:25;:54;;;-1:-1:-1;56010:7:0;56037:13;96508:7;:25;;96479:54;96475:103;;;96557:9;96315:428;-1:-1:-1;;96315:428:0:o;96475:103::-;96600:21;96613:7;96600:12;:21::i;:::-;96588:33;;96636:9;:16;;;96632:65;;;96676:9;96315:428;-1:-1:-1;;96315:428:0:o;96632:65::-;96714:21;96727:7;96714:12;:21::i;122534:560::-;122642:13;122673:16;122681:7;122673;:16::i;:::-;122668:59;;122698:29;;-1:-1:-1;;;122698:29:0;;;;;;;;;;;122668:59;122740:21;122764:10;:8;:10::i;:::-;122740:34;;122813:7;122807:21;122832:1;122807:26;:279;;;;;;;;;;;;;;;;;122925:7;122959:18;122969:7;122959:9;:18::i;:::-;123004;122882:163;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;122787:299;122534:560;-1:-1:-1;;;122534:560:0:o;26655:149::-;25848:7;25875:12;;;:6;:12;;;;;:22;;;23843:16;23854:4;23843:10;:16::i;:::-;26770:26:::1;26782:4;26788:7;26770:11;:26::i;120512:97::-:0;120584:17;120589:2;120593:7;120584:4;:17::i;119965:430::-;120298:9;120293:95;120317:9;:16;120313:1;:20;120293:95;;;120355:21;120360:9;120370:1;120360:12;;;;;;;;:::i;:::-;;;;;;;120374:1;120355:4;:21::i;:::-;120335:3;;;;:::i;:::-;;;;120293:95;;123864:395;-1:-1:-1;;;;;68078:25:0;;;124006:4;68078:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;124102:13;;124006:4;;68078:35;;;;;124102:13;124094:38;124090:136;;124156:13;;:58;;-1:-1:-1;;;124156:58:0;;-1:-1:-1;;;;;23734:15:1;;;124156:58:0;;;23716:34:1;23786:15;;;23766:18;;;23759:43;23845:14;;23838:22;23818:18;;;23811:50;124156:13:0;;;;:30;;23651:18:1;;124156:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;124149:65;;;;;31793:201;30773:13;:11;:13::i;:::-;-1:-1:-1;;;;;31882:22:0;::::1;31874:73;;;::::0;-1:-1:-1;;;31874:73:0;;24324:2:1;31874:73:0::1;::::0;::::1;24306:21:1::0;24363:2;24343:18;;;24336:30;24402:34;24382:18;;;24375:62;-1:-1:-1;;;24453:18:1;;;24446:36;24499:19;;31874:73:0::1;24122:402:1::0;31874:73:0::1;31958:28;31977:8;31958:18;:28::i;:::-;31793:201:::0;:::o;23951:204::-;24036:4;-1:-1:-1;;;;;;24060:47:0;;-1:-1:-1;;;24060:47:0;;:87;;-1:-1:-1;;;;;;;;;;6022:40:0;;;24111:36;5913:157;59615:639;59700:4;-1:-1:-1;;;;;;;;;60024:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;60101:25:0;;;60024:102;:179;;;-1:-1:-1;;;;;;;;60178:25:0;-1:-1:-1;;;60178:25:0;;59615:639::o;68379:282::-;68444:4;68500:7;119161:1;68481:26;;:66;;;;;68534:13;;68524:7;:23;68481:66;:153;;;;-1:-1:-1;;68585:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;68585:44:0;:49;;68379:282::o;112470:718::-;112586:22;;-1:-1:-1;;;;;112586:22:0;112729:31;;;;;:68;;;112796:1;112772:8;-1:-1:-1;;;;;112764:29:0;;:33;112729:68;112725:456;;;113047:51;;-1:-1:-1;;;113047:51:0;;113082:4;113047:51;;;17322:34:1;-1:-1:-1;;;;;17392:15:1;;;17372:18;;;17365:43;113047:26:0;;;;;17257:18:1;;113047:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113042:128;;113126:28;;-1:-1:-1;;;113126:28:0;;-1:-1:-1;;;;;1902:32:1;;113126:28:0;;;1884:51:1;1857:18;;113126:28:0;1738:203:1;66441:408:0;66530:13;66546:16;66554:7;66546;:16::i;:::-;66530:32;-1:-1:-1;3931:10:0;-1:-1:-1;;;;;66579:28:0;;;66575:175;;66627:44;66644:5;3931:10;123864:395;:::i;66627:44::-;66622:128;;66699:35;;-1:-1:-1;;;66699:35:0;;;;;;;;;;;66622:128;66762:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;66762:35:0;-1:-1:-1;;;;;66762:35:0;;;;;;;;;66813:28;;66762:24;;66813:28;;;;;;;66519:330;66441:408;;:::o;134893:752::-;134988:7;;;135036:104;135106:21;;;;;;;;:::i;:::-;135089:39;;;;;;;24678:2:1;24674:15;;;;-1:-1:-1;;24670:53:1;24658:66;;24749:2;24740:12;;24529:229;135089:39:0;;;;-1:-1:-1;;135089:39:0;;;;;;;;;135079:50;;135089:39;135079:50;;;;27007:66:1;40032:58:0;;;26995:79:1;27090:12;;;;27083:28;;;;40032:58:0;;;;;;;;;;27127:12:1;;;;40032:58:0;;;40022:69;;;;;;39830:269;135036:104;135017:123;-1:-1:-1;135151:18:0;135172:49;135017:123;135196:24;;;;:10;:24;:::i;:::-;135172:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;135172:13:0;;-1:-1:-1;;;135172:49:0:i;:::-;135151:70;-1:-1:-1;135234:16:0;135253:259;135363:19;;;;;;;;:::i;:::-;135405:15;;;;:10;:15;:::i;:::-;135324:162;;;;;;;135443:24;;;135324:162;;;:::i;135253:259::-;135234:278;-1:-1:-1;135523:18:0;135544:49;135234:278;135568:24;;;;:10;:24;:::i;135544:49::-;135614:10;;135523:70;;-1:-1:-1;134893:752:0;;-1:-1:-1;;;;;134893:752:0:o;131222:208::-;131327:11;;119161:1;56542:12;56329:7;56526:13;131316:8;;56526:28;;-1:-1:-1;;56526:46:0;131300:24;;;;:::i;:::-;:38;131296:88;;;131360:24;;-1:-1:-1;;;131360:24:0;;;;;;;;;;;131296:88;131397:25;131409:2;131413:8;131397:11;:25::i;134251:241::-;-1:-1:-1;;;;;58427:25:0;;134364;58427;;;:18;134166:2;58427:25;;;;;134147:21;;134364:58;;134433:51;134441:6;134478:5;134472:2;134450:18;-1:-1:-1;;;;;134450:24:0;;;134449:34;134433:7;:51::i;62251:166::-;62321:21;;:::i;:::-;62362:47;62381:27;62400:7;62381:18;:27::i;:::-;62362:18;:47::i;31052:132::-;3931:10;31116:7;:5;:7::i;:::-;-1:-1:-1;;;;;31116:23:0;;31108:68;;;;-1:-1:-1;;;31108:68:0;;25930:2:1;31108:68:0;;;25912:21:1;;;25949:18;;;25942:30;26008:34;25988:18;;;25981:62;26060:18;;31108:68:0;25728:356:1;70647:2825:0;70789:27;70819;70838:7;70819:18;:27::i;:::-;70789:57;;70904:4;-1:-1:-1;;;;;70863:45:0;70879:19;-1:-1:-1;;;;;70863:45:0;;70859:86;;70917:28;;-1:-1:-1;;;70917:28:0;;;;;;;;;;;70859:86;70959:27;69755:24;;;:15;:24;;;;;69983:26;;3931:10;69380:30;;;-1:-1:-1;;;;;69073:28:0;;69358:20;;;69355:56;71145:180;;71238:43;71255:4;3931:10;123864:395;:::i;71238:43::-;71233:92;;71290:35;;-1:-1:-1;;;71290:35:0;;;;;;;;;;;71233:92;-1:-1:-1;;;;;71342:16:0;;71338:52;;71367:23;;-1:-1:-1;;;71367:23:0;;;;;;;;;;;71338:52;71403:43;71425:4;71431:2;71435:7;71444:1;71403:21;:43::i;:::-;71539:15;71536:160;;;71679:1;71658:19;71651:30;71536:160;-1:-1:-1;;;;;72076:24:0;;;;;;;:18;:24;;;;;;72074:26;;-1:-1:-1;;72074:26:0;;;72145:22;;;;;;;;;72143:24;;-1:-1:-1;72143:24:0;;;65299:11;65274:23;65270:41;65257:63;-1:-1:-1;;;65257:63:0;72438:26;;;;:17;:26;;;;;:175;;;;-1:-1:-1;;;72733:47:0;;:52;;72729:627;;72838:1;72828:11;;72806:19;72961:30;;;:17;:30;;;;;;:35;;72957:384;;73099:13;;73084:11;:28;73080:242;;73246:30;;;;:17;:30;;;;;:52;;;73080:242;72787:569;72729:627;73403:7;73399:2;-1:-1:-1;;;;;73384:27:0;73393:4;-1:-1:-1;;;;;73384:27:0;;;;;;;;;;;73422:42;70778:2694;;;70647:2825;;;:::o;24698:105::-;24765:30;24776:4;3931:10;24765;:30::i;28956:238::-;29040:22;29048:4;29054:7;29040;:22::i;:::-;29035:152;;29079:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;29079:29:0;;;;;;;;;:36;;-1:-1:-1;;29079:36:0;29111:4;29079:36;;;29162:12;3931:10;;3851:98;29162:12;-1:-1:-1;;;;;29135:40:0;29153:7;-1:-1:-1;;;;;29135:40:0;29147:4;29135:40;;;;;;;;;;28956:238;;:::o;29374:239::-;29458:22;29466:4;29472:7;29458;:22::i;:::-;29454:152;;;29529:5;29497:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;29497:29:0;;;;;;;;;;:37;;-1:-1:-1;;29497:37:0;;;29554:40;3931:10;;29497:12;;29554:40;;29529:5;29554:40;29374:239;;:::o;73568:193::-;73714:39;73731:4;73737:2;73741:7;73714:39;;;;;;;;;;;;:16;:39::i;63065:1275::-;63132:7;63167;;119161:1;63216:23;63212:1061;;63269:13;;63262:4;:20;63258:1015;;;63307:14;63324:23;;;:17;:23;;;;;;;-1:-1:-1;;;63413:24:0;;:29;;63409:845;;64078:113;64085:6;64095:1;64085:11;64078:113;;-1:-1:-1;;;64156:6:0;64138:25;;;;:17;:25;;;;;;64078:113;;63409:845;63284:989;63258:1015;64301:31;;-1:-1:-1;;;64301:31:0;;;;;;;;;;;32154:191;32247:6;;;-1:-1:-1;;;;;32264:17:0;;;-1:-1:-1;;;;;;32264:17:0;;;;;;;32297:40;;32247:6;;;32264:17;32247:6;;32297:40;;32228:16;;32297:40;32217:128;32154:191;:::o;62513:161::-;62581:21;;:::i;:::-;62641:24;;;;:17;:24;;;;;;62622:44;;:18;:44::i;134576:222::-;134661:28;134692:33;134718:6;-1:-1:-1;;;;;58427:25:0;133747:6;58427:25;;;:18;:25;;;;;;51985:3;58427:40;133859:18;133841:36;;133659:228;134692:33;134661:64;;134736:54;134744:6;134768:21;134762:2;134753:5;-1:-1:-1;;;;;134753:11:0;;;134752:37;134736:7;:54::i;124338:386::-;124503:13;;-1:-1:-1;;;;;124503:13:0;124495:38;;;;:66;;;124560:1;124537:8;-1:-1:-1;;;;;124537:20:0;;:24;124495:66;124477:186;;;124588:13;;:63;;-1:-1:-1;;;124588:63:0;;124620:10;124588:63;;;23716:34:1;-1:-1:-1;;;;;23786:15:1;;;23766:18;;;23759:43;23845:14;;23838:22;23818:18;;;23811:50;124588:13:0;;;;:31;;23651:18:1;;124588:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124477:186;124673:43;124697:8;124707;124673:23;:43::i;74359:407::-;74534:31;74547:4;74553:2;74557:7;74534:12;:31::i;:::-;-1:-1:-1;;;;;74580:14:0;;;:19;74576:183;;74619:56;74650:4;74656:2;74660:7;74669:5;74619:30;:56::i;:::-;74614:145;;74703:40;;-1:-1:-1;;;74703:40:0;;;;;;;;;;;125228:390;125288:13;125343:1;125324:8;125318:22;;;;;:::i;:::-;;;:26;125314:74;;;125368:8;125361:15;;;;;:::i;125314:74::-;125542:8;:6;:8::i;:::-;125445:150;;;;;;;;:::i;:::-;;;;;;;;;;;;;125400:210;;125228:390;:::o;90894:1745::-;90959:17;91393:4;91386;91380:11;91376:22;91485:1;91479:4;91472:15;91560:4;91557:1;91553:12;91546:19;;;91642:1;91637:3;91630:14;91746:3;91985:5;91967:428;92033:1;92028:3;92024:11;92017:18;;92204:2;92198:4;92194:13;92190:2;92186:22;92181:3;92173:36;92298:2;92288:13;;92355:25;91967:428;92355:25;-1:-1:-1;92425:13:0;;;-1:-1:-1;;92540:14:0;;;92602:19;;;92540:14;90894:1745;-1:-1:-1;90894:1745:0:o;36140:231::-;36218:7;36239:17;36258:18;36280:27;36291:4;36297:9;36280:10;:27::i;:::-;36238:69;;;;36318:18;36330:5;36318:11;:18::i;:::-;-1:-1:-1;36354:9:0;36140:231;-1:-1:-1;;;36140:231:0:o;78028:2966::-;78101:20;78124:13;;;78152;;;78148:44;;78174:18;;-1:-1:-1;;;78174:18:0;;;;;;;;;;;78148:44;78205:61;78235:1;78239:2;78243:12;78257:8;78205:21;:61::i;:::-;-1:-1:-1;;;;;78680:22:0;;;;;;:18;:22;;;;51749:2;78680:22;;;:71;;78718:32;78706:45;;78680:71;;;78994:31;;;:17;:31;;;;;-1:-1:-1;65730:15:0;;65704:24;65700:46;65299:11;65274:23;65270:41;65267:52;65257:63;;78994:173;;79229:23;;;;78994:31;;78680:22;;79994:25;78680:22;;79847:335;80508:1;80494:12;80490:20;80448:346;80549:3;80540:7;80537:16;80448:346;;80767:7;80757:8;80754:1;80727:25;80724:1;80721;80716:59;80602:1;80589:15;80448:346;;;80452:77;80827:8;80839:1;80827:13;80823:45;;80849:19;;-1:-1:-1;;;80849:19:0;;;;;;;;;;;80823:45;80885:13;:19;-1:-1:-1;136212:250:0;;;:::o;58664:404::-;-1:-1:-1;;;;;58753:25:0;;;58736:14;58753:25;;;:18;:25;;;;;;;-1:-1:-1;;;;;58953:32:0;51985:3;58990:24;;;;58952:63;;;;59026:34;;58664:404::o;64439:366::-;64505:31;;:::i;:::-;-1:-1:-1;;;;;64549:41:0;;;;-1:-1:-1;;;;;52270:3:0;64635:33;;;64601:68;:24;;;:68;-1:-1:-1;;;64699:24:0;;:29;;64680:16;;;:48;52791:3;64768:28;;;;64739:19;;;:58;64549:9;64439:366::o;120958:639::-;-1:-1:-1;;;;;121218:16:0;;;;;;:38;;;121238:13;121248:2;121238:9;:13::i;:::-;:18;121218:38;121214:128;;;121302:11;:13;;;;;;121214:128;-1:-1:-1;;;;;121443:18:0;;;;;;:42;;;121465:15;121475:4;121465:9;:15::i;:::-;121484:1;121465:20;121443:42;:61;;;;;121503:1;121489:11;;:15;121443:61;121439:151;;;121550:11;:13;;-1:-1:-1;;121550:13:0;;;120958:639;;;;:::o;25093:492::-;25182:22;25190:4;25196:7;25182;:22::i;:::-;25177:401;;25370:28;25390:7;25370:19;:28::i;:::-;25471:38;25499:4;25506:2;25471:19;:38::i;:::-;25275:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;25275:257:0;;;;;;;;;;-1:-1:-1;;;25221:345:0;;;;;;;:::i;67566:234::-;3931:10;67661:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;67661:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;67661:60:0;;;;;;;;;;67737:55;;636:41:1;;;67661:49:0;;3931:10;67737:55;;609:18:1;67737:55:0;;;;;;;67566:234;;:::o;76850:716::-;77034:88;;-1:-1:-1;;;77034:88:0;;77013:4;;-1:-1:-1;;;;;77034:45:0;;;;;:88;;3931:10;;77101:4;;77107:7;;77116:5;;77034:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77034:88:0;;;;;;;;-1:-1:-1;;77034:88:0;;;;;;;;;;;;:::i;:::-;;;77030:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77317:6;:13;77334:1;77317:18;77313:235;;77363:40;;-1:-1:-1;;;77363:40:0;;;;;;;;;;;77313:235;77506:6;77500:13;77491:6;77487:2;77483:15;77476:38;77030:529;-1:-1:-1;;;;;;77193:64:0;-1:-1:-1;;;77193:64:0;;-1:-1:-1;77030:529:0;76850:716;;;;;;:::o;34591:747::-;34672:7;34681:12;34710:9;:16;34730:2;34710:22;34706:625;;35054:4;35039:20;;35033:27;35104:4;35089:20;;35083:27;35162:4;35147:20;;35141:27;34749:9;35133:36;35205:25;35216:4;35133:36;35033:27;35083;35205:10;:25::i;:::-;35198:32;;;;;;;;;34706:625;-1:-1:-1;35279:1:0;;-1:-1:-1;35283:35:0;34706:625;34591:747;;;;;:::o;32984:521::-;33062:20;33053:5;:29;;;;;;;;:::i;:::-;;33049:449;;32984:521;:::o;33049:449::-;33160:29;33151:5;:38;;;;;;;;:::i;:::-;;33147:351;;33206:34;;-1:-1:-1;;;33206:34:0;;29049:2:1;33206:34:0;;;29031:21:1;29088:2;29068:18;;;29061:30;29127:26;29107:18;;;29100:54;29171:18;;33206:34:0;28847:348:1;33147:351:0;33271:35;33262:5;:44;;;;;;;;:::i;:::-;;33258:240;;33323:41;;-1:-1:-1;;;33323:41:0;;29402:2:1;33323:41:0;;;29384:21:1;29441:2;29421:18;;;29414:30;29480:33;29460:18;;;29453:61;29531:18;;33323:41:0;29200:355:1;33258:240:0;33395:30;33386:5;:39;;;;;;;;:::i;:::-;;33382:116;;33442:44;;-1:-1:-1;;;33442:44:0;;29762:2:1;33442:44:0;;;29744:21:1;29801:2;29781:18;;;29774:30;29840:34;29820:18;;;29813:62;-1:-1:-1;;;29891:18:1;;;29884:32;29933:19;;33442:44:0;29560:398:1;21184:151:0;21242:13;21275:52;-1:-1:-1;;;;;21287:22:0;;19339:2;20580:447;20655:13;20681:19;20713:10;20717:6;20713:1;:10;:::i;:::-;:14;;20726:1;20713:14;:::i;:::-;-1:-1:-1;;;;;20703:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20703:25:0;;20681:47;;-1:-1:-1;;;20739:6:0;20746:1;20739:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;20739:15:0;;;;;;;;;-1:-1:-1;;;20765:6:0;20772:1;20765:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;20765:15:0;;;;;;;;-1:-1:-1;20796:9:0;20808:10;20812:6;20808:1;:10;:::i;:::-;:14;;20821:1;20808:14;:::i;:::-;20796:26;;20791:131;20828:1;20824;:5;20791:131;;;-1:-1:-1;;;20872:5:0;20880:3;20872:11;20863:21;;;;;;;:::i;:::-;;;;20851:6;20858:1;20851:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;20851:33:0;;;;;;;;-1:-1:-1;20909:1:0;20899:11;;;;;20831:3;;;:::i;:::-;;;20791:131;;;-1:-1:-1;20940:10:0;;20932:55;;;;-1:-1:-1;;;20932:55:0;;30306:2:1;20932:55:0;;;30288:21:1;;;30325:18;;;30318:30;30384:34;30364:18;;;30357:62;30436:18;;20932:55:0;30104:356:1;37592:1520:0;37723:7;;38657:66;38644:79;;38640:163;;;-1:-1:-1;38756:1:0;;-1:-1:-1;38760:30:0;38740:51;;38640:163;38917:24;;;38900:14;38917:24;;;;;;;;;30692:25:1;;;30765:4;30753:17;;30733:18;;;30726:45;;;;30787:18;;;30780:34;;;30830:18;;;30823:34;;;38917:24:0;;30664:19:1;;38917:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;38917:24:0;;-1:-1:-1;;38917:24:0;;;-1:-1:-1;;;;;;;38956:20:0;;38952:103;;39009:1;39013:29;38993:50;;;;;;;38952:103;39075:6;-1:-1:-1;39083:20:0;;-1:-1:-1;37592:1520:0;;;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;688:250::-;773:1;783:113;797:6;794:1;791:13;783:113;;;873:11;;;867:18;854:11;;;847:39;819:2;812:10;783:113;;;-1:-1:-1;;930:1:1;912:16;;905:27;688:250::o;943:271::-;985:3;1023:5;1017:12;1050:6;1045:3;1038:19;1066:76;1135:6;1128:4;1123:3;1119:14;1112:4;1105:5;1101:16;1066:76;:::i;:::-;1196:2;1175:15;-1:-1:-1;;1171:29:1;1162:39;;;;1203:4;1158:50;;943:271;-1:-1:-1;;943:271:1:o;1219:220::-;1368:2;1357:9;1350:21;1331:4;1388:45;1429:2;1418:9;1414:18;1406:6;1388:45;:::i;1444:180::-;1503:6;1556:2;1544:9;1535:7;1531:23;1527:32;1524:52;;;1572:1;1569;1562:12;1524:52;-1:-1:-1;1595:23:1;;1444:180;-1:-1:-1;1444:180:1:o;1946:173::-;2014:20;;-1:-1:-1;;;;;2063:31:1;;2053:42;;2043:70;;2109:1;2106;2099:12;2043:70;1946:173;;;:::o;2124:254::-;2192:6;2200;2253:2;2241:9;2232:7;2228:23;2224:32;2221:52;;;2269:1;2266;2259:12;2221:52;2292:29;2311:9;2292:29;:::i;:::-;2282:39;2368:2;2353:18;;;;2340:32;;-1:-1:-1;;;2124:254:1:o;2383:458::-;2481:6;2489;2542:2;2530:9;2521:7;2517:23;2513:32;2510:52;;;2558:1;2555;2548:12;2510:52;2598:9;2585:23;-1:-1:-1;;;;;2623:6:1;2620:30;2617:50;;;2663:1;2660;2653:12;2617:50;2686:22;;2742:3;2724:16;;;2720:26;2717:46;;;2759:1;2756;2749:12;2846:349;2930:12;;-1:-1:-1;;;;;2926:38:1;2914:51;;3018:4;3007:16;;;3001:23;-1:-1:-1;;;;;2997:48:1;2981:14;;;2974:72;3109:4;3098:16;;;3092:23;3085:31;3078:39;3062:14;;;3055:63;3171:4;3160:16;;;3154:23;3179:8;3150:38;3134:14;;3127:62;2846:349::o;3200:268::-;3398:3;3383:19;;3411:51;3387:9;3444:6;3411:51;:::i;3655:1457::-;3830:2;3819:9;3812:21;3875:6;3869:13;3864:2;3853:9;3849:18;3842:41;3937:2;3929:6;3925:15;3919:22;3914:2;3903:9;3899:18;3892:50;3996:2;3988:6;3984:15;3978:22;3973:2;3962:9;3958:18;3951:50;4056:2;4048:6;4044:15;4038:22;4032:3;4021:9;4017:19;4010:51;4116:3;4108:6;4104:16;4098:23;4092:3;4081:9;4077:19;4070:52;4177:3;4169:6;4165:16;4159:23;4153:3;4142:9;4138:19;4131:52;3793:4;4230:3;4222:6;4218:16;4212:23;4244:53;4292:3;4281:9;4277:19;4263:12;-1:-1:-1;;;;;1695:31:1;1683:44;;1629:104;4244:53;;4346:3;4338:6;4334:16;4328:23;4370:3;4382:54;4432:2;4421:9;4417:18;4401:14;-1:-1:-1;;;;;1695:31:1;1683:44;;1629:104;4382:54;4473:15;;4467:22;;-1:-1:-1;4508:3:1;4520:51;4552:18;;;4467:22;470:13;463:21;451:34;;400:91;4520:51;4608:15;;4602:22;;-1:-1:-1;4643:3:1;4655:51;4687:18;;;4602:22;470:13;463:21;451:34;;400:91;4655:51;4755:2;4747:6;4743:15;4737:22;4715:44;;;4778:6;4803:3;4842:2;4837;4826:9;4822:18;4815:30;4868:54;4917:3;4906:9;4902:19;4886:14;4868:54;:::i;:::-;4959:15;;;4953:22;5015;;;-1:-1:-1;;5011:36:1;4991:18;;;4984:64;4854:68;;-1:-1:-1;5065:41:1;4854:68;4953:22;5065:41;:::i;:::-;5057:49;3655:1457;-1:-1:-1;;;;;;3655:1457:1:o;5117:328::-;5194:6;5202;5210;5263:2;5251:9;5242:7;5238:23;5234:32;5231:52;;;5279:1;5276;5269:12;5231:52;5302:29;5321:9;5302:29;:::i;:::-;5292:39;;5350:38;5384:2;5373:9;5369:18;5350:38;:::i;:::-;5340:48;;5435:2;5424:9;5420:18;5407:32;5397:42;;5117:328;;;;;:::o;5817:254::-;5885:6;5893;5946:2;5934:9;5925:7;5921:23;5917:32;5914:52;;;5962:1;5959;5952:12;5914:52;5998:9;5985:23;5975:33;;6027:38;6061:2;6050:9;6046:18;6027:38;:::i;:::-;6017:48;;5817:254;;;;;:::o;6076:186::-;6135:6;6188:2;6176:9;6167:7;6163:23;6159:32;6156:52;;;6204:1;6201;6194:12;6156:52;6227:29;6246:9;6227:29;:::i;6267:127::-;6328:10;6323:3;6319:20;6316:1;6309:31;6359:4;6356:1;6349:15;6383:4;6380:1;6373:15;6399:275;6470:2;6464:9;6535:2;6516:13;;-1:-1:-1;;6512:27:1;6500:40;;-1:-1:-1;;;;;6555:34:1;;6591:22;;;6552:62;6549:88;;;6617:18;;:::i;:::-;6653:2;6646:22;6399:275;;-1:-1:-1;6399:275:1:o;6679:407::-;6744:5;-1:-1:-1;;;;;6770:6:1;6767:30;6764:56;;;6800:18;;:::i;:::-;6838:57;6883:2;6862:15;;-1:-1:-1;;6858:29:1;6889:4;6854:40;6838:57;:::i;:::-;6829:66;;6918:6;6911:5;6904:21;6958:3;6949:6;6944:3;6940:16;6937:25;6934:45;;;6975:1;6972;6965:12;6934:45;7024:6;7019:3;7012:4;7005:5;7001:16;6988:43;7078:1;7071:4;7062:6;7055:5;7051:18;7047:29;7040:40;6679:407;;;;;:::o;7091:451::-;7160:6;7213:2;7201:9;7192:7;7188:23;7184:32;7181:52;;;7229:1;7226;7219:12;7181:52;7269:9;7256:23;-1:-1:-1;;;;;7294:6:1;7291:30;7288:50;;;7334:1;7331;7324:12;7288:50;7357:22;;7410:4;7402:13;;7398:27;-1:-1:-1;7388:55:1;;7439:1;7436;7429:12;7388:55;7462:74;7528:7;7523:2;7510:16;7505:2;7501;7497:11;7462:74;:::i;7778:592::-;7849:6;7857;7910:2;7898:9;7889:7;7885:23;7881:32;7878:52;;;7926:1;7923;7916:12;7878:52;7966:9;7953:23;-1:-1:-1;;;;;8036:2:1;8028:6;8025:14;8022:34;;;8052:1;8049;8042:12;8022:34;8090:6;8079:9;8075:22;8065:32;;8135:7;8128:4;8124:2;8120:13;8116:27;8106:55;;8157:1;8154;8147:12;8106:55;8197:2;8184:16;8223:2;8215:6;8212:14;8209:34;;;8239:1;8236;8229:12;8209:34;8284:7;8279:2;8270:6;8266:2;8262:15;8258:24;8255:37;8252:57;;;8305:1;8302;8295:12;8252:57;8336:2;8328:11;;;;;8358:6;;-1:-1:-1;7778:592:1;;-1:-1:-1;;;;7778:592:1:o;8375:269::-;8432:6;8485:2;8473:9;8464:7;8460:23;8456:32;8453:52;;;8501:1;8498;8491:12;8453:52;8540:9;8527:23;8590:4;8583:5;8579:16;8572:5;8569:27;8559:55;;8610:1;8607;8600:12;8873:615;8959:6;8967;9020:2;9008:9;8999:7;8995:23;8991:32;8988:52;;;9036:1;9033;9026:12;8988:52;9076:9;9063:23;-1:-1:-1;;;;;9146:2:1;9138:6;9135:14;9132:34;;;9162:1;9159;9152:12;9132:34;9200:6;9189:9;9185:22;9175:32;;9245:7;9238:4;9234:2;9230:13;9226:27;9216:55;;9267:1;9264;9257:12;9216:55;9307:2;9294:16;9333:2;9325:6;9322:14;9319:34;;;9349:1;9346;9339:12;9319:34;9402:7;9397:2;9387:6;9384:1;9380:14;9376:2;9372:23;9368:32;9365:45;9362:65;;;9423:1;9420;9413:12;9493:724;9728:2;9780:21;;;9850:13;;9753:18;;;9872:22;;;9699:4;;9728:2;9951:15;;;;9925:2;9910:18;;;9699:4;9994:197;10008:6;10005:1;10002:13;9994:197;;;10057:52;10105:3;10096:6;10090:13;10057:52;:::i;:::-;10166:15;;;;10138:4;10129:14;;;;;10030:1;10023:9;9994:197;;10222:632;10393:2;10445:21;;;10515:13;;10418:18;;;10537:22;;;10364:4;;10393:2;10616:15;;;;10590:2;10575:18;;;10364:4;10659:169;10673:6;10670:1;10667:13;10659:169;;;10734:13;;10722:26;;10803:15;;;;10768:12;;;;10695:1;10688:9;10659:169;;11298:322;11375:6;11383;11391;11444:2;11432:9;11423:7;11419:23;11415:32;11412:52;;;11460:1;11457;11450:12;11412:52;11483:29;11502:9;11483:29;:::i;:::-;11473:39;11559:2;11544:18;;11531:32;;-1:-1:-1;11610:2:1;11595:18;;;11582:32;;11298:322;-1:-1:-1;;;11298:322:1:o;11625:118::-;11711:5;11704:13;11697:21;11690:5;11687:32;11677:60;;11733:1;11730;11723:12;11748:315;11813:6;11821;11874:2;11862:9;11853:7;11849:23;11845:32;11842:52;;;11890:1;11887;11880:12;11842:52;11913:29;11932:9;11913:29;:::i;:::-;11903:39;;11992:2;11981:9;11977:18;11964:32;12005:28;12027:5;12005:28;:::i;:::-;12052:5;12042:15;;;11748:315;;;;;:::o;12308:667::-;12403:6;12411;12419;12427;12480:3;12468:9;12459:7;12455:23;12451:33;12448:53;;;12497:1;12494;12487:12;12448:53;12520:29;12539:9;12520:29;:::i;:::-;12510:39;;12568:38;12602:2;12591:9;12587:18;12568:38;:::i;:::-;12558:48;;12653:2;12642:9;12638:18;12625:32;12615:42;;12708:2;12697:9;12693:18;12680:32;-1:-1:-1;;;;;12727:6:1;12724:30;12721:50;;;12767:1;12764;12757:12;12721:50;12790:22;;12843:4;12835:13;;12831:27;-1:-1:-1;12821:55:1;;12872:1;12869;12862:12;12821:55;12895:74;12961:7;12956:2;12943:16;12938:2;12934;12930:11;12895:74;:::i;:::-;12885:84;;;12308:667;;;;;;;:::o;12980:183::-;13040:4;-1:-1:-1;;;;;13065:6:1;13062:30;13059:56;;;13095:18;;:::i;:::-;-1:-1:-1;13140:1:1;13136:14;13152:4;13132:25;;12980:183::o;13168:662::-;13222:5;13275:3;13268:4;13260:6;13256:17;13252:27;13242:55;;13293:1;13290;13283:12;13242:55;13329:6;13316:20;13355:4;13379:60;13395:43;13435:2;13395:43;:::i;:::-;13379:60;:::i;:::-;13473:15;;;13559:1;13555:10;;;;13543:23;;13539:32;;;13504:12;;;;13583:15;;;13580:35;;;13611:1;13608;13601:12;13580:35;13647:2;13639:6;13635:15;13659:142;13675:6;13670:3;13667:15;13659:142;;;13741:17;;13729:30;;13779:12;;;;13692;;13659:142;;;-1:-1:-1;13819:5:1;13168:662;-1:-1:-1;;;;;;13168:662:1:o;13835:1146::-;13953:6;13961;14014:2;14002:9;13993:7;13989:23;13985:32;13982:52;;;14030:1;14027;14020:12;13982:52;14070:9;14057:23;-1:-1:-1;;;;;14140:2:1;14132:6;14129:14;14126:34;;;14156:1;14153;14146:12;14126:34;14194:6;14183:9;14179:22;14169:32;;14239:7;14232:4;14228:2;14224:13;14220:27;14210:55;;14261:1;14258;14251:12;14210:55;14297:2;14284:16;14319:4;14343:60;14359:43;14399:2;14359:43;:::i;14343:60::-;14437:15;;;14519:1;14515:10;;;;14507:19;;14503:28;;;14468:12;;;;14543:19;;;14540:39;;;14575:1;14572;14565:12;14540:39;14599:11;;;;14619:148;14635:6;14630:3;14627:15;14619:148;;;14701:23;14720:3;14701:23;:::i;:::-;14689:36;;14652:12;;;;14745;;;;14619:148;;;14786:5;-1:-1:-1;;14829:18:1;;14816:32;;-1:-1:-1;;14860:16:1;;;14857:36;;;14889:1;14886;14879:12;14857:36;;14912:63;14967:7;14956:8;14945:9;14941:24;14912:63;:::i;:::-;14902:73;;;13835:1146;;;;;:::o;15191:260::-;15259:6;15267;15320:2;15308:9;15299:7;15295:23;15291:32;15288:52;;;15336:1;15333;15326:12;15288:52;15359:29;15378:9;15359:29;:::i;:::-;15349:39;;15407:38;15441:2;15430:9;15426:18;15407:38;:::i;15456:380::-;15535:1;15531:12;;;;15578;;;15599:61;;15653:4;15645:6;15641:17;15631:27;;15599:61;15706:2;15698:6;15695:14;15675:18;15672:38;15669:161;;15752:10;15747:3;15743:20;15740:1;15733:31;15787:4;15784:1;15777:15;15815:4;15812:1;15805:15;15669:161;;15456:380;;;:::o;15841:127::-;15902:10;15897:3;15893:20;15890:1;15883:31;15933:4;15930:1;15923:15;15957:4;15954:1;15947:15;15973:125;16038:9;;;16059:10;;;16056:36;;;16072:18;;:::i;16103:168::-;16176:9;;;16207;;16224:15;;;16218:22;;16204:37;16194:71;;16245:18;;:::i;17961:545::-;18063:2;18058:3;18055:11;18052:448;;;18099:1;18124:5;18120:2;18113:17;18169:4;18165:2;18155:19;18239:2;18227:10;18223:19;18220:1;18216:27;18210:4;18206:38;18275:4;18263:10;18260:20;18257:47;;;-1:-1:-1;18298:4:1;18257:47;18353:2;18348:3;18344:12;18341:1;18337:20;18331:4;18327:31;18317:41;;18408:82;18426:2;18419:5;18416:13;18408:82;;;18471:17;;;18452:1;18441:13;18408:82;;18682:1352;18808:3;18802:10;-1:-1:-1;;;;;18827:6:1;18824:30;18821:56;;;18857:18;;:::i;:::-;18886:97;18976:6;18936:38;18968:4;18962:11;18936:38;:::i;:::-;18930:4;18886:97;:::i;:::-;19038:4;;19102:2;19091:14;;19119:1;19114:663;;;;19821:1;19838:6;19835:89;;;-1:-1:-1;19890:19:1;;;19884:26;19835:89;-1:-1:-1;;18639:1:1;18635:11;;;18631:24;18627:29;18617:40;18663:1;18659:11;;;18614:57;19937:81;;19084:944;;19114:663;17908:1;17901:14;;;17945:4;17932:18;;-1:-1:-1;;19150:20:1;;;19268:236;19282:7;19279:1;19276:14;19268:236;;;19371:19;;;19365:26;19350:42;;19463:27;;;;19431:1;19419:14;;;;19298:19;;19268:236;;;19272:3;19532:6;19523:7;19520:19;19517:201;;;19593:19;;;19587:26;-1:-1:-1;;19676:1:1;19672:14;;;19688:3;19668:24;19664:37;19660:42;19645:58;19630:74;;19517:201;-1:-1:-1;;;;;19764:1:1;19748:14;;;19744:22;19731:36;;-1:-1:-1;18682:1352:1:o;20452:1206::-;-1:-1:-1;;;;;20571:3:1;20568:27;20565:53;;;20598:18;;:::i;:::-;20627:94;20717:3;20677:38;20709:4;20703:11;20677:38;:::i;:::-;20671:4;20627:94;:::i;:::-;20747:1;20772:2;20767:3;20764:11;20789:1;20784:616;;;;21444:1;21461:3;21458:93;;;-1:-1:-1;21517:19:1;;;21504:33;21458:93;-1:-1:-1;;18639:1:1;18635:11;;;18631:24;18627:29;18617:40;18663:1;18659:11;;;18614:57;21564:78;;20757:895;;20784:616;17908:1;17901:14;;;17945:4;17932:18;;-1:-1:-1;;20820:17:1;;;20921:9;20943:229;20957:7;20954:1;20951:14;20943:229;;;21046:19;;;21033:33;21018:49;;21153:4;21138:20;;;;21106:1;21094:14;;;;20973:12;20943:229;;;20947:3;21200;21191:7;21188:16;21185:159;;;21324:1;21320:6;21314:3;21308;21305:1;21301:11;21297:21;21293:34;21289:39;21276:9;21271:3;21267:19;21254:33;21250:79;21242:6;21235:95;21185:159;;;21387:1;21381:3;21378:1;21374:11;21370:19;21364:4;21357:33;20757:895;;20452:1206;;;:::o;21949:127::-;22010:10;22005:3;22001:20;21998:1;21991:31;22041:4;22038:1;22031:15;22065:4;22062:1;22055:15;22081:1256;22305:3;22343:6;22337:13;22369:4;22382:64;22439:6;22434:3;22429:2;22421:6;22417:15;22382:64;:::i;:::-;22509:13;;22468:16;;;;22531:68;22509:13;22468:16;22566:15;;;22531:68;:::i;:::-;22688:13;;22621:20;;;22661:1;;22726:36;22688:13;22726:36;:::i;:::-;22781:1;22798:18;;;22825:141;;;;22980:1;22975:337;;;;22791:521;;22825:141;-1:-1:-1;;22860:24:1;;22846:39;;22937:16;;22930:24;22916:39;;22905:51;;;-1:-1:-1;22825:141:1;;22975:337;23006:6;23003:1;22996:17;23054:2;23051:1;23041:16;23079:1;23093:169;23107:8;23104:1;23101:15;23093:169;;;23189:14;;23174:13;;;23167:37;23232:16;;;;23124:10;;23093:169;;;23097:3;;23293:8;23286:5;23282:20;23275:27;;22791:521;-1:-1:-1;23328:3:1;;22081:1256;-1:-1:-1;;;;;;;;;;22081:1256:1:o;23342:135::-;23381:3;23402:17;;;23399:43;;23422:18;;:::i;:::-;-1:-1:-1;23469:1:1;23458:13;;23342:135::o;23872:245::-;23939:6;23992:2;23980:9;23971:7;23967:23;23963:32;23960:52;;;24008:1;24005;23998:12;23960:52;24040:9;24034:16;24059:28;24081:5;24059:28;:::i;24763:521::-;24840:4;24846:6;24906:11;24893:25;25000:2;24996:7;24985:8;24969:14;24965:29;24961:43;24941:18;24937:68;24927:96;;25019:1;25016;25009:12;24927:96;25046:33;;25098:20;;;-1:-1:-1;;;;;;25130:30:1;;25127:50;;;25173:1;25170;25163:12;25127:50;25206:4;25194:17;;-1:-1:-1;25237:14:1;25233:27;;;25223:38;;25220:58;;;25274:1;25271;25264:12;25289:434;25539:26;25535:31;25526:6;25522:2;25518:15;25514:53;25509:3;25502:66;25612:6;25604;25599:2;25594:3;25590:12;25577:42;25678:2;25638:16;;25670:11;;;25663:27;25714:2;25706:11;;25289:434;-1:-1:-1;;25289:434:1:o;26089:671::-;26452:34;26447:3;26440:47;26422:3;-1:-1:-1;;;26539:2:1;26534;26529:3;26525:12;26518:24;26571:6;26565:13;26587:73;26653:6;26648:2;26643:3;26639:12;26634:2;26626:6;26622:15;26587:73;:::i;:::-;26719:2;26679:16;;26711:11;;;26704:23;-1:-1:-1;26751:2:1;26743:11;;26089:671;-1:-1:-1;26089:671:1:o;27150:812::-;27561:25;27556:3;27549:38;27531:3;27616:6;27610:13;27632:75;27700:6;27695:2;27690:3;27686:12;27679:4;27671:6;27667:17;27632:75;:::i;:::-;-1:-1:-1;;;27766:2:1;27726:16;;;27758:11;;;27751:40;27816:13;;27838:76;27816:13;27900:2;27892:11;;27885:4;27873:17;;27838:76;:::i;:::-;27934:17;27953:2;27930:26;;27150:812;-1:-1:-1;;;;27150:812:1:o;27967:489::-;-1:-1:-1;;;;;28236:15:1;;;28218:34;;28288:15;;28283:2;28268:18;;28261:43;28335:2;28320:18;;28313:34;;;28383:3;28378:2;28363:18;;28356:31;;;28161:4;;28404:46;;28430:19;;28422:6;28404:46;:::i;28461:249::-;28530:6;28583:2;28571:9;28562:7;28558:23;28554:32;28551:52;;;28599:1;28596;28589:12;28551:52;28631:9;28625:16;28650:30;28674:5;28650:30;:::i;28715:127::-;28776:10;28771:3;28767:20;28764:1;28757:31;28807:4;28804:1;28797:15;28831:4;28828:1;28821:15;29963:136;30002:3;30030:5;30020:39;;30039:18;;:::i;:::-;-1:-1:-1;;;30075:18:1;;29963:136::o

Swarm Source

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