ETH Price: $3,344.26 (+0.29%)

Token

KUNLER (KUNLER)
 

Overview

Max Total Supply

9,001 KUNLER

Holders

1,831

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
5 KUNLER
0x6673086e80746874244f8ff82f5d4345f545d9c2
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
NFT

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-09-19
*/

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


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

pragma solidity ^0.8.0;

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


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

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 *  Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.
 *  See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 *  In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

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


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

pragma solidity ^0.8.0;

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


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/IERC721A.sol


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom}
     * whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

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

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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/ERC721A.sol


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

pragma solidity ^0.8.4;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId].value;
    }

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

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

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

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

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

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

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

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

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

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/extensions/IERC721AQueryable.sol


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

pragma solidity ^0.8.4;


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

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

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

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

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

// File: erc721a/contracts/extensions/ERC721AQueryable.sol


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

pragma solidity ^0.8.4;



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

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

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

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

// File: contracts/nft.sol



pragma solidity >=0.8.9 <0.9.0;







contract NFT is ERC721AQueryable, Ownable, ReentrancyGuard {
  string public uriPrefix = "";
  string public uriSuffix = "";
  string public uriOrigin = "";
  
  uint256 public cost;
  uint256 public maxSupply;
  uint256 public maxMintAmountPerTx;
  uint256 public publicSupply = 0;
  mapping(address => uint256) private mintCount;

  bool public paused = true;

  constructor(
  ) ERC721A("KUNLER", "KUNLER") {
    setCost(0);
    maxSupply = 10000;
    setMaxMintAmountPerTx(5);
    setUriOrigin("ipfs://bafybeifzc7a4qbfvtjojkop3v7mxzjru2uquk64o7zgzmqtzt5lshszk7i");
  }
  
  modifier mintCompliance(uint256 _mintAmount) {
    require(_mintAmount > 0 && _mintAmount <= maxMintAmountPerTx, "Invalid mint amount!");
    require(totalSupply() + _mintAmount <= maxSupply, "Max supply exceeded!");
    require(publicSupply + _mintAmount <= maxSupply - 1000, "Max supply exceeded!");
    _;
  }

  function mint(uint256 _mintAmount) public mintCompliance(_mintAmount) {
    require(!paused, "The contract is paused!");
    require(mintCount[_msgSender()] + _mintAmount <= 5, "Over minted!");
    _safeMint(_msgSender(), _mintAmount);
    mintCount[_msgSender()] += _mintAmount;
    publicSupply += _mintAmount;
  }
  
  function mintForAddress(uint256 _mintAmount, address _receiver) public onlyOwner {
    require(_mintAmount > 0, "Invalid mint amount!");
    require(totalSupply() + _mintAmount <= maxSupply, "Max supply exceeded!");
    _safeMint(_receiver, _mintAmount);
  }

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

    string memory currentBaseURI = _baseURI();
    return bytes(currentBaseURI).length > 0
        ? string(abi.encodePacked(currentBaseURI, Strings.toString(_tokenId), uriSuffix))
        : string(uriOrigin);
  }


  function setCost(uint256 _cost) public onlyOwner {
    cost = _cost;
  }

  function setMaxMintAmountPerTx(uint256 _maxMintAmountPerTx) public onlyOwner {
    maxMintAmountPerTx = _maxMintAmountPerTx;
  }

  function setUriOrigin(string memory _uriOrigin) public onlyOwner {
    uriOrigin = _uriOrigin;
  }

  function setUriPrefix(string memory _uriPrefix) public onlyOwner {
    uriPrefix = _uriPrefix;
  }

  function setUriSuffix(string memory _uriSuffix) public onlyOwner {
    uriSuffix = _uriSuffix;
  }

  function setPaused(bool _state) public onlyOwner {
    paused = _state;
  }

  function withdraw() public onlyOwner nonReentrant {
    (bool os, ) = payable(owner()).call{value: address(this).balance}("");
    require(os);
  }

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":"maxMintAmountPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"mintForAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMintAmountPerTx","type":"uint256"}],"name":"setMaxMintAmountPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriOrigin","type":"string"}],"name":"setUriOrigin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriPrefix","type":"string"}],"name":"setUriPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriSuffix","type":"string"}],"name":"setUriSuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriOrigin","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriSuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260405180602001604052806000815250600a908162000024919062000623565b5060405180602001604052806000815250600b908162000045919062000623565b5060405180602001604052806000815250600c908162000066919062000623565b5060006010556001601260006101000a81548160ff0219169083151502179055503480156200009457600080fd5b506040518060400160405280600681526020017f4b554e4c455200000000000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f4b554e4c45520000000000000000000000000000000000000000000000000000815250816002908162000112919062000623565b50806003908162000124919062000623565b5062000135620001c260201b60201c565b60008190555050506200015d62000151620001c760201b60201c565b620001cf60201b60201c565b60016009819055506200017760006200029560201b60201c565b612710600e81905550620001926005620002af60201b60201c565b620001bc604051806080016040528060428152602001620046bf60429139620002c960201b60201c565b6200078d565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620002a5620002ee60201b60201c565b80600d8190555050565b620002bf620002ee60201b60201c565b80600f8190555050565b620002d9620002ee60201b60201c565b80600c9081620002ea919062000623565b5050565b620002fe620001c760201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620003246200037f60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16146200037d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000374906200076b565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200042b57607f821691505b602082108103620004415762000440620003e3565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004ab7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200046c565b620004b786836200046c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000504620004fe620004f884620004cf565b620004d9565b620004cf565b9050919050565b6000819050919050565b6200052083620004e3565b620005386200052f826200050b565b84845462000479565b825550505050565b600090565b6200054f62000540565b6200055c81848462000515565b505050565b5b8181101562000584576200057860008262000545565b60018101905062000562565b5050565b601f821115620005d3576200059d8162000447565b620005a8846200045c565b81016020851015620005b8578190505b620005d0620005c7856200045c565b83018262000561565b50505b505050565b600082821c905092915050565b6000620005f860001984600802620005d8565b1980831691505092915050565b6000620006138383620005e5565b9150826002028217905092915050565b6200062e82620003a9565b67ffffffffffffffff8111156200064a5762000649620003b4565b5b62000656825462000412565b6200066382828562000588565b600060209050601f8311600181146200069b576000841562000686578287015190505b62000692858262000605565b86555062000702565b601f198416620006ab8662000447565b60005b82811015620006d557848901518255600182019150602085019450602081019050620006ae565b86831015620006f55784890151620006f1601f891682620005e5565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000620007536020836200070a565b915062000760826200071b565b602082019050919050565b60006020820190508181036000830152620007868162000744565b9050919050565b613f22806200079d6000396000f3fe6080604052600436106102255760003560e01c8063715018a611610123578063a22cb465116100ab578063c87b56dd1161006f578063c87b56dd146107d1578063d5abeb011461080e578063e985e9c514610839578063efbd73f414610876578063f2fde38b1461089f57610225565b8063a22cb465146106fd578063b071401b14610726578063b88d4fde1461074f578063b8a717af1461076b578063c23dc68f1461079457610225565b80638da5cb5b116100f25780638da5cb5b1461061657806394354fd01461064157806395d89b411461066c57806399a2557a14610697578063a0712d68146106d457610225565b8063715018a61461056e5780637ec4a6591461058557806381772171146105ae5780638462151c146105d957610225565b80633ccfd60b116101b15780635c975abb116101755780635c975abb146104735780635e84d7231461049e57806362b99ad4146104c95780636352211e146104f457806370a082311461053157610225565b80633ccfd60b146103af57806342842e0e146103c657806344a0d68a146103e25780635503a0e81461040b5780635bbb21771461043657610225565b806313faede6116101f857806313faede6146102eb57806316ba10e01461031657806316c38b3c1461033f57806318160ddd1461036857806323b872dd1461039357610225565b806301ffc9a71461022a57806306fdde0314610267578063081812fc14610292578063095ea7b3146102cf575b600080fd5b34801561023657600080fd5b50610251600480360381019061024c9190612a30565b6108c8565b60405161025e9190612a78565b60405180910390f35b34801561027357600080fd5b5061027c61095a565b6040516102899190612b23565b60405180910390f35b34801561029e57600080fd5b506102b960048036038101906102b49190612b7b565b6109ec565b6040516102c69190612be9565b60405180910390f35b6102e960048036038101906102e49190612c30565b610a6b565b005b3480156102f757600080fd5b50610300610baf565b60405161030d9190612c7f565b60405180910390f35b34801561032257600080fd5b5061033d60048036038101906103389190612dcf565b610bb5565b005b34801561034b57600080fd5b5061036660048036038101906103619190612e44565b610bd0565b005b34801561037457600080fd5b5061037d610bf5565b60405161038a9190612c7f565b60405180910390f35b6103ad60048036038101906103a89190612e71565b610c0c565b005b3480156103bb57600080fd5b506103c4610f2e565b005b6103e060048036038101906103db9190612e71565b61100b565b005b3480156103ee57600080fd5b5061040960048036038101906104049190612b7b565b61102b565b005b34801561041757600080fd5b5061042061103d565b60405161042d9190612b23565b60405180910390f35b34801561044257600080fd5b5061045d60048036038101906104589190612f24565b6110cb565b60405161046a91906130d4565b60405180910390f35b34801561047f57600080fd5b5061048861118e565b6040516104959190612a78565b60405180910390f35b3480156104aa57600080fd5b506104b36111a1565b6040516104c09190612c7f565b60405180910390f35b3480156104d557600080fd5b506104de6111a7565b6040516104eb9190612b23565b60405180910390f35b34801561050057600080fd5b5061051b60048036038101906105169190612b7b565b611235565b6040516105289190612be9565b60405180910390f35b34801561053d57600080fd5b50610558600480360381019061055391906130f6565b611247565b6040516105659190612c7f565b60405180910390f35b34801561057a57600080fd5b506105836112ff565b005b34801561059157600080fd5b506105ac60048036038101906105a79190612dcf565b611313565b005b3480156105ba57600080fd5b506105c361132e565b6040516105d09190612b23565b60405180910390f35b3480156105e557600080fd5b5061060060048036038101906105fb91906130f6565b6113bc565b60405161060d91906131e1565b60405180910390f35b34801561062257600080fd5b5061062b6114ff565b6040516106389190612be9565b60405180910390f35b34801561064d57600080fd5b50610656611529565b6040516106639190612c7f565b60405180910390f35b34801561067857600080fd5b5061068161152f565b60405161068e9190612b23565b60405180910390f35b3480156106a357600080fd5b506106be60048036038101906106b99190613203565b6115c1565b6040516106cb91906131e1565b60405180910390f35b3480156106e057600080fd5b506106fb60048036038101906106f69190612b7b565b6117cd565b005b34801561070957600080fd5b50610724600480360381019061071f9190613256565b611a45565b005b34801561073257600080fd5b5061074d60048036038101906107489190612b7b565b611b50565b005b61076960048036038101906107649190613337565b611b62565b005b34801561077757600080fd5b50610792600480360381019061078d9190612dcf565b611bd5565b005b3480156107a057600080fd5b506107bb60048036038101906107b69190612b7b565b611bf0565b6040516107c8919061340f565b60405180910390f35b3480156107dd57600080fd5b506107f860048036038101906107f39190612b7b565b611c5a565b6040516108059190612b23565b60405180910390f35b34801561081a57600080fd5b50610823611d7f565b6040516108309190612c7f565b60405180910390f35b34801561084557600080fd5b50610860600480360381019061085b919061342a565b611d85565b60405161086d9190612a78565b60405180910390f35b34801561088257600080fd5b5061089d6004803603810190610898919061346a565b611e19565b005b3480156108ab57600080fd5b506108c660048036038101906108c191906130f6565b611ec9565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061092357506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109535750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610969906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054610995906134d9565b80156109e25780601f106109b7576101008083540402835291602001916109e2565b820191906000526020600020905b8154815290600101906020018083116109c557829003601f168201915b5050505050905090565b60006109f782611f4c565b610a2d576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a7682611235565b90508073ffffffffffffffffffffffffffffffffffffffff16610a97611fab565b73ffffffffffffffffffffffffffffffffffffffff1614610afa57610ac381610abe611fab565b611d85565b610af9576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600d5481565b610bbd611fb3565b80600b9081610bcc91906136b6565b5050565b610bd8611fb3565b80601260006101000a81548160ff02191690831515021790555050565b6000610bff612031565b6001546000540303905090565b6000610c1782612036565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c7e576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c8a84612102565b91509150610ca08187610c9b611fab565b612129565b610cec57610cb586610cb0611fab565b611d85565b610ceb576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610d52576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d5f868686600161216d565b8015610d6a57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e3885610e14888887612173565b7c02000000000000000000000000000000000000000000000000000000001761219b565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610ebe5760006001850190506000600460008381526020019081526020016000205403610ebc576000548114610ebb578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610f2686868660016121c6565b505050505050565b610f36611fb3565b600260095403610f7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f72906137d4565b60405180910390fd5b60026009819055506000610f8d6114ff565b73ffffffffffffffffffffffffffffffffffffffff1647604051610fb090613825565b60006040518083038185875af1925050503d8060008114610fed576040519150601f19603f3d011682016040523d82523d6000602084013e610ff2565b606091505b505090508061100057600080fd5b506001600981905550565b61102683838360405180602001604052806000815250611b62565b505050565b611033611fb3565b80600d8190555050565b600b805461104a906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611076906134d9565b80156110c35780601f10611098576101008083540402835291602001916110c3565b820191906000526020600020905b8154815290600101906020018083116110a657829003601f168201915b505050505081565b6060600083839050905060008167ffffffffffffffff8111156110f1576110f0612ca4565b5b60405190808252806020026020018201604052801561112a57816020015b611117612975565b81526020019060019003908161110f5790505b50905060005b8281146111825761115986868381811061114d5761114c61383a565b5b90506020020135611bf0565b82828151811061116c5761116b61383a565b5b6020026020010181905250806001019050611130565b50809250505092915050565b601260009054906101000a900460ff1681565b60105481565b600a80546111b4906134d9565b80601f01602080910402602001604051908101604052809291908181526020018280546111e0906134d9565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b505050505081565b600061124082612036565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112ae576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611307611fb3565b61131160006121cc565b565b61131b611fb3565b80600a908161132a91906136b6565b5050565b600c805461133b906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611367906134d9565b80156113b45780601f10611389576101008083540402835291602001916113b4565b820191906000526020600020905b81548152906001019060200180831161139757829003601f168201915b505050505081565b606060008060006113cc85611247565b905060008167ffffffffffffffff8111156113ea576113e9612ca4565b5b6040519080825280602002602001820160405280156114185781602001602082028036833780820191505090505b509050611423612975565b600061142d612031565b90505b8386146114f15761144081612292565b915081604001516114e657600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461148b57816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036114e557808387806001019850815181106114d8576114d761383a565b5b6020026020010181815250505b5b806001019050611430565b508195505050505050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600f5481565b60606003805461153e906134d9565b80601f016020809104026020016040519081016040528092919081815260200182805461156a906134d9565b80156115b75780601f1061158c576101008083540402835291602001916115b7565b820191906000526020600020905b81548152906001019060200180831161159a57829003601f168201915b5050505050905090565b60608183106115fc576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806116076122bd565b9050611611612031565b85101561162357611620612031565b94505b8084111561162f578093505b600061163a87611247565b90508486101561165d576000868603905081811015611657578091505b50611662565b600090505b60008167ffffffffffffffff81111561167e5761167d612ca4565b5b6040519080825280602002602001820160405280156116ac5781602001602082028036833780820191505090505b509050600082036116c357809450505050506117c6565b60006116ce88611bf0565b9050600081604001516116e357816000015190505b60008990505b8881141580156116f95750848714155b156117b85761170781612292565b925082604001516117ad57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161461175257826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117ac578084888060010199508151811061179f5761179e61383a565b5b6020026020010181815250505b5b8060010190506116e9565b508583528296505050505050505b9392505050565b806000811180156117e05750600f548111155b61181f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611816906138b5565b60405180910390fd5b600e548161182b610bf5565b6118359190613904565b1115611876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186d90613984565b60405180910390fd5b6103e8600e5461188691906139a4565b816010546118949190613904565b11156118d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118cc90613984565b60405180910390fd5b601260009054906101000a900460ff1615611925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191c90613a24565b60405180910390fd5b600582601160006119346122c6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546119799190613904565b11156119ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b190613a90565b60405180910390fd5b6119cb6119c56122c6565b836122ce565b81601160006119d86122c6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a219190613904565b925050819055508160106000828254611a3a9190613904565b925050819055505050565b8060076000611a52611fab565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611aff611fab565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611b449190612a78565b60405180910390a35050565b611b58611fb3565b80600f8190555050565b611b6d848484610c0c565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611bcf57611b98848484846122ec565b611bce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611bdd611fb3565b80600c9081611bec91906136b6565b5050565b611bf8612975565b611c00612975565b611c08612031565b831080611c1c5750611c186122bd565b8310155b15611c2a5780915050611c55565b611c3383612292565b9050806040015115611c485780915050611c55565b611c518361243c565b9150505b919050565b6060611c6582611f4c565b611ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9b90613b22565b60405180910390fd5b6000611cae61245c565b90506000815111611d4957600c8054611cc6906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611cf2906134d9565b8015611d3f5780601f10611d1457610100808354040283529160200191611d3f565b820191906000526020600020905b815481529060010190602001808311611d2257829003601f168201915b5050505050611d77565b80611d53846124ee565b600b604051602001611d6793929190613c01565b6040516020818303038152906040525b915050919050565b600e5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611e21611fb3565b60008211611e64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5b906138b5565b60405180910390fd5b600e5482611e70610bf5565b611e7a9190613904565b1115611ebb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb290613984565b60405180910390fd5b611ec581836122ce565b5050565b611ed1611fb3565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3790613ca4565b60405180910390fd5b611f49816121cc565b50565b600081611f57612031565b11158015611f66575060005482105b8015611fa4575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b611fbb6122c6565b73ffffffffffffffffffffffffffffffffffffffff16611fd96114ff565b73ffffffffffffffffffffffffffffffffffffffff161461202f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202690613d10565b60405180910390fd5b565b600090565b60008082905080612045612031565b116120cb576000548110156120ca5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036120c8575b600081036120be576004600083600190039350838152602001908152602001600020549050612094565b80925050506120fd565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861218a86868461264e565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61229a612975565b6122b66004600084815260200190815260200160002054612657565b9050919050565b60008054905090565b600033905090565b6122e882826040518060200160405280600081525061270d565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612312611fab565b8786866040518563ffffffff1660e01b81526004016123349493929190613d85565b6020604051808303816000875af192505050801561237057506040513d601f19601f8201168201806040525081019061236d9190613de6565b60015b6123e9573d80600081146123a0576040519150601f19603f3d011682016040523d82523d6000602084013e6123a5565b606091505b5060008151036123e1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612444612975565b61245561245083612036565b612657565b9050919050565b6060600a805461246b906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054612497906134d9565b80156124e45780601f106124b9576101008083540402835291602001916124e4565b820191906000526020600020905b8154815290600101906020018083116124c757829003601f168201915b5050505050905090565b606060008203612535576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612649565b600082905060005b6000821461256757808061255090613e13565b915050600a826125609190613e8a565b915061253d565b60008167ffffffffffffffff81111561258357612582612ca4565b5b6040519080825280601f01601f1916602001820160405280156125b55781602001600182028036833780820191505090505b5090505b60008514612642576001826125ce91906139a4565b9150600a856125dd9190613ebb565b60306125e99190613904565b60f81b8183815181106125ff576125fe61383a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561263b9190613e8a565b94506125b9565b8093505050505b919050565b60009392505050565b61265f612975565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b61271783836127aa565b60008373ffffffffffffffffffffffffffffffffffffffff163b146127a557600080549050600083820390505b61275760008683806001019450866122ec565b61278d576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106127445781600054146127a257600080fd5b50505b505050565b600080549050600082036127ea576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127f7600084838561216d565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061286e8361285f6000866000612173565b61286885612965565b1761219b565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461290f57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506128d4565b506000820361294a576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061296060008483856121c6565b505050565b60006001821460e11b9050919050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612a0d816129d8565b8114612a1857600080fd5b50565b600081359050612a2a81612a04565b92915050565b600060208284031215612a4657612a456129ce565b5b6000612a5484828501612a1b565b91505092915050565b60008115159050919050565b612a7281612a5d565b82525050565b6000602082019050612a8d6000830184612a69565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612acd578082015181840152602081019050612ab2565b60008484015250505050565b6000601f19601f8301169050919050565b6000612af582612a93565b612aff8185612a9e565b9350612b0f818560208601612aaf565b612b1881612ad9565b840191505092915050565b60006020820190508181036000830152612b3d8184612aea565b905092915050565b6000819050919050565b612b5881612b45565b8114612b6357600080fd5b50565b600081359050612b7581612b4f565b92915050565b600060208284031215612b9157612b906129ce565b5b6000612b9f84828501612b66565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612bd382612ba8565b9050919050565b612be381612bc8565b82525050565b6000602082019050612bfe6000830184612bda565b92915050565b612c0d81612bc8565b8114612c1857600080fd5b50565b600081359050612c2a81612c04565b92915050565b60008060408385031215612c4757612c466129ce565b5b6000612c5585828601612c1b565b9250506020612c6685828601612b66565b9150509250929050565b612c7981612b45565b82525050565b6000602082019050612c946000830184612c70565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cdc82612ad9565b810181811067ffffffffffffffff82111715612cfb57612cfa612ca4565b5b80604052505050565b6000612d0e6129c4565b9050612d1a8282612cd3565b919050565b600067ffffffffffffffff821115612d3a57612d39612ca4565b5b612d4382612ad9565b9050602081019050919050565b82818337600083830152505050565b6000612d72612d6d84612d1f565b612d04565b905082815260208101848484011115612d8e57612d8d612c9f565b5b612d99848285612d50565b509392505050565b600082601f830112612db657612db5612c9a565b5b8135612dc6848260208601612d5f565b91505092915050565b600060208284031215612de557612de46129ce565b5b600082013567ffffffffffffffff811115612e0357612e026129d3565b5b612e0f84828501612da1565b91505092915050565b612e2181612a5d565b8114612e2c57600080fd5b50565b600081359050612e3e81612e18565b92915050565b600060208284031215612e5a57612e596129ce565b5b6000612e6884828501612e2f565b91505092915050565b600080600060608486031215612e8a57612e896129ce565b5b6000612e9886828701612c1b565b9350506020612ea986828701612c1b565b9250506040612eba86828701612b66565b9150509250925092565b600080fd5b600080fd5b60008083601f840112612ee457612ee3612c9a565b5b8235905067ffffffffffffffff811115612f0157612f00612ec4565b5b602083019150836020820283011115612f1d57612f1c612ec9565b5b9250929050565b60008060208385031215612f3b57612f3a6129ce565b5b600083013567ffffffffffffffff811115612f5957612f586129d3565b5b612f6585828601612ece565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612fa681612bc8565b82525050565b600067ffffffffffffffff82169050919050565b612fc981612fac565b82525050565b612fd881612a5d565b82525050565b600062ffffff82169050919050565b612ff681612fde565b82525050565b6080820160008201516130126000850182612f9d565b5060208201516130256020850182612fc0565b5060408201516130386040850182612fcf565b50606082015161304b6060850182612fed565b50505050565b600061305d8383612ffc565b60808301905092915050565b6000602082019050919050565b600061308182612f71565b61308b8185612f7c565b935061309683612f8d565b8060005b838110156130c75781516130ae8882613051565b97506130b983613069565b92505060018101905061309a565b5085935050505092915050565b600060208201905081810360008301526130ee8184613076565b905092915050565b60006020828403121561310c5761310b6129ce565b5b600061311a84828501612c1b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61315881612b45565b82525050565b600061316a838361314f565b60208301905092915050565b6000602082019050919050565b600061318e82613123565b613198818561312e565b93506131a38361313f565b8060005b838110156131d45781516131bb888261315e565b97506131c683613176565b9250506001810190506131a7565b5085935050505092915050565b600060208201905081810360008301526131fb8184613183565b905092915050565b60008060006060848603121561321c5761321b6129ce565b5b600061322a86828701612c1b565b935050602061323b86828701612b66565b925050604061324c86828701612b66565b9150509250925092565b6000806040838503121561326d5761326c6129ce565b5b600061327b85828601612c1b565b925050602061328c85828601612e2f565b9150509250929050565b600067ffffffffffffffff8211156132b1576132b0612ca4565b5b6132ba82612ad9565b9050602081019050919050565b60006132da6132d584613296565b612d04565b9050828152602081018484840111156132f6576132f5612c9f565b5b613301848285612d50565b509392505050565b600082601f83011261331e5761331d612c9a565b5b813561332e8482602086016132c7565b91505092915050565b60008060008060808587031215613351576133506129ce565b5b600061335f87828801612c1b565b945050602061337087828801612c1b565b935050604061338187828801612b66565b925050606085013567ffffffffffffffff8111156133a2576133a16129d3565b5b6133ae87828801613309565b91505092959194509250565b6080820160008201516133d06000850182612f9d565b5060208201516133e36020850182612fc0565b5060408201516133f66040850182612fcf565b5060608201516134096060850182612fed565b50505050565b600060808201905061342460008301846133ba565b92915050565b60008060408385031215613441576134406129ce565b5b600061344f85828601612c1b565b925050602061346085828601612c1b565b9150509250929050565b60008060408385031215613481576134806129ce565b5b600061348f85828601612b66565b92505060206134a085828601612c1b565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806134f157607f821691505b602082108103613504576135036134aa565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261356c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261352f565b613576868361352f565b95508019841693508086168417925050509392505050565b6000819050919050565b60006135b36135ae6135a984612b45565b61358e565b612b45565b9050919050565b6000819050919050565b6135cd83613598565b6135e16135d9826135ba565b84845461353c565b825550505050565b600090565b6135f66135e9565b6136018184846135c4565b505050565b5b818110156136255761361a6000826135ee565b600181019050613607565b5050565b601f82111561366a5761363b8161350a565b6136448461351f565b81016020851015613653578190505b61366761365f8561351f565b830182613606565b50505b505050565b600082821c905092915050565b600061368d6000198460080261366f565b1980831691505092915050565b60006136a6838361367c565b9150826002028217905092915050565b6136bf82612a93565b67ffffffffffffffff8111156136d8576136d7612ca4565b5b6136e282546134d9565b6136ed828285613629565b600060209050601f831160018114613720576000841561370e578287015190505b613718858261369a565b865550613780565b601f19841661372e8661350a565b60005b8281101561375657848901518255600182019150602085019450602081019050613731565b86831015613773578489015161376f601f89168261367c565b8355505b6001600288020188555050505b505050505050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006137be601f83612a9e565b91506137c982613788565b602082019050919050565b600060208201905081810360008301526137ed816137b1565b9050919050565b600081905092915050565b50565b600061380f6000836137f4565b915061381a826137ff565b600082019050919050565b600061383082613802565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f496e76616c6964206d696e7420616d6f756e7421000000000000000000000000600082015250565b600061389f601483612a9e565b91506138aa82613869565b602082019050919050565b600060208201905081810360008301526138ce81613892565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061390f82612b45565b915061391a83612b45565b9250828201905080821115613932576139316138d5565b5b92915050565b7f4d617820737570706c7920657863656564656421000000000000000000000000600082015250565b600061396e601483612a9e565b915061397982613938565b602082019050919050565b6000602082019050818103600083015261399d81613961565b9050919050565b60006139af82612b45565b91506139ba83612b45565b92508282039050818111156139d2576139d16138d5565b5b92915050565b7f54686520636f6e74726163742069732070617573656421000000000000000000600082015250565b6000613a0e601783612a9e565b9150613a19826139d8565b602082019050919050565b60006020820190508181036000830152613a3d81613a01565b9050919050565b7f4f766572206d696e746564210000000000000000000000000000000000000000600082015250565b6000613a7a600c83612a9e565b9150613a8582613a44565b602082019050919050565b60006020820190508181036000830152613aa981613a6d565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613b0c602f83612a9e565b9150613b1782613ab0565b604082019050919050565b60006020820190508181036000830152613b3b81613aff565b9050919050565b600081905092915050565b6000613b5882612a93565b613b628185613b42565b9350613b72818560208601612aaf565b80840191505092915050565b60008154613b8b816134d9565b613b958186613b42565b94506001821660008114613bb05760018114613bc557613bf8565b60ff1983168652811515820286019350613bf8565b613bce8561350a565b60005b83811015613bf057815481890152600182019150602081019050613bd1565b838801955050505b50505092915050565b6000613c0d8286613b4d565b9150613c198285613b4d565b9150613c258284613b7e565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613c8e602683612a9e565b9150613c9982613c32565b604082019050919050565b60006020820190508181036000830152613cbd81613c81565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613cfa602083612a9e565b9150613d0582613cc4565b602082019050919050565b60006020820190508181036000830152613d2981613ced565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613d5782613d30565b613d618185613d3b565b9350613d71818560208601612aaf565b613d7a81612ad9565b840191505092915050565b6000608082019050613d9a6000830187612bda565b613da76020830186612bda565b613db46040830185612c70565b8181036060830152613dc68184613d4c565b905095945050505050565b600081519050613de081612a04565b92915050565b600060208284031215613dfc57613dfb6129ce565b5b6000613e0a84828501613dd1565b91505092915050565b6000613e1e82612b45565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613e5057613e4f6138d5565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613e9582612b45565b9150613ea083612b45565b925082613eb057613eaf613e5b565b5b828204905092915050565b6000613ec682612b45565b9150613ed183612b45565b925082613ee157613ee0613e5b565b5b82820690509291505056fea2646970667358221220de912d63baa993283320e2e1afe3e71782c34ae8422b26309137ece5f8faf96e64736f6c63430008110033697066733a2f2f62616679626569667a6337613471626676746a6f6a6b6f703376376d787a6a7275327571756b36346f377a677a6d71747a74356c7368737a6b3769

Deployed Bytecode

0x6080604052600436106102255760003560e01c8063715018a611610123578063a22cb465116100ab578063c87b56dd1161006f578063c87b56dd146107d1578063d5abeb011461080e578063e985e9c514610839578063efbd73f414610876578063f2fde38b1461089f57610225565b8063a22cb465146106fd578063b071401b14610726578063b88d4fde1461074f578063b8a717af1461076b578063c23dc68f1461079457610225565b80638da5cb5b116100f25780638da5cb5b1461061657806394354fd01461064157806395d89b411461066c57806399a2557a14610697578063a0712d68146106d457610225565b8063715018a61461056e5780637ec4a6591461058557806381772171146105ae5780638462151c146105d957610225565b80633ccfd60b116101b15780635c975abb116101755780635c975abb146104735780635e84d7231461049e57806362b99ad4146104c95780636352211e146104f457806370a082311461053157610225565b80633ccfd60b146103af57806342842e0e146103c657806344a0d68a146103e25780635503a0e81461040b5780635bbb21771461043657610225565b806313faede6116101f857806313faede6146102eb57806316ba10e01461031657806316c38b3c1461033f57806318160ddd1461036857806323b872dd1461039357610225565b806301ffc9a71461022a57806306fdde0314610267578063081812fc14610292578063095ea7b3146102cf575b600080fd5b34801561023657600080fd5b50610251600480360381019061024c9190612a30565b6108c8565b60405161025e9190612a78565b60405180910390f35b34801561027357600080fd5b5061027c61095a565b6040516102899190612b23565b60405180910390f35b34801561029e57600080fd5b506102b960048036038101906102b49190612b7b565b6109ec565b6040516102c69190612be9565b60405180910390f35b6102e960048036038101906102e49190612c30565b610a6b565b005b3480156102f757600080fd5b50610300610baf565b60405161030d9190612c7f565b60405180910390f35b34801561032257600080fd5b5061033d60048036038101906103389190612dcf565b610bb5565b005b34801561034b57600080fd5b5061036660048036038101906103619190612e44565b610bd0565b005b34801561037457600080fd5b5061037d610bf5565b60405161038a9190612c7f565b60405180910390f35b6103ad60048036038101906103a89190612e71565b610c0c565b005b3480156103bb57600080fd5b506103c4610f2e565b005b6103e060048036038101906103db9190612e71565b61100b565b005b3480156103ee57600080fd5b5061040960048036038101906104049190612b7b565b61102b565b005b34801561041757600080fd5b5061042061103d565b60405161042d9190612b23565b60405180910390f35b34801561044257600080fd5b5061045d60048036038101906104589190612f24565b6110cb565b60405161046a91906130d4565b60405180910390f35b34801561047f57600080fd5b5061048861118e565b6040516104959190612a78565b60405180910390f35b3480156104aa57600080fd5b506104b36111a1565b6040516104c09190612c7f565b60405180910390f35b3480156104d557600080fd5b506104de6111a7565b6040516104eb9190612b23565b60405180910390f35b34801561050057600080fd5b5061051b60048036038101906105169190612b7b565b611235565b6040516105289190612be9565b60405180910390f35b34801561053d57600080fd5b50610558600480360381019061055391906130f6565b611247565b6040516105659190612c7f565b60405180910390f35b34801561057a57600080fd5b506105836112ff565b005b34801561059157600080fd5b506105ac60048036038101906105a79190612dcf565b611313565b005b3480156105ba57600080fd5b506105c361132e565b6040516105d09190612b23565b60405180910390f35b3480156105e557600080fd5b5061060060048036038101906105fb91906130f6565b6113bc565b60405161060d91906131e1565b60405180910390f35b34801561062257600080fd5b5061062b6114ff565b6040516106389190612be9565b60405180910390f35b34801561064d57600080fd5b50610656611529565b6040516106639190612c7f565b60405180910390f35b34801561067857600080fd5b5061068161152f565b60405161068e9190612b23565b60405180910390f35b3480156106a357600080fd5b506106be60048036038101906106b99190613203565b6115c1565b6040516106cb91906131e1565b60405180910390f35b3480156106e057600080fd5b506106fb60048036038101906106f69190612b7b565b6117cd565b005b34801561070957600080fd5b50610724600480360381019061071f9190613256565b611a45565b005b34801561073257600080fd5b5061074d60048036038101906107489190612b7b565b611b50565b005b61076960048036038101906107649190613337565b611b62565b005b34801561077757600080fd5b50610792600480360381019061078d9190612dcf565b611bd5565b005b3480156107a057600080fd5b506107bb60048036038101906107b69190612b7b565b611bf0565b6040516107c8919061340f565b60405180910390f35b3480156107dd57600080fd5b506107f860048036038101906107f39190612b7b565b611c5a565b6040516108059190612b23565b60405180910390f35b34801561081a57600080fd5b50610823611d7f565b6040516108309190612c7f565b60405180910390f35b34801561084557600080fd5b50610860600480360381019061085b919061342a565b611d85565b60405161086d9190612a78565b60405180910390f35b34801561088257600080fd5b5061089d6004803603810190610898919061346a565b611e19565b005b3480156108ab57600080fd5b506108c660048036038101906108c191906130f6565b611ec9565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061092357506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109535750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610969906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054610995906134d9565b80156109e25780601f106109b7576101008083540402835291602001916109e2565b820191906000526020600020905b8154815290600101906020018083116109c557829003601f168201915b5050505050905090565b60006109f782611f4c565b610a2d576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a7682611235565b90508073ffffffffffffffffffffffffffffffffffffffff16610a97611fab565b73ffffffffffffffffffffffffffffffffffffffff1614610afa57610ac381610abe611fab565b611d85565b610af9576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600d5481565b610bbd611fb3565b80600b9081610bcc91906136b6565b5050565b610bd8611fb3565b80601260006101000a81548160ff02191690831515021790555050565b6000610bff612031565b6001546000540303905090565b6000610c1782612036565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c7e576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c8a84612102565b91509150610ca08187610c9b611fab565b612129565b610cec57610cb586610cb0611fab565b611d85565b610ceb576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610d52576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d5f868686600161216d565b8015610d6a57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e3885610e14888887612173565b7c02000000000000000000000000000000000000000000000000000000001761219b565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610ebe5760006001850190506000600460008381526020019081526020016000205403610ebc576000548114610ebb578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610f2686868660016121c6565b505050505050565b610f36611fb3565b600260095403610f7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f72906137d4565b60405180910390fd5b60026009819055506000610f8d6114ff565b73ffffffffffffffffffffffffffffffffffffffff1647604051610fb090613825565b60006040518083038185875af1925050503d8060008114610fed576040519150601f19603f3d011682016040523d82523d6000602084013e610ff2565b606091505b505090508061100057600080fd5b506001600981905550565b61102683838360405180602001604052806000815250611b62565b505050565b611033611fb3565b80600d8190555050565b600b805461104a906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611076906134d9565b80156110c35780601f10611098576101008083540402835291602001916110c3565b820191906000526020600020905b8154815290600101906020018083116110a657829003601f168201915b505050505081565b6060600083839050905060008167ffffffffffffffff8111156110f1576110f0612ca4565b5b60405190808252806020026020018201604052801561112a57816020015b611117612975565b81526020019060019003908161110f5790505b50905060005b8281146111825761115986868381811061114d5761114c61383a565b5b90506020020135611bf0565b82828151811061116c5761116b61383a565b5b6020026020010181905250806001019050611130565b50809250505092915050565b601260009054906101000a900460ff1681565b60105481565b600a80546111b4906134d9565b80601f01602080910402602001604051908101604052809291908181526020018280546111e0906134d9565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b505050505081565b600061124082612036565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112ae576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611307611fb3565b61131160006121cc565b565b61131b611fb3565b80600a908161132a91906136b6565b5050565b600c805461133b906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611367906134d9565b80156113b45780601f10611389576101008083540402835291602001916113b4565b820191906000526020600020905b81548152906001019060200180831161139757829003601f168201915b505050505081565b606060008060006113cc85611247565b905060008167ffffffffffffffff8111156113ea576113e9612ca4565b5b6040519080825280602002602001820160405280156114185781602001602082028036833780820191505090505b509050611423612975565b600061142d612031565b90505b8386146114f15761144081612292565b915081604001516114e657600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461148b57816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036114e557808387806001019850815181106114d8576114d761383a565b5b6020026020010181815250505b5b806001019050611430565b508195505050505050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600f5481565b60606003805461153e906134d9565b80601f016020809104026020016040519081016040528092919081815260200182805461156a906134d9565b80156115b75780601f1061158c576101008083540402835291602001916115b7565b820191906000526020600020905b81548152906001019060200180831161159a57829003601f168201915b5050505050905090565b60608183106115fc576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806116076122bd565b9050611611612031565b85101561162357611620612031565b94505b8084111561162f578093505b600061163a87611247565b90508486101561165d576000868603905081811015611657578091505b50611662565b600090505b60008167ffffffffffffffff81111561167e5761167d612ca4565b5b6040519080825280602002602001820160405280156116ac5781602001602082028036833780820191505090505b509050600082036116c357809450505050506117c6565b60006116ce88611bf0565b9050600081604001516116e357816000015190505b60008990505b8881141580156116f95750848714155b156117b85761170781612292565b925082604001516117ad57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161461175257826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117ac578084888060010199508151811061179f5761179e61383a565b5b6020026020010181815250505b5b8060010190506116e9565b508583528296505050505050505b9392505050565b806000811180156117e05750600f548111155b61181f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611816906138b5565b60405180910390fd5b600e548161182b610bf5565b6118359190613904565b1115611876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186d90613984565b60405180910390fd5b6103e8600e5461188691906139a4565b816010546118949190613904565b11156118d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118cc90613984565b60405180910390fd5b601260009054906101000a900460ff1615611925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191c90613a24565b60405180910390fd5b600582601160006119346122c6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546119799190613904565b11156119ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119b190613a90565b60405180910390fd5b6119cb6119c56122c6565b836122ce565b81601160006119d86122c6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a219190613904565b925050819055508160106000828254611a3a9190613904565b925050819055505050565b8060076000611a52611fab565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611aff611fab565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611b449190612a78565b60405180910390a35050565b611b58611fb3565b80600f8190555050565b611b6d848484610c0c565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611bcf57611b98848484846122ec565b611bce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611bdd611fb3565b80600c9081611bec91906136b6565b5050565b611bf8612975565b611c00612975565b611c08612031565b831080611c1c5750611c186122bd565b8310155b15611c2a5780915050611c55565b611c3383612292565b9050806040015115611c485780915050611c55565b611c518361243c565b9150505b919050565b6060611c6582611f4c565b611ca4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9b90613b22565b60405180910390fd5b6000611cae61245c565b90506000815111611d4957600c8054611cc6906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054611cf2906134d9565b8015611d3f5780601f10611d1457610100808354040283529160200191611d3f565b820191906000526020600020905b815481529060010190602001808311611d2257829003601f168201915b5050505050611d77565b80611d53846124ee565b600b604051602001611d6793929190613c01565b6040516020818303038152906040525b915050919050565b600e5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611e21611fb3565b60008211611e64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5b906138b5565b60405180910390fd5b600e5482611e70610bf5565b611e7a9190613904565b1115611ebb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb290613984565b60405180910390fd5b611ec581836122ce565b5050565b611ed1611fb3565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f3790613ca4565b60405180910390fd5b611f49816121cc565b50565b600081611f57612031565b11158015611f66575060005482105b8015611fa4575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b611fbb6122c6565b73ffffffffffffffffffffffffffffffffffffffff16611fd96114ff565b73ffffffffffffffffffffffffffffffffffffffff161461202f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202690613d10565b60405180910390fd5b565b600090565b60008082905080612045612031565b116120cb576000548110156120ca5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036120c8575b600081036120be576004600083600190039350838152602001908152602001600020549050612094565b80925050506120fd565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861218a86868461264e565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61229a612975565b6122b66004600084815260200190815260200160002054612657565b9050919050565b60008054905090565b600033905090565b6122e882826040518060200160405280600081525061270d565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612312611fab565b8786866040518563ffffffff1660e01b81526004016123349493929190613d85565b6020604051808303816000875af192505050801561237057506040513d601f19601f8201168201806040525081019061236d9190613de6565b60015b6123e9573d80600081146123a0576040519150601f19603f3d011682016040523d82523d6000602084013e6123a5565b606091505b5060008151036123e1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612444612975565b61245561245083612036565b612657565b9050919050565b6060600a805461246b906134d9565b80601f0160208091040260200160405190810160405280929190818152602001828054612497906134d9565b80156124e45780601f106124b9576101008083540402835291602001916124e4565b820191906000526020600020905b8154815290600101906020018083116124c757829003601f168201915b5050505050905090565b606060008203612535576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612649565b600082905060005b6000821461256757808061255090613e13565b915050600a826125609190613e8a565b915061253d565b60008167ffffffffffffffff81111561258357612582612ca4565b5b6040519080825280601f01601f1916602001820160405280156125b55781602001600182028036833780820191505090505b5090505b60008514612642576001826125ce91906139a4565b9150600a856125dd9190613ebb565b60306125e99190613904565b60f81b8183815181106125ff576125fe61383a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561263b9190613e8a565b94506125b9565b8093505050505b919050565b60009392505050565b61265f612975565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b61271783836127aa565b60008373ffffffffffffffffffffffffffffffffffffffff163b146127a557600080549050600083820390505b61275760008683806001019450866122ec565b61278d576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106127445781600054146127a257600080fd5b50505b505050565b600080549050600082036127ea576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127f7600084838561216d565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061286e8361285f6000866000612173565b61286885612965565b1761219b565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461290f57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506128d4565b506000820361294a576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061296060008483856121c6565b505050565b60006001821460e11b9050919050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612a0d816129d8565b8114612a1857600080fd5b50565b600081359050612a2a81612a04565b92915050565b600060208284031215612a4657612a456129ce565b5b6000612a5484828501612a1b565b91505092915050565b60008115159050919050565b612a7281612a5d565b82525050565b6000602082019050612a8d6000830184612a69565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612acd578082015181840152602081019050612ab2565b60008484015250505050565b6000601f19601f8301169050919050565b6000612af582612a93565b612aff8185612a9e565b9350612b0f818560208601612aaf565b612b1881612ad9565b840191505092915050565b60006020820190508181036000830152612b3d8184612aea565b905092915050565b6000819050919050565b612b5881612b45565b8114612b6357600080fd5b50565b600081359050612b7581612b4f565b92915050565b600060208284031215612b9157612b906129ce565b5b6000612b9f84828501612b66565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612bd382612ba8565b9050919050565b612be381612bc8565b82525050565b6000602082019050612bfe6000830184612bda565b92915050565b612c0d81612bc8565b8114612c1857600080fd5b50565b600081359050612c2a81612c04565b92915050565b60008060408385031215612c4757612c466129ce565b5b6000612c5585828601612c1b565b9250506020612c6685828601612b66565b9150509250929050565b612c7981612b45565b82525050565b6000602082019050612c946000830184612c70565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cdc82612ad9565b810181811067ffffffffffffffff82111715612cfb57612cfa612ca4565b5b80604052505050565b6000612d0e6129c4565b9050612d1a8282612cd3565b919050565b600067ffffffffffffffff821115612d3a57612d39612ca4565b5b612d4382612ad9565b9050602081019050919050565b82818337600083830152505050565b6000612d72612d6d84612d1f565b612d04565b905082815260208101848484011115612d8e57612d8d612c9f565b5b612d99848285612d50565b509392505050565b600082601f830112612db657612db5612c9a565b5b8135612dc6848260208601612d5f565b91505092915050565b600060208284031215612de557612de46129ce565b5b600082013567ffffffffffffffff811115612e0357612e026129d3565b5b612e0f84828501612da1565b91505092915050565b612e2181612a5d565b8114612e2c57600080fd5b50565b600081359050612e3e81612e18565b92915050565b600060208284031215612e5a57612e596129ce565b5b6000612e6884828501612e2f565b91505092915050565b600080600060608486031215612e8a57612e896129ce565b5b6000612e9886828701612c1b565b9350506020612ea986828701612c1b565b9250506040612eba86828701612b66565b9150509250925092565b600080fd5b600080fd5b60008083601f840112612ee457612ee3612c9a565b5b8235905067ffffffffffffffff811115612f0157612f00612ec4565b5b602083019150836020820283011115612f1d57612f1c612ec9565b5b9250929050565b60008060208385031215612f3b57612f3a6129ce565b5b600083013567ffffffffffffffff811115612f5957612f586129d3565b5b612f6585828601612ece565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612fa681612bc8565b82525050565b600067ffffffffffffffff82169050919050565b612fc981612fac565b82525050565b612fd881612a5d565b82525050565b600062ffffff82169050919050565b612ff681612fde565b82525050565b6080820160008201516130126000850182612f9d565b5060208201516130256020850182612fc0565b5060408201516130386040850182612fcf565b50606082015161304b6060850182612fed565b50505050565b600061305d8383612ffc565b60808301905092915050565b6000602082019050919050565b600061308182612f71565b61308b8185612f7c565b935061309683612f8d565b8060005b838110156130c75781516130ae8882613051565b97506130b983613069565b92505060018101905061309a565b5085935050505092915050565b600060208201905081810360008301526130ee8184613076565b905092915050565b60006020828403121561310c5761310b6129ce565b5b600061311a84828501612c1b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61315881612b45565b82525050565b600061316a838361314f565b60208301905092915050565b6000602082019050919050565b600061318e82613123565b613198818561312e565b93506131a38361313f565b8060005b838110156131d45781516131bb888261315e565b97506131c683613176565b9250506001810190506131a7565b5085935050505092915050565b600060208201905081810360008301526131fb8184613183565b905092915050565b60008060006060848603121561321c5761321b6129ce565b5b600061322a86828701612c1b565b935050602061323b86828701612b66565b925050604061324c86828701612b66565b9150509250925092565b6000806040838503121561326d5761326c6129ce565b5b600061327b85828601612c1b565b925050602061328c85828601612e2f565b9150509250929050565b600067ffffffffffffffff8211156132b1576132b0612ca4565b5b6132ba82612ad9565b9050602081019050919050565b60006132da6132d584613296565b612d04565b9050828152602081018484840111156132f6576132f5612c9f565b5b613301848285612d50565b509392505050565b600082601f83011261331e5761331d612c9a565b5b813561332e8482602086016132c7565b91505092915050565b60008060008060808587031215613351576133506129ce565b5b600061335f87828801612c1b565b945050602061337087828801612c1b565b935050604061338187828801612b66565b925050606085013567ffffffffffffffff8111156133a2576133a16129d3565b5b6133ae87828801613309565b91505092959194509250565b6080820160008201516133d06000850182612f9d565b5060208201516133e36020850182612fc0565b5060408201516133f66040850182612fcf565b5060608201516134096060850182612fed565b50505050565b600060808201905061342460008301846133ba565b92915050565b60008060408385031215613441576134406129ce565b5b600061344f85828601612c1b565b925050602061346085828601612c1b565b9150509250929050565b60008060408385031215613481576134806129ce565b5b600061348f85828601612b66565b92505060206134a085828601612c1b565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806134f157607f821691505b602082108103613504576135036134aa565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261356c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261352f565b613576868361352f565b95508019841693508086168417925050509392505050565b6000819050919050565b60006135b36135ae6135a984612b45565b61358e565b612b45565b9050919050565b6000819050919050565b6135cd83613598565b6135e16135d9826135ba565b84845461353c565b825550505050565b600090565b6135f66135e9565b6136018184846135c4565b505050565b5b818110156136255761361a6000826135ee565b600181019050613607565b5050565b601f82111561366a5761363b8161350a565b6136448461351f565b81016020851015613653578190505b61366761365f8561351f565b830182613606565b50505b505050565b600082821c905092915050565b600061368d6000198460080261366f565b1980831691505092915050565b60006136a6838361367c565b9150826002028217905092915050565b6136bf82612a93565b67ffffffffffffffff8111156136d8576136d7612ca4565b5b6136e282546134d9565b6136ed828285613629565b600060209050601f831160018114613720576000841561370e578287015190505b613718858261369a565b865550613780565b601f19841661372e8661350a565b60005b8281101561375657848901518255600182019150602085019450602081019050613731565b86831015613773578489015161376f601f89168261367c565b8355505b6001600288020188555050505b505050505050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006137be601f83612a9e565b91506137c982613788565b602082019050919050565b600060208201905081810360008301526137ed816137b1565b9050919050565b600081905092915050565b50565b600061380f6000836137f4565b915061381a826137ff565b600082019050919050565b600061383082613802565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f496e76616c6964206d696e7420616d6f756e7421000000000000000000000000600082015250565b600061389f601483612a9e565b91506138aa82613869565b602082019050919050565b600060208201905081810360008301526138ce81613892565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061390f82612b45565b915061391a83612b45565b9250828201905080821115613932576139316138d5565b5b92915050565b7f4d617820737570706c7920657863656564656421000000000000000000000000600082015250565b600061396e601483612a9e565b915061397982613938565b602082019050919050565b6000602082019050818103600083015261399d81613961565b9050919050565b60006139af82612b45565b91506139ba83612b45565b92508282039050818111156139d2576139d16138d5565b5b92915050565b7f54686520636f6e74726163742069732070617573656421000000000000000000600082015250565b6000613a0e601783612a9e565b9150613a19826139d8565b602082019050919050565b60006020820190508181036000830152613a3d81613a01565b9050919050565b7f4f766572206d696e746564210000000000000000000000000000000000000000600082015250565b6000613a7a600c83612a9e565b9150613a8582613a44565b602082019050919050565b60006020820190508181036000830152613aa981613a6d565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613b0c602f83612a9e565b9150613b1782613ab0565b604082019050919050565b60006020820190508181036000830152613b3b81613aff565b9050919050565b600081905092915050565b6000613b5882612a93565b613b628185613b42565b9350613b72818560208601612aaf565b80840191505092915050565b60008154613b8b816134d9565b613b958186613b42565b94506001821660008114613bb05760018114613bc557613bf8565b60ff1983168652811515820286019350613bf8565b613bce8561350a565b60005b83811015613bf057815481890152600182019150602081019050613bd1565b838801955050505b50505092915050565b6000613c0d8286613b4d565b9150613c198285613b4d565b9150613c258284613b7e565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613c8e602683612a9e565b9150613c9982613c32565b604082019050919050565b60006020820190508181036000830152613cbd81613c81565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613cfa602083612a9e565b9150613d0582613cc4565b602082019050919050565b60006020820190508181036000830152613d2981613ced565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613d5782613d30565b613d618185613d3b565b9350613d71818560208601612aaf565b613d7a81612ad9565b840191505092915050565b6000608082019050613d9a6000830187612bda565b613da76020830186612bda565b613db46040830185612c70565b8181036060830152613dc68184613d4c565b905095945050505050565b600081519050613de081612a04565b92915050565b600060208284031215613dfc57613dfb6129ce565b5b6000613e0a84828501613dd1565b91505092915050565b6000613e1e82612b45565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613e5057613e4f6138d5565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613e9582612b45565b9150613ea083612b45565b925082613eb057613eaf613e5b565b5b828204905092915050565b6000613ec682612b45565b9150613ed183612b45565b925082613ee157613ee0613e5b565b5b82820690509291505056fea2646970667358221220de912d63baa993283320e2e1afe3e71782c34ae8422b26309137ece5f8faf96e64736f6c63430008110033

Deployed Bytecode Sourcemap

91154:2822:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49067:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49969:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56460:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55893:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91321:19;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93524:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93630:77;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45720:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60099:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93713:150;;;;;;;;;;;;;:::i;:::-;;63020:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93096:74;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91251:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86290:528;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91500:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91412:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91218:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51362:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46904:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29846:103;;;;;;;;;;;;;:::i;:::-;;93418:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91284:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90166:900;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29198:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91374:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50145:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87206:2513;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92076:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57018:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93176:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63811:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93312:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85703:428;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92674:414;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91345:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57409:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92406:262;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30104:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49067:639;49152:4;49491:10;49476:25;;:11;:25;;;;:102;;;;49568:10;49553:25;;:11;:25;;;;49476:102;:179;;;;49645:10;49630:25;;:11;:25;;;;49476:179;49456:199;;49067:639;;;:::o;49969:100::-;50023:13;50056:5;50049:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49969:100;:::o;56460:218::-;56536:7;56561:16;56569:7;56561;:16::i;:::-;56556:64;;56586:34;;;;;;;;;;;;;;56556:64;56640:15;:24;56656:7;56640:24;;;;;;;;;;;:30;;;;;;;;;;;;56633:37;;56460:218;;;:::o;55893:408::-;55982:13;55998:16;56006:7;55998;:16::i;:::-;55982:32;;56054:5;56031:28;;:19;:17;:19::i;:::-;:28;;;56027:175;;56079:44;56096:5;56103:19;:17;:19::i;:::-;56079:16;:44::i;:::-;56074:128;;56151:35;;;;;;;;;;;;;;56074:128;56027:175;56247:2;56214:15;:24;56230:7;56214:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;56285:7;56281:2;56265:28;;56274:5;56265:28;;;;;;;;;;;;55971:330;55893:408;;:::o;91321:19::-;;;;:::o;93524:100::-;29084:13;:11;:13::i;:::-;93608:10:::1;93596:9;:22;;;;;;:::i;:::-;;93524:100:::0;:::o;93630:77::-;29084:13;:11;:13::i;:::-;93695:6:::1;93686;;:15;;;;;;;;;;;;;;;;;;93630:77:::0;:::o;45720:323::-;45781:7;46009:15;:13;:15::i;:::-;45994:12;;45978:13;;:28;:46;45971:53;;45720:323;:::o;60099:2825::-;60241:27;60271;60290:7;60271:18;:27::i;:::-;60241:57;;60356:4;60315:45;;60331:19;60315:45;;;60311:86;;60369:28;;;;;;;;;;;;;;60311:86;60411:27;60440:23;60467:35;60494:7;60467:26;:35::i;:::-;60410:92;;;;60602:68;60627:15;60644:4;60650:19;:17;:19::i;:::-;60602:24;:68::i;:::-;60597:180;;60690:43;60707:4;60713:19;:17;:19::i;:::-;60690:16;:43::i;:::-;60685:92;;60742:35;;;;;;;;;;;;;;60685:92;60597:180;60808:1;60794:16;;:2;:16;;;60790:52;;60819:23;;;;;;;;;;;;;;60790:52;60855:43;60877:4;60883:2;60887:7;60896:1;60855:21;:43::i;:::-;60991:15;60988:160;;;61131:1;61110:19;61103:30;60988:160;61528:18;:24;61547:4;61528:24;;;;;;;;;;;;;;;;61526:26;;;;;;;;;;;;61597:18;:22;61616:2;61597:22;;;;;;;;;;;;;;;;61595:24;;;;;;;;;;;61919:146;61956:2;62005:45;62020:4;62026:2;62030:19;62005:14;:45::i;:::-;42119:8;61977:73;61919:18;:146::i;:::-;61890:17;:26;61908:7;61890:26;;;;;;;;;;;:175;;;;62236:1;42119:8;62185:19;:47;:52;62181:627;;62258:19;62290:1;62280:7;:11;62258:33;;62447:1;62413:17;:30;62431:11;62413:30;;;;;;;;;;;;:35;62409:384;;62551:13;;62536:11;:28;62532:242;;62731:19;62698:17;:30;62716:11;62698:30;;;;;;;;;;;:52;;;;62532:242;62409:384;62239:569;62181:627;62855:7;62851:2;62836:27;;62845:4;62836:27;;;;;;;;;;;;62874:42;62895:4;62901:2;62905:7;62914:1;62874:20;:42::i;:::-;60230:2694;;;60099:2825;;;:::o;93713:150::-;29084:13;:11;:13::i;:::-;17398:1:::1;17996:7;;:19:::0;17988:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;17398:1;18129:7;:18;;;;93771:7:::2;93792;:5;:7::i;:::-;93784:21;;93813;93784:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93770:69;;;93854:2;93846:11;;;::::0;::::2;;93763:100;17354:1:::1;18308:7;:22;;;;93713:150::o:0;63020:193::-;63166:39;63183:4;63189:2;63193:7;63166:39;;;;;;;;;;;;:16;:39::i;:::-;63020:193;;;:::o;93096:74::-;29084:13;:11;:13::i;:::-;93159:5:::1;93152:4;:12;;;;93096:74:::0;:::o;91251:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;86290:528::-;86434:23;86500:22;86525:8;;:15;;86500:40;;86555:34;86613:14;86592:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;86555:73;;86648:9;86643:125;86664:14;86659:1;:19;86643:125;;86720:32;86740:8;;86749:1;86740:11;;;;;;;:::i;:::-;;;;;;;;86720:19;:32::i;:::-;86704:10;86715:1;86704:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;86680:3;;;;;86643:125;;;;86789:10;86782:17;;;;86290:528;;;;:::o;91500:25::-;;;;;;;;;;;;;:::o;91412:31::-;;;;:::o;91218:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;51362:152::-;51434:7;51477:27;51496:7;51477:18;:27::i;:::-;51454:52;;51362:152;;;:::o;46904:233::-;46976:7;47017:1;47000:19;;:5;:19;;;46996:60;;47028:28;;;;;;;;;;;;;;46996:60;41063:13;47074:18;:25;47093:5;47074:25;;;;;;;;;;;;;;;;:55;47067:62;;46904:233;;;:::o;29846:103::-;29084:13;:11;:13::i;:::-;29911:30:::1;29938:1;29911:18;:30::i;:::-;29846:103::o:0;93418:100::-;29084:13;:11;:13::i;:::-;93502:10:::1;93490:9;:22;;;;;;:::i;:::-;;93418:100:::0;:::o;91284:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;90166:900::-;90244:16;90298:19;90332:25;90372:22;90397:16;90407:5;90397:9;:16::i;:::-;90372:41;;90428:25;90470:14;90456:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90428:57;;90500:31;;:::i;:::-;90551:9;90563:15;:13;:15::i;:::-;90551:27;;90546:472;90595:14;90580:11;:29;90546:472;;90647:15;90660:1;90647:12;:15::i;:::-;90635:27;;90685:9;:16;;;90726:8;90681:73;90802:1;90776:28;;:9;:14;;;:28;;;90772:111;;90849:9;:14;;;90829:34;;90772:111;90926:5;90905:26;;:17;:26;;;90901:102;;90982:1;90956:8;90965:13;;;;;;90956:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;90901:102;90546:472;90611:3;;;;;90546:472;;;;91039:8;91032:15;;;;;;;90166:900;;;:::o;29198:87::-;29244:7;29271:6;;;;;;;;;;;29264:13;;29198:87;:::o;91374:33::-;;;;:::o;50145:104::-;50201:13;50234:7;50227:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50145:104;:::o;87206:2513::-;87349:16;87416:4;87407:5;:13;87403:45;;87429:19;;;;;;;;;;;;;;87403:45;87463:19;87497:17;87517:14;:12;:14::i;:::-;87497:34;;87617:15;:13;:15::i;:::-;87609:5;:23;87605:87;;;87661:15;:13;:15::i;:::-;87653:23;;87605:87;87768:9;87761:4;:16;87757:73;;;87805:9;87798:16;;87757:73;87844:25;87872:16;87882:5;87872:9;:16::i;:::-;87844:44;;88066:4;88058:5;:12;88054:278;;;88091:19;88120:5;88113:4;:12;88091:34;;88162:17;88148:11;:31;88144:111;;;88224:11;88204:31;;88144:111;88072:198;88054:278;;;88315:1;88295:21;;88054:278;88346:25;88388:17;88374:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88346:60;;88446:1;88425:17;:22;88421:78;;88475:8;88468:15;;;;;;;;88421:78;88643:31;88677:26;88697:5;88677:19;:26::i;:::-;88643:60;;88718:25;88963:9;:16;;;88958:92;;89020:9;:14;;;89000:34;;88958:92;89069:9;89081:5;89069:17;;89064:478;89093:4;89088:1;:9;;:45;;;;;89116:17;89101:11;:32;;89088:45;89064:478;;;89171:15;89184:1;89171:12;:15::i;:::-;89159:27;;89209:9;:16;;;89250:8;89205:73;89326:1;89300:28;;:9;:14;;;:28;;;89296:111;;89373:9;:14;;;89353:34;;89296:111;89450:5;89429:26;;:17;:26;;;89425:102;;89506:1;89480:8;89489:13;;;;;;89480:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;89425:102;89064:478;89135:3;;;;;89064:478;;;;89644:11;89634:8;89627:29;89692:8;89685:15;;;;;;;;87206:2513;;;;;;:::o;92076:322::-;92133:11;91827:1;91813:11;:15;:52;;;;;91847:18;;91832:11;:33;;91813:52;91805:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;91936:9;;91921:11;91905:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;91897:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;92027:4;92015:9;;:16;;;;:::i;:::-;92000:11;91985:12;;:26;;;;:::i;:::-;:46;;91977:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;92162:6:::1;;;;;;;;;;;92161:7;92153:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;92252:1;92237:11;92211:9;:23;92221:12;:10;:12::i;:::-;92211:23;;;;;;;;;;;;;;;;:37;;;;:::i;:::-;:42;;92203:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;92277:36;92287:12;:10;:12::i;:::-;92301:11;92277:9;:36::i;:::-;92347:11;92320:9;:23;92330:12;:10;:12::i;:::-;92320:23;;;;;;;;;;;;;;;;:38;;;;;;;:::i;:::-;;;;;;;;92381:11;92365:12;;:27;;;;;;;:::i;:::-;;;;;;;;92076:322:::0;;:::o;57018:234::-;57165:8;57113:18;:39;57132:19;:17;:19::i;:::-;57113:39;;;;;;;;;;;;;;;:49;57153:8;57113:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;57225:8;57189:55;;57204:19;:17;:19::i;:::-;57189:55;;;57235:8;57189:55;;;;;;:::i;:::-;;;;;;;;57018:234;;:::o;93176:130::-;29084:13;:11;:13::i;:::-;93281:19:::1;93260:18;:40;;;;93176:130:::0;:::o;63811:407::-;63986:31;63999:4;64005:2;64009:7;63986:12;:31::i;:::-;64050:1;64032:2;:14;;;:19;64028:183;;64071:56;64102:4;64108:2;64112:7;64121:5;64071:30;:56::i;:::-;64066:145;;64155:40;;;;;;;;;;;;;;64066:145;64028:183;63811:407;;;;:::o;93312:100::-;29084:13;:11;:13::i;:::-;93396:10:::1;93384:9;:22;;;;;;:::i;:::-;;93312:100:::0;:::o;85703:428::-;85787:21;;:::i;:::-;85821:31;;:::i;:::-;85877:15;:13;:15::i;:::-;85867:7;:25;:54;;;;85907:14;:12;:14::i;:::-;85896:7;:25;;85867:54;85863:103;;;85945:9;85938:16;;;;;85863:103;85988:21;86001:7;85988:12;:21::i;:::-;85976:33;;86024:9;:16;;;86020:65;;;86064:9;86057:16;;;;;86020:65;86102:21;86115:7;86102:12;:21::i;:::-;86095:28;;;85703:428;;;;:::o;92674:414::-;92767:13;92797:17;92805:8;92797:7;:17::i;:::-;92789:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;92875:28;92906:10;:8;:10::i;:::-;92875:41;;92961:1;92936:14;92930:28;:32;:152;;93072:9;92930:152;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92998:14;93014:26;93031:8;93014:16;:26::i;:::-;93042:9;92981:71;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;92930:152;92923:159;;;92674:414;;;:::o;91345:24::-;;;;:::o;57409:164::-;57506:4;57530:18;:25;57549:5;57530:25;;;;;;;;;;;;;;;:35;57556:8;57530:35;;;;;;;;;;;;;;;;;;;;;;;;;57523:42;;57409:164;;;;:::o;92406:262::-;29084:13;:11;:13::i;:::-;92516:1:::1;92502:11;:15;92494:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;92588:9;;92573:11;92557:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;92549:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;92629:33;92639:9;92650:11;92629:9;:33::i;:::-;92406:262:::0;;:::o;30104:201::-;29084:13;:11;:13::i;:::-;30213:1:::1;30193:22;;:8;:22;;::::0;30185:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;30269:28;30288:8;30269:18;:28::i;:::-;30104:201:::0;:::o;57831:282::-;57896:4;57952:7;57933:15;:13;:15::i;:::-;:26;;:66;;;;;57986:13;;57976:7;:23;57933:66;:153;;;;;58085:1;41839:8;58037:17;:26;58055:7;58037:26;;;;;;;;;;;;:44;:49;57933:153;57913:173;;57831:282;;;:::o;80139:105::-;80199:7;80226:10;80219:17;;80139:105;:::o;29363:132::-;29438:12;:10;:12::i;:::-;29427:23;;:7;:5;:7::i;:::-;:23;;;29419:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;29363:132::o;45236:92::-;45292:7;45236:92;:::o;52517:1275::-;52584:7;52604:12;52619:7;52604:22;;52687:4;52668:15;:13;:15::i;:::-;:23;52664:1061;;52721:13;;52714:4;:20;52710:1015;;;52759:14;52776:17;:23;52794:4;52776:23;;;;;;;;;;;;52759:40;;52893:1;41839:8;52865:6;:24;:29;52861:845;;53530:113;53547:1;53537:6;:11;53530:113;;53590:17;:25;53608:6;;;;;;;53590:25;;;;;;;;;;;;53581:34;;53530:113;;;53676:6;53669:13;;;;;;52861:845;52736:989;52710:1015;52664:1061;53753:31;;;;;;;;;;;;;;52517:1275;;;;:::o;58994:485::-;59096:27;59125:23;59166:38;59207:15;:24;59223:7;59207:24;;;;;;;;;;;59166:65;;59384:18;59361:41;;59441:19;59435:26;59416:45;;59346:126;58994:485;;;:::o;58222:659::-;58371:11;58536:16;58529:5;58525:28;58516:37;;58696:16;58685:9;58681:32;58668:45;;58846:15;58835:9;58832:30;58824:5;58813:9;58810:20;58807:56;58797:66;;58222:659;;;;;:::o;64880:159::-;;;;;:::o;79448:311::-;79583:7;79603:16;42243:3;79629:19;:41;;79603:68;;42243:3;79697:31;79708:4;79714:2;79718:9;79697:10;:31::i;:::-;79689:40;;:62;;79682:69;;;79448:311;;;;;:::o;54340:450::-;54420:14;54588:16;54581:5;54577:28;54568:37;;54765:5;54751:11;54726:23;54722:41;54719:52;54712:5;54709:63;54699:73;;54340:450;;;;:::o;65704:158::-;;;;;:::o;30465:191::-;30539:16;30558:6;;;;;;;;;;;30539:25;;30584:8;30575:6;;:17;;;;;;;;;;;;;;;;;;30639:8;30608:40;;30629:8;30608:40;;;;;;;;;;;;30528:128;30465:191;:::o;51965:161::-;52033:21;;:::i;:::-;52074:44;52093:17;:24;52111:5;52093:24;;;;;;;;;;;;52074:18;:44::i;:::-;52067:51;;51965:161;;;:::o;45407:103::-;45462:7;45489:13;;45482:20;;45407:103;:::o;27749:98::-;27802:7;27829:10;27822:17;;27749:98;:::o;73971:112::-;74048:27;74058:2;74062:8;74048:27;;;;;;;;;;;;:9;:27::i;:::-;73971:112;;:::o;66302:716::-;66465:4;66511:2;66486:45;;;66532:19;:17;:19::i;:::-;66553:4;66559:7;66568:5;66486:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;66482:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66786:1;66769:6;:13;:18;66765:235;;66815:40;;;;;;;;;;;;;;66765:235;66958:6;66952:13;66943:6;66939:2;66935:15;66928:38;66482:529;66655:54;;;66645:64;;;:6;:64;;;;66638:71;;;66302:716;;;;;;:::o;51703:166::-;51773:21;;:::i;:::-;51814:47;51833:27;51852:7;51833:18;:27::i;:::-;51814:18;:47::i;:::-;51807:54;;51703:166;;;:::o;93869:104::-;93929:13;93958:9;93951:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93869:104;:::o;430:723::-;486:13;716:1;707:5;:10;703:53;;734:10;;;;;;;;;;;;;;;;;;;;;703:53;766:12;781:5;766:20;;797:14;822:78;837:1;829:4;:9;822:78;;855:8;;;;;:::i;:::-;;;;886:2;878:10;;;;;:::i;:::-;;;822:78;;;910:19;942:6;932:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;910:39;;960:154;976:1;967:5;:10;960:154;;1004:1;994:11;;;;;:::i;:::-;;;1071:2;1063:5;:10;;;;:::i;:::-;1050:2;:24;;;;:::i;:::-;1037:39;;1020:6;1027;1020:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;1100:2;1091:11;;;;;:::i;:::-;;;960:154;;;1138:6;1124:21;;;;;430:723;;;;:::o;79149:147::-;79286:6;79149:147;;;;;:::o;53891:366::-;53957:31;;:::i;:::-;54034:6;54001:9;:14;;:41;;;;;;;;;;;41722:3;54087:6;:33;;54053:9;:24;;:68;;;;;;;;;;;54179:1;41839:8;54151:6;:24;:29;;54132:9;:16;;:48;;;;;;;;;;;42243:3;54220:6;:28;;54191:9;:19;;:58;;;;;;;;;;;53891:366;;;:::o;73198:689::-;73329:19;73335:2;73339:8;73329:5;:19::i;:::-;73408:1;73390:2;:14;;;:19;73386:483;;73430:11;73444:13;;73430:27;;73476:13;73498:8;73492:3;:14;73476:30;;73525:233;73556:62;73595:1;73599:2;73603:7;;;;;;73612:5;73556:30;:62::i;:::-;73551:167;;73654:40;;;;;;;;;;;;;;73551:167;73753:3;73745:5;:11;73525:233;;73840:3;73823:13;;:20;73819:34;;73845:8;;;73819:34;73411:458;;73386:483;73198:689;;;:::o;67480:2966::-;67553:20;67576:13;;67553:36;;67616:1;67604:8;:13;67600:44;;67626:18;;;;;;;;;;;;;;67600:44;67657:61;67687:1;67691:2;67695:12;67709:8;67657:21;:61::i;:::-;68201:1;41201:2;68171:1;:26;;68170:32;68158:8;:45;68132:18;:22;68151:2;68132:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;68480:139;68517:2;68571:33;68594:1;68598:2;68602:1;68571:14;:33::i;:::-;68538:30;68559:8;68538:20;:30::i;:::-;:66;68480:18;:139::i;:::-;68446:17;:31;68464:12;68446:31;;;;;;;;;;;:173;;;;68636:16;68667:11;68696:8;68681:12;:23;68667:37;;69217:16;69213:2;69209:25;69197:37;;69589:12;69549:8;69508:1;69446:25;69387:1;69326;69299:335;69960:1;69946:12;69942:20;69900:346;70001:3;69992:7;69989:16;69900:346;;70219:7;70209:8;70206:1;70179:25;70176:1;70173;70168:59;70054:1;70045:7;70041:15;70030:26;;69900:346;;;69904:77;70291:1;70279:8;:13;70275:45;;70301:19;;;;;;;;;;;;;;70275:45;70353:3;70337:13;:19;;;;67906:2462;;70378:60;70407:1;70411:2;70415:12;70429:8;70378:20;:60::i;:::-;67542:2904;67480:2966;;:::o;54892:324::-;54962:14;55195:1;55185:8;55182:15;55156:24;55152:46;55142:56;;54892:324;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:117::-;5351:1;5348;5341:12;5365:117;5474:1;5471;5464:12;5488:180;5536:77;5533:1;5526:88;5633:4;5630:1;5623:15;5657:4;5654:1;5647:15;5674:281;5757:27;5779:4;5757:27;:::i;:::-;5749:6;5745:40;5887:6;5875:10;5872:22;5851:18;5839:10;5836:34;5833:62;5830:88;;;5898:18;;:::i;:::-;5830:88;5938:10;5934:2;5927:22;5717:238;5674:281;;:::o;5961:129::-;5995:6;6022:20;;:::i;:::-;6012:30;;6051:33;6079:4;6071:6;6051:33;:::i;:::-;5961:129;;;:::o;6096:308::-;6158:4;6248:18;6240:6;6237:30;6234:56;;;6270:18;;:::i;:::-;6234:56;6308:29;6330:6;6308:29;:::i;:::-;6300:37;;6392:4;6386;6382:15;6374:23;;6096:308;;;:::o;6410:146::-;6507:6;6502:3;6497;6484:30;6548:1;6539:6;6534:3;6530:16;6523:27;6410:146;;;:::o;6562:425::-;6640:5;6665:66;6681:49;6723:6;6681:49;:::i;:::-;6665:66;:::i;:::-;6656:75;;6754:6;6747:5;6740:21;6792:4;6785:5;6781:16;6830:3;6821:6;6816:3;6812:16;6809:25;6806:112;;;6837:79;;:::i;:::-;6806:112;6927:54;6974:6;6969:3;6964;6927:54;:::i;:::-;6646:341;6562:425;;;;;:::o;7007:340::-;7063:5;7112:3;7105:4;7097:6;7093:17;7089:27;7079:122;;7120:79;;:::i;:::-;7079:122;7237:6;7224:20;7262:79;7337:3;7329:6;7322:4;7314:6;7310:17;7262:79;:::i;:::-;7253:88;;7069:278;7007:340;;;;:::o;7353:509::-;7422:6;7471:2;7459:9;7450:7;7446:23;7442:32;7439:119;;;7477:79;;:::i;:::-;7439:119;7625:1;7614:9;7610:17;7597:31;7655:18;7647:6;7644:30;7641:117;;;7677:79;;:::i;:::-;7641:117;7782:63;7837:7;7828:6;7817:9;7813:22;7782:63;:::i;:::-;7772:73;;7568:287;7353:509;;;;:::o;7868:116::-;7938:21;7953:5;7938:21;:::i;:::-;7931:5;7928:32;7918:60;;7974:1;7971;7964:12;7918:60;7868:116;:::o;7990:133::-;8033:5;8071:6;8058:20;8049:29;;8087:30;8111:5;8087:30;:::i;:::-;7990:133;;;;:::o;8129:323::-;8185:6;8234:2;8222:9;8213:7;8209:23;8205:32;8202:119;;;8240:79;;:::i;:::-;8202:119;8360:1;8385:50;8427:7;8418:6;8407:9;8403:22;8385:50;:::i;:::-;8375:60;;8331:114;8129:323;;;;:::o;8458:619::-;8535:6;8543;8551;8600:2;8588:9;8579:7;8575:23;8571:32;8568:119;;;8606:79;;:::i;:::-;8568:119;8726:1;8751:53;8796:7;8787:6;8776:9;8772:22;8751:53;:::i;:::-;8741:63;;8697:117;8853:2;8879:53;8924:7;8915:6;8904:9;8900:22;8879:53;:::i;:::-;8869:63;;8824:118;8981:2;9007:53;9052:7;9043:6;9032:9;9028:22;9007:53;:::i;:::-;8997:63;;8952:118;8458:619;;;;;:::o;9083:117::-;9192:1;9189;9182:12;9206:117;9315:1;9312;9305:12;9346:568;9419:8;9429:6;9479:3;9472:4;9464:6;9460:17;9456:27;9446:122;;9487:79;;:::i;:::-;9446:122;9600:6;9587:20;9577:30;;9630:18;9622:6;9619:30;9616:117;;;9652:79;;:::i;:::-;9616:117;9766:4;9758:6;9754:17;9742:29;;9820:3;9812:4;9804:6;9800:17;9790:8;9786:32;9783:41;9780:128;;;9827:79;;:::i;:::-;9780:128;9346:568;;;;;:::o;9920:559::-;10006:6;10014;10063:2;10051:9;10042:7;10038:23;10034:32;10031:119;;;10069:79;;:::i;:::-;10031:119;10217:1;10206:9;10202:17;10189:31;10247:18;10239:6;10236:30;10233:117;;;10269:79;;:::i;:::-;10233:117;10382:80;10454:7;10445:6;10434:9;10430:22;10382:80;:::i;:::-;10364:98;;;;10160:312;9920:559;;;;;:::o;10485:146::-;10584:6;10618:5;10612:12;10602:22;;10485:146;;;:::o;10637:216::-;10768:11;10802:6;10797:3;10790:19;10842:4;10837:3;10833:14;10818:29;;10637:216;;;;:::o;10859:164::-;10958:4;10981:3;10973:11;;11011:4;11006:3;11002:14;10994:22;;10859:164;;;:::o;11029:108::-;11106:24;11124:5;11106:24;:::i;:::-;11101:3;11094:37;11029:108;;:::o;11143:101::-;11179:7;11219:18;11212:5;11208:30;11197:41;;11143:101;;;:::o;11250:105::-;11325:23;11342:5;11325:23;:::i;:::-;11320:3;11313:36;11250:105;;:::o;11361:99::-;11432:21;11447:5;11432:21;:::i;:::-;11427:3;11420:34;11361:99;;:::o;11466:91::-;11502:7;11542:8;11535:5;11531:20;11520:31;;11466:91;;;:::o;11563:105::-;11638:23;11655:5;11638:23;:::i;:::-;11633:3;11626:36;11563:105;;:::o;11746:866::-;11897:4;11892:3;11888:14;11984:4;11977:5;11973:16;11967:23;12003:63;12060:4;12055:3;12051:14;12037:12;12003:63;:::i;:::-;11912:164;12168:4;12161:5;12157:16;12151:23;12187:61;12242:4;12237:3;12233:14;12219:12;12187:61;:::i;:::-;12086:172;12342:4;12335:5;12331:16;12325:23;12361:57;12412:4;12407:3;12403:14;12389:12;12361:57;:::i;:::-;12268:160;12515:4;12508:5;12504:16;12498:23;12534:61;12589:4;12584:3;12580:14;12566:12;12534:61;:::i;:::-;12438:167;11866:746;11746:866;;:::o;12618:307::-;12751:10;12772:110;12878:3;12870:6;12772:110;:::i;:::-;12914:4;12909:3;12905:14;12891:28;;12618:307;;;;:::o;12931:145::-;13033:4;13065;13060:3;13056:14;13048:22;;12931:145;;;:::o;13158:988::-;13341:3;13370:86;13450:5;13370:86;:::i;:::-;13472:118;13583:6;13578:3;13472:118;:::i;:::-;13465:125;;13614:88;13696:5;13614:88;:::i;:::-;13725:7;13756:1;13741:380;13766:6;13763:1;13760:13;13741:380;;;13842:6;13836:13;13869:127;13992:3;13977:13;13869:127;:::i;:::-;13862:134;;14019:92;14104:6;14019:92;:::i;:::-;14009:102;;13801:320;13788:1;13785;13781:9;13776:14;;13741:380;;;13745:14;14137:3;14130:10;;13346:800;;;13158:988;;;;:::o;14152:501::-;14359:4;14397:2;14386:9;14382:18;14374:26;;14446:9;14440:4;14436:20;14432:1;14421:9;14417:17;14410:47;14474:172;14641:4;14632:6;14474:172;:::i;:::-;14466:180;;14152:501;;;;:::o;14659:329::-;14718:6;14767:2;14755:9;14746:7;14742:23;14738:32;14735:119;;;14773:79;;:::i;:::-;14735:119;14893:1;14918:53;14963:7;14954:6;14943:9;14939:22;14918:53;:::i;:::-;14908:63;;14864:117;14659:329;;;;:::o;14994:114::-;15061:6;15095:5;15089:12;15079:22;;14994:114;;;:::o;15114:184::-;15213:11;15247:6;15242:3;15235:19;15287:4;15282:3;15278:14;15263:29;;15114:184;;;;:::o;15304:132::-;15371:4;15394:3;15386:11;;15424:4;15419:3;15415:14;15407:22;;15304:132;;;:::o;15442:108::-;15519:24;15537:5;15519:24;:::i;:::-;15514:3;15507:37;15442:108;;:::o;15556:179::-;15625:10;15646:46;15688:3;15680:6;15646:46;:::i;:::-;15724:4;15719:3;15715:14;15701:28;;15556:179;;;;:::o;15741:113::-;15811:4;15843;15838:3;15834:14;15826:22;;15741:113;;;:::o;15890:732::-;16009:3;16038:54;16086:5;16038:54;:::i;:::-;16108:86;16187:6;16182:3;16108:86;:::i;:::-;16101:93;;16218:56;16268:5;16218:56;:::i;:::-;16297:7;16328:1;16313:284;16338:6;16335:1;16332:13;16313:284;;;16414:6;16408:13;16441:63;16500:3;16485:13;16441:63;:::i;:::-;16434:70;;16527:60;16580:6;16527:60;:::i;:::-;16517:70;;16373:224;16360:1;16357;16353:9;16348:14;;16313:284;;;16317:14;16613:3;16606:10;;16014:608;;;15890:732;;;;:::o;16628:373::-;16771:4;16809:2;16798:9;16794:18;16786:26;;16858:9;16852:4;16848:20;16844:1;16833:9;16829:17;16822:47;16886:108;16989:4;16980:6;16886:108;:::i;:::-;16878:116;;16628:373;;;;:::o;17007:619::-;17084:6;17092;17100;17149:2;17137:9;17128:7;17124:23;17120:32;17117:119;;;17155:79;;:::i;:::-;17117:119;17275:1;17300:53;17345:7;17336:6;17325:9;17321:22;17300:53;:::i;:::-;17290:63;;17246:117;17402:2;17428:53;17473:7;17464:6;17453:9;17449:22;17428:53;:::i;:::-;17418:63;;17373:118;17530:2;17556:53;17601:7;17592:6;17581:9;17577:22;17556:53;:::i;:::-;17546:63;;17501:118;17007:619;;;;;:::o;17632:468::-;17697:6;17705;17754:2;17742:9;17733:7;17729:23;17725:32;17722:119;;;17760:79;;:::i;:::-;17722:119;17880:1;17905:53;17950:7;17941:6;17930:9;17926:22;17905:53;:::i;:::-;17895:63;;17851:117;18007:2;18033:50;18075:7;18066:6;18055:9;18051:22;18033:50;:::i;:::-;18023:60;;17978:115;17632:468;;;;;:::o;18106:307::-;18167:4;18257:18;18249:6;18246:30;18243:56;;;18279:18;;:::i;:::-;18243:56;18317:29;18339:6;18317:29;:::i;:::-;18309:37;;18401:4;18395;18391:15;18383:23;;18106:307;;;:::o;18419:423::-;18496:5;18521:65;18537:48;18578:6;18537:48;:::i;:::-;18521:65;:::i;:::-;18512:74;;18609:6;18602:5;18595:21;18647:4;18640:5;18636:16;18685:3;18676:6;18671:3;18667:16;18664:25;18661:112;;;18692:79;;:::i;:::-;18661:112;18782:54;18829:6;18824:3;18819;18782:54;:::i;:::-;18502:340;18419:423;;;;;:::o;18861:338::-;18916:5;18965:3;18958:4;18950:6;18946:17;18942:27;18932:122;;18973:79;;:::i;:::-;18932:122;19090:6;19077:20;19115:78;19189:3;19181:6;19174:4;19166:6;19162:17;19115:78;:::i;:::-;19106:87;;18922:277;18861:338;;;;:::o;19205:943::-;19300:6;19308;19316;19324;19373:3;19361:9;19352:7;19348:23;19344:33;19341:120;;;19380:79;;:::i;:::-;19341:120;19500:1;19525:53;19570:7;19561:6;19550:9;19546:22;19525:53;:::i;:::-;19515:63;;19471:117;19627:2;19653:53;19698:7;19689:6;19678:9;19674:22;19653:53;:::i;:::-;19643:63;;19598:118;19755:2;19781:53;19826:7;19817:6;19806:9;19802:22;19781:53;:::i;:::-;19771:63;;19726:118;19911:2;19900:9;19896:18;19883:32;19942:18;19934:6;19931:30;19928:117;;;19964:79;;:::i;:::-;19928:117;20069:62;20123:7;20114:6;20103:9;20099:22;20069:62;:::i;:::-;20059:72;;19854:287;19205:943;;;;;;;:::o;20226:876::-;20387:4;20382:3;20378:14;20474:4;20467:5;20463:16;20457:23;20493:63;20550:4;20545:3;20541:14;20527:12;20493:63;:::i;:::-;20402:164;20658:4;20651:5;20647:16;20641:23;20677:61;20732:4;20727:3;20723:14;20709:12;20677:61;:::i;:::-;20576:172;20832:4;20825:5;20821:16;20815:23;20851:57;20902:4;20897:3;20893:14;20879:12;20851:57;:::i;:::-;20758:160;21005:4;20998:5;20994:16;20988:23;21024:61;21079:4;21074:3;21070:14;21056:12;21024:61;:::i;:::-;20928:167;20356:746;20226:876;;:::o;21108:351::-;21265:4;21303:3;21292:9;21288:19;21280:27;;21317:135;21449:1;21438:9;21434:17;21425:6;21317:135;:::i;:::-;21108:351;;;;:::o;21465:474::-;21533:6;21541;21590:2;21578:9;21569:7;21565:23;21561:32;21558:119;;;21596:79;;:::i;:::-;21558:119;21716:1;21741:53;21786:7;21777:6;21766:9;21762:22;21741:53;:::i;:::-;21731:63;;21687:117;21843:2;21869:53;21914:7;21905:6;21894:9;21890:22;21869:53;:::i;:::-;21859:63;;21814:118;21465:474;;;;;:::o;21945:::-;22013:6;22021;22070:2;22058:9;22049:7;22045:23;22041:32;22038:119;;;22076:79;;:::i;:::-;22038:119;22196:1;22221:53;22266:7;22257:6;22246:9;22242:22;22221:53;:::i;:::-;22211:63;;22167:117;22323:2;22349:53;22394:7;22385:6;22374:9;22370:22;22349:53;:::i;:::-;22339:63;;22294:118;21945:474;;;;;:::o;22425:180::-;22473:77;22470:1;22463:88;22570:4;22567:1;22560:15;22594:4;22591:1;22584:15;22611:320;22655:6;22692:1;22686:4;22682:12;22672:22;;22739:1;22733:4;22729:12;22760:18;22750:81;;22816:4;22808:6;22804:17;22794:27;;22750:81;22878:2;22870:6;22867:14;22847:18;22844:38;22841:84;;22897:18;;:::i;:::-;22841:84;22662:269;22611:320;;;:::o;22937:141::-;22986:4;23009:3;23001:11;;23032:3;23029:1;23022:14;23066:4;23063:1;23053:18;23045:26;;22937:141;;;:::o;23084:93::-;23121:6;23168:2;23163;23156:5;23152:14;23148:23;23138:33;;23084:93;;;:::o;23183:107::-;23227:8;23277:5;23271:4;23267:16;23246:37;;23183:107;;;;:::o;23296:393::-;23365:6;23415:1;23403:10;23399:18;23438:97;23468:66;23457:9;23438:97;:::i;:::-;23556:39;23586:8;23575:9;23556:39;:::i;:::-;23544:51;;23628:4;23624:9;23617:5;23613:21;23604:30;;23677:4;23667:8;23663:19;23656:5;23653:30;23643:40;;23372:317;;23296:393;;;;;:::o;23695:60::-;23723:3;23744:5;23737:12;;23695:60;;;:::o;23761:142::-;23811:9;23844:53;23862:34;23871:24;23889:5;23871:24;:::i;:::-;23862:34;:::i;:::-;23844:53;:::i;:::-;23831:66;;23761:142;;;:::o;23909:75::-;23952:3;23973:5;23966:12;;23909:75;;;:::o;23990:269::-;24100:39;24131:7;24100:39;:::i;:::-;24161:91;24210:41;24234:16;24210:41;:::i;:::-;24202:6;24195:4;24189:11;24161:91;:::i;:::-;24155:4;24148:105;24066:193;23990:269;;;:::o;24265:73::-;24310:3;24265:73;:::o;24344:189::-;24421:32;;:::i;:::-;24462:65;24520:6;24512;24506:4;24462:65;:::i;:::-;24397:136;24344:189;;:::o;24539:186::-;24599:120;24616:3;24609:5;24606:14;24599:120;;;24670:39;24707:1;24700:5;24670:39;:::i;:::-;24643:1;24636:5;24632:13;24623:22;;24599:120;;;24539:186;;:::o;24731:543::-;24832:2;24827:3;24824:11;24821:446;;;24866:38;24898:5;24866:38;:::i;:::-;24950:29;24968:10;24950:29;:::i;:::-;24940:8;24936:44;25133:2;25121:10;25118:18;25115:49;;;25154:8;25139:23;;25115:49;25177:80;25233:22;25251:3;25233:22;:::i;:::-;25223:8;25219:37;25206:11;25177:80;:::i;:::-;24836:431;;24821:446;24731:543;;;:::o;25280:117::-;25334:8;25384:5;25378:4;25374:16;25353:37;;25280:117;;;;:::o;25403:169::-;25447:6;25480:51;25528:1;25524:6;25516:5;25513:1;25509:13;25480:51;:::i;:::-;25476:56;25561:4;25555;25551:15;25541:25;;25454:118;25403:169;;;;:::o;25577:295::-;25653:4;25799:29;25824:3;25818:4;25799:29;:::i;:::-;25791:37;;25861:3;25858:1;25854:11;25848:4;25845:21;25837:29;;25577:295;;;;:::o;25877:1395::-;25994:37;26027:3;25994:37;:::i;:::-;26096:18;26088:6;26085:30;26082:56;;;26118:18;;:::i;:::-;26082:56;26162:38;26194:4;26188:11;26162:38;:::i;:::-;26247:67;26307:6;26299;26293:4;26247:67;:::i;:::-;26341:1;26365:4;26352:17;;26397:2;26389:6;26386:14;26414:1;26409:618;;;;27071:1;27088:6;27085:77;;;27137:9;27132:3;27128:19;27122:26;27113:35;;27085:77;27188:67;27248:6;27241:5;27188:67;:::i;:::-;27182:4;27175:81;27044:222;26379:887;;26409:618;26461:4;26457:9;26449:6;26445:22;26495:37;26527:4;26495:37;:::i;:::-;26554:1;26568:208;26582:7;26579:1;26576:14;26568:208;;;26661:9;26656:3;26652:19;26646:26;26638:6;26631:42;26712:1;26704:6;26700:14;26690:24;;26759:2;26748:9;26744:18;26731:31;;26605:4;26602:1;26598:12;26593:17;;26568:208;;;26804:6;26795:7;26792:19;26789:179;;;26862:9;26857:3;26853:19;26847:26;26905:48;26947:4;26939:6;26935:17;26924:9;26905:48;:::i;:::-;26897:6;26890:64;26812:156;26789:179;27014:1;27010;27002:6;26998:14;26994:22;26988:4;26981:36;26416:611;;;26379:887;;25969:1303;;;25877:1395;;:::o;27278:181::-;27418:33;27414:1;27406:6;27402:14;27395:57;27278:181;:::o;27465:366::-;27607:3;27628:67;27692:2;27687:3;27628:67;:::i;:::-;27621:74;;27704:93;27793:3;27704:93;:::i;:::-;27822:2;27817:3;27813:12;27806:19;;27465:366;;;:::o;27837:419::-;28003:4;28041:2;28030:9;28026:18;28018:26;;28090:9;28084:4;28080:20;28076:1;28065:9;28061:17;28054:47;28118:131;28244:4;28118:131;:::i;:::-;28110:139;;27837:419;;;:::o;28262:147::-;28363:11;28400:3;28385:18;;28262:147;;;;:::o;28415:114::-;;:::o;28535:398::-;28694:3;28715:83;28796:1;28791:3;28715:83;:::i;:::-;28708:90;;28807:93;28896:3;28807:93;:::i;:::-;28925:1;28920:3;28916:11;28909:18;;28535:398;;;:::o;28939:379::-;29123:3;29145:147;29288:3;29145:147;:::i;:::-;29138:154;;29309:3;29302:10;;28939:379;;;:::o;29324:180::-;29372:77;29369:1;29362:88;29469:4;29466:1;29459:15;29493:4;29490:1;29483:15;29510:170;29650:22;29646:1;29638:6;29634:14;29627:46;29510:170;:::o;29686:366::-;29828:3;29849:67;29913:2;29908:3;29849:67;:::i;:::-;29842:74;;29925:93;30014:3;29925:93;:::i;:::-;30043:2;30038:3;30034:12;30027:19;;29686:366;;;:::o;30058:419::-;30224:4;30262:2;30251:9;30247:18;30239:26;;30311:9;30305:4;30301:20;30297:1;30286:9;30282:17;30275:47;30339:131;30465:4;30339:131;:::i;:::-;30331:139;;30058:419;;;:::o;30483:180::-;30531:77;30528:1;30521:88;30628:4;30625:1;30618:15;30652:4;30649:1;30642:15;30669:191;30709:3;30728:20;30746:1;30728:20;:::i;:::-;30723:25;;30762:20;30780:1;30762:20;:::i;:::-;30757:25;;30805:1;30802;30798:9;30791:16;;30826:3;30823:1;30820:10;30817:36;;;30833:18;;:::i;:::-;30817:36;30669:191;;;;:::o;30866:170::-;31006:22;31002:1;30994:6;30990:14;30983:46;30866:170;:::o;31042:366::-;31184:3;31205:67;31269:2;31264:3;31205:67;:::i;:::-;31198:74;;31281:93;31370:3;31281:93;:::i;:::-;31399:2;31394:3;31390:12;31383:19;;31042:366;;;:::o;31414:419::-;31580:4;31618:2;31607:9;31603:18;31595:26;;31667:9;31661:4;31657:20;31653:1;31642:9;31638:17;31631:47;31695:131;31821:4;31695:131;:::i;:::-;31687:139;;31414:419;;;:::o;31839:194::-;31879:4;31899:20;31917:1;31899:20;:::i;:::-;31894:25;;31933:20;31951:1;31933:20;:::i;:::-;31928:25;;31977:1;31974;31970:9;31962:17;;32001:1;31995:4;31992:11;31989:37;;;32006:18;;:::i;:::-;31989:37;31839:194;;;;:::o;32039:173::-;32179:25;32175:1;32167:6;32163:14;32156:49;32039:173;:::o;32218:366::-;32360:3;32381:67;32445:2;32440:3;32381:67;:::i;:::-;32374:74;;32457:93;32546:3;32457:93;:::i;:::-;32575:2;32570:3;32566:12;32559:19;;32218:366;;;:::o;32590:419::-;32756:4;32794:2;32783:9;32779:18;32771:26;;32843:9;32837:4;32833:20;32829:1;32818:9;32814:17;32807:47;32871:131;32997:4;32871:131;:::i;:::-;32863:139;;32590:419;;;:::o;33015:162::-;33155:14;33151:1;33143:6;33139:14;33132:38;33015:162;:::o;33183:366::-;33325:3;33346:67;33410:2;33405:3;33346:67;:::i;:::-;33339:74;;33422:93;33511:3;33422:93;:::i;:::-;33540:2;33535:3;33531:12;33524:19;;33183:366;;;:::o;33555:419::-;33721:4;33759:2;33748:9;33744:18;33736:26;;33808:9;33802:4;33798:20;33794:1;33783:9;33779:17;33772:47;33836:131;33962:4;33836:131;:::i;:::-;33828:139;;33555:419;;;:::o;33980:234::-;34120:34;34116:1;34108:6;34104:14;34097:58;34189:17;34184:2;34176:6;34172:15;34165:42;33980:234;:::o;34220:366::-;34362:3;34383:67;34447:2;34442:3;34383:67;:::i;:::-;34376:74;;34459:93;34548:3;34459:93;:::i;:::-;34577:2;34572:3;34568:12;34561:19;;34220:366;;;:::o;34592:419::-;34758:4;34796:2;34785:9;34781:18;34773:26;;34845:9;34839:4;34835:20;34831:1;34820:9;34816:17;34809:47;34873:131;34999:4;34873:131;:::i;:::-;34865:139;;34592:419;;;:::o;35017:148::-;35119:11;35156:3;35141:18;;35017:148;;;;:::o;35171:390::-;35277:3;35305:39;35338:5;35305:39;:::i;:::-;35360:89;35442:6;35437:3;35360:89;:::i;:::-;35353:96;;35458:65;35516:6;35511:3;35504:4;35497:5;35493:16;35458:65;:::i;:::-;35548:6;35543:3;35539:16;35532:23;;35281:280;35171:390;;;;:::o;35591:874::-;35694:3;35731:5;35725:12;35760:36;35786:9;35760:36;:::i;:::-;35812:89;35894:6;35889:3;35812:89;:::i;:::-;35805:96;;35932:1;35921:9;35917:17;35948:1;35943:166;;;;36123:1;36118:341;;;;35910:549;;35943:166;36027:4;36023:9;36012;36008:25;36003:3;35996:38;36089:6;36082:14;36075:22;36067:6;36063:35;36058:3;36054:45;36047:52;;35943:166;;36118:341;36185:38;36217:5;36185:38;:::i;:::-;36245:1;36259:154;36273:6;36270:1;36267:13;36259:154;;;36347:7;36341:14;36337:1;36332:3;36328:11;36321:35;36397:1;36388:7;36384:15;36373:26;;36295:4;36292:1;36288:12;36283:17;;36259:154;;;36442:6;36437:3;36433:16;36426:23;;36125:334;;35910:549;;35698:767;;35591:874;;;;:::o;36471:589::-;36696:3;36718:95;36809:3;36800:6;36718:95;:::i;:::-;36711:102;;36830:95;36921:3;36912:6;36830:95;:::i;:::-;36823:102;;36942:92;37030:3;37021:6;36942:92;:::i;:::-;36935:99;;37051:3;37044:10;;36471:589;;;;;;:::o;37066:225::-;37206:34;37202:1;37194:6;37190:14;37183:58;37275:8;37270:2;37262:6;37258:15;37251:33;37066:225;:::o;37297:366::-;37439:3;37460:67;37524:2;37519:3;37460:67;:::i;:::-;37453:74;;37536:93;37625:3;37536:93;:::i;:::-;37654:2;37649:3;37645:12;37638:19;;37297:366;;;:::o;37669:419::-;37835:4;37873:2;37862:9;37858:18;37850:26;;37922:9;37916:4;37912:20;37908:1;37897:9;37893:17;37886:47;37950:131;38076:4;37950:131;:::i;:::-;37942:139;;37669:419;;;:::o;38094:182::-;38234:34;38230:1;38222:6;38218:14;38211:58;38094:182;:::o;38282:366::-;38424:3;38445:67;38509:2;38504:3;38445:67;:::i;:::-;38438:74;;38521:93;38610:3;38521:93;:::i;:::-;38639:2;38634:3;38630:12;38623:19;;38282:366;;;:::o;38654:419::-;38820:4;38858:2;38847:9;38843:18;38835:26;;38907:9;38901:4;38897:20;38893:1;38882:9;38878:17;38871:47;38935:131;39061:4;38935:131;:::i;:::-;38927:139;;38654:419;;;:::o;39079:98::-;39130:6;39164:5;39158:12;39148:22;;39079:98;;;:::o;39183:168::-;39266:11;39300:6;39295:3;39288:19;39340:4;39335:3;39331:14;39316:29;;39183:168;;;;:::o;39357:373::-;39443:3;39471:38;39503:5;39471:38;:::i;:::-;39525:70;39588:6;39583:3;39525:70;:::i;:::-;39518:77;;39604:65;39662:6;39657:3;39650:4;39643:5;39639:16;39604:65;:::i;:::-;39694:29;39716:6;39694:29;:::i;:::-;39689:3;39685:39;39678:46;;39447:283;39357:373;;;;:::o;39736:640::-;39931:4;39969:3;39958:9;39954:19;39946:27;;39983:71;40051:1;40040:9;40036:17;40027:6;39983:71;:::i;:::-;40064:72;40132:2;40121:9;40117:18;40108:6;40064:72;:::i;:::-;40146;40214:2;40203:9;40199:18;40190:6;40146:72;:::i;:::-;40265:9;40259:4;40255:20;40250:2;40239:9;40235:18;40228:48;40293:76;40364:4;40355:6;40293:76;:::i;:::-;40285:84;;39736:640;;;;;;;:::o;40382:141::-;40438:5;40469:6;40463:13;40454:22;;40485:32;40511:5;40485:32;:::i;:::-;40382:141;;;;:::o;40529:349::-;40598:6;40647:2;40635:9;40626:7;40622:23;40618:32;40615:119;;;40653:79;;:::i;:::-;40615:119;40773:1;40798:63;40853:7;40844:6;40833:9;40829:22;40798:63;:::i;:::-;40788:73;;40744:127;40529:349;;;;:::o;40884:233::-;40923:3;40946:24;40964:5;40946:24;:::i;:::-;40937:33;;40992:66;40985:5;40982:77;40979:103;;41062:18;;:::i;:::-;40979:103;41109:1;41102:5;41098:13;41091:20;;40884:233;;;:::o;41123:180::-;41171:77;41168:1;41161:88;41268:4;41265:1;41258:15;41292:4;41289:1;41282:15;41309:185;41349:1;41366:20;41384:1;41366:20;:::i;:::-;41361:25;;41400:20;41418:1;41400:20;:::i;:::-;41395:25;;41439:1;41429:35;;41444:18;;:::i;:::-;41429:35;41486:1;41483;41479:9;41474:14;;41309:185;;;;:::o;41500:176::-;41532:1;41549:20;41567:1;41549:20;:::i;:::-;41544:25;;41583:20;41601:1;41583:20;:::i;:::-;41578:25;;41622:1;41612:35;;41627:18;;:::i;:::-;41612:35;41668:1;41665;41661:9;41656:14;;41500:176;;;;:::o

Swarm Source

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