ETH Price: $3,389.06 (+1.23%)

Token

AStrandOfHair (ASOH)
 

Overview

Max Total Supply

10,358 ASOH

Holders

1,563

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
222112.eth
Balance
1 ASOH
0xA0cbE4Fa67BDA88E1e3f0084762Bb00ab0691d02
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

A Strand Of Hair is an NFT collection that based on witch.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
AStrandOfHair

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-07-25
*/

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.7;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,
     * consuming from one or the other at each step according to the instructions given by
     * `proofFlags`.
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

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


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


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

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


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



/**
 * @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/Strings.sol


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


/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_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) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @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] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

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

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


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


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

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

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


// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)


/**
 * @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/access/AccessControl.sol


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






/**
 * @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(uint160(account), 20),
                        " 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: erc721a/contracts/IERC721A.sol


// ERC721A Contracts v4.2.0
// 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();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

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

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

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

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

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

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

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

    // =============================================================
    //                        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/ERC721A.sol


// ERC721A Contracts v4.2.0
// 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 {
    // Reference type for token approval.
    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 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 {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _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]`.
        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 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 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 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.
            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`.
                )

                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 ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

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

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for {
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp {
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } {
                // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }

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

// File: contracts/AStrandOfHair.sol

/**
                                                                                               
    @@@@@@       @@@@@@   @@@@@@@  @@@@@@@    @@@@@@   @@@  @@@  @@@@@@@       @@@@@@   @@@@@@@@      @@@  @@@   @@@@@@   @@@  @@@@@@@   
    @@@@@@@@     @@@@@@@   @@@@@@@  @@@@@@@@  @@@@@@@@  @@@@ @@@  @@@@@@@@     @@@@@@@@  @@@@@@@@     @@@  @@@  @@@@@@@@  @@@  @@@@@@@@  
    @@!  @@@     !@@         @@!    @@!  @@@  @@!  @@@  @@!@!@@@  @@!  @@@     @@!  @@@  @@!          @@!  @@@  @@!  @@@  @@!  @@!  @@@ 
    !@!  @!@     !@!         !@!    !@!  @!@  !@!  @!@  !@!!@!@!  !@!  @!@     !@!  @!@  !@!          !@!  @!@  !@!  @!@  !@!  !@!  @!@  
    @!@!@!@!     !!@@!!      @!!    @!@!!@!   @!@!@!@!  @!@ !!@!  @!@  !@!     @!@  !@!  @!!!:!       @!@!@!@!  @!@!@!@!  !!@  @!@!!@!  
    !!!@!!!!      !!@!!!     !!!    !!@!@!    !!!@!!!!  !@!  !!!  !@!  !!!     !@!  !!!  !!!!!:       !!!@!!!!  !!!@!!!!  !!!  !!@!@! 
    !!:  !!!          !:!    !!:    !!: :!!   !!:  !!!  !!:  !!!  !!:  !!!     !!:  !!!  !!:          !!:  !!!  !!:  !!!  !!:  !!: :!!
    :!:  !:!         !:!     :!:    :!:  !:!  :!:  !:!  :!:  !:!  :!:  !:!     :!:  !:!  :!:          :!:  !:!  :!:  !:!  :!:  :!:  !:!  
    ::   :::     :::: ::      ::    ::   :::  ::   :::   ::   ::   :::: ::     ::::: ::   ::          ::   :::  ::   :::   ::  ::   :::  
    :   : :     :: : :       :      :   : :   :   : :  ::    :   :: :  :       : :  :    :            :   : :   :   : :  :     :   : : 
                                                                                                                            
*/

pragma solidity ^0.8.7;




contract AStrandOfHair is ERC721A, AccessControl {
    event FreeMint(address indexed account, uint256 indexed amount);
    event Mint(address indexed account, uint256 indexed amount);

    bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
    uint256 public constant MAX_SUPPLY = 10000;

    string public baseURI;
    string public notRevealURI;

    bool public isReveal;
    bool public isFreeMint = true;
    bool public isPaused;

    bytes32 private _root;
    mapping(uint256 => bool) private _advanced;
    mapping(address => uint256) private _freeMintedPerWallet;
    mapping(address => uint256) private _publicMintedPerWallet;

    uint32 public maxAmountPerWalletInFree;
    uint32 public maxAmountPerWalletInPublic;
    uint32 private _freeMinted;
    uint32 private _freeLimit;
    uint32 private _publicLimit;
    uint32 private _totalFree;
    uint32 private _publicMinted;
    uint32 private _totalPublic;

    constructor(
        string memory _name,
        string memory _symbol,
        string memory _unrevealURI,
        uint32 totalFree_,
        uint32 freeLimit_,
        uint32 totalPublic_,
        uint32 publicLimit_,
        uint32 maxAmountPerWalletInFree_,
        uint32 maxAmountPerWalletInPublic_
    ) ERC721A(_name, _symbol) {
        _grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _grantRole(MANAGER_ROLE, _msgSender());

        _totalFree = totalFree_;
        _freeLimit = freeLimit_;
        _publicLimit = publicLimit_;
        _totalPublic = totalPublic_;
        maxAmountPerWalletInFree = maxAmountPerWalletInFree_;
        maxAmountPerWalletInPublic = maxAmountPerWalletInPublic_;
        notRevealURI = _unrevealURI;
        isPaused = true;

        _mint(_msgSender(), 100);
        _freeMinted += 100;
    }

    modifier onlyEOA() {
        require(tx.origin == msg.sender, "Not EOA");
        _;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////// PUBLIC FUNCTION ////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////

    function mint(uint32 _amount) public onlyEOA {
        require(!isPaused, "Already paused");
        require(!isFreeMint, "Invalid mint");
        require(!isReveal, "Already reveal");
        address account = _msgSender();
        _publicMinted += _amount;
        _publicMintedPerWallet[account] += _amount;
        require(_publicMinted <= _publicLimit, "Exceed max public total");
        require(
            _publicMintedPerWallet[account] <= maxAmountPerWalletInPublic,
            "Exceed max amount per account"
        );

        _mint(account, _amount);

        emit Mint(account, _amount);
    }

    function freeMint(bytes32[] memory proof, uint32 _amount) public onlyEOA {
        require(!isPaused, "Already paused");
        require(isFreeMint, "Invalid mint");
        require(!isReveal, "Already reveal");
        address account = _msgSender();
        require(isWhiteList(proof, account), "Ineligible Wallet");

        _freeMinted += _amount;
        _freeMintedPerWallet[account] += _amount;

        require(_freeMinted <= _freeLimit, "Exceed max free total");
        require(
            _freeMintedPerWallet[account] <= maxAmountPerWalletInFree,
            "Exceed max amount"
        );

        _mint(account, _amount);

        emit FreeMint(account, _amount);
    }

    function mint(address[] memory accounts, uint32[] memory amounts)
        public
        onlyRole(MANAGER_ROLE)
    {
        uint32 _minted = 0;

        for (uint256 i = 0; i < accounts.length; i++) {
            address account = accounts[i];
            uint32 amount = amounts[i];

            _minted++;
            _mint(account, amount);

            emit FreeMint(account, amount);
        }

        if (isFreeMint) {
            _freeMinted += _minted;
            require(_freeMinted <= _totalFree, "Exceed free amount");
        } else {
            _publicMinted += _minted;
            require(_publicMinted <= _totalPublic, "Exceed public amount");
        }
    }

    function isWhiteList(bytes32[] memory _proof, address account)
        public
        view
        returns (bool)
    {
        bytes32 leaf = keccak256(abi.encodePacked(account));
        return MerkleProof.verify(_proof, _root, leaf);
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////// MANAGER ROLE FUNCTION //////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////

    function endFreeMint() public onlyRole(MANAGER_ROLE) {
        isFreeMint = false;
    }

    function updateRoot(bytes32 root) public onlyRole(MANAGER_ROLE) {
        _root = root;
    }

    function setBaseURIAndReveal(string memory _baseURI)
        public
        onlyRole(MANAGER_ROLE)
    {
        baseURI = _baseURI;
        isReveal = true;
    }

    function setNotRevealURI(string memory _notRevealURI)
        public
        onlyRole(MANAGER_ROLE)
    {
        notRevealURI = _notRevealURI;
    }

    function toggleReveal() public onlyRole(MANAGER_ROLE) {
        isReveal = !isReveal;
    }

    function setAdvancedFur(uint256[] memory tokenIds)
        public
        onlyRole(MANAGER_ROLE)
    {
        for (uint256 i = 0; i < tokenIds.length; i++) {
            _advanced[tokenIds[i]] = true;
        }
    }

    function setPublicLimit(uint32 publicLimit_) public onlyRole(MANAGER_ROLE) {
        _publicLimit = publicLimit_;
    }

    function setFreeLimit(uint32 freeLimit_) public onlyRole(MANAGER_ROLE) {
        _freeLimit = freeLimit_;
    }

    function togglePause() public onlyRole(MANAGER_ROLE) {
        isPaused = !isPaused;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////  VIEW FUNCTION /////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////

    function isAdvanced(uint256 tokenId) public view returns (bool) {
        return _advanced[tokenId];
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
        return
            isReveal
                ? string(abi.encodePacked(baseURI, _toString(tokenId), ".json"))
                : notRevealURI;
    }

    function supportsInterface(bytes4 interfaceId)
        public
        pure
        override(ERC721A, AccessControl)
        returns (bool)
    {
        return
            interfaceId == 0x7965db0b || // ERC165 interface ID for AccessControl
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    function totalFree() public view returns (uint256) {
        return _totalFree;
    }

    function totalPublic() public view returns (uint256) {
        return _totalPublic;
    }

    function freeMinted() public view returns (uint256) {
        return _freeMinted;
    }

    function publicMinted() public view returns (uint256) {
        return _publicMinted;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_unrevealURI","type":"string"},{"internalType":"uint32","name":"totalFree_","type":"uint32"},{"internalType":"uint32","name":"freeLimit_","type":"uint32"},{"internalType":"uint32","name":"totalPublic_","type":"uint32"},{"internalType":"uint32","name":"publicLimit_","type":"uint32"},{"internalType":"uint32","name":"maxAmountPerWalletInFree_","type":"uint32"},{"internalType":"uint32","name":"maxAmountPerWalletInPublic_","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FreeMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","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"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endFreeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint32","name":"_amount","type":"uint32"}],"name":"freeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"uint256","name":"tokenId","type":"uint256"}],"name":"isAdvanced","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":"isFreeMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReveal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"account","type":"address"}],"name":"isWhiteList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAmountPerWalletInFree","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAmountPerWalletInPublic","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint32[]","name":"amounts","type":"uint32[]"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_amount","type":"uint32"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"setAdvancedFur","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURIAndReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"freeLimit_","type":"uint32"}],"name":"setFreeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealURI","type":"string"}],"name":"setNotRevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"publicLimit_","type":"uint32"}],"name":"setPublicLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"togglePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPublic","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"updateRoot","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526001600b60016101000a81548160ff0219169083151502179055503480156200002c57600080fd5b506040516200532d3803806200532d833981810160405281019062000052919062000787565b888881600290805190602001906200006c92919062000642565b5080600390805190602001906200008592919062000642565b50620000966200026f60201b60201c565b6000819055505050620000c26000801b620000b66200027460201b60201c565b6200027c60201b60201c565b620001037f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08620000f76200027460201b60201c565b6200027c60201b60201c565b85601060146101000a81548163ffffffff021916908363ffffffff160217905550846010600c6101000a81548163ffffffff021916908363ffffffff160217905550826010806101000a81548163ffffffff021916908363ffffffff160217905550836010601c6101000a81548163ffffffff021916908363ffffffff16021790555081601060006101000a81548163ffffffff021916908363ffffffff16021790555080601060046101000a81548163ffffffff021916908363ffffffff16021790555086600a9080519060200190620001e092919062000642565b506001600b60026101000a81548160ff0219169083151502179055506200021e620002106200027460201b60201c565b60646200036e60201b60201c565b6064601060088282829054906101000a900463ffffffff1662000242919062000922565b92506101000a81548163ffffffff021916908363ffffffff16021790555050505050505050505062000ae1565b600090565b600033905090565b6200028e82826200055760201b60201c565b6200036a5760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200030f6200027460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000805490506000821415620003b0576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620003c56000848385620005c260201b60201c565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506200045483620004366000866000620005c860201b60201c565b6200044785620005f860201b60201c565b176200060860201b60201c565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114620004f757808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050620004ba565b50600082141562000534576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506200055260008483856200063360201b60201c565b505050565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b50505050565b60008060e883901c905060e8620005e78686846200063960201b60201c565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60009392505050565b8280546200065090620009a9565b90600052602060002090601f016020900481019282620006745760008555620006c0565b82601f106200068f57805160ff1916838001178555620006c0565b82800160010185558215620006c0579182015b82811115620006bf578251825591602001919060010190620006a2565b5b509050620006cf9190620006d3565b5090565b5b80821115620006ee576000816000905550600101620006d4565b5090565b6000620007096200070384620008ec565b620008c3565b90508281526020810184848401111562000728576200072762000aa7565b5b6200073584828562000973565b509392505050565b600082601f83011262000755576200075462000aa2565b5b815162000767848260208601620006f2565b91505092915050565b600081519050620007818162000ac7565b92915050565b60008060008060008060008060006101208a8c031215620007ad57620007ac62000ab1565b5b60008a015167ffffffffffffffff811115620007ce57620007cd62000aac565b5b620007dc8c828d016200073d565b99505060208a015167ffffffffffffffff8111156200080057620007ff62000aac565b5b6200080e8c828d016200073d565b98505060408a015167ffffffffffffffff81111562000832576200083162000aac565b5b620008408c828d016200073d565b9750506060620008538c828d0162000770565b9650506080620008668c828d0162000770565b95505060a0620008798c828d0162000770565b94505060c06200088c8c828d0162000770565b93505060e06200089f8c828d0162000770565b925050610100620008b38c828d0162000770565b9150509295985092959850929598565b6000620008cf620008e2565b9050620008dd8282620009df565b919050565b6000604051905090565b600067ffffffffffffffff8211156200090a576200090962000a73565b5b620009158262000ab6565b9050602081019050919050565b60006200092f8262000963565b91506200093c8362000963565b92508263ffffffff0382111562000958576200095762000a15565b5b828201905092915050565b600063ffffffff82169050919050565b60005b838110156200099357808201518184015260208101905062000976565b83811115620009a3576000848401525b50505050565b60006002820490506001821680620009c257607f821691505b60208210811415620009d957620009d862000a44565b5b50919050565b620009ea8262000ab6565b810181811067ffffffffffffffff8211171562000a0c5762000a0b62000a73565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b62000ad28162000963565b811462000ade57600080fd5b50565b61483c8062000af16000396000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c80637fdce74a11610167578063b88d4fde116100ce578063d10a1a2b11610087578063d10a1a2b1461079c578063d547741f146107ba578063e985e9c5146107d6578063ec87621c14610806578063f9d3208d14610824578063fae4c7f91461085457610295565b8063b88d4fde146106ee578063bb95848d1461070a578063c2d05a6e14610726578063c4ae316814610744578063c87b56dd1461074e578063d021aa501461077e57610295565b8063a217fddf11610120578063a217fddf1461063e578063a22cb4651461065c578063a4f4f8af14610678578063a71bbebe14610696578063b0b20f54146106b2578063b187bd26146106d057610295565b80637fdce74a1461057e57806385e4a9b41461059a5780638bd179df146105b657806391d14854146105c057806395589bdd146105f057806395d89b411461062057610295565b8063333e44e61161020b5780635b8ad429116101c45780635b8ad429146104be5780635d386ed3146104c85780636352211e146104e45780636c0360eb1461051457806370a08231146105325780637b1a87f51461056257610295565b8063333e44e61461041257806336568abe1461043057806342842e0e1461044c57806351169d7114610468578063533a2cad146104865780635accac99146104a257610295565b806321ff99701161025d57806321ff99701461035257806323b872dd1461036e57806323d07d1b1461038a578063248a9ca3146103a85780632f2ff15d146103d857806332cb6b0c146103f457610295565b806301ffc9a71461029a57806306fdde03146102ca578063081812fc146102e8578063095ea7b31461031857806318160ddd14610334575b600080fd5b6102b460048036038101906102af9190613799565b610872565b6040516102c19190613d35565b60405180910390f35b6102d2610934565b6040516102df9190613d6b565b60405180910390f35b61030260048036038101906102fd919061383c565b6109c6565b60405161030f9190613cce565b60405180910390f35b610332600480360381019061032d9190613573565b610a45565b005b61033c610b89565b6040516103499190613f2d565b60405180910390f35b61036c6004803603810190610367919061372c565b610ba0565b005b6103886004803603810190610383919061345d565b610bd5565b005b610392610efa565b60405161039f9190613f2d565b60405180910390f35b6103c260048036038101906103bd919061372c565b610f1a565b6040516103cf9190613d50565b60405180910390f35b6103f260048036038101906103ed9190613759565b610f3a565b005b6103fc610f5b565b6040516104099190613f2d565b60405180910390f35b61041a610f61565b6040516104279190613f2d565b60405180910390f35b61044a60048036038101906104459190613759565b610f81565b005b6104666004803603810190610461919061345d565b611004565b005b610470611024565b60405161047d9190613f48565b60405180910390f35b6104a0600480360381019061049b91906136e3565b61103a565b005b6104bc60048036038101906104b791906137f3565b6110ce565b005b6104c6611113565b005b6104e260048036038101906104dd91906137f3565b61116a565b005b6104fe60048036038101906104f9919061383c565b6111ca565b60405161050b9190613cce565b60405180910390f35b61051c6111dc565b6040516105299190613d6b565b60405180910390f35b61054c600480360381019061054791906133f0565b61126a565b6040516105599190613f2d565b60405180910390f35b61057c60048036038101906105779190613687565b611323565b005b61059860048036038101906105939190613869565b6116dc565b005b6105b460048036038101906105af91906135b3565b61172b565b005b6105be6119a3565b005b6105da60048036038101906105d59190613759565b6119eb565b6040516105e79190613d35565b60405180910390f35b61060a6004803603810190610605919061383c565b611a56565b6040516106179190613d35565b60405180910390f35b610628611a80565b6040516106359190613d6b565b60405180910390f35b610646611b12565b6040516106539190613d50565b60405180910390f35b61067660048036038101906106719190613533565b611b19565b005b610680611c91565b60405161068d9190613f2d565b60405180910390f35b6106b060048036038101906106ab9190613869565b611cb1565b005b6106ba61201f565b6040516106c79190613f48565b60405180910390f35b6106d8612035565b6040516106e59190613d35565b60405180910390f35b610708600480360381019061070391906134b0565b612048565b005b610724600480360381019061071f9190613869565b6120bb565b005b61072e612109565b60405161073b9190613d35565b60405180910390f35b61074c61211c565b005b6107686004803603810190610763919061383c565b612173565b6040516107759190613d6b565b60405180910390f35b61078661228b565b6040516107939190613d6b565b60405180910390f35b6107a4612319565b6040516107b19190613f2d565b60405180910390f35b6107d460048036038101906107cf9190613759565b612339565b005b6107f060048036038101906107eb919061341d565b61235a565b6040516107fd9190613d35565b60405180910390f35b61080e6123ee565b60405161081b9190613d50565b60405180910390f35b61083e6004803603810190610839919061362b565b612412565b60405161084b9190613d35565b60405180910390f35b61085c612454565b6040516108699190613d35565b60405180910390f35b6000637965db0b60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108cd57506301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108fd57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061092d5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610943906142d6565b80601f016020809104026020016040519081016040528092919081815260200182805461096f906142d6565b80156109bc5780601f10610991576101008083540402835291602001916109bc565b820191906000526020600020905b81548152906001019060200180831161099f57829003601f168201915b5050505050905090565b60006109d182612467565b610a07576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a50826111ca565b90508073ffffffffffffffffffffffffffffffffffffffff16610a716124c6565b73ffffffffffffffffffffffffffffffffffffffff1614610ad457610a9d81610a986124c6565b61235a565b610ad3576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610b936124ce565b6001546000540303905090565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08610bca816124d3565b81600c819055505050565b6000610be0826124e7565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c47576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c53846125b5565b91509150610c698187610c646124c6565b6125dc565b610cb557610c7e86610c796124c6565b61235a565b610cb4576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610d1c576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d298686866001612620565b8015610d3457600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e0285610dde888887612626565b7c02000000000000000000000000000000000000000000000000000000001761264e565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610e8a576000600185019050600060046000838152602001908152602001600020541415610e88576000548114610e87578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610ef28686866001612679565b505050505050565b60006010601c9054906101000a900463ffffffff1663ffffffff16905090565b600060086000838152602001908152602001600020600101549050919050565b610f4382610f1a565b610f4c816124d3565b610f56838361267f565b505050565b61271081565b6000601060149054906101000a900463ffffffff1663ffffffff16905090565b610f89612760565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ff6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fed90613f0d565b60405180910390fd5b6110008282612768565b5050565b61101f83838360405180602001604052806000815250612048565b505050565b601060009054906101000a900463ffffffff1681565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611064816124d3565b60005b82518110156110c9576001600d600085848151811061108957611088614431565b5b6020026020010151815260200190815260200160002060006101000a81548160ff02191690831515021790555080806110c190614339565b915050611067565b505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b086110f8816124d3565b81600a908051906020019061110e929190612f62565b505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0861113d816124d3565b600b60009054906101000a900460ff1615600b60006101000a81548160ff02191690831515021790555050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611194816124d3565b81600990805190602001906111aa929190612f62565b506001600b60006101000a81548160ff0219169083151502179055505050565b60006111d5826124e7565b9050919050565b600980546111e9906142d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611215906142d6565b80156112625780601f1061123757610100808354040283529160200191611262565b820191906000526020600020905b81548152906001019060200180831161124557829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156112d2576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611391576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138890613dad565b60405180910390fd5b600b60029054906101000a900460ff16156113e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d890613e8d565b60405180910390fd5b600b60019054906101000a900460ff16611430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142790613e0d565b60405180910390fd5b600b60009054906101000a900460ff1615611480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147790613ded565b60405180910390fd5b600061148a612760565b90506114968382612412565b6114d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114cc90613eed565b60405180910390fd5b81601060088282829054906101000a900463ffffffff166114f69190614148565b92506101000a81548163ffffffff021916908363ffffffff1602179055508163ffffffff16600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461156991906140f2565b925050819055506010600c9054906101000a900463ffffffff1663ffffffff16601060089054906101000a900463ffffffff1663ffffffff1611156115e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115da90613e4d565b60405180910390fd5b601060009054906101000a900463ffffffff1663ffffffff16600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054111561167d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167490613ecd565b60405180910390fd5b61168d818363ffffffff1661284a565b8163ffffffff168173ffffffffffffffffffffffffffffffffffffffff167f1a75c98f3caa5c596c30e5e4c83e0802685273950677d98a322c514a03b05b5760405160405180910390a3505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611706816124d3565b816010600c6101000a81548163ffffffff021916908363ffffffff1602179055505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611755816124d3565b6000805b845181101561181d57600085828151811061177757611776614431565b5b60200260200101519050600085838151811061179657611795614431565b5b6020026020010151905083806117ab90614382565b9450506117be828263ffffffff1661284a565b8063ffffffff168273ffffffffffffffffffffffffffffffffffffffff167f1a75c98f3caa5c596c30e5e4c83e0802685273950677d98a322c514a03b05b5760405160405180910390a35050808061181590614339565b915050611759565b50600b60019054906101000a900460ff16156118ea5780601060088282829054906101000a900463ffffffff166118549190614148565b92506101000a81548163ffffffff021916908363ffffffff160217905550601060149054906101000a900463ffffffff1663ffffffff16601060089054906101000a900463ffffffff1663ffffffff1611156118e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118dc90613dcd565b60405180910390fd5b61199d565b80601060188282829054906101000a900463ffffffff1661190b9190614148565b92506101000a81548163ffffffff021916908363ffffffff1602179055506010601c9054906101000a900463ffffffff1663ffffffff16601060189054906101000a900463ffffffff1663ffffffff16111561199c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199390613e2d565b60405180910390fd5b5b50505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b086119cd816124d3565b6000600b60016101000a81548160ff02191690831515021790555050565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600d600083815260200190815260200160002060009054906101000a900460ff169050919050565b606060038054611a8f906142d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611abb906142d6565b8015611b085780601f10611add57610100808354040283529160200191611b08565b820191906000526020600020905b815481529060010190602001808311611aeb57829003601f168201915b5050505050905090565b6000801b81565b611b216124c6565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b86576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000611b936124c6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611c406124c6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611c859190613d35565b60405180910390a35050565b6000601060189054906101000a900463ffffffff1663ffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611d1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1690613dad565b60405180910390fd5b600b60029054906101000a900460ff1615611d6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d6690613e8d565b60405180910390fd5b600b60019054906101000a900460ff1615611dbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db690613e0d565b60405180910390fd5b600b60009054906101000a900460ff1615611e0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0690613ded565b60405180910390fd5b6000611e19612760565b905081601060188282829054906101000a900463ffffffff16611e3c9190614148565b92506101000a81548163ffffffff021916908363ffffffff1602179055508163ffffffff16600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611eaf91906140f2565b9250508190555060108054906101000a900463ffffffff1663ffffffff16601060189054906101000a900463ffffffff1663ffffffff161115611f27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1e90613ead565b60405180910390fd5b601060049054906101000a900463ffffffff1663ffffffff16600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611fc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb890613e6d565b60405180910390fd5b611fd1818363ffffffff1661284a565b8163ffffffff168173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688560405160405180910390a35050565b601060049054906101000a900463ffffffff1681565b600b60029054906101000a900460ff1681565b612053848484610bd5565b60008373ffffffffffffffffffffffffffffffffffffffff163b146120b55761207e84848484612a07565b6120b4576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b086120e5816124d3565b816010806101000a81548163ffffffff021916908363ffffffff1602179055505050565b600b60019054906101000a900460ff1681565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08612146816124d3565b600b60029054906101000a900460ff1615600b60026101000a81548160ff02191690831515021790555050565b606061217e82612467565b6121b4576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b60009054906101000a900460ff1661225857600a80546121d5906142d6565b80601f0160208091040260200160405190810160405280929190818152602001828054612201906142d6565b801561224e5780601f106122235761010080835404028352916020019161224e565b820191906000526020600020905b81548152906001019060200180831161223157829003601f168201915b5050505050612284565b600961226383612b67565b604051602001612274929190613c65565b6040516020818303038152906040525b9050919050565b600a8054612298906142d6565b80601f01602080910402602001604051908101604052809291908181526020018280546122c4906142d6565b80156123115780601f106122e657610100808354040283529160200191612311565b820191906000526020600020905b8154815290600101906020018083116122f457829003601f168201915b505050505081565b6000601060089054906101000a900463ffffffff1663ffffffff16905090565b61234282610f1a565b61234b816124d3565b6123558383612768565b505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0881565b600080826040516020016124269190613c4a565b60405160208183030381529060405280519060200120905061244b84600c5483612bc1565b91505092915050565b600b60009054906101000a900460ff1681565b6000816124726124ce565b11158015612481575060005482105b80156124bf575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b6124e4816124df612760565b612bd8565b50565b600080829050806124f66124ce565b1161257e5760005481101561257d5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216141561257b575b6000811415612571576004600083600190039350838152602001908152602001600020549050612546565b80925050506125b0565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861263d868684612c75565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b61268982826119eb565b61275c5760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612701612760565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b61277282826119eb565b156128465760006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506127eb612760565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b600080549050600082141561288b576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128986000848385612620565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061290f836129006000866000612626565b61290985612c7e565b1761264e565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146129b057808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612975565b5060008214156129ec576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612a026000848385612679565b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612a2d6124c6565b8786866040518563ffffffff1660e01b8152600401612a4f9493929190613ce9565b602060405180830381600087803b158015612a6957600080fd5b505af1925050508015612a9a57506040513d601f19601f82011682018060405250810190612a9791906137c6565b60015b612b14573d8060008114612aca576040519150601f19603f3d011682016040523d82523d6000602084013e612acf565b606091505b50600081511415612b0c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b8015612bad57600183039250600a81066030018353600a81049050612b8d565b508181036020830392508083525050919050565b600082612bce8584612c8e565b1490509392505050565b612be282826119eb565b612c7157612c078173ffffffffffffffffffffffffffffffffffffffff166014612ce4565b612c158360001c6020612ce4565b604051602001612c26929190613c94565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c689190613d6b565b60405180910390fd5b5050565b60009392505050565b60006001821460e11b9050919050565b60008082905060005b8451811015612cd957612cc482868381518110612cb757612cb6614431565b5b6020026020010151612f20565b91508080612cd190614339565b915050612c97565b508091505092915050565b606060006002836002612cf79190614182565b612d0191906140f2565b67ffffffffffffffff811115612d1a57612d19614460565b5b6040519080825280601f01601f191660200182016040528015612d4c5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612d8457612d83614431565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612de857612de7614431565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612e289190614182565b612e3291906140f2565b90505b6001811115612ed2577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612e7457612e73614431565b5b1a60f81b828281518110612e8b57612e8a614431565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612ecb906142ac565b9050612e35565b5060008414612f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0d90613d8d565b60405180910390fd5b8091505092915050565b6000818310612f3857612f338284612f4b565b612f43565b612f428383612f4b565b5b905092915050565b600082600052816020526040600020905092915050565b828054612f6e906142d6565b90600052602060002090601f016020900481019282612f905760008555612fd7565b82601f10612fa957805160ff1916838001178555612fd7565b82800160010185558215612fd7579182015b82811115612fd6578251825591602001919060010190612fbb565b5b509050612fe49190612fe8565b5090565b5b80821115613001576000816000905550600101612fe9565b5090565b600061301861301384613f88565b613f63565b9050808382526020820190508285602086028201111561303b5761303a614494565b5b60005b8581101561306b57816130518882613249565b84526020840193506020830192505060018101905061303e565b5050509392505050565b600061308861308384613fb4565b613f63565b905080838252602082019050828560208602820111156130ab576130aa614494565b5b60005b858110156130db57816130c1888261332b565b8452602084019350602083019250506001810190506130ae565b5050509392505050565b60006130f86130f384613fe0565b613f63565b9050808382526020820190508285602086028201111561311b5761311a614494565b5b60005b8581101561314b578161313188826133c6565b84526020840193506020830192505060018101905061311e565b5050509392505050565b60006131686131638461400c565b613f63565b9050808382526020820190508285602086028201111561318b5761318a614494565b5b60005b858110156131bb57816131a188826133db565b84526020840193506020830192505060018101905061318e565b5050509392505050565b60006131d86131d384614038565b613f63565b9050828152602081018484840111156131f4576131f3614499565b5b6131ff84828561426a565b509392505050565b600061321a61321584614069565b613f63565b90508281526020810184848401111561323657613235614499565b5b61324184828561426a565b509392505050565b6000813590506132588161477c565b92915050565b600082601f8301126132735761327261448f565b5b8135613283848260208601613005565b91505092915050565b600082601f8301126132a1576132a061448f565b5b81356132b1848260208601613075565b91505092915050565b600082601f8301126132cf576132ce61448f565b5b81356132df8482602086016130e5565b91505092915050565b600082601f8301126132fd576132fc61448f565b5b813561330d848260208601613155565b91505092915050565b60008135905061332581614793565b92915050565b60008135905061333a816147aa565b92915050565b60008135905061334f816147c1565b92915050565b600081519050613364816147c1565b92915050565b600082601f83011261337f5761337e61448f565b5b813561338f8482602086016131c5565b91505092915050565b600082601f8301126133ad576133ac61448f565b5b81356133bd848260208601613207565b91505092915050565b6000813590506133d5816147d8565b92915050565b6000813590506133ea816147ef565b92915050565b600060208284031215613406576134056144a3565b5b600061341484828501613249565b91505092915050565b60008060408385031215613434576134336144a3565b5b600061344285828601613249565b925050602061345385828601613249565b9150509250929050565b600080600060608486031215613476576134756144a3565b5b600061348486828701613249565b935050602061349586828701613249565b92505060406134a6868287016133c6565b9150509250925092565b600080600080608085870312156134ca576134c96144a3565b5b60006134d887828801613249565b94505060206134e987828801613249565b93505060406134fa878288016133c6565b925050606085013567ffffffffffffffff81111561351b5761351a61449e565b5b6135278782880161336a565b91505092959194509250565b6000806040838503121561354a576135496144a3565b5b600061355885828601613249565b925050602061356985828601613316565b9150509250929050565b6000806040838503121561358a576135896144a3565b5b600061359885828601613249565b92505060206135a9858286016133c6565b9150509250929050565b600080604083850312156135ca576135c96144a3565b5b600083013567ffffffffffffffff8111156135e8576135e761449e565b5b6135f48582860161325e565b925050602083013567ffffffffffffffff8111156136155761361461449e565b5b613621858286016132e8565b9150509250929050565b60008060408385031215613642576136416144a3565b5b600083013567ffffffffffffffff8111156136605761365f61449e565b5b61366c8582860161328c565b925050602061367d85828601613249565b9150509250929050565b6000806040838503121561369e5761369d6144a3565b5b600083013567ffffffffffffffff8111156136bc576136bb61449e565b5b6136c88582860161328c565b92505060206136d9858286016133db565b9150509250929050565b6000602082840312156136f9576136f86144a3565b5b600082013567ffffffffffffffff8111156137175761371661449e565b5b613723848285016132ba565b91505092915050565b600060208284031215613742576137416144a3565b5b60006137508482850161332b565b91505092915050565b600080604083850312156137705761376f6144a3565b5b600061377e8582860161332b565b925050602061378f85828601613249565b9150509250929050565b6000602082840312156137af576137ae6144a3565b5b60006137bd84828501613340565b91505092915050565b6000602082840312156137dc576137db6144a3565b5b60006137ea84828501613355565b91505092915050565b600060208284031215613809576138086144a3565b5b600082013567ffffffffffffffff8111156138275761382661449e565b5b61383384828501613398565b91505092915050565b600060208284031215613852576138516144a3565b5b6000613860848285016133c6565b91505092915050565b60006020828403121561387f5761387e6144a3565b5b600061388d848285016133db565b91505092915050565b61389f816141dc565b82525050565b6138b66138b1826141dc565b6143af565b82525050565b6138c5816141ee565b82525050565b6138d4816141fa565b82525050565b60006138e5826140af565b6138ef81856140c5565b93506138ff818560208601614279565b613908816144a8565b840191505092915050565b600061391e826140ba565b61392881856140d6565b9350613938818560208601614279565b613941816144a8565b840191505092915050565b6000613957826140ba565b61396181856140e7565b9350613971818560208601614279565b80840191505092915050565b6000815461398a816142d6565b61399481866140e7565b945060018216600081146139af57600181146139c0576139f3565b60ff198316865281860193506139f3565b6139c98561409a565b60005b838110156139eb578154818901526001820191506020810190506139cc565b838801955050505b50505092915050565b6000613a096020836140d6565b9150613a14826144c6565b602082019050919050565b6000613a2c6007836140d6565b9150613a37826144ef565b602082019050919050565b6000613a4f6012836140d6565b9150613a5a82614518565b602082019050919050565b6000613a72600e836140d6565b9150613a7d82614541565b602082019050919050565b6000613a95600c836140d6565b9150613aa08261456a565b602082019050919050565b6000613ab86014836140d6565b9150613ac382614593565b602082019050919050565b6000613adb6015836140d6565b9150613ae6826145bc565b602082019050919050565b6000613afe601d836140d6565b9150613b09826145e5565b602082019050919050565b6000613b216005836140e7565b9150613b2c8261460e565b600582019050919050565b6000613b44600e836140d6565b9150613b4f82614637565b602082019050919050565b6000613b676017836140d6565b9150613b7282614660565b602082019050919050565b6000613b8a6011836140d6565b9150613b9582614689565b602082019050919050565b6000613bad6017836140e7565b9150613bb8826146b2565b601782019050919050565b6000613bd06011836140d6565b9150613bdb826146db565b602082019050919050565b6000613bf36011836140e7565b9150613bfe82614704565b601182019050919050565b6000613c16602f836140d6565b9150613c218261472d565b604082019050919050565b613c3581614250565b82525050565b613c448161425a565b82525050565b6000613c5682846138a5565b60148201915081905092915050565b6000613c71828561397d565b9150613c7d828461394c565b9150613c8882613b14565b91508190509392505050565b6000613c9f82613ba0565b9150613cab828561394c565b9150613cb682613be6565b9150613cc2828461394c565b91508190509392505050565b6000602082019050613ce36000830184613896565b92915050565b6000608082019050613cfe6000830187613896565b613d0b6020830186613896565b613d186040830185613c2c565b8181036060830152613d2a81846138da565b905095945050505050565b6000602082019050613d4a60008301846138bc565b92915050565b6000602082019050613d6560008301846138cb565b92915050565b60006020820190508181036000830152613d858184613913565b905092915050565b60006020820190508181036000830152613da6816139fc565b9050919050565b60006020820190508181036000830152613dc681613a1f565b9050919050565b60006020820190508181036000830152613de681613a42565b9050919050565b60006020820190508181036000830152613e0681613a65565b9050919050565b60006020820190508181036000830152613e2681613a88565b9050919050565b60006020820190508181036000830152613e4681613aab565b9050919050565b60006020820190508181036000830152613e6681613ace565b9050919050565b60006020820190508181036000830152613e8681613af1565b9050919050565b60006020820190508181036000830152613ea681613b37565b9050919050565b60006020820190508181036000830152613ec681613b5a565b9050919050565b60006020820190508181036000830152613ee681613b7d565b9050919050565b60006020820190508181036000830152613f0681613bc3565b9050919050565b60006020820190508181036000830152613f2681613c09565b9050919050565b6000602082019050613f426000830184613c2c565b92915050565b6000602082019050613f5d6000830184613c3b565b92915050565b6000613f6d613f7e565b9050613f798282614308565b919050565b6000604051905090565b600067ffffffffffffffff821115613fa357613fa2614460565b5b602082029050602081019050919050565b600067ffffffffffffffff821115613fcf57613fce614460565b5b602082029050602081019050919050565b600067ffffffffffffffff821115613ffb57613ffa614460565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561402757614026614460565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561405357614052614460565b5b61405c826144a8565b9050602081019050919050565b600067ffffffffffffffff82111561408457614083614460565b5b61408d826144a8565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006140fd82614250565b915061410883614250565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561413d5761413c6143d3565b5b828201905092915050565b60006141538261425a565b915061415e8361425a565b92508263ffffffff03821115614177576141766143d3565b5b828201905092915050565b600061418d82614250565b915061419883614250565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156141d1576141d06143d3565b5b828202905092915050565b60006141e782614230565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b82818337600083830152505050565b60005b8381101561429757808201518184015260208101905061427c565b838111156142a6576000848401525b50505050565b60006142b782614250565b915060008214156142cb576142ca6143d3565b5b600182039050919050565b600060028204905060018216806142ee57607f821691505b6020821081141561430257614301614402565b5b50919050565b614311826144a8565b810181811067ffffffffffffffff821117156143305761432f614460565b5b80604052505050565b600061434482614250565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614377576143766143d3565b5b600182019050919050565b600061438d8261425a565b915063ffffffff8214156143a4576143a36143d3565b5b600182019050919050565b60006143ba826143c1565b9050919050565b60006143cc826144b9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f4e6f7420454f4100000000000000000000000000000000000000000000000000600082015250565b7f457863656564206672656520616d6f756e740000000000000000000000000000600082015250565b7f416c72656164792072657665616c000000000000000000000000000000000000600082015250565b7f496e76616c6964206d696e740000000000000000000000000000000000000000600082015250565b7f457863656564207075626c696320616d6f756e74000000000000000000000000600082015250565b7f457863656564206d6178206672656520746f74616c0000000000000000000000600082015250565b7f457863656564206d617820616d6f756e7420706572206163636f756e74000000600082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f416c726561647920706175736564000000000000000000000000000000000000600082015250565b7f457863656564206d6178207075626c696320746f74616c000000000000000000600082015250565b7f457863656564206d617820616d6f756e74000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f496e656c696769626c652057616c6c6574000000000000000000000000000000600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b614785816141dc565b811461479057600080fd5b50565b61479c816141ee565b81146147a757600080fd5b50565b6147b3816141fa565b81146147be57600080fd5b50565b6147ca81614204565b81146147d557600080fd5b50565b6147e181614250565b81146147ec57600080fd5b50565b6147f88161425a565b811461480357600080fd5b5056fea26469706673582212204a8ca531c5fb07a8ac66e6d25cf97841eaa0620b954f454fa45ea37d0229f7a764736f6c634300080700330000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000d41537472616e644f664861697200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000441534f4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005068747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d58557743694b72515662376a364b78693676376b3533345068386466363733386879534d437536524a774a6900000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102955760003560e01c80637fdce74a11610167578063b88d4fde116100ce578063d10a1a2b11610087578063d10a1a2b1461079c578063d547741f146107ba578063e985e9c5146107d6578063ec87621c14610806578063f9d3208d14610824578063fae4c7f91461085457610295565b8063b88d4fde146106ee578063bb95848d1461070a578063c2d05a6e14610726578063c4ae316814610744578063c87b56dd1461074e578063d021aa501461077e57610295565b8063a217fddf11610120578063a217fddf1461063e578063a22cb4651461065c578063a4f4f8af14610678578063a71bbebe14610696578063b0b20f54146106b2578063b187bd26146106d057610295565b80637fdce74a1461057e57806385e4a9b41461059a5780638bd179df146105b657806391d14854146105c057806395589bdd146105f057806395d89b411461062057610295565b8063333e44e61161020b5780635b8ad429116101c45780635b8ad429146104be5780635d386ed3146104c85780636352211e146104e45780636c0360eb1461051457806370a08231146105325780637b1a87f51461056257610295565b8063333e44e61461041257806336568abe1461043057806342842e0e1461044c57806351169d7114610468578063533a2cad146104865780635accac99146104a257610295565b806321ff99701161025d57806321ff99701461035257806323b872dd1461036e57806323d07d1b1461038a578063248a9ca3146103a85780632f2ff15d146103d857806332cb6b0c146103f457610295565b806301ffc9a71461029a57806306fdde03146102ca578063081812fc146102e8578063095ea7b31461031857806318160ddd14610334575b600080fd5b6102b460048036038101906102af9190613799565b610872565b6040516102c19190613d35565b60405180910390f35b6102d2610934565b6040516102df9190613d6b565b60405180910390f35b61030260048036038101906102fd919061383c565b6109c6565b60405161030f9190613cce565b60405180910390f35b610332600480360381019061032d9190613573565b610a45565b005b61033c610b89565b6040516103499190613f2d565b60405180910390f35b61036c6004803603810190610367919061372c565b610ba0565b005b6103886004803603810190610383919061345d565b610bd5565b005b610392610efa565b60405161039f9190613f2d565b60405180910390f35b6103c260048036038101906103bd919061372c565b610f1a565b6040516103cf9190613d50565b60405180910390f35b6103f260048036038101906103ed9190613759565b610f3a565b005b6103fc610f5b565b6040516104099190613f2d565b60405180910390f35b61041a610f61565b6040516104279190613f2d565b60405180910390f35b61044a60048036038101906104459190613759565b610f81565b005b6104666004803603810190610461919061345d565b611004565b005b610470611024565b60405161047d9190613f48565b60405180910390f35b6104a0600480360381019061049b91906136e3565b61103a565b005b6104bc60048036038101906104b791906137f3565b6110ce565b005b6104c6611113565b005b6104e260048036038101906104dd91906137f3565b61116a565b005b6104fe60048036038101906104f9919061383c565b6111ca565b60405161050b9190613cce565b60405180910390f35b61051c6111dc565b6040516105299190613d6b565b60405180910390f35b61054c600480360381019061054791906133f0565b61126a565b6040516105599190613f2d565b60405180910390f35b61057c60048036038101906105779190613687565b611323565b005b61059860048036038101906105939190613869565b6116dc565b005b6105b460048036038101906105af91906135b3565b61172b565b005b6105be6119a3565b005b6105da60048036038101906105d59190613759565b6119eb565b6040516105e79190613d35565b60405180910390f35b61060a6004803603810190610605919061383c565b611a56565b6040516106179190613d35565b60405180910390f35b610628611a80565b6040516106359190613d6b565b60405180910390f35b610646611b12565b6040516106539190613d50565b60405180910390f35b61067660048036038101906106719190613533565b611b19565b005b610680611c91565b60405161068d9190613f2d565b60405180910390f35b6106b060048036038101906106ab9190613869565b611cb1565b005b6106ba61201f565b6040516106c79190613f48565b60405180910390f35b6106d8612035565b6040516106e59190613d35565b60405180910390f35b610708600480360381019061070391906134b0565b612048565b005b610724600480360381019061071f9190613869565b6120bb565b005b61072e612109565b60405161073b9190613d35565b60405180910390f35b61074c61211c565b005b6107686004803603810190610763919061383c565b612173565b6040516107759190613d6b565b60405180910390f35b61078661228b565b6040516107939190613d6b565b60405180910390f35b6107a4612319565b6040516107b19190613f2d565b60405180910390f35b6107d460048036038101906107cf9190613759565b612339565b005b6107f060048036038101906107eb919061341d565b61235a565b6040516107fd9190613d35565b60405180910390f35b61080e6123ee565b60405161081b9190613d50565b60405180910390f35b61083e6004803603810190610839919061362b565b612412565b60405161084b9190613d35565b60405180910390f35b61085c612454565b6040516108699190613d35565b60405180910390f35b6000637965db0b60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108cd57506301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108fd57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061092d5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610943906142d6565b80601f016020809104026020016040519081016040528092919081815260200182805461096f906142d6565b80156109bc5780601f10610991576101008083540402835291602001916109bc565b820191906000526020600020905b81548152906001019060200180831161099f57829003601f168201915b5050505050905090565b60006109d182612467565b610a07576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a50826111ca565b90508073ffffffffffffffffffffffffffffffffffffffff16610a716124c6565b73ffffffffffffffffffffffffffffffffffffffff1614610ad457610a9d81610a986124c6565b61235a565b610ad3576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610b936124ce565b6001546000540303905090565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08610bca816124d3565b81600c819055505050565b6000610be0826124e7565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c47576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c53846125b5565b91509150610c698187610c646124c6565b6125dc565b610cb557610c7e86610c796124c6565b61235a565b610cb4576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610d1c576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d298686866001612620565b8015610d3457600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e0285610dde888887612626565b7c02000000000000000000000000000000000000000000000000000000001761264e565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610e8a576000600185019050600060046000838152602001908152602001600020541415610e88576000548114610e87578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610ef28686866001612679565b505050505050565b60006010601c9054906101000a900463ffffffff1663ffffffff16905090565b600060086000838152602001908152602001600020600101549050919050565b610f4382610f1a565b610f4c816124d3565b610f56838361267f565b505050565b61271081565b6000601060149054906101000a900463ffffffff1663ffffffff16905090565b610f89612760565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ff6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fed90613f0d565b60405180910390fd5b6110008282612768565b5050565b61101f83838360405180602001604052806000815250612048565b505050565b601060009054906101000a900463ffffffff1681565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611064816124d3565b60005b82518110156110c9576001600d600085848151811061108957611088614431565b5b6020026020010151815260200190815260200160002060006101000a81548160ff02191690831515021790555080806110c190614339565b915050611067565b505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b086110f8816124d3565b81600a908051906020019061110e929190612f62565b505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0861113d816124d3565b600b60009054906101000a900460ff1615600b60006101000a81548160ff02191690831515021790555050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611194816124d3565b81600990805190602001906111aa929190612f62565b506001600b60006101000a81548160ff0219169083151502179055505050565b60006111d5826124e7565b9050919050565b600980546111e9906142d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611215906142d6565b80156112625780601f1061123757610100808354040283529160200191611262565b820191906000526020600020905b81548152906001019060200180831161124557829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156112d2576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611391576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138890613dad565b60405180910390fd5b600b60029054906101000a900460ff16156113e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d890613e8d565b60405180910390fd5b600b60019054906101000a900460ff16611430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142790613e0d565b60405180910390fd5b600b60009054906101000a900460ff1615611480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147790613ded565b60405180910390fd5b600061148a612760565b90506114968382612412565b6114d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114cc90613eed565b60405180910390fd5b81601060088282829054906101000a900463ffffffff166114f69190614148565b92506101000a81548163ffffffff021916908363ffffffff1602179055508163ffffffff16600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461156991906140f2565b925050819055506010600c9054906101000a900463ffffffff1663ffffffff16601060089054906101000a900463ffffffff1663ffffffff1611156115e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115da90613e4d565b60405180910390fd5b601060009054906101000a900463ffffffff1663ffffffff16600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054111561167d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167490613ecd565b60405180910390fd5b61168d818363ffffffff1661284a565b8163ffffffff168173ffffffffffffffffffffffffffffffffffffffff167f1a75c98f3caa5c596c30e5e4c83e0802685273950677d98a322c514a03b05b5760405160405180910390a3505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611706816124d3565b816010600c6101000a81548163ffffffff021916908363ffffffff1602179055505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08611755816124d3565b6000805b845181101561181d57600085828151811061177757611776614431565b5b60200260200101519050600085838151811061179657611795614431565b5b6020026020010151905083806117ab90614382565b9450506117be828263ffffffff1661284a565b8063ffffffff168273ffffffffffffffffffffffffffffffffffffffff167f1a75c98f3caa5c596c30e5e4c83e0802685273950677d98a322c514a03b05b5760405160405180910390a35050808061181590614339565b915050611759565b50600b60019054906101000a900460ff16156118ea5780601060088282829054906101000a900463ffffffff166118549190614148565b92506101000a81548163ffffffff021916908363ffffffff160217905550601060149054906101000a900463ffffffff1663ffffffff16601060089054906101000a900463ffffffff1663ffffffff1611156118e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118dc90613dcd565b60405180910390fd5b61199d565b80601060188282829054906101000a900463ffffffff1661190b9190614148565b92506101000a81548163ffffffff021916908363ffffffff1602179055506010601c9054906101000a900463ffffffff1663ffffffff16601060189054906101000a900463ffffffff1663ffffffff16111561199c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199390613e2d565b60405180910390fd5b5b50505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b086119cd816124d3565b6000600b60016101000a81548160ff02191690831515021790555050565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600d600083815260200190815260200160002060009054906101000a900460ff169050919050565b606060038054611a8f906142d6565b80601f0160208091040260200160405190810160405280929190818152602001828054611abb906142d6565b8015611b085780601f10611add57610100808354040283529160200191611b08565b820191906000526020600020905b815481529060010190602001808311611aeb57829003601f168201915b5050505050905090565b6000801b81565b611b216124c6565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b86576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000611b936124c6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611c406124c6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611c859190613d35565b60405180910390a35050565b6000601060189054906101000a900463ffffffff1663ffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611d1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1690613dad565b60405180910390fd5b600b60029054906101000a900460ff1615611d6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d6690613e8d565b60405180910390fd5b600b60019054906101000a900460ff1615611dbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db690613e0d565b60405180910390fd5b600b60009054906101000a900460ff1615611e0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0690613ded565b60405180910390fd5b6000611e19612760565b905081601060188282829054906101000a900463ffffffff16611e3c9190614148565b92506101000a81548163ffffffff021916908363ffffffff1602179055508163ffffffff16600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611eaf91906140f2565b9250508190555060108054906101000a900463ffffffff1663ffffffff16601060189054906101000a900463ffffffff1663ffffffff161115611f27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1e90613ead565b60405180910390fd5b601060049054906101000a900463ffffffff1663ffffffff16600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611fc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb890613e6d565b60405180910390fd5b611fd1818363ffffffff1661284a565b8163ffffffff168173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688560405160405180910390a35050565b601060049054906101000a900463ffffffff1681565b600b60029054906101000a900460ff1681565b612053848484610bd5565b60008373ffffffffffffffffffffffffffffffffffffffff163b146120b55761207e84848484612a07565b6120b4576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b086120e5816124d3565b816010806101000a81548163ffffffff021916908363ffffffff1602179055505050565b600b60019054906101000a900460ff1681565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08612146816124d3565b600b60029054906101000a900460ff1615600b60026101000a81548160ff02191690831515021790555050565b606061217e82612467565b6121b4576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b60009054906101000a900460ff1661225857600a80546121d5906142d6565b80601f0160208091040260200160405190810160405280929190818152602001828054612201906142d6565b801561224e5780601f106122235761010080835404028352916020019161224e565b820191906000526020600020905b81548152906001019060200180831161223157829003601f168201915b5050505050612284565b600961226383612b67565b604051602001612274929190613c65565b6040516020818303038152906040525b9050919050565b600a8054612298906142d6565b80601f01602080910402602001604051908101604052809291908181526020018280546122c4906142d6565b80156123115780601f106122e657610100808354040283529160200191612311565b820191906000526020600020905b8154815290600101906020018083116122f457829003601f168201915b505050505081565b6000601060089054906101000a900463ffffffff1663ffffffff16905090565b61234282610f1a565b61234b816124d3565b6123558383612768565b505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b7f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0881565b600080826040516020016124269190613c4a565b60405160208183030381529060405280519060200120905061244b84600c5483612bc1565b91505092915050565b600b60009054906101000a900460ff1681565b6000816124726124ce565b11158015612481575060005482105b80156124bf575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b6124e4816124df612760565b612bd8565b50565b600080829050806124f66124ce565b1161257e5760005481101561257d5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216141561257b575b6000811415612571576004600083600190039350838152602001908152602001600020549050612546565b80925050506125b0565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861263d868684612c75565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b61268982826119eb565b61275c5760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612701612760565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b61277282826119eb565b156128465760006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506127eb612760565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b600080549050600082141561288b576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128986000848385612620565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061290f836129006000866000612626565b61290985612c7e565b1761264e565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146129b057808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612975565b5060008214156129ec576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612a026000848385612679565b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612a2d6124c6565b8786866040518563ffffffff1660e01b8152600401612a4f9493929190613ce9565b602060405180830381600087803b158015612a6957600080fd5b505af1925050508015612a9a57506040513d601f19601f82011682018060405250810190612a9791906137c6565b60015b612b14573d8060008114612aca576040519150601f19603f3d011682016040523d82523d6000602084013e612acf565b606091505b50600081511415612b0c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b8015612bad57600183039250600a81066030018353600a81049050612b8d565b508181036020830392508083525050919050565b600082612bce8584612c8e565b1490509392505050565b612be282826119eb565b612c7157612c078173ffffffffffffffffffffffffffffffffffffffff166014612ce4565b612c158360001c6020612ce4565b604051602001612c26929190613c94565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c689190613d6b565b60405180910390fd5b5050565b60009392505050565b60006001821460e11b9050919050565b60008082905060005b8451811015612cd957612cc482868381518110612cb757612cb6614431565b5b6020026020010151612f20565b91508080612cd190614339565b915050612c97565b508091505092915050565b606060006002836002612cf79190614182565b612d0191906140f2565b67ffffffffffffffff811115612d1a57612d19614460565b5b6040519080825280601f01601f191660200182016040528015612d4c5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612d8457612d83614431565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612de857612de7614431565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612e289190614182565b612e3291906140f2565b90505b6001811115612ed2577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612e7457612e73614431565b5b1a60f81b828281518110612e8b57612e8a614431565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612ecb906142ac565b9050612e35565b5060008414612f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0d90613d8d565b60405180910390fd5b8091505092915050565b6000818310612f3857612f338284612f4b565b612f43565b612f428383612f4b565b5b905092915050565b600082600052816020526040600020905092915050565b828054612f6e906142d6565b90600052602060002090601f016020900481019282612f905760008555612fd7565b82601f10612fa957805160ff1916838001178555612fd7565b82800160010185558215612fd7579182015b82811115612fd6578251825591602001919060010190612fbb565b5b509050612fe49190612fe8565b5090565b5b80821115613001576000816000905550600101612fe9565b5090565b600061301861301384613f88565b613f63565b9050808382526020820190508285602086028201111561303b5761303a614494565b5b60005b8581101561306b57816130518882613249565b84526020840193506020830192505060018101905061303e565b5050509392505050565b600061308861308384613fb4565b613f63565b905080838252602082019050828560208602820111156130ab576130aa614494565b5b60005b858110156130db57816130c1888261332b565b8452602084019350602083019250506001810190506130ae565b5050509392505050565b60006130f86130f384613fe0565b613f63565b9050808382526020820190508285602086028201111561311b5761311a614494565b5b60005b8581101561314b578161313188826133c6565b84526020840193506020830192505060018101905061311e565b5050509392505050565b60006131686131638461400c565b613f63565b9050808382526020820190508285602086028201111561318b5761318a614494565b5b60005b858110156131bb57816131a188826133db565b84526020840193506020830192505060018101905061318e565b5050509392505050565b60006131d86131d384614038565b613f63565b9050828152602081018484840111156131f4576131f3614499565b5b6131ff84828561426a565b509392505050565b600061321a61321584614069565b613f63565b90508281526020810184848401111561323657613235614499565b5b61324184828561426a565b509392505050565b6000813590506132588161477c565b92915050565b600082601f8301126132735761327261448f565b5b8135613283848260208601613005565b91505092915050565b600082601f8301126132a1576132a061448f565b5b81356132b1848260208601613075565b91505092915050565b600082601f8301126132cf576132ce61448f565b5b81356132df8482602086016130e5565b91505092915050565b600082601f8301126132fd576132fc61448f565b5b813561330d848260208601613155565b91505092915050565b60008135905061332581614793565b92915050565b60008135905061333a816147aa565b92915050565b60008135905061334f816147c1565b92915050565b600081519050613364816147c1565b92915050565b600082601f83011261337f5761337e61448f565b5b813561338f8482602086016131c5565b91505092915050565b600082601f8301126133ad576133ac61448f565b5b81356133bd848260208601613207565b91505092915050565b6000813590506133d5816147d8565b92915050565b6000813590506133ea816147ef565b92915050565b600060208284031215613406576134056144a3565b5b600061341484828501613249565b91505092915050565b60008060408385031215613434576134336144a3565b5b600061344285828601613249565b925050602061345385828601613249565b9150509250929050565b600080600060608486031215613476576134756144a3565b5b600061348486828701613249565b935050602061349586828701613249565b92505060406134a6868287016133c6565b9150509250925092565b600080600080608085870312156134ca576134c96144a3565b5b60006134d887828801613249565b94505060206134e987828801613249565b93505060406134fa878288016133c6565b925050606085013567ffffffffffffffff81111561351b5761351a61449e565b5b6135278782880161336a565b91505092959194509250565b6000806040838503121561354a576135496144a3565b5b600061355885828601613249565b925050602061356985828601613316565b9150509250929050565b6000806040838503121561358a576135896144a3565b5b600061359885828601613249565b92505060206135a9858286016133c6565b9150509250929050565b600080604083850312156135ca576135c96144a3565b5b600083013567ffffffffffffffff8111156135e8576135e761449e565b5b6135f48582860161325e565b925050602083013567ffffffffffffffff8111156136155761361461449e565b5b613621858286016132e8565b9150509250929050565b60008060408385031215613642576136416144a3565b5b600083013567ffffffffffffffff8111156136605761365f61449e565b5b61366c8582860161328c565b925050602061367d85828601613249565b9150509250929050565b6000806040838503121561369e5761369d6144a3565b5b600083013567ffffffffffffffff8111156136bc576136bb61449e565b5b6136c88582860161328c565b92505060206136d9858286016133db565b9150509250929050565b6000602082840312156136f9576136f86144a3565b5b600082013567ffffffffffffffff8111156137175761371661449e565b5b613723848285016132ba565b91505092915050565b600060208284031215613742576137416144a3565b5b60006137508482850161332b565b91505092915050565b600080604083850312156137705761376f6144a3565b5b600061377e8582860161332b565b925050602061378f85828601613249565b9150509250929050565b6000602082840312156137af576137ae6144a3565b5b60006137bd84828501613340565b91505092915050565b6000602082840312156137dc576137db6144a3565b5b60006137ea84828501613355565b91505092915050565b600060208284031215613809576138086144a3565b5b600082013567ffffffffffffffff8111156138275761382661449e565b5b61383384828501613398565b91505092915050565b600060208284031215613852576138516144a3565b5b6000613860848285016133c6565b91505092915050565b60006020828403121561387f5761387e6144a3565b5b600061388d848285016133db565b91505092915050565b61389f816141dc565b82525050565b6138b66138b1826141dc565b6143af565b82525050565b6138c5816141ee565b82525050565b6138d4816141fa565b82525050565b60006138e5826140af565b6138ef81856140c5565b93506138ff818560208601614279565b613908816144a8565b840191505092915050565b600061391e826140ba565b61392881856140d6565b9350613938818560208601614279565b613941816144a8565b840191505092915050565b6000613957826140ba565b61396181856140e7565b9350613971818560208601614279565b80840191505092915050565b6000815461398a816142d6565b61399481866140e7565b945060018216600081146139af57600181146139c0576139f3565b60ff198316865281860193506139f3565b6139c98561409a565b60005b838110156139eb578154818901526001820191506020810190506139cc565b838801955050505b50505092915050565b6000613a096020836140d6565b9150613a14826144c6565b602082019050919050565b6000613a2c6007836140d6565b9150613a37826144ef565b602082019050919050565b6000613a4f6012836140d6565b9150613a5a82614518565b602082019050919050565b6000613a72600e836140d6565b9150613a7d82614541565b602082019050919050565b6000613a95600c836140d6565b9150613aa08261456a565b602082019050919050565b6000613ab86014836140d6565b9150613ac382614593565b602082019050919050565b6000613adb6015836140d6565b9150613ae6826145bc565b602082019050919050565b6000613afe601d836140d6565b9150613b09826145e5565b602082019050919050565b6000613b216005836140e7565b9150613b2c8261460e565b600582019050919050565b6000613b44600e836140d6565b9150613b4f82614637565b602082019050919050565b6000613b676017836140d6565b9150613b7282614660565b602082019050919050565b6000613b8a6011836140d6565b9150613b9582614689565b602082019050919050565b6000613bad6017836140e7565b9150613bb8826146b2565b601782019050919050565b6000613bd06011836140d6565b9150613bdb826146db565b602082019050919050565b6000613bf36011836140e7565b9150613bfe82614704565b601182019050919050565b6000613c16602f836140d6565b9150613c218261472d565b604082019050919050565b613c3581614250565b82525050565b613c448161425a565b82525050565b6000613c5682846138a5565b60148201915081905092915050565b6000613c71828561397d565b9150613c7d828461394c565b9150613c8882613b14565b91508190509392505050565b6000613c9f82613ba0565b9150613cab828561394c565b9150613cb682613be6565b9150613cc2828461394c565b91508190509392505050565b6000602082019050613ce36000830184613896565b92915050565b6000608082019050613cfe6000830187613896565b613d0b6020830186613896565b613d186040830185613c2c565b8181036060830152613d2a81846138da565b905095945050505050565b6000602082019050613d4a60008301846138bc565b92915050565b6000602082019050613d6560008301846138cb565b92915050565b60006020820190508181036000830152613d858184613913565b905092915050565b60006020820190508181036000830152613da6816139fc565b9050919050565b60006020820190508181036000830152613dc681613a1f565b9050919050565b60006020820190508181036000830152613de681613a42565b9050919050565b60006020820190508181036000830152613e0681613a65565b9050919050565b60006020820190508181036000830152613e2681613a88565b9050919050565b60006020820190508181036000830152613e4681613aab565b9050919050565b60006020820190508181036000830152613e6681613ace565b9050919050565b60006020820190508181036000830152613e8681613af1565b9050919050565b60006020820190508181036000830152613ea681613b37565b9050919050565b60006020820190508181036000830152613ec681613b5a565b9050919050565b60006020820190508181036000830152613ee681613b7d565b9050919050565b60006020820190508181036000830152613f0681613bc3565b9050919050565b60006020820190508181036000830152613f2681613c09565b9050919050565b6000602082019050613f426000830184613c2c565b92915050565b6000602082019050613f5d6000830184613c3b565b92915050565b6000613f6d613f7e565b9050613f798282614308565b919050565b6000604051905090565b600067ffffffffffffffff821115613fa357613fa2614460565b5b602082029050602081019050919050565b600067ffffffffffffffff821115613fcf57613fce614460565b5b602082029050602081019050919050565b600067ffffffffffffffff821115613ffb57613ffa614460565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561402757614026614460565b5b602082029050602081019050919050565b600067ffffffffffffffff82111561405357614052614460565b5b61405c826144a8565b9050602081019050919050565b600067ffffffffffffffff82111561408457614083614460565b5b61408d826144a8565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006140fd82614250565b915061410883614250565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561413d5761413c6143d3565b5b828201905092915050565b60006141538261425a565b915061415e8361425a565b92508263ffffffff03821115614177576141766143d3565b5b828201905092915050565b600061418d82614250565b915061419883614250565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156141d1576141d06143d3565b5b828202905092915050565b60006141e782614230565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b82818337600083830152505050565b60005b8381101561429757808201518184015260208101905061427c565b838111156142a6576000848401525b50505050565b60006142b782614250565b915060008214156142cb576142ca6143d3565b5b600182039050919050565b600060028204905060018216806142ee57607f821691505b6020821081141561430257614301614402565b5b50919050565b614311826144a8565b810181811067ffffffffffffffff821117156143305761432f614460565b5b80604052505050565b600061434482614250565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614377576143766143d3565b5b600182019050919050565b600061438d8261425a565b915063ffffffff8214156143a4576143a36143d3565b5b600182019050919050565b60006143ba826143c1565b9050919050565b60006143cc826144b9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f4e6f7420454f4100000000000000000000000000000000000000000000000000600082015250565b7f457863656564206672656520616d6f756e740000000000000000000000000000600082015250565b7f416c72656164792072657665616c000000000000000000000000000000000000600082015250565b7f496e76616c6964206d696e740000000000000000000000000000000000000000600082015250565b7f457863656564207075626c696320616d6f756e74000000000000000000000000600082015250565b7f457863656564206d6178206672656520746f74616c0000000000000000000000600082015250565b7f457863656564206d617820616d6f756e7420706572206163636f756e74000000600082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f416c726561647920706175736564000000000000000000000000000000000000600082015250565b7f457863656564206d6178207075626c696320746f74616c000000000000000000600082015250565b7f457863656564206d617820616d6f756e74000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f496e656c696769626c652057616c6c6574000000000000000000000000000000600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b614785816141dc565b811461479057600080fd5b50565b61479c816141ee565b81146147a757600080fd5b50565b6147b3816141fa565b81146147be57600080fd5b50565b6147ca81614204565b81146147d557600080fd5b50565b6147e181614250565b81146147ec57600080fd5b50565b6147f88161425a565b811461480357600080fd5b5056fea26469706673582212204a8ca531c5fb07a8ac66e6d25cf97841eaa0620b954f454fa45ea37d0229f7a764736f6c63430008070033

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

0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000d41537472616e644f664861697200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000441534f4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005068747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d58557743694b72515662376a364b78693676376b3533345068386466363733386879534d437536524a774a6900000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): AStrandOfHair
Arg [1] : _symbol (string): ASOH
Arg [2] : _unrevealURI (string): https://gateway.pinata.cloud/ipfs/QmXUwCiKrQVb7j6Kxi6v7k534Ph8df6738hySMCu6RJwJi
Arg [3] : totalFree_ (uint32): 5000
Arg [4] : freeLimit_ (uint32): 1000
Arg [5] : totalPublic_ (uint32): 5000
Arg [6] : publicLimit_ (uint32): 5000
Arg [7] : maxAmountPerWalletInFree_ (uint32): 3
Arg [8] : maxAmountPerWalletInPublic_ (uint32): 2

-----Encoded View---------------
17 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [4] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [5] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [6] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [10] : 41537472616e644f664861697200000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [12] : 41534f4800000000000000000000000000000000000000000000000000000000
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000050
Arg [14] : 68747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066
Arg [15] : 732f516d58557743694b72515662376a364b78693676376b3533345068386466
Arg [16] : 363733386879534d437536524a774a6900000000000000000000000000000000


Deployed Bytecode Sourcemap

78145:7687:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84945:492;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44548:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51031:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50472:400;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40299:323;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83063:95;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54738:2817;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85540:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21365:131;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21806:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78410:42;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85445:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22950:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57651:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78823:38;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83606:224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83343:154;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83505:93;;;:::i;:::-;;83166:169;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45941:152;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78461:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41483:233;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81005:703;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83967:113;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81716:703;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82965:90;;;:::i;:::-;;19825:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84469:108;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44724:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18930:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51589:308;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85736:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80371:626;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78868:40;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78587:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58434:399;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83838:121;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78551:29;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84088:92;;;:::i;:::-;;84585:352;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78489:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85639:89;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22246:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52054:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78339:64;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82427:249;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78524:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84945:492;85082:4;85139:10;85124:25;;:11;:25;;;;:108;;;;85222:10;85207:25;;:11;:25;;;;85124:108;:185;;;;85299:10;85284:25;;:11;:25;;;;85124:185;:262;;;;85376:10;85361:25;;:11;:25;;;;85124:262;85104:282;;84945:492;;;:::o;44548:100::-;44602:13;44635:5;44628:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44548:100;:::o;51031:218::-;51107:7;51132:16;51140:7;51132;:16::i;:::-;51127:64;;51157:34;;;;;;;;;;;;;;51127:64;51211:15;:24;51227:7;51211:24;;;;;;;;;;;:30;;;;;;;;;;;;51204:37;;51031:218;;;:::o;50472:400::-;50553:13;50569:16;50577:7;50569;:16::i;:::-;50553:32;;50625:5;50602:28;;:19;:17;:19::i;:::-;:28;;;50598:175;;50650:44;50667:5;50674:19;:17;:19::i;:::-;50650:16;:44::i;:::-;50645:128;;50722:35;;;;;;;;;;;;;;50645:128;50598:175;50818:2;50785:15;:24;50801:7;50785:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;50856:7;50852:2;50836:28;;50845:5;50836:28;;;;;;;;;;;;50542:330;50472:400;;:::o;40299:323::-;40360:7;40588:15;:13;:15::i;:::-;40573:12;;40557:13;;:28;:46;40550:53;;40299:323;:::o;83063:95::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;83146:4:::1;83138:5;:12;;;;83063:95:::0;;:::o;54738:2817::-;54872:27;54902;54921:7;54902:18;:27::i;:::-;54872:57;;54987:4;54946:45;;54962:19;54946:45;;;54942:86;;55000:28;;;;;;;;;;;;;;54942:86;55042:27;55071:23;55098:35;55125:7;55098:26;:35::i;:::-;55041:92;;;;55233:68;55258:15;55275:4;55281:19;:17;:19::i;:::-;55233:24;:68::i;:::-;55228:180;;55321:43;55338:4;55344:19;:17;:19::i;:::-;55321:16;:43::i;:::-;55316:92;;55373:35;;;;;;;;;;;;;;55316:92;55228:180;55439:1;55425:16;;:2;:16;;;55421:52;;;55450:23;;;;;;;;;;;;;;55421:52;55486:43;55508:4;55514:2;55518:7;55527:1;55486:21;:43::i;:::-;55622:15;55619:160;;;55762:1;55741:19;55734:30;55619:160;56159:18;:24;56178:4;56159:24;;;;;;;;;;;;;;;;56157:26;;;;;;;;;;;;56228:18;:22;56247:2;56228:22;;;;;;;;;;;;;;;;56226:24;;;;;;;;;;;56550:146;56587:2;56636:45;56651:4;56657:2;56661:19;56636:14;:45::i;:::-;36698:8;56608:73;56550:18;:146::i;:::-;56521:17;:26;56539:7;56521:26;;;;;;;;;;;:175;;;;56867:1;36698:8;56816:19;:47;:52;56812:627;;;56889:19;56921:1;56911:7;:11;56889:33;;57078:1;57044:17;:30;57062:11;57044:30;;;;;;;;;;;;:35;57040:384;;;57182:13;;57167:11;:28;57163:242;;57362:19;57329:17;:30;57347:11;57329:30;;;;;;;;;;;:52;;;;57163:242;57040:384;56870:569;56812:627;57486:7;57482:2;57467:27;;57476:4;57467:27;;;;;;;;;;;;57505:42;57526:4;57532:2;57536:7;57545:1;57505:20;:42::i;:::-;54861:2694;;;54738:2817;;;:::o;85540:91::-;85584:7;85611:12;;;;;;;;;;;85604:19;;;;85540:91;:::o;21365:131::-;21439:7;21466:6;:12;21473:4;21466:12;;;;;;;;;;;:22;;;21459:29;;21365:131;;;:::o;21806:147::-;21889:18;21902:4;21889:12;:18::i;:::-;19421:16;19432:4;19421:10;:16::i;:::-;21920:25:::1;21931:4;21937:7;21920:10;:25::i;:::-;21806:147:::0;;;:::o;78410:42::-;78447:5;78410:42;:::o;85445:87::-;85487:7;85514:10;;;;;;;;;;;85507:17;;;;85445:87;:::o;22950:218::-;23057:12;:10;:12::i;:::-;23046:23;;:7;:23;;;23038:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;23134:26;23146:4;23152:7;23134:11;:26::i;:::-;22950:218;;:::o;57651:185::-;57789:39;57806:4;57812:2;57816:7;57789:39;;;;;;;;;;;;:16;:39::i;:::-;57651:185;;;:::o;78823:38::-;;;;;;;;;;;;;:::o;83606:224::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;83726:9:::1;83721:102;83745:8;:15;83741:1;:19;83721:102;;;83807:4;83782:9;:22;83792:8;83801:1;83792:11;;;;;;;;:::i;:::-;;;;;;;;83782:22;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;83762:3;;;;;:::i;:::-;;;;83721:102;;;;83606:224:::0;;:::o;83343:154::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;83476:13:::1;83461:12;:28;;;;;;;;;;;;:::i;:::-;;83343:154:::0;;:::o;83505:93::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;83582:8:::1;;;;;;;;;;;83581:9;83570:8;;:20;;;;;;;;;;;;;;;;;;83505:93:::0;:::o;83166:169::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;83293:8:::1;83283:7;:18;;;;;;;;;;;;:::i;:::-;;83323:4;83312:8;;:15;;;;;;;;;;;;;;;;;;83166:169:::0;;:::o;45941:152::-;46013:7;46056:27;46075:7;46056:18;:27::i;:::-;46033:52;;45941:152;;;:::o;78461:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;41483:233::-;41555:7;41596:1;41579:19;;:5;:19;;;41575:60;;;41607:28;;;;;;;;;;;;;;41575:60;35642:13;41653:18;:25;41672:5;41653:25;;;;;;;;;;;;;;;;:55;41646:62;;41483:233;;;:::o;81005:703::-;80040:10;80027:23;;:9;:23;;;80019:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;81098:8:::1;;;;;;;;;;;81097:9;81089:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;81144:10;;;;;;;;;;;81136:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;81191:8;;;;;;;;;;;81190:9;81182:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;81229:15;81247:12;:10;:12::i;:::-;81229:30;;81278:27;81290:5;81297:7;81278:11;:27::i;:::-;81270:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;81355:7;81340:11;;:22;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;81406:7;81373:40;;:20;:29;81394:7;81373:29;;;;;;;;;;;;;;;;:40;;;;;;;:::i;:::-;;;;;;;;81449:10;;;;;;;;;;;81434:25;;:11;;;;;;;;;;;:25;;;;81426:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;81551:24;;;;;;;;;;;81518:57;;:20;:29;81539:7;81518:29;;;;;;;;;;;;;;;;:57;;81496:124;;;;;;;;;;;;:::i;:::-;;;;;;;;;81633:23;81639:7;81648;81633:23;;:5;:23::i;:::-;81692:7;81674:26;;81683:7;81674:26;;;;;;;;;;;;81078:630;81005:703:::0;;:::o;83967:113::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;84062:10:::1;84049;;:23;;;;;;;;;;;;;;;;;;83967:113:::0;;:::o;81716:703::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;81846:14:::1;81882:9:::0;81877:253:::1;81901:8;:15;81897:1;:19;81877:253;;;81938:15;81956:8;81965:1;81956:11;;;;;;;;:::i;:::-;;;;;;;;81938:29;;81982:13;81998:7;82006:1;81998:10;;;;;;;;:::i;:::-;;;;;;;;81982:26;;82025:9;;;;;:::i;:::-;;;;82049:22;82055:7;82064:6;82049:22;;:5;:22::i;:::-;82111:6;82093:25;;82102:7;82093:25;;;;;;;;;;;;81923:207;;81918:3;;;;;:::i;:::-;;;;81877:253;;;;82146:10;;;;;;;;;;;82142:270;;;82188:7;82173:11;;:22;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;82233:10;;;;;;;;;;;82218:25;;:11;;;;;;;;;;;:25;;;;82210:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;82142:270;;;82316:7;82299:13;;:24;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;82363:12;;;;;;;;;;;82346:29;;:13;;;;;;;;;;;:29;;;;82338:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;82142:270;81835:584;81716:703:::0;;;:::o;82965:90::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;83042:5:::1;83029:10;;:18;;;;;;;;;;;;;;;;;;82965:90:::0;:::o;19825:147::-;19911:4;19935:6;:12;19942:4;19935:12;;;;;;;;;;;:20;;:29;19956:7;19935:29;;;;;;;;;;;;;;;;;;;;;;;;;19928:36;;19825:147;;;;:::o;84469:108::-;84527:4;84551:9;:18;84561:7;84551:18;;;;;;;;;;;;;;;;;;;;;84544:25;;84469:108;;;:::o;44724:104::-;44780:13;44813:7;44806:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44724:104;:::o;18930:49::-;18975:4;18930:49;;;:::o;51589:308::-;51700:19;:17;:19::i;:::-;51688:31;;:8;:31;;;51684:61;;;51728:17;;;;;;;;;;;;;;51684:61;51810:8;51758:18;:39;51777:19;:17;:19::i;:::-;51758:39;;;;;;;;;;;;;;;:49;51798:8;51758:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;51870:8;51834:55;;51849:19;:17;:19::i;:::-;51834:55;;;51880:8;51834:55;;;;;;:::i;:::-;;;;;;;;51589:308;;:::o;85736:93::-;85781:7;85808:13;;;;;;;;;;;85801:20;;;;85736:93;:::o;80371:626::-;80040:10;80027:23;;:9;:23;;;80019:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;80436:8:::1;;;;;;;;;;;80435:9;80427:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;80483:10;;;;;;;;;;;80482:11;80474:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;80530:8;;;;;;;;;;;80529:9;80521:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;80568:15;80586:12;:10;:12::i;:::-;80568:30;;80626:7;80609:13;;:24;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;80679:7;80644:42;;:22;:31;80667:7;80644:31;;;;;;;;;;;;;;;;:42;;;;;;;:::i;:::-;;;;;;;;80722:12;::::0;::::1;;;;;;;;80705:29;;:13;;;;;;;;;;;:29;;;;80697:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;80830:26;;;;;;;;;;;80795:61;;:22;:31;80818:7;80795:31;;;;;;;;;;;;;;;;:61;;80773:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;80926:23;80932:7;80941;80926:23;;:5;:23::i;:::-;80981:7;80967:22;;80972:7;80967:22;;;;;;;;;;;;80416:581;80371:626:::0;:::o;78868:40::-;;;;;;;;;;;;;:::o;78587:20::-;;;;;;;;;;;;;:::o;58434:399::-;58601:31;58614:4;58620:2;58624:7;58601:12;:31::i;:::-;58665:1;58647:2;:14;;;:19;58643:183;;58686:56;58717:4;58723:2;58727:7;58736:5;58686:30;:56::i;:::-;58681:145;;58770:40;;;;;;;;;;;;;;58681:145;58643:183;58434:399;;;;:::o;83838:121::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;83939:12:::1;83924;::::0;:27:::1;;;;;;;;;;;;;;;;;;83838:121:::0;;:::o;78551:29::-;;;;;;;;;;;;;:::o;84088:92::-;78378:25;19421:16;19432:4;19421:10;:16::i;:::-;84164:8:::1;;;;;;;;;;;84163:9;84152:8;;:20;;;;;;;;;;;;;;;;;;84088:92:::0;:::o;84585:352::-;84686:13;84722:16;84730:7;84722;:16::i;:::-;84717:59;;84747:29;;;;;;;;;;;;;;84717:59;84807:8;;;;;;;;;;;:122;;84917:12;84807:122;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84859:7;84868:18;84878:7;84868:9;:18::i;:::-;84842:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;84807:122;84787:142;;84585:352;;;:::o;78489:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;85639:89::-;85682:7;85709:11;;;;;;;;;;;85702:18;;;;85639:89;:::o;22246:149::-;22330:18;22343:4;22330:12;:18::i;:::-;19421:16;19432:4;19421:10;:16::i;:::-;22361:26:::1;22373:4;22379:7;22361:11;:26::i;:::-;22246:149:::0;;;:::o;52054:164::-;52151:4;52175:18;:25;52194:5;52175:25;;;;;;;;;;;;;;;:35;52201:8;52175:35;;;;;;;;;;;;;;;;;;;;;;;;;52168:42;;52054:164;;;;:::o;78339:64::-;78378:25;78339:64;:::o;82427:249::-;82538:4;82560:12;82602:7;82585:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;82575:36;;;;;;82560:51;;82629:39;82648:6;82656:5;;82663:4;82629:18;:39::i;:::-;82622:46;;;82427:249;;;;:::o;78524:20::-;;;;;;;;;;;;;:::o;52476:282::-;52541:4;52597:7;52578:15;:13;:15::i;:::-;:26;;:66;;;;;52631:13;;52621:7;:23;52578:66;:153;;;;;52730:1;36418:8;52682:17;:26;52700:7;52682:26;;;;;;;;;;;;:44;:49;52578:153;52558:173;;52476:282;;;:::o;74242:105::-;74302:7;74329:10;74322:17;;74242:105;:::o;39815:92::-;39871:7;39815:92;:::o;20276:105::-;20343:30;20354:4;20360:12;:10;:12::i;:::-;20343:10;:30::i;:::-;20276:105;:::o;47096:1275::-;47163:7;47183:12;47198:7;47183:22;;47266:4;47247:15;:13;:15::i;:::-;:23;47243:1061;;47300:13;;47293:4;:20;47289:1015;;;47338:14;47355:17;:23;47373:4;47355:23;;;;;;;;;;;;47338:40;;47472:1;36418:8;47444:6;:24;:29;47440:845;;;48109:113;48126:1;48116:6;:11;48109:113;;;48169:17;:25;48187:6;;;;;;;48169:25;;;;;;;;;;;;48160:34;;48109:113;;;48255:6;48248:13;;;;;;47440:845;47315:989;47289:1015;47243:1061;48332:31;;;;;;;;;;;;;;47096:1275;;;;:::o;53639:479::-;53741:27;53770:23;53811:38;53852:15;:24;53868:7;53852:24;;;;;;;;;;;53811:65;;54023:18;54000:41;;54080:19;54074:26;54055:45;;53985:126;53639:479;;;:::o;52867:659::-;53016:11;53181:16;53174:5;53170:28;53161:37;;53341:16;53330:9;53326:32;53313:45;;53491:15;53480:9;53477:30;53469:5;53458:9;53455:20;53452:56;53442:66;;52867:659;;;;;:::o;59495:159::-;;;;;:::o;73551:311::-;73686:7;73706:16;36822:3;73732:19;:41;;73706:68;;36822:3;73800:31;73811:4;73817:2;73821:9;73800:10;:31::i;:::-;73792:40;;:62;;73785:69;;;73551:311;;;;;:::o;48919:450::-;48999:14;49167:16;49160:5;49156:28;49147:37;;49344:5;49330:11;49305:23;49301:41;49298:52;49291:5;49288:63;49278:73;;48919:450;;;;:::o;60319:158::-;;;;;:::o;24547:238::-;24631:22;24639:4;24645:7;24631;:22::i;:::-;24626:152;;24702:4;24670:6;:12;24677:4;24670:12;;;;;;;;;;;:20;;:29;24691:7;24670:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;24753:12;:10;:12::i;:::-;24726:40;;24744:7;24726:40;;24738:4;24726:40;;;;;;;;;;24626:152;24547:238;;:::o;13747:98::-;13800:7;13827:10;13820:17;;13747:98;:::o;24965:239::-;25049:22;25057:4;25063:7;25049;:22::i;:::-;25045:152;;;25120:5;25088:6;:12;25095:4;25088:12;;;;;;;;;;;:20;;:29;25109:7;25088:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;25172:12;:10;:12::i;:::-;25145:40;;25163:7;25145:40;;25157:4;25145:40;;;;;;;;;;25045:152;24965:239;;:::o;62095:2454::-;62168:20;62191:13;;62168:36;;62231:1;62219:8;:13;62215:44;;;62241:18;;;;;;;;;;;;;;62215:44;62272:61;62302:1;62306:2;62310:12;62324:8;62272:21;:61::i;:::-;62816:1;35780:2;62786:1;:26;;62785:32;62773:8;:45;62747:18;:22;62766:2;62747:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;63095:139;63132:2;63186:33;63209:1;63213:2;63217:1;63186:14;:33::i;:::-;63153:30;63174:8;63153:20;:30::i;:::-;:66;63095:18;:139::i;:::-;63061:17;:31;63079:12;63061:31;;;;;;;;;;;:173;;;;63251:16;63282:11;63311:8;63296:12;:23;63282:37;;63566:16;63562:2;63558:25;63546:37;;63938:12;63898:8;63857:1;63795:25;63736:1;63675;63648:335;64063:1;64049:12;64045:20;64003:346;64104:3;64095:7;64092:16;64003:346;;64322:7;64312:8;64309:1;64282:25;64279:1;64276;64271:59;64157:1;64148:7;64144:15;64133:26;;64003:346;;;64007:77;64394:1;64382:8;:13;64378:45;;;64404:19;;;;;;;;;;;;;;64378:45;64456:3;64440:13;:19;;;;62521:1950;;64481:60;64510:1;64514:2;64518:12;64532:8;64481:20;:60::i;:::-;62157:2392;62095:2454;;:::o;60917:716::-;61080:4;61126:2;61101:45;;;61147:19;:17;:19::i;:::-;61168:4;61174:7;61183:5;61101:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;61097:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61401:1;61384:6;:13;:18;61380:235;;;61430:40;;;;;;;;;;;;;;61380:235;61573:6;61567:13;61558:6;61554:2;61550:15;61543:38;61097:529;61270:54;;;61260:64;;;:6;:64;;;;61253:71;;;60917:716;;;;;;:::o;74449:2002::-;74514:17;74933:3;74926:4;74920:11;74916:21;74909:28;;75024:3;75018:4;75011:17;75130:3;75586:5;75716:1;75711:3;75707:11;75700:18;;75887:2;75881:4;75877:13;75873:2;75869:22;75864:3;75856:36;75928:2;75922:4;75918:13;75910:21;;75478:731;75947:4;75478:731;;;76138:1;76133:3;76129:11;76122:18;;76189:2;76183:4;76179:13;76175:2;76171:22;76166:3;76158:36;76042:2;76036:4;76032:13;76024:21;;75478:731;;;75482:464;76248:3;76243;76239:13;76363:2;76358:3;76354:12;76347:19;;76426:6;76421:3;76414:19;74553:1891;;74449:2002;;;:::o;1219:190::-;1344:4;1397;1368:25;1381:5;1388:4;1368:12;:25::i;:::-;:33;1361:40;;1219:190;;;;;:::o;20671:505::-;20760:22;20768:4;20774:7;20760;:22::i;:::-;20755:414;;20948:41;20976:7;20948:41;;20986:2;20948:19;:41::i;:::-;21062:38;21090:4;21082:13;;21097:2;21062:19;:38::i;:::-;20853:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;20799:358;;;;;;;;;;;:::i;:::-;;;;;;;;20755:414;20671:505;;:::o;73252:147::-;73389:6;73252:147;;;;;:::o;49471:324::-;49541:14;49774:1;49764:8;49761:15;49735:24;49731:46;49721:56;;49471:324;;;:::o;2086:296::-;2169:7;2189:20;2212:4;2189:27;;2232:9;2227:118;2251:5;:12;2247:1;:16;2227:118;;;2300:33;2310:12;2324:5;2330:1;2324:8;;;;;;;;:::i;:::-;;;;;;;;2300:9;:33::i;:::-;2285:48;;2265:3;;;;;:::i;:::-;;;;2227:118;;;;2362:12;2355:19;;;2086:296;;;;:::o;12327:451::-;12402:13;12428:19;12473:1;12464:6;12460:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;12450:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12428:47;;12486:15;:6;12493:1;12486:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;12512;:6;12519:1;12512:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;12543:9;12568:1;12559:6;12555:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;12543:26;;12538:135;12575:1;12571;:5;12538:135;;;12610:12;12631:3;12623:5;:11;12610:25;;;;;;;:::i;:::-;;;;;12598:6;12605:1;12598:9;;;;;;;;:::i;:::-;;;;;:37;;;;;;;;;;;12660:1;12650:11;;;;;12578:3;;;;:::i;:::-;;;12538:135;;;;12700:1;12691:5;:10;12683:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;12763:6;12749:21;;;12327:451;;;;:::o;8293:149::-;8356:7;8387:1;8383;:5;:51;;8414:20;8429:1;8432;8414:14;:20::i;:::-;8383:51;;;8391:20;8406:1;8409;8391:14;:20::i;:::-;8383:51;8376:58;;8293:149;;;;:::o;8450:268::-;8518:13;8625:1;8619:4;8612:15;8654:1;8648:4;8641:15;8695:4;8689;8679:21;8670:30;;8450:268;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;24:722:1:-;120:5;145:81;161:64;218:6;161:64;:::i;:::-;145:81;:::i;:::-;136:90;;246:5;275:6;268:5;261:21;309:4;302:5;298:16;291:23;;335:6;385:3;377:4;369:6;365:17;360:3;356:27;353:36;350:143;;;404:79;;:::i;:::-;350:143;517:1;502:238;527:6;524:1;521:13;502:238;;;595:3;624:37;657:3;645:10;624:37;:::i;:::-;619:3;612:50;691:4;686:3;682:14;675:21;;725:4;720:3;716:14;709:21;;562:178;549:1;546;542:9;537:14;;502:238;;;506:14;126:620;;24:722;;;;;:::o;769:::-;865:5;890:81;906:64;963:6;906:64;:::i;:::-;890:81;:::i;:::-;881:90;;991:5;1020:6;1013:5;1006:21;1054:4;1047:5;1043:16;1036:23;;1080:6;1130:3;1122:4;1114:6;1110:17;1105:3;1101:27;1098:36;1095:143;;;1149:79;;:::i;:::-;1095:143;1262:1;1247:238;1272:6;1269:1;1266:13;1247:238;;;1340:3;1369:37;1402:3;1390:10;1369:37;:::i;:::-;1364:3;1357:50;1436:4;1431:3;1427:14;1420:21;;1470:4;1465:3;1461:14;1454:21;;1307:178;1294:1;1291;1287:9;1282:14;;1247:238;;;1251:14;871:620;;769:722;;;;;:::o;1514:::-;1610:5;1635:81;1651:64;1708:6;1651:64;:::i;:::-;1635:81;:::i;:::-;1626:90;;1736:5;1765:6;1758:5;1751:21;1799:4;1792:5;1788:16;1781:23;;1825:6;1875:3;1867:4;1859:6;1855:17;1850:3;1846:27;1843:36;1840:143;;;1894:79;;:::i;:::-;1840:143;2007:1;1992:238;2017:6;2014:1;2011:13;1992:238;;;2085:3;2114:37;2147:3;2135:10;2114:37;:::i;:::-;2109:3;2102:50;2181:4;2176:3;2172:14;2165:21;;2215:4;2210:3;2206:14;2199:21;;2052:178;2039:1;2036;2032:9;2027:14;;1992:238;;;1996:14;1616:620;;1514:722;;;;;:::o;2258:719::-;2353:5;2378:80;2394:63;2450:6;2394:63;:::i;:::-;2378:80;:::i;:::-;2369:89;;2478:5;2507:6;2500:5;2493:21;2541:4;2534:5;2530:16;2523:23;;2567:6;2617:3;2609:4;2601:6;2597:17;2592:3;2588:27;2585:36;2582:143;;;2636:79;;:::i;:::-;2582:143;2749:1;2734:237;2759:6;2756:1;2753:13;2734:237;;;2827:3;2856:36;2888:3;2876:10;2856:36;:::i;:::-;2851:3;2844:49;2922:4;2917:3;2913:14;2906:21;;2956:4;2951:3;2947:14;2940:21;;2794:177;2781:1;2778;2774:9;2769:14;;2734:237;;;2738:14;2359:618;;2258:719;;;;;:::o;2983:410::-;3060:5;3085:65;3101:48;3142:6;3101:48;:::i;:::-;3085:65;:::i;:::-;3076:74;;3173:6;3166:5;3159:21;3211:4;3204:5;3200:16;3249:3;3240:6;3235:3;3231:16;3228:25;3225:112;;;3256:79;;:::i;:::-;3225:112;3346:41;3380:6;3375:3;3370;3346:41;:::i;:::-;3066:327;2983:410;;;;;:::o;3399:412::-;3477:5;3502:66;3518:49;3560:6;3518:49;:::i;:::-;3502:66;:::i;:::-;3493:75;;3591:6;3584:5;3577:21;3629:4;3622:5;3618:16;3667:3;3658:6;3653:3;3649:16;3646:25;3643:112;;;3674:79;;:::i;:::-;3643:112;3764:41;3798:6;3793:3;3788;3764:41;:::i;:::-;3483:328;3399:412;;;;;:::o;3817:139::-;3863:5;3901:6;3888:20;3879:29;;3917:33;3944:5;3917:33;:::i;:::-;3817:139;;;;:::o;3979:370::-;4050:5;4099:3;4092:4;4084:6;4080:17;4076:27;4066:122;;4107:79;;:::i;:::-;4066:122;4224:6;4211:20;4249:94;4339:3;4331:6;4324:4;4316:6;4312:17;4249:94;:::i;:::-;4240:103;;4056:293;3979:370;;;;:::o;4372:::-;4443:5;4492:3;4485:4;4477:6;4473:17;4469:27;4459:122;;4500:79;;:::i;:::-;4459:122;4617:6;4604:20;4642:94;4732:3;4724:6;4717:4;4709:6;4705:17;4642:94;:::i;:::-;4633:103;;4449:293;4372:370;;;;:::o;4765:::-;4836:5;4885:3;4878:4;4870:6;4866:17;4862:27;4852:122;;4893:79;;:::i;:::-;4852:122;5010:6;4997:20;5035:94;5125:3;5117:6;5110:4;5102:6;5098:17;5035:94;:::i;:::-;5026:103;;4842:293;4765:370;;;;:::o;5157:368::-;5227:5;5276:3;5269:4;5261:6;5257:17;5253:27;5243:122;;5284:79;;:::i;:::-;5243:122;5401:6;5388:20;5426:93;5515:3;5507:6;5500:4;5492:6;5488:17;5426:93;:::i;:::-;5417:102;;5233:292;5157:368;;;;:::o;5531:133::-;5574:5;5612:6;5599:20;5590:29;;5628:30;5652:5;5628:30;:::i;:::-;5531:133;;;;:::o;5670:139::-;5716:5;5754:6;5741:20;5732:29;;5770:33;5797:5;5770:33;:::i;:::-;5670:139;;;;:::o;5815:137::-;5860:5;5898:6;5885:20;5876:29;;5914:32;5940:5;5914:32;:::i;:::-;5815:137;;;;:::o;5958:141::-;6014:5;6045:6;6039:13;6030:22;;6061:32;6087:5;6061:32;:::i;:::-;5958:141;;;;:::o;6118:338::-;6173:5;6222:3;6215:4;6207:6;6203:17;6199:27;6189:122;;6230:79;;:::i;:::-;6189:122;6347:6;6334:20;6372:78;6446:3;6438:6;6431:4;6423:6;6419:17;6372:78;:::i;:::-;6363:87;;6179:277;6118:338;;;;:::o;6476:340::-;6532:5;6581:3;6574:4;6566:6;6562:17;6558:27;6548:122;;6589:79;;:::i;:::-;6548:122;6706:6;6693:20;6731:79;6806:3;6798:6;6791:4;6783:6;6779:17;6731:79;:::i;:::-;6722:88;;6538:278;6476:340;;;;:::o;6822:139::-;6868:5;6906:6;6893:20;6884:29;;6922:33;6949:5;6922:33;:::i;:::-;6822:139;;;;:::o;6967:137::-;7012:5;7050:6;7037:20;7028:29;;7066:32;7092:5;7066:32;:::i;:::-;6967:137;;;;:::o;7110:329::-;7169:6;7218:2;7206:9;7197:7;7193:23;7189:32;7186:119;;;7224:79;;:::i;:::-;7186:119;7344:1;7369:53;7414:7;7405:6;7394:9;7390:22;7369:53;:::i;:::-;7359:63;;7315:117;7110:329;;;;:::o;7445:474::-;7513:6;7521;7570:2;7558:9;7549:7;7545:23;7541:32;7538:119;;;7576:79;;:::i;:::-;7538:119;7696:1;7721:53;7766:7;7757:6;7746:9;7742:22;7721:53;:::i;:::-;7711:63;;7667:117;7823:2;7849:53;7894:7;7885:6;7874:9;7870:22;7849:53;:::i;:::-;7839:63;;7794:118;7445:474;;;;;:::o;7925:619::-;8002:6;8010;8018;8067:2;8055:9;8046:7;8042:23;8038:32;8035:119;;;8073:79;;:::i;:::-;8035:119;8193:1;8218:53;8263:7;8254:6;8243:9;8239:22;8218:53;:::i;:::-;8208:63;;8164:117;8320:2;8346:53;8391:7;8382:6;8371:9;8367:22;8346:53;:::i;:::-;8336:63;;8291:118;8448:2;8474:53;8519:7;8510:6;8499:9;8495:22;8474:53;:::i;:::-;8464:63;;8419:118;7925:619;;;;;:::o;8550:943::-;8645:6;8653;8661;8669;8718:3;8706:9;8697:7;8693:23;8689:33;8686:120;;;8725:79;;:::i;:::-;8686:120;8845:1;8870:53;8915:7;8906:6;8895:9;8891:22;8870:53;:::i;:::-;8860:63;;8816:117;8972:2;8998:53;9043:7;9034:6;9023:9;9019:22;8998:53;:::i;:::-;8988:63;;8943:118;9100:2;9126:53;9171:7;9162:6;9151:9;9147:22;9126:53;:::i;:::-;9116:63;;9071:118;9256:2;9245:9;9241:18;9228:32;9287:18;9279:6;9276:30;9273:117;;;9309:79;;:::i;:::-;9273:117;9414:62;9468:7;9459:6;9448:9;9444:22;9414:62;:::i;:::-;9404:72;;9199:287;8550:943;;;;;;;:::o;9499:468::-;9564:6;9572;9621:2;9609:9;9600:7;9596:23;9592:32;9589:119;;;9627:79;;:::i;:::-;9589:119;9747:1;9772:53;9817:7;9808:6;9797:9;9793:22;9772:53;:::i;:::-;9762:63;;9718:117;9874:2;9900:50;9942:7;9933:6;9922:9;9918:22;9900:50;:::i;:::-;9890:60;;9845:115;9499:468;;;;;:::o;9973:474::-;10041:6;10049;10098:2;10086:9;10077:7;10073:23;10069:32;10066:119;;;10104:79;;:::i;:::-;10066:119;10224:1;10249:53;10294:7;10285:6;10274:9;10270:22;10249:53;:::i;:::-;10239:63;;10195:117;10351:2;10377:53;10422:7;10413:6;10402:9;10398:22;10377:53;:::i;:::-;10367:63;;10322:118;9973:474;;;;;:::o;10453:892::-;10570:6;10578;10627:2;10615:9;10606:7;10602:23;10598:32;10595:119;;;10633:79;;:::i;:::-;10595:119;10781:1;10770:9;10766:17;10753:31;10811:18;10803:6;10800:30;10797:117;;;10833:79;;:::i;:::-;10797:117;10938:78;11008:7;10999:6;10988:9;10984:22;10938:78;:::i;:::-;10928:88;;10724:302;11093:2;11082:9;11078:18;11065:32;11124:18;11116:6;11113:30;11110:117;;;11146:79;;:::i;:::-;11110:117;11251:77;11320:7;11311:6;11300:9;11296:22;11251:77;:::i;:::-;11241:87;;11036:302;10453:892;;;;;:::o;11351:684::-;11444:6;11452;11501:2;11489:9;11480:7;11476:23;11472:32;11469:119;;;11507:79;;:::i;:::-;11469:119;11655:1;11644:9;11640:17;11627:31;11685:18;11677:6;11674:30;11671:117;;;11707:79;;:::i;:::-;11671:117;11812:78;11882:7;11873:6;11862:9;11858:22;11812:78;:::i;:::-;11802:88;;11598:302;11939:2;11965:53;12010:7;12001:6;11990:9;11986:22;11965:53;:::i;:::-;11955:63;;11910:118;11351:684;;;;;:::o;12041:682::-;12133:6;12141;12190:2;12178:9;12169:7;12165:23;12161:32;12158:119;;;12196:79;;:::i;:::-;12158:119;12344:1;12333:9;12329:17;12316:31;12374:18;12366:6;12363:30;12360:117;;;12396:79;;:::i;:::-;12360:117;12501:78;12571:7;12562:6;12551:9;12547:22;12501:78;:::i;:::-;12491:88;;12287:302;12628:2;12654:52;12698:7;12689:6;12678:9;12674:22;12654:52;:::i;:::-;12644:62;;12599:117;12041:682;;;;;:::o;12729:539::-;12813:6;12862:2;12850:9;12841:7;12837:23;12833:32;12830:119;;;12868:79;;:::i;:::-;12830:119;13016:1;13005:9;13001:17;12988:31;13046:18;13038:6;13035:30;13032:117;;;13068:79;;:::i;:::-;13032:117;13173:78;13243:7;13234:6;13223:9;13219:22;13173:78;:::i;:::-;13163:88;;12959:302;12729:539;;;;:::o;13274:329::-;13333:6;13382:2;13370:9;13361:7;13357:23;13353:32;13350:119;;;13388:79;;:::i;:::-;13350:119;13508:1;13533:53;13578:7;13569:6;13558:9;13554:22;13533:53;:::i;:::-;13523:63;;13479:117;13274:329;;;;:::o;13609:474::-;13677:6;13685;13734:2;13722:9;13713:7;13709:23;13705:32;13702:119;;;13740:79;;:::i;:::-;13702:119;13860:1;13885:53;13930:7;13921:6;13910:9;13906:22;13885:53;:::i;:::-;13875:63;;13831:117;13987:2;14013:53;14058:7;14049:6;14038:9;14034:22;14013:53;:::i;:::-;14003:63;;13958:118;13609:474;;;;;:::o;14089:327::-;14147:6;14196:2;14184:9;14175:7;14171:23;14167:32;14164:119;;;14202:79;;:::i;:::-;14164:119;14322:1;14347:52;14391:7;14382:6;14371:9;14367:22;14347:52;:::i;:::-;14337:62;;14293:116;14089:327;;;;:::o;14422:349::-;14491:6;14540:2;14528:9;14519:7;14515:23;14511:32;14508:119;;;14546:79;;:::i;:::-;14508:119;14666:1;14691:63;14746:7;14737:6;14726:9;14722:22;14691:63;:::i;:::-;14681:73;;14637:127;14422:349;;;;:::o;14777:509::-;14846:6;14895:2;14883:9;14874:7;14870:23;14866:32;14863:119;;;14901:79;;:::i;:::-;14863:119;15049:1;15038:9;15034:17;15021:31;15079:18;15071:6;15068:30;15065:117;;;15101:79;;:::i;:::-;15065:117;15206:63;15261:7;15252:6;15241:9;15237:22;15206:63;:::i;:::-;15196:73;;14992:287;14777:509;;;;:::o;15292:329::-;15351:6;15400:2;15388:9;15379:7;15375:23;15371:32;15368:119;;;15406:79;;:::i;:::-;15368:119;15526:1;15551:53;15596:7;15587:6;15576:9;15572:22;15551:53;:::i;:::-;15541:63;;15497:117;15292:329;;;;:::o;15627:327::-;15685:6;15734:2;15722:9;15713:7;15709:23;15705:32;15702:119;;;15740:79;;:::i;:::-;15702:119;15860:1;15885:52;15929:7;15920:6;15909:9;15905:22;15885:52;:::i;:::-;15875:62;;15831:116;15627:327;;;;:::o;15960:118::-;16047:24;16065:5;16047:24;:::i;:::-;16042:3;16035:37;15960:118;;:::o;16084:157::-;16189:45;16209:24;16227:5;16209:24;:::i;:::-;16189:45;:::i;:::-;16184:3;16177:58;16084:157;;:::o;16247:109::-;16328:21;16343:5;16328:21;:::i;:::-;16323:3;16316:34;16247:109;;:::o;16362:118::-;16449:24;16467:5;16449:24;:::i;:::-;16444:3;16437:37;16362:118;;:::o;16486:360::-;16572:3;16600:38;16632:5;16600:38;:::i;:::-;16654:70;16717:6;16712:3;16654:70;:::i;:::-;16647:77;;16733:52;16778:6;16773:3;16766:4;16759:5;16755:16;16733:52;:::i;:::-;16810:29;16832:6;16810:29;:::i;:::-;16805:3;16801:39;16794:46;;16576:270;16486:360;;;;:::o;16852:364::-;16940:3;16968:39;17001:5;16968:39;:::i;:::-;17023:71;17087:6;17082:3;17023:71;:::i;:::-;17016:78;;17103:52;17148:6;17143:3;17136:4;17129:5;17125:16;17103:52;:::i;:::-;17180:29;17202:6;17180:29;:::i;:::-;17175:3;17171:39;17164:46;;16944:272;16852:364;;;;:::o;17222:377::-;17328:3;17356:39;17389:5;17356:39;:::i;:::-;17411:89;17493:6;17488:3;17411:89;:::i;:::-;17404:96;;17509:52;17554:6;17549:3;17542:4;17535:5;17531:16;17509:52;:::i;:::-;17586:6;17581:3;17577:16;17570:23;;17332:267;17222:377;;;;:::o;17629:845::-;17732:3;17769:5;17763:12;17798:36;17824:9;17798:36;:::i;:::-;17850:89;17932:6;17927:3;17850:89;:::i;:::-;17843:96;;17970:1;17959:9;17955:17;17986:1;17981:137;;;;18132:1;18127:341;;;;17948:520;;17981:137;18065:4;18061:9;18050;18046:25;18041:3;18034:38;18101:6;18096:3;18092:16;18085:23;;17981:137;;18127:341;18194:38;18226:5;18194:38;:::i;:::-;18254:1;18268:154;18282:6;18279:1;18276:13;18268:154;;;18356:7;18350:14;18346:1;18341:3;18337:11;18330:35;18406:1;18397:7;18393:15;18382:26;;18304:4;18301:1;18297:12;18292:17;;18268:154;;;18451:6;18446:3;18442:16;18435:23;;18134:334;;17948:520;;17736:738;;17629:845;;;;:::o;18480:366::-;18622:3;18643:67;18707:2;18702:3;18643:67;:::i;:::-;18636:74;;18719:93;18808:3;18719:93;:::i;:::-;18837:2;18832:3;18828:12;18821:19;;18480:366;;;:::o;18852:365::-;18994:3;19015:66;19079:1;19074:3;19015:66;:::i;:::-;19008:73;;19090:93;19179:3;19090:93;:::i;:::-;19208:2;19203:3;19199:12;19192:19;;18852:365;;;:::o;19223:366::-;19365:3;19386:67;19450:2;19445:3;19386:67;:::i;:::-;19379:74;;19462:93;19551:3;19462:93;:::i;:::-;19580:2;19575:3;19571:12;19564:19;;19223:366;;;:::o;19595:::-;19737:3;19758:67;19822:2;19817:3;19758:67;:::i;:::-;19751:74;;19834:93;19923:3;19834:93;:::i;:::-;19952:2;19947:3;19943:12;19936:19;;19595:366;;;:::o;19967:::-;20109:3;20130:67;20194:2;20189:3;20130:67;:::i;:::-;20123:74;;20206:93;20295:3;20206:93;:::i;:::-;20324:2;20319:3;20315:12;20308:19;;19967:366;;;:::o;20339:::-;20481:3;20502:67;20566:2;20561:3;20502:67;:::i;:::-;20495:74;;20578:93;20667:3;20578:93;:::i;:::-;20696:2;20691:3;20687:12;20680:19;;20339:366;;;:::o;20711:::-;20853:3;20874:67;20938:2;20933:3;20874:67;:::i;:::-;20867:74;;20950:93;21039:3;20950:93;:::i;:::-;21068:2;21063:3;21059:12;21052:19;;20711:366;;;:::o;21083:::-;21225:3;21246:67;21310:2;21305:3;21246:67;:::i;:::-;21239:74;;21322:93;21411:3;21322:93;:::i;:::-;21440:2;21435:3;21431:12;21424:19;;21083:366;;;:::o;21455:400::-;21615:3;21636:84;21718:1;21713:3;21636:84;:::i;:::-;21629:91;;21729:93;21818:3;21729:93;:::i;:::-;21847:1;21842:3;21838:11;21831:18;;21455:400;;;:::o;21861:366::-;22003:3;22024:67;22088:2;22083:3;22024:67;:::i;:::-;22017:74;;22100:93;22189:3;22100:93;:::i;:::-;22218:2;22213:3;22209:12;22202:19;;21861:366;;;:::o;22233:::-;22375:3;22396:67;22460:2;22455:3;22396:67;:::i;:::-;22389:74;;22472:93;22561:3;22472:93;:::i;:::-;22590:2;22585:3;22581:12;22574:19;;22233:366;;;:::o;22605:::-;22747:3;22768:67;22832:2;22827:3;22768:67;:::i;:::-;22761:74;;22844:93;22933:3;22844:93;:::i;:::-;22962:2;22957:3;22953:12;22946:19;;22605:366;;;:::o;22977:402::-;23137:3;23158:85;23240:2;23235:3;23158:85;:::i;:::-;23151:92;;23252:93;23341:3;23252:93;:::i;:::-;23370:2;23365:3;23361:12;23354:19;;22977:402;;;:::o;23385:366::-;23527:3;23548:67;23612:2;23607:3;23548:67;:::i;:::-;23541:74;;23624:93;23713:3;23624:93;:::i;:::-;23742:2;23737:3;23733:12;23726:19;;23385:366;;;:::o;23757:402::-;23917:3;23938:85;24020:2;24015:3;23938:85;:::i;:::-;23931:92;;24032:93;24121:3;24032:93;:::i;:::-;24150:2;24145:3;24141:12;24134:19;;23757:402;;;:::o;24165:366::-;24307:3;24328:67;24392:2;24387:3;24328:67;:::i;:::-;24321:74;;24404:93;24493:3;24404:93;:::i;:::-;24522:2;24517:3;24513:12;24506:19;;24165:366;;;:::o;24537:118::-;24624:24;24642:5;24624:24;:::i;:::-;24619:3;24612:37;24537:118;;:::o;24661:115::-;24746:23;24763:5;24746:23;:::i;:::-;24741:3;24734:36;24661:115;;:::o;24782:256::-;24894:3;24909:75;24980:3;24971:6;24909:75;:::i;:::-;25009:2;25004:3;25000:12;24993:19;;25029:3;25022:10;;24782:256;;;;:::o;25044:695::-;25322:3;25344:92;25432:3;25423:6;25344:92;:::i;:::-;25337:99;;25453:95;25544:3;25535:6;25453:95;:::i;:::-;25446:102;;25565:148;25709:3;25565:148;:::i;:::-;25558:155;;25730:3;25723:10;;25044:695;;;;;:::o;25745:967::-;26127:3;26149:148;26293:3;26149:148;:::i;:::-;26142:155;;26314:95;26405:3;26396:6;26314:95;:::i;:::-;26307:102;;26426:148;26570:3;26426:148;:::i;:::-;26419:155;;26591:95;26682:3;26673:6;26591:95;:::i;:::-;26584:102;;26703:3;26696:10;;25745:967;;;;;:::o;26718:222::-;26811:4;26849:2;26838:9;26834:18;26826:26;;26862:71;26930:1;26919:9;26915:17;26906:6;26862:71;:::i;:::-;26718:222;;;;:::o;26946:640::-;27141:4;27179:3;27168:9;27164:19;27156:27;;27193:71;27261:1;27250:9;27246:17;27237:6;27193:71;:::i;:::-;27274:72;27342:2;27331:9;27327:18;27318:6;27274:72;:::i;:::-;27356;27424:2;27413:9;27409:18;27400:6;27356:72;:::i;:::-;27475:9;27469:4;27465:20;27460:2;27449:9;27445:18;27438:48;27503:76;27574:4;27565:6;27503:76;:::i;:::-;27495:84;;26946:640;;;;;;;:::o;27592:210::-;27679:4;27717:2;27706:9;27702:18;27694:26;;27730:65;27792:1;27781:9;27777:17;27768:6;27730:65;:::i;:::-;27592:210;;;;:::o;27808:222::-;27901:4;27939:2;27928:9;27924:18;27916:26;;27952:71;28020:1;28009:9;28005:17;27996:6;27952:71;:::i;:::-;27808:222;;;;:::o;28036:313::-;28149:4;28187:2;28176:9;28172:18;28164:26;;28236:9;28230:4;28226:20;28222:1;28211:9;28207:17;28200:47;28264:78;28337:4;28328:6;28264:78;:::i;:::-;28256:86;;28036:313;;;;:::o;28355:419::-;28521:4;28559:2;28548:9;28544:18;28536:26;;28608:9;28602:4;28598:20;28594:1;28583:9;28579:17;28572:47;28636:131;28762:4;28636:131;:::i;:::-;28628:139;;28355:419;;;:::o;28780:::-;28946:4;28984:2;28973:9;28969:18;28961:26;;29033:9;29027:4;29023:20;29019:1;29008:9;29004:17;28997:47;29061:131;29187:4;29061:131;:::i;:::-;29053:139;;28780:419;;;:::o;29205:::-;29371:4;29409:2;29398:9;29394:18;29386:26;;29458:9;29452:4;29448:20;29444:1;29433:9;29429:17;29422:47;29486:131;29612:4;29486:131;:::i;:::-;29478:139;;29205:419;;;:::o;29630:::-;29796:4;29834:2;29823:9;29819:18;29811:26;;29883:9;29877:4;29873:20;29869:1;29858:9;29854:17;29847:47;29911:131;30037:4;29911:131;:::i;:::-;29903:139;;29630:419;;;:::o;30055:::-;30221:4;30259:2;30248:9;30244:18;30236:26;;30308:9;30302:4;30298:20;30294:1;30283:9;30279:17;30272:47;30336:131;30462:4;30336:131;:::i;:::-;30328:139;;30055:419;;;:::o;30480:::-;30646:4;30684:2;30673:9;30669:18;30661:26;;30733:9;30727:4;30723:20;30719:1;30708:9;30704:17;30697:47;30761:131;30887:4;30761:131;:::i;:::-;30753:139;;30480:419;;;:::o;30905:::-;31071:4;31109:2;31098:9;31094:18;31086:26;;31158:9;31152:4;31148:20;31144:1;31133:9;31129:17;31122:47;31186:131;31312:4;31186:131;:::i;:::-;31178:139;;30905:419;;;:::o;31330:::-;31496:4;31534:2;31523:9;31519:18;31511:26;;31583:9;31577:4;31573:20;31569:1;31558:9;31554:17;31547:47;31611:131;31737:4;31611:131;:::i;:::-;31603:139;;31330:419;;;:::o;31755:::-;31921:4;31959:2;31948:9;31944:18;31936:26;;32008:9;32002:4;31998:20;31994:1;31983:9;31979:17;31972:47;32036:131;32162:4;32036:131;:::i;:::-;32028:139;;31755:419;;;:::o;32180:::-;32346:4;32384:2;32373:9;32369:18;32361:26;;32433:9;32427:4;32423:20;32419:1;32408:9;32404:17;32397:47;32461:131;32587:4;32461:131;:::i;:::-;32453:139;;32180:419;;;:::o;32605:::-;32771:4;32809:2;32798:9;32794:18;32786:26;;32858:9;32852:4;32848:20;32844:1;32833:9;32829:17;32822:47;32886:131;33012:4;32886:131;:::i;:::-;32878:139;;32605:419;;;:::o;33030:::-;33196:4;33234:2;33223:9;33219:18;33211:26;;33283:9;33277:4;33273:20;33269:1;33258:9;33254:17;33247:47;33311:131;33437:4;33311:131;:::i;:::-;33303:139;;33030:419;;;:::o;33455:::-;33621:4;33659:2;33648:9;33644:18;33636:26;;33708:9;33702:4;33698:20;33694:1;33683:9;33679:17;33672:47;33736:131;33862:4;33736:131;:::i;:::-;33728:139;;33455:419;;;:::o;33880:222::-;33973:4;34011:2;34000:9;33996:18;33988:26;;34024:71;34092:1;34081:9;34077:17;34068:6;34024:71;:::i;:::-;33880:222;;;;:::o;34108:218::-;34199:4;34237:2;34226:9;34222:18;34214:26;;34250:69;34316:1;34305:9;34301:17;34292:6;34250:69;:::i;:::-;34108:218;;;;:::o;34332:129::-;34366:6;34393:20;;:::i;:::-;34383:30;;34422:33;34450:4;34442:6;34422:33;:::i;:::-;34332:129;;;:::o;34467:75::-;34500:6;34533:2;34527:9;34517:19;;34467:75;:::o;34548:311::-;34625:4;34715:18;34707:6;34704:30;34701:56;;;34737:18;;:::i;:::-;34701:56;34787:4;34779:6;34775:17;34767:25;;34847:4;34841;34837:15;34829:23;;34548:311;;;:::o;34865:::-;34942:4;35032:18;35024:6;35021:30;35018:56;;;35054:18;;:::i;:::-;35018:56;35104:4;35096:6;35092:17;35084:25;;35164:4;35158;35154:15;35146:23;;34865:311;;;:::o;35182:::-;35259:4;35349:18;35341:6;35338:30;35335:56;;;35371:18;;:::i;:::-;35335:56;35421:4;35413:6;35409:17;35401:25;;35481:4;35475;35471:15;35463:23;;35182:311;;;:::o;35499:310::-;35575:4;35665:18;35657:6;35654:30;35651:56;;;35687:18;;:::i;:::-;35651:56;35737:4;35729:6;35725:17;35717:25;;35797:4;35791;35787:15;35779:23;;35499:310;;;:::o;35815:307::-;35876:4;35966:18;35958:6;35955:30;35952:56;;;35988:18;;:::i;:::-;35952:56;36026:29;36048:6;36026:29;:::i;:::-;36018:37;;36110:4;36104;36100:15;36092:23;;35815:307;;;:::o;36128:308::-;36190:4;36280:18;36272:6;36269:30;36266:56;;;36302:18;;:::i;:::-;36266:56;36340:29;36362:6;36340:29;:::i;:::-;36332:37;;36424:4;36418;36414:15;36406:23;;36128:308;;;:::o;36442:141::-;36491:4;36514:3;36506:11;;36537:3;36534:1;36527:14;36571:4;36568:1;36558:18;36550:26;;36442:141;;;:::o;36589:98::-;36640:6;36674:5;36668:12;36658:22;;36589:98;;;:::o;36693:99::-;36745:6;36779:5;36773:12;36763:22;;36693:99;;;:::o;36798:168::-;36881:11;36915:6;36910:3;36903:19;36955:4;36950:3;36946:14;36931:29;;36798:168;;;;:::o;36972:169::-;37056:11;37090:6;37085:3;37078:19;37130:4;37125:3;37121:14;37106:29;;36972:169;;;;:::o;37147:148::-;37249:11;37286:3;37271:18;;37147:148;;;;:::o;37301:305::-;37341:3;37360:20;37378:1;37360:20;:::i;:::-;37355:25;;37394:20;37412:1;37394:20;:::i;:::-;37389:25;;37548:1;37480:66;37476:74;37473:1;37470:81;37467:107;;;37554:18;;:::i;:::-;37467:107;37598:1;37595;37591:9;37584:16;;37301:305;;;;:::o;37612:246::-;37651:3;37670:19;37687:1;37670:19;:::i;:::-;37665:24;;37703:19;37720:1;37703:19;:::i;:::-;37698:24;;37800:1;37788:10;37784:18;37781:1;37778:25;37775:51;;;37806:18;;:::i;:::-;37775:51;37850:1;37847;37843:9;37836:16;;37612:246;;;;:::o;37864:348::-;37904:7;37927:20;37945:1;37927:20;:::i;:::-;37922:25;;37961:20;37979:1;37961:20;:::i;:::-;37956:25;;38149:1;38081:66;38077:74;38074:1;38071:81;38066:1;38059:9;38052:17;38048:105;38045:131;;;38156:18;;:::i;:::-;38045:131;38204:1;38201;38197:9;38186:20;;37864:348;;;;:::o;38218:96::-;38255:7;38284:24;38302:5;38284:24;:::i;:::-;38273:35;;38218:96;;;:::o;38320:90::-;38354:7;38397:5;38390:13;38383:21;38372:32;;38320:90;;;:::o;38416:77::-;38453:7;38482:5;38471:16;;38416:77;;;:::o;38499:149::-;38535:7;38575:66;38568:5;38564:78;38553:89;;38499:149;;;:::o;38654:126::-;38691:7;38731:42;38724:5;38720:54;38709:65;;38654:126;;;:::o;38786:77::-;38823:7;38852:5;38841:16;;38786:77;;;:::o;38869:93::-;38905:7;38945:10;38938:5;38934:22;38923:33;;38869:93;;;:::o;38968:154::-;39052:6;39047:3;39042;39029:30;39114:1;39105:6;39100:3;39096:16;39089:27;38968:154;;;:::o;39128:307::-;39196:1;39206:113;39220:6;39217:1;39214:13;39206:113;;;39305:1;39300:3;39296:11;39290:18;39286:1;39281:3;39277:11;39270:39;39242:2;39239:1;39235:10;39230:15;;39206:113;;;39337:6;39334:1;39331:13;39328:101;;;39417:1;39408:6;39403:3;39399:16;39392:27;39328:101;39177:258;39128:307;;;:::o;39441:171::-;39480:3;39503:24;39521:5;39503:24;:::i;:::-;39494:33;;39549:4;39542:5;39539:15;39536:41;;;39557:18;;:::i;:::-;39536:41;39604:1;39597:5;39593:13;39586:20;;39441:171;;;:::o;39618:320::-;39662:6;39699:1;39693:4;39689:12;39679:22;;39746:1;39740:4;39736:12;39767:18;39757:81;;39823:4;39815:6;39811:17;39801:27;;39757:81;39885:2;39877:6;39874:14;39854:18;39851:38;39848:84;;;39904:18;;:::i;:::-;39848:84;39669:269;39618:320;;;:::o;39944:281::-;40027:27;40049:4;40027:27;:::i;:::-;40019:6;40015:40;40157:6;40145:10;40142:22;40121:18;40109:10;40106:34;40103:62;40100:88;;;40168:18;;:::i;:::-;40100:88;40208:10;40204:2;40197:22;39987:238;39944:281;;:::o;40231:233::-;40270:3;40293:24;40311:5;40293:24;:::i;:::-;40284:33;;40339:66;40332:5;40329:77;40326:103;;;40409:18;;:::i;:::-;40326:103;40456:1;40449:5;40445:13;40438:20;;40231:233;;;:::o;40470:175::-;40508:3;40531:23;40548:5;40531:23;:::i;:::-;40522:32;;40576:10;40569:5;40566:21;40563:47;;;40590:18;;:::i;:::-;40563:47;40637:1;40630:5;40626:13;40619:20;;40470:175;;;:::o;40651:100::-;40690:7;40719:26;40739:5;40719:26;:::i;:::-;40708:37;;40651:100;;;:::o;40757:94::-;40796:7;40825:20;40839:5;40825:20;:::i;:::-;40814:31;;40757:94;;;:::o;40857:180::-;40905:77;40902:1;40895:88;41002:4;40999:1;40992:15;41026:4;41023:1;41016:15;41043:180;41091:77;41088:1;41081:88;41188:4;41185:1;41178:15;41212:4;41209:1;41202:15;41229:180;41277:77;41274:1;41267:88;41374:4;41371:1;41364:15;41398:4;41395:1;41388:15;41415:180;41463:77;41460:1;41453:88;41560:4;41557:1;41550:15;41584:4;41581:1;41574:15;41601:117;41710:1;41707;41700:12;41724:117;41833:1;41830;41823:12;41847:117;41956:1;41953;41946:12;41970:117;42079:1;42076;42069:12;42093:117;42202:1;42199;42192:12;42216:102;42257:6;42308:2;42304:7;42299:2;42292:5;42288:14;42284:28;42274:38;;42216:102;;;:::o;42324:94::-;42357:8;42405:5;42401:2;42397:14;42376:35;;42324:94;;;:::o;42424:182::-;42564:34;42560:1;42552:6;42548:14;42541:58;42424:182;:::o;42612:157::-;42752:9;42748:1;42740:6;42736:14;42729:33;42612:157;:::o;42775:168::-;42915:20;42911:1;42903:6;42899:14;42892:44;42775:168;:::o;42949:164::-;43089:16;43085:1;43077:6;43073:14;43066:40;42949:164;:::o;43119:162::-;43259:14;43255:1;43247:6;43243:14;43236:38;43119:162;:::o;43287:170::-;43427:22;43423:1;43415:6;43411:14;43404:46;43287:170;:::o;43463:171::-;43603:23;43599:1;43591:6;43587:14;43580:47;43463:171;:::o;43640:179::-;43780:31;43776:1;43768:6;43764:14;43757:55;43640:179;:::o;43825:155::-;43965:7;43961:1;43953:6;43949:14;43942:31;43825:155;:::o;43986:164::-;44126:16;44122:1;44114:6;44110:14;44103:40;43986:164;:::o;44156:173::-;44296:25;44292:1;44284:6;44280:14;44273:49;44156:173;:::o;44335:167::-;44475:19;44471:1;44463:6;44459:14;44452:43;44335:167;:::o;44508:173::-;44648:25;44644:1;44636:6;44632:14;44625:49;44508:173;:::o;44687:167::-;44827:19;44823:1;44815:6;44811:14;44804:43;44687:167;:::o;44860:::-;45000:19;44996:1;44988:6;44984:14;44977:43;44860:167;:::o;45033:234::-;45173:34;45169:1;45161:6;45157:14;45150:58;45242:17;45237:2;45229:6;45225:15;45218:42;45033:234;:::o;45273:122::-;45346:24;45364:5;45346:24;:::i;:::-;45339:5;45336:35;45326:63;;45385:1;45382;45375:12;45326:63;45273:122;:::o;45401:116::-;45471:21;45486:5;45471:21;:::i;:::-;45464:5;45461:32;45451:60;;45507:1;45504;45497:12;45451:60;45401:116;:::o;45523:122::-;45596:24;45614:5;45596:24;:::i;:::-;45589:5;45586:35;45576:63;;45635:1;45632;45625:12;45576:63;45523:122;:::o;45651:120::-;45723:23;45740:5;45723:23;:::i;:::-;45716:5;45713:34;45703:62;;45761:1;45758;45751:12;45703:62;45651:120;:::o;45777:122::-;45850:24;45868:5;45850:24;:::i;:::-;45843:5;45840:35;45830:63;;45889:1;45886;45879:12;45830:63;45777:122;:::o;45905:120::-;45977:23;45994:5;45977:23;:::i;:::-;45970:5;45967:34;45957:62;;46015:1;46012;46005:12;45957:62;45905:120;:::o

Swarm Source

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