ETH Price: $3,270.15 (+0.84%)
Gas: 2 Gwei

Token

Kyojin Senshi (KYO)
 

Overview

Max Total Supply

3,200 KYO

Holders

0

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 0 Decimals)

Balance
1 KYO

Value
$0.00
0x5b033b4e794136f763e82eba877df6fddfb1f1ea
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:
KyojinSenshi

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-02-26
*/

// SPDX-License-Identifier: MIT
// 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/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol


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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol


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

pragma solidity ^0.8.0;


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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/interfaces/IERC2981.sol


// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(
        uint256 tokenId,
        uint256 salePrice
    ) external view returns (address receiver, uint256 royaltyAmount);
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/common/ERC2981.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;



/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

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

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

// File: operator-filter-registry/src/lib/Constants.sol


pragma solidity ^0.8.17;

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

// File: operator-filter-registry/src/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: operator-filter-registry/src/OperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 *         Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract OperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS);

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

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

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

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

// File: operator-filter-registry/src/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 * @dev    Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol


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

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * 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.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
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 simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _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}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _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 sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds 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 from 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) {
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds 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 from 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) {
            unchecked {
                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: contracts/Nft_Staking.sol


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

pragma solidity ^0.8.4;

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
    );
}

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

        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 Returns whether the ownership slot at `index` is initialized.
     * An uninitialized slot does not necessarily mean that the slot has no owner.
     */
    function _ownershipIsInitialized(uint256 index)
        internal
        view
        virtual
        returns (bool)
    {
        return _packedOwnerships[index] != 0;
    }

    /**
     * @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 packed)
    {
        if (_startTokenId() <= tokenId) {
            packed = _packedOwnerships[tokenId];
            // If the data at the starting slot does not exist, start the scan.
            if (packed == 0) {
                if (tokenId >= _currentIndex)
                    _revert(OwnerQueryForNonexistentToken.selector);
                // 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, `tokenId` will not underflow.
                //
                // We can directly compare the packed value.
                // If the address is zero, packed will be zero.
                for (;;) {
                    unchecked {
                        packed = _packedOwnerships[--tokenId];
                    }
                    if (packed == 0) continue;
                    if (packed & _BITMASK_BURNED == 0) return packed;
                    // Otherwise, the token is burned, and we must revert.
                    // This handles the case of batch burned tokens, where only the burned bit
                    // of the starting slot is set, and remaining slots are left uninitialized.
                    _revert(OwnerQueryForNonexistentToken.selector);
                }
            }
            // Otherwise, the data exists and we can skip the scan.
            // This is possible because we have already achieved the target condition.
            // This saves 2143 gas on transfers of initialized tokens.
            // If the token is not burned, return `packed`. Otherwise, revert.
            if (packed & _BITMASK_BURNED == 0) return packed;
        }
        _revert(OwnerQueryForNonexistentToken.selector);
    }

    /**
     * @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. See {ERC721A-_approve}.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     */
    function approve(address to, uint256 tokenId)
        public
        payable
        virtual
        override
    {
        _approve(to, tokenId, true);
    }

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

        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 result)
    {
        if (_startTokenId() <= tokenId) {
            if (tokenId < _currentIndex) {
                uint256 packed;
                while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId;
                result = packed & _BITMASK_BURNED == 0;
            }
        }
    }

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

        // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
        from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS));

        if (address(uint160(prevOwnershipPacked)) != from)
            _revert(TransferFromIncorrectOwner.selector);

        (
            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.selector);

        _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;
                    }
                }
            }
        }

        // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
        uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
        assembly {
            // 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.
                from, // `from`.
                toMasked, // `to`.
                tokenId // `tokenId`.
            )
        }
        if (toMasked == 0) _revert(TransferToZeroAddress.selector);

        _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.selector);
            }
    }

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

        _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:
            // - `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)
            );

            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] +=
                quantity *
                ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
            uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;

            if (toMasked == 0) _revert(MintToZeroAddress.selector);

            uint256 end = startTokenId + quantity;
            uint256 tokenId = startTokenId;

            do {
                assembly {
                    // 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`.
                        tokenId // `tokenId`.
                    )
                }
                // The `!=` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
            } while (++tokenId != end);

            _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.selector);
        if (quantity == 0) _revert(MintZeroQuantity.selector);
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT)
            _revert(MintERC2309QuantityExceedsLimit.selector);

        _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.selector
                        );
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) _revert(bytes4(0));
            }
        }
    }

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

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

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

    /**
     * @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:
     *
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        bool approvalCheck
    ) internal virtual {
        address owner = ownerOf(tokenId);

        if (approvalCheck && _msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                _revert(ApprovalCallerNotOwnerNorApproved.selector);
            }

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

    // =============================================================
    //                        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.selector);
        }

        _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.selector);
        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)
        }
    }

    /**
     * @dev For more efficient reverts.
     */
    function _revert(bytes4 errorSelector) internal pure {
        assembly {
            mstore(0x00, errorSelector)
            revert(0x00, 0x04)
        }
    }
}

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);
}

/**
 * @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 ownership)
    {
        unchecked {
            if (tokenId >= _startTokenId()) {
                if (tokenId < _nextTokenId()) {
                    // If the `tokenId` is within bounds,
                    // scan backwards for the initialized ownership slot.
                    while (!_ownershipIsInitialized(tokenId)) --tokenId;
                    return _ownershipAt(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)
    {
        TokenOwnership[] memory ownerships;
        uint256 i = tokenIds.length;
        assembly {
            // Grab the free memory pointer.
            ownerships := mload(0x40)
            // Store the length.
            mstore(ownerships, i)
            // Allocate one word for the length,
            // `tokenIds.length` words for the pointers.
            i := shl(5, i) // Multiply `i` by 32.
            mstore(0x40, add(add(ownerships, 0x20), i))
        }
        while (i != 0) {
            uint256 tokenId;
            assembly {
                i := sub(i, 0x20)
                tokenId := calldataload(add(tokenIds.offset, i))
            }
            TokenOwnership memory ownership = explicitOwnershipOf(tokenId);
            assembly {
                // Store the pointer of `ownership` in the `ownerships` array.
                mstore(add(add(ownerships, 0x20), i), ownership)
            }
        }
        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) {
        return _tokensOfOwnerIn(owner, start, stop);
    }

    /**
     * @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)
    {
        uint256 start = _startTokenId();
        uint256 stop = _nextTokenId();
        uint256[] memory tokenIds;
        if (start != stop) tokenIds = _tokensOfOwnerIn(owner, start, stop);
        return tokenIds;
    }

    /**
     * @dev Helper function for returning an array of token IDs owned by `owner`.
     *
     * Note that this function is optimized for smaller bytecode size over runtime gas,
     * since it is meant to be called off-chain.
     */
    function _tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) private view returns (uint256[] memory) {
        unchecked {
            if (start >= stop) _revert(InvalidQueryRange.selector);
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            uint256 stopLimit = _nextTokenId();
            // Set `stop = min(stop, stopLimit)`.
            if (stop >= stopLimit) {
                stop = stopLimit;
            }
            uint256[] memory tokenIds;
            uint256 tokenIdsMaxLength = balanceOf(owner);
            bool startLtStop = start < stop;
            assembly {
                // Set `tokenIdsMaxLength` to zero if `start` is less than `stop`.
                tokenIdsMaxLength := mul(tokenIdsMaxLength, startLtStop)
            }
            if (tokenIdsMaxLength != 0) {
                // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
                // to cater for cases where `balanceOf(owner)` is too big.
                if (stop - start <= tokenIdsMaxLength) {
                    tokenIdsMaxLength = stop - start;
                }
                assembly {
                    // Grab the free memory pointer.
                    tokenIds := mload(0x40)
                    // Allocate one word for the length, and `tokenIdsMaxLength` words
                    // for the data. `shl(5, x)` is equivalent to `mul(32, x)`.
                    mstore(
                        0x40,
                        add(tokenIds, shl(5, add(tokenIdsMaxLength, 1)))
                    )
                }
                // 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;
                }
                uint256 tokenIdsIdx;
                // Use a do-while, which is slightly more efficient for this case,
                // as the array will at least contain one element.
                do {
                    ownership = _ownershipAt(start);
                    assembly {
                        switch mload(add(ownership, 0x40))
                        // if `ownership.burned == false`.
                        case 0 {
                            // if `ownership.addr != address(0)`.
                            // The `addr` already has it's upper 96 bits clearned,
                            // since it is written to memory with regular Solidity.
                            if mload(ownership) {
                                currOwnershipAddr := mload(ownership)
                            }
                            // if `currOwnershipAddr == owner`.
                            // The `shl(96, x)` is to make the comparison agnostic to any
                            // dirty upper 96 bits in `owner`.
                            if iszero(shl(96, xor(currOwnershipAddr, owner))) {
                                tokenIdsIdx := add(tokenIdsIdx, 1)
                                mstore(
                                    add(tokenIds, shl(5, tokenIdsIdx)),
                                    start
                                )
                            }
                        }
                        // Otherwise, reset `currOwnershipAddr`.
                        // This handles the case of batch burned tokens
                        // (burned bit of first slot set, remaining slots left uninitialized).
                        default {
                            currOwnershipAddr := 0
                        }
                        start := add(start, 1)
                    }
                } while (!(start == stop || tokenIdsIdx == tokenIdsMaxLength));
                // Store the length of the array.
                assembly {
                    mstore(tokenIds, tokenIdsIdx)
                }
            }
            return tokenIds;
        }
    }
}

/**
 * @dev Interface of ERC721ABurnable.
 */
interface IERC721ABurnable is IERC721A {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) external;
}

/**
 * @title ERC721ABurnable.
 *
 * @dev ERC721A token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual override {
        _burn(tokenId, true);
    }
}


interface ERC20 {
    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}


pragma solidity ^0.8.17;

contract KyojinSenshi is
    ERC721AQueryable,
    ERC721ABurnable,
    ERC2981,
    DefaultOperatorFilterer,
    Ownable
{
    IERC20 private _ethToken;
    uint256 public MAX_SUPPLY;
    uint256 public MINT_PRICE = 0 ether;
    uint256 public MAX_PER_WALLET = 1;
    uint256 public REWARD_AMOUNT_AZMURA = 1 ether; //
    uint256 public REWARD_AMOUNT_MAZUNO = 1 ether; //
    uint256 public REWARD_AMOUNT_NIRODA = 1 ether; //
    uint256 public REWARD_AMOUNT_YATSUI = 1 ether; //

    uint256 public REWARD_INTERVAL = 1 days; // 1 day
    address public ethTokenAddress = 0x544279829C40802faC96d25Feae9347473593E00;

    string public baseURI =
        "ipfs://Qmf4g8HVouyCa78vPjRjUNWHrgBAFhhpmfaeMt91siGLLT/";
    string public uriSuffix = ".json";

    bytes32 public merkleRootAzmura =
        0x7b0e4a35445a923ac54757d1027165cc6b7450cd9ab67a12bd21a0a1e934c2f9;
    bytes32 public merkleRootMazuno =
        0x3fbb393eeaab07f0562b820d99c8045bd3d589cdf5521289502c044a8ee50eb8;
    bytes32 public merkleRootNiroda =
        0xb1f4a6a6422dd9e0b61f4e2af3ab21fd608b8ae2ce5debd45688fa0765ff16b3;
    bytes32 public merkleRootYatsui =
        0x2ec4dfa3300fac13f8f7ba83caec0c27a1947f7e3dbdbb726f7fe06426f753fa;

    bytes32 public merkleRootWL =
        0xca9248acb357df49906452042960077cd486d1babe77a4584fc0c6744530908b;

    bool public WL_MINT_STATUS = true;

    mapping(uint256 => mapping(address => uint256)) public _lastRewardTime;
    mapping(address => uint256) public _claimedRewards;
    mapping(address => uint256) public publicMintAllowed;

    event Minted(address indexed owner, uint256 count);

    constructor() ERC721A("Kyojin Senshi", "KYO") {
        MAX_SUPPLY = 3200;
        _ethToken = IERC20(ethTokenAddress);
    }

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

    function mint(uint256 _amount) external payable {
        require(
            publicMintAllowed[msg.sender] + _amount <= MAX_PER_WALLET,
            "Max limit per wallet reached!"
        );
        require(totalSupply() + _amount <= MAX_SUPPLY, "Sold out");
        require(!WL_MINT_STATUS, "Public Mint is turned off at the moment");
        require(_amount > 0 && _amount <= MAX_PER_WALLET, "Invalid Amount!");
     
        require(msg.value >= MINT_PRICE * _amount, "Not enough ether provided!");

        for (uint256 i = 1; i <= _amount; i++) {
            uint256 token = totalSupply() + i;
            _lastRewardTime[token][msg.sender] = block.timestamp;
        }

        publicMintAllowed[msg.sender] += _amount;
        _safeMint(msg.sender, _amount);
        emit Minted(msg.sender, _amount);
    }

    function mintWL(bytes32[] memory merkleProof, uint256 _amount)
        external
        payable
    {
        require(
            MerkleProof.verify(
                merkleProof,
                merkleRootWL,
                keccak256(abi.encodePacked(msg.sender))
            ),
            "Not a part of Allowlist"
        );
        require(WL_MINT_STATUS, "Public Mint is turned off at the moment");
        require(
            publicMintAllowed[msg.sender] + _amount <= MAX_PER_WALLET,
            "Max limit per wallet reached!"
        );
        require(totalSupply() + _amount <= MAX_SUPPLY, "Sold out");
        require(_amount > 0 && _amount <= MAX_PER_WALLET, "Invalid Amount!");
        
        require(msg.value >= MINT_PRICE * _amount, "Not enough ether provided!");

        for (uint256 i = 1; i <= _amount; i++) {
            uint256 token = totalSupply() + i;
            _lastRewardTime[token][msg.sender] = block.timestamp;
        }

        publicMintAllowed[msg.sender] += _amount;
        _safeMint(msg.sender, _amount);
        emit Minted(msg.sender, _amount);
    }

    function claimReward(
        uint256[] memory tokensOwned,
        bytes32[][] memory merkleProof
    ) external {
        uint256 totalRewards = 0;
        for (uint256 i = 0; i < tokensOwned.length; i++) {
            string memory tokenString = Strings.toString(tokensOwned[i]);
            bytes32 leaf = keccak256(abi.encodePacked(tokenString));
            bytes32[] memory _merkleProof = merkleProof[i];
            require(
                ownerOf(tokensOwned[i]) == msg.sender,
                "You are not the owner of this token."
            );

            if (MerkleProof.verify(_merkleProof, merkleRootAzmura, leaf)) {
                uint256 lastRewardTime = _lastRewardTime[tokensOwned[i]][
                    msg.sender
                ];
                if (lastRewardTime + REWARD_INTERVAL <= block.timestamp) {
                    uint256 numRewards = (block.timestamp - lastRewardTime) /
                        REWARD_INTERVAL;
                    require(numRewards > 0, "No rewards available");
                    uint256 reward = REWARD_AMOUNT_AZMURA * numRewards;
                    totalRewards += reward;
                    require(_ethToken.balanceOf(address(this)) >= reward);
                    _claimedRewards[msg.sender] += reward;
                    _lastRewardTime[tokensOwned[i]][msg.sender] +=
                        numRewards *
                        REWARD_INTERVAL;
                    require(
                        _ethToken.balanceOf(address(this)) >= reward,
                        "Insufficient contract balance"
                    );
                    _ethToken.approve(address(this), reward);
                    require(
                        _ethToken.transferFrom(
                            address(this),
                            msg.sender,
                            reward
                        ),
                        "transfer failed"
                    );
                }
            }

            if (MerkleProof.verify(_merkleProof, merkleRootMazuno, leaf)) {
                uint256 lastRewardTime = _lastRewardTime[tokensOwned[i]][
                    msg.sender
                ];
                if (lastRewardTime + REWARD_INTERVAL <= block.timestamp) {
                    uint256 numRewards = (block.timestamp - lastRewardTime) /
                        REWARD_INTERVAL;
                    require(numRewards > 0, "No rewards available");
                    uint256 reward = REWARD_AMOUNT_MAZUNO * numRewards;
                    totalRewards += reward;
                    require(_ethToken.balanceOf(address(this)) >= reward);
                    _claimedRewards[msg.sender] += reward;
                    _lastRewardTime[tokensOwned[i]][msg.sender] +=
                        numRewards *
                        REWARD_INTERVAL;
                    require(
                        _ethToken.balanceOf(address(this)) >= reward,
                        "Insufficient contract balance"
                    );
                    _ethToken.approve(address(this), reward);
                    require(
                        _ethToken.transferFrom(
                            address(this),
                            msg.sender,
                            reward
                        ),
                        "transfer failed"
                    );
                }
            }

            if (MerkleProof.verify(_merkleProof, merkleRootNiroda, leaf)) {
                uint256 lastRewardTime = _lastRewardTime[tokensOwned[i]][
                    msg.sender
                ];
                if (lastRewardTime + REWARD_INTERVAL <= block.timestamp) {
                    uint256 numRewards = (block.timestamp - lastRewardTime) /
                        REWARD_INTERVAL;
                    require(numRewards > 0, "No rewards available");
                    uint256 reward = REWARD_AMOUNT_NIRODA * numRewards;
                    totalRewards += reward;
                    require(_ethToken.balanceOf(address(this)) >= reward);
                    _claimedRewards[msg.sender] += reward;
                    _lastRewardTime[tokensOwned[i]][msg.sender] +=
                        numRewards *
                        REWARD_INTERVAL;
                    require(
                        _ethToken.balanceOf(address(this)) >= reward,
                        "Insufficient contract balance"
                    );
                    _ethToken.approve(address(this), reward);
                    require(
                        _ethToken.transferFrom(
                            address(this),
                            msg.sender,
                            reward
                        ),
                        "transfer failed"
                    );
                }
            }

            if (MerkleProof.verify(_merkleProof, merkleRootYatsui, leaf)) {
                uint256 lastRewardTime = _lastRewardTime[tokensOwned[i]][
                    msg.sender
                ];
                if (lastRewardTime + REWARD_INTERVAL <= block.timestamp) {
                    uint256 numRewards = (block.timestamp - lastRewardTime) /
                        REWARD_INTERVAL;
                    require(numRewards > 0, "No rewards available");
                    uint256 reward = REWARD_AMOUNT_YATSUI * numRewards;
                    totalRewards += reward;
                    require(_ethToken.balanceOf(address(this)) >= reward);
                    _claimedRewards[msg.sender] += reward;
                    _lastRewardTime[tokensOwned[i]][msg.sender] +=
                        numRewards *
                        REWARD_INTERVAL;
                    require(
                        _ethToken.balanceOf(address(this)) >= reward,
                        "Insufficient contract balance"
                    );
                    _ethToken.approve(address(this), reward);
                    require(
                        _ethToken.transferFrom(
                            address(this),
                            msg.sender,
                            reward
                        ),
                        "transfer failed"
                    );
                }
            }
        }
        require(totalRewards > 0, "Cannot claim 0 rewards");
    }

    function airdrop(address[] calldata _to, uint256 amount)
        external
        payable
        onlyOwner
    {
        require(totalSupply() + amount <= MAX_SUPPLY, "Sold out");
        for (uint256 i = 0; i < _to.length; i++) {
            _safeMint(_to[i], amount);
        }
    }

    function airdropMultiple(address[] calldata _to, uint256[] calldata amount)
        external
        payable
        onlyOwner
    {
        for (uint256 i = 0; i < _to.length; i++) {
            require(totalSupply() + amount[i] <= MAX_SUPPLY, "Sold out");
            _safeMint(_to[i], amount[i]);
        }
    }

    function treasuryMint(uint256 quantity) public onlyOwner {
        require(quantity > 0, "Invalid mint amount");
        require(
            totalSupply() + quantity <= MAX_SUPPLY,
            "Maximum supply exceeded"
        );
        _safeMint(msg.sender, quantity);
    }

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

        return
            bytes(baseURI).length > 0
                ? string(
                    abi.encodePacked(baseURI, _toString(tokenId), uriSuffix)
                )
                : "";
    }

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

    function withdraw_token(address _token) public onlyOwner {
        uint256 balance = ERC20(_token).balanceOf(address(this));
        require(balance > 0, "zero amount");
        ERC20(_token).transfer(msg.sender, balance);
    }

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

    function setPrice(uint256 _price) public onlyOwner {
        MINT_PRICE = _price;
    }

    function toggleWLMintStatus() public onlyOwner {
        WL_MINT_STATUS = !WL_MINT_STATUS;
    }

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

    function setMaxPerWallet(uint256 _value) public onlyOwner {
        MAX_PER_WALLET = _value;
    }

    function setMerkleRootWL(bytes32 _merkleRoot) external onlyOwner {
        merkleRootWL = _merkleRoot;
    }

    function setRewardAmountAzmura(uint256 _reward) external onlyOwner {
        REWARD_AMOUNT_AZMURA = _reward;
    }

    function setRewardAmountMazuno(uint256 _reward) external onlyOwner {
        REWARD_AMOUNT_MAZUNO = _reward;
    }

    function setRewardAmountNiroda(uint256 _reward) external onlyOwner {
        REWARD_AMOUNT_NIRODA = _reward;
    }

    function setRewardAmountYatsui(uint256 _reward) external onlyOwner {
        REWARD_AMOUNT_YATSUI = _reward;
    }

    function setRewardInterval(uint256 _interval) external onlyOwner {
        REWARD_INTERVAL = _interval;
    }

    

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

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

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

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

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

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC721A, IERC721A, ERC2981)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

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":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","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":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"Minted","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":[],"name":"MAX_PER_WALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_AMOUNT_AZMURA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_AMOUNT_MAZUNO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_AMOUNT_NIRODA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_AMOUNT_YATSUI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WL_MINT_STATUS","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_claimedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"_lastRewardTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_to","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_to","type":"address[]"},{"internalType":"uint256[]","name":"amount","type":"uint256[]"}],"name":"airdropMultiple","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokensOwned","type":"uint256[]"},{"internalType":"bytes32[][]","name":"merkleProof","type":"bytes32[][]"}],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ethTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"ownership","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":"merkleRootAzmura","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRootMazuno","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRootNiroda","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRootWL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRootYatsui","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintWL","outputs":[],"stateMutability":"payable","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":[{"internalType":"address","name":"","type":"address"}],"name":"publicMintAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"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":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRootWL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"setRewardAmountAzmura","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"setRewardAmountMazuno","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"setRewardAmountNiroda","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"setRewardAmountYatsui","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_interval","type":"uint256"}],"name":"setRewardInterval","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":[],"name":"toggleWLMintStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"treasuryMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriSuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"withdraw_token","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6000600d556001600e55670de0b6b3a7640000600f8190556010819055601181905560125562015180601355601480546001600160a01b03191673544279829c40802fac96d25feae9347473593e0017905560e060405260366080818152906200473460a03960159062000074908262000469565b50604080518082019091526005815264173539b7b760d91b6020820152601690620000a0908262000469565b507f7b0e4a35445a923ac54757d1027165cc6b7450cd9ab67a12bd21a0a1e934c2f96017557f3fbb393eeaab07f0562b820d99c8045bd3d589cdf5521289502c044a8ee50eb86018557fb1f4a6a6422dd9e0b61f4e2af3ab21fd608b8ae2ce5debd45688fa0765ff16b36019557f2ec4dfa3300fac13f8f7ba83caec0c27a1947f7e3dbdbb726f7fe06426f753fa601a557fca9248acb357df49906452042960077cd486d1babe77a4584fc0c6744530908b601b55601c805460ff191660011790553480156200016f57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600d81526020016c4b796f6a696e2053656e73686960981b815250604051806040016040528060038152602001624b594f60e81b8152508160029081620001da919062000469565b506003620001e9828262000469565b50600160005550506daaeb6d7670e522a718067333cd4e3b15620003365780156200028457604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200026557600080fd5b505af11580156200027a573d6000803e3d6000fd5b5050505062000336565b6001600160a01b03821615620002d55760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af2903906044016200024a565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200031c57600080fd5b505af115801562000331573d6000803e3d6000fd5b505050505b506200034490503362000372565b610c80600c55601454600b80546001600160a01b0319166001600160a01b0390921691909117905562000535565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620003ef57607f821691505b6020821081036200041057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200046457600081815260208120601f850160051c810160208610156200043f5750805b601f850160051c820191505b8181101562000460578281556001016200044b565b5050505b505050565b81516001600160401b03811115620004855762000485620003c4565b6200049d81620004968454620003da565b8462000416565b602080601f831160018114620004d55760008415620004bc5750858301515b600019600386901b1c1916600185901b17855562000460565b600085815260208120601f198616915b828110156200050657888601518255948401946001909101908401620004e5565b5085821015620005255787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6141ef80620005456000396000f3fe6080604052600436106103ad5760003560e01c806391333f83116101e7578063c23dc68f1161010d578063e268e4d3116100a0578063efdc77881161006f578063efdc778814610a85578063f2fde38b14610aa5578063fbe641d114610ac5578063ffd4fa0614610af257600080fd5b8063e268e4d3146109e6578063e38a2f6f14610a06578063e3e8421314610a1c578063e985e9c514610a3c57600080fd5b8063cc02b870116100dc578063cc02b8701461097a578063d6492d8114610990578063d9190a90146109a6578063df341bf6146109c657600080fd5b8063c23dc68f146108f7578063c3dfbcd714610924578063c87b56dd14610944578063ca8512471461096457600080fd5b8063a0712d6811610185578063b600ab2211610154578063b600ab22146108a6578063b88d4fde146108bb578063c002d23d146108ce578063c204642c146108e457600080fd5b8063a0712d6814610839578063a22cb4651461084c578063a258fd2d1461086c578063ad3e31b71461088657600080fd5b80639674dd9f116101c15780639674dd9f146107ae57806397db21f5146107e657806399a2557a146107f95780639cd3cb5d1461081957600080fd5b806391333f831461076357806391b7f5ed1461077957806395d89b411461079957600080fd5b80635503a0e8116102d757806370a082311161026a5780637e6f9a03116102395780637e6f9a03146106d85780638462151c146106f85780638ccc51df146107255780638da5cb5b1461074557600080fd5b806370a0823114610677578063715018a61461069757806379395c7b146106ac5780637bd209a3146106c257600080fd5b80636352211e116102a65780636352211e1461060257806366fa216f1461062257806367e4f9a8146106355780636c0360eb1461066257600080fd5b80635503a0e81461058a57806355f804b31461059f5780635bbb2177146105bf5780635dbdda69146105ec57600080fd5b806323b872dd1161034f5780633ccfd60b1161031e5780633ccfd60b1461052d57806341f434341461053557806342842e0e1461055757806342966c681461056a57600080fd5b806323b872dd146104af5780632a55205a146104c25780632c7c02531461050157806332cb6b0c1461051757600080fd5b8063095ea7b31161038b578063095ea7b3146104415780630f2cdd6c1461045657806314cf47011461047a57806318160ddd1461049a57600080fd5b806301ffc9a7146103b257806306fdde03146103e7578063081812fc14610409575b600080fd5b3480156103be57600080fd5b506103d26103cd3660046135a5565b610b08565b60405190151581526020015b60405180910390f35b3480156103f357600080fd5b506103fc610b19565b6040516103de9190613612565b34801561041557600080fd5b50610429610424366004613625565b610bab565b6040516001600160a01b0390911681526020016103de565b61045461044f366004613655565b610be6565b005b34801561046257600080fd5b5061046c600e5481565b6040519081526020016103de565b34801561048657600080fd5b50601454610429906001600160a01b031681565b3480156104a657600080fd5b5061046c610bff565b6104546104bd36600461367f565b610c0d565b3480156104ce57600080fd5b506104e26104dd3660046136bb565b610c69565b604080516001600160a01b0390931683526020830191909152016103de565b34801561050d57600080fd5b5061046c601a5481565b34801561052357600080fd5b5061046c600c5481565b610454610d17565b34801561054157600080fd5b506104296daaeb6d7670e522a718067333cd4e81565b61045461056536600461367f565b610d93565b34801561057657600080fd5b50610454610585366004613625565b610db8565b34801561059657600080fd5b506103fc610dc3565b3480156105ab57600080fd5b506104546105ba36600461377a565b610e51565b3480156105cb57600080fd5b506105df6105da366004613806565b610e69565b6040516103de9190613883565b3480156105f857600080fd5b5061046c60135481565b34801561060e57600080fd5b5061042961061d366004613625565b610eb5565b6104546106303660046138c5565b610ec0565b34801561064157600080fd5b5061046c610650366004613930565b601e6020526000908152604090205481565b34801561066e57600080fd5b506103fc610f89565b34801561068357600080fd5b5061046c610692366004613930565b610f96565b3480156106a357600080fd5b50610454610fdb565b3480156106b857600080fd5b5061046c60115481565b3480156106ce57600080fd5b5061046c60105481565b3480156106e457600080fd5b506104546106f3366004613625565b610fef565b34801561070457600080fd5b50610718610713366004613930565b610ffc565b6040516103de919061394b565b34801561073157600080fd5b50610454610740366004613625565b611023565b34801561075157600080fd5b50600a546001600160a01b0316610429565b34801561076f57600080fd5b5061046c600f5481565b34801561078557600080fd5b50610454610794366004613625565b611030565b3480156107a557600080fd5b506103fc61103d565b3480156107ba57600080fd5b5061046c6107c9366004613983565b601d60209081526000928352604080842090915290825290205481565b6104546107f4366004613a3d565b61104c565b34801561080557600080fd5b50610718610814366004613a81565b611300565b34801561082557600080fd5b50610454610834366004613930565b61130d565b610454610847366004613625565b611431565b34801561085857600080fd5b50610454610867366004613ac2565b611657565b34801561087857600080fd5b50601c546103d29060ff1681565b34801561089257600080fd5b506104546108a1366004613625565b61166b565b3480156108b257600080fd5b50610454611678565b6104546108c9366004613af9565b611694565b3480156108da57600080fd5b5061046c600d5481565b6104546108f2366004613b74565b6116f2565b34801561090357600080fd5b50610917610912366004613625565b611781565b6040516103de9190613bbf565b34801561093057600080fd5b5061045461093f366004613c4c565b6117e5565b34801561095057600080fd5b506103fc61095f366004613625565b612737565b34801561097057600080fd5b5061046c60125481565b34801561098657600080fd5b5061046c60175481565b34801561099c57600080fd5b5061046c601b5481565b3480156109b257600080fd5b506104546109c1366004613625565b61280c565b3480156109d257600080fd5b506104546109e1366004613625565b612819565b3480156109f257600080fd5b50610454610a01366004613625565b612826565b348015610a1257600080fd5b5061046c60195481565b348015610a2857600080fd5b50610454610a37366004613625565b612833565b348015610a4857600080fd5b506103d2610a57366004613d04565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610a9157600080fd5b50610454610aa0366004613625565b612840565b348015610ab157600080fd5b50610454610ac0366004613930565b6128fc565b348015610ad157600080fd5b5061046c610ae0366004613930565b601f6020526000908152604090205481565b348015610afe57600080fd5b5061046c60185481565b6000610b1382612972565b92915050565b606060028054610b2890613d2e565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5490613d2e565b8015610ba15780601f10610b7657610100808354040283529160200191610ba1565b820191906000526020600020905b815481529060010190602001808311610b8457829003601f168201915b5050505050905090565b6000610bb6826129a7565b610bca57610bca6333d1c03960e21b6129f3565b506000908152600660205260409020546001600160a01b031690565b81610bf0816129fd565b610bfa8383612ab6565b505050565b600154600054036000190190565b826001600160a01b0381163314610c2757610c27336129fd565b610c32848484612ac2565b506000908152601d602090815260408083206001600160a01b03958616845290915280822042908190559290931681529190912055565b60008281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610cde5750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610cfd906001600160601b031687613d7e565b610d079190613dab565b91519350909150505b9250929050565b610d1f612c31565b6000610d33600a546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610d7d576040519150601f19603f3d011682016040523d82523d6000602084013e610d82565b606091505b5050905080610d9057600080fd5b50565b826001600160a01b0381163314610dad57610dad336129fd565b610c32848484612c8b565b610d90816001612ca6565b60168054610dd090613d2e565b80601f0160208091040260200160405190810160405280929190818152602001828054610dfc90613d2e565b8015610e495780601f10610e1e57610100808354040283529160200191610e49565b820191906000526020600020905b815481529060010190602001808311610e2c57829003601f168201915b505050505081565b610e59612c31565b6015610e658282613e0d565b5050565b60408051828152600583901b8082016020019092526060915b8015610ead57601f1980820191860101356000610e9e82611781565b8484016020015250610e829050565b509392505050565b6000610b1382612de7565b610ec8612c31565b60005b83811015610f8257600c54838383818110610ee857610ee8613ecc565b90506020020135610ef7610bff565b610f019190613ee2565b1115610f285760405162461bcd60e51b8152600401610f1f90613ef5565b60405180910390fd5b610f70858583818110610f3d57610f3d613ecc565b9050602002016020810190610f529190613930565b848484818110610f6457610f64613ecc565b90506020020135612e88565b80610f7a81613f17565b915050610ecb565b5050505050565b60158054610dd090613d2e565b60006001600160a01b038216610fb657610fb66323d3ad8160e21b6129f3565b506001600160a01b03166000908152600560205260409020546001600160401b031690565b610fe3612c31565b610fed6000612ea2565b565b610ff7612c31565b601055565b6000546060906001908282821461101b57611018858484612ef4565b90505b949350505050565b61102b612c31565b601155565b611038612c31565b600d55565b606060038054610b2890613d2e565b601b546040516bffffffffffffffffffffffff193360601b16602082015261108e91849160340160405160208183030381529060405280519060200120612ff3565b6110da5760405162461bcd60e51b815260206004820152601760248201527f4e6f7420612070617274206f6620416c6c6f776c6973740000000000000000006044820152606401610f1f565b601c5460ff166110fc5760405162461bcd60e51b8152600401610f1f90613f30565b600e54336000908152601f602052604090205461111a908390613ee2565b11156111685760405162461bcd60e51b815260206004820152601d60248201527f4d6178206c696d6974207065722077616c6c65742072656163686564210000006044820152606401610f1f565b600c5481611174610bff565b61117e9190613ee2565b111561119c5760405162461bcd60e51b8152600401610f1f90613ef5565b6000811180156111ae5750600e548111155b6111ec5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420416d6f756e742160881b6044820152606401610f1f565b80600d546111fa9190613d7e565b3410156112495760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f7567682065746865722070726f7669646564210000000000006044820152606401610f1f565b60015b8181116112975760008161125e610bff565b6112689190613ee2565b6000908152601d602090815260408083203384529091529020429055508061128f81613f17565b91505061124c565b50336000908152601f6020526040812080548392906112b7908490613ee2565b909155506112c790503382612e88565b60405181815233907f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe9060200160405180910390a25050565b606061101b848484612ef4565b611315612c31565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561135c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113809190613f77565b9050600081116113c05760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc8185b5bdd5b9d60aa1b6044820152606401610f1f565b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303816000875af115801561140d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfa9190613f90565b600e54336000908152601f602052604090205461144f908390613ee2565b111561149d5760405162461bcd60e51b815260206004820152601d60248201527f4d6178206c696d6974207065722077616c6c65742072656163686564210000006044820152606401610f1f565b600c54816114a9610bff565b6114b39190613ee2565b11156114d15760405162461bcd60e51b8152600401610f1f90613ef5565b601c5460ff16156114f45760405162461bcd60e51b8152600401610f1f90613f30565b6000811180156115065750600e548111155b6115445760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420416d6f756e742160881b6044820152606401610f1f565b80600d546115529190613d7e565b3410156115a15760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f7567682065746865722070726f7669646564210000000000006044820152606401610f1f565b60015b8181116115ef576000816115b6610bff565b6115c09190613ee2565b6000908152601d60209081526040808320338452909152902042905550806115e781613f17565b9150506115a4565b50336000908152601f60205260408120805483929061160f908490613ee2565b9091555061161f90503382612e88565b60405181815233907f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe9060200160405180910390a250565b81611661816129fd565b610bfa8383613009565b611673612c31565b601b55565b611680612c31565b601c805460ff19811660ff90911615179055565b836001600160a01b03811633146116ae576116ae336129fd565b6116ba85858585613075565b50506000908152601d602090815260408083206001600160a01b03958616845290915280822042908190559290931681529190912055565b6116fa612c31565b600c5481611706610bff565b6117109190613ee2565b111561172e5760405162461bcd60e51b8152600401610f1f90613ef5565b60005b8281101561177b5761176984848381811061174e5761174e613ecc565b90506020020160208101906117639190613930565b83612e88565b8061177381613f17565b915050611731565b50505050565b604080516080810182526000808252602082018190529181018290526060810191909152600182106117e0576000548210156117e0575b6000828152600460205260409020546117d757600019909101906117b8565b610b13826130b0565b919050565b6000805b83518110156126ed57600061181685838151811061180957611809613ecc565b602002602001015161312e565b905060008160405160200161182b9190613fad565b604051602081830303815290604052805190602001209050600085848151811061185757611857613ecc565b60200260200101519050336001600160a01b031661188d88868151811061188057611880613ecc565b6020026020010151610eb5565b6001600160a01b0316146118ef5760405162461bcd60e51b8152602060048201526024808201527f596f7520617265206e6f7420746865206f776e6572206f66207468697320746f60448201526335b2b71760e11b6064820152608401610f1f565b6118fc8160175484612ff3565b15611c69576000601d600089878151811061191957611919613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b0316815260200190815260200160002054905042601354826119649190613ee2565b11611c67576013546000906119798342613fc9565b6119839190613dab565b9050600081116119a55760405162461bcd60e51b8152600401610f1f90613fdc565b600081600f546119b59190613d7e565b90506119c18189613ee2565b600b546040516370a0823160e01b815230600482015291995082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015611a0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a329190613f77565b1015611a3d57600080fd5b336000908152601e602052604081208054839290611a5c908490613ee2565b9091555050601354611a6e9083613d7e565b601d60008c8a81518110611a8457611a84613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b031681526020019081526020016000206000828254611acc9190613ee2565b9091555050600b546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015611b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3d9190613f77565b1015611b5b5760405162461bcd60e51b8152600401610f1f9061400a565b600b5460405163095ea7b360e01b8152306004820152602481018390526001600160a01b039091169063095ea7b3906044016020604051808303816000875af1158015611bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd09190613f90565b50600b546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611c0590309033908690600401614041565b6020604051808303816000875af1158015611c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c489190613f90565b611c645760405162461bcd60e51b8152600401610f1f90614065565b50505b505b611c768160185484612ff3565b15611fe3576000601d6000898781518110611c9357611c93613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b031681526020019081526020016000205490504260135482611cde9190613ee2565b11611fe157601354600090611cf38342613fc9565b611cfd9190613dab565b905060008111611d1f5760405162461bcd60e51b8152600401610f1f90613fdc565b600081601054611d2f9190613d7e565b9050611d3b8189613ee2565b600b546040516370a0823160e01b815230600482015291995082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190613f77565b1015611db757600080fd5b336000908152601e602052604081208054839290611dd6908490613ee2565b9091555050601354611de89083613d7e565b601d60008c8a81518110611dfe57611dfe613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b031681526020019081526020016000206000828254611e469190613ee2565b9091555050600b546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015611e93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb79190613f77565b1015611ed55760405162461bcd60e51b8152600401610f1f9061400a565b600b5460405163095ea7b360e01b8152306004820152602481018390526001600160a01b039091169063095ea7b3906044016020604051808303816000875af1158015611f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4a9190613f90565b50600b546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611f7f90309033908690600401614041565b6020604051808303816000875af1158015611f9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc29190613f90565b611fde5760405162461bcd60e51b8152600401610f1f90614065565b50505b505b611ff08160195484612ff3565b1561235d576000601d600089878151811061200d5761200d613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b0316815260200190815260200160002054905042601354826120589190613ee2565b1161235b5760135460009061206d8342613fc9565b6120779190613dab565b9050600081116120995760405162461bcd60e51b8152600401610f1f90613fdc565b6000816011546120a99190613d7e565b90506120b58189613ee2565b600b546040516370a0823160e01b815230600482015291995082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015612102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121269190613f77565b101561213157600080fd5b336000908152601e602052604081208054839290612150908490613ee2565b90915550506013546121629083613d7e565b601d60008c8a8151811061217857612178613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b0316815260200190815260200160002060008282546121c09190613ee2565b9091555050600b546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa15801561220d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122319190613f77565b101561224f5760405162461bcd60e51b8152600401610f1f9061400a565b600b5460405163095ea7b360e01b8152306004820152602481018390526001600160a01b039091169063095ea7b3906044016020604051808303816000875af11580156122a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c49190613f90565b50600b546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906122f990309033908690600401614041565b6020604051808303816000875af1158015612318573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233c9190613f90565b6123585760405162461bcd60e51b8152600401610f1f90614065565b50505b505b61236a81601a5484612ff3565b156126d7576000601d600089878151811061238757612387613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b0316815260200190815260200160002054905042601354826123d29190613ee2565b116126d5576013546000906123e78342613fc9565b6123f19190613dab565b9050600081116124135760405162461bcd60e51b8152600401610f1f90613fdc565b6000816012546124239190613d7e565b905061242f8189613ee2565b600b546040516370a0823160e01b815230600482015291995082916001600160a01b03909116906370a0823190602401602060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a09190613f77565b10156124ab57600080fd5b336000908152601e6020526040812080548392906124ca908490613ee2565b90915550506013546124dc9083613d7e565b601d60008c8a815181106124f2576124f2613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b03168152602001908152602001600020600082825461253a9190613ee2565b9091555050600b546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ab9190613f77565b10156125c95760405162461bcd60e51b8152600401610f1f9061400a565b600b5460405163095ea7b360e01b8152306004820152602481018390526001600160a01b039091169063095ea7b3906044016020604051808303816000875af115801561261a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061263e9190613f90565b50600b546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061267390309033908690600401614041565b6020604051808303816000875af1158015612692573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b69190613f90565b6126d25760405162461bcd60e51b8152600401610f1f90614065565b50505b505b50505080806126e590613f17565b9150506117e9565b5060008111610bfa5760405162461bcd60e51b815260206004820152601660248201527543616e6e6f7420636c61696d2030207265776172647360501b6044820152606401610f1f565b6060612742826129a7565b6127ad5760405162461bcd60e51b815260206004820152603660248201527f4572723a20455243373231414d65746164617461202d20555249207175657279604482015275103337b9103737b732bc34b9ba32b73a103a37b5b2b760511b6064820152608401610f1f565b6000601580546127bc90613d2e565b9050116127d85760405180602001604052806000815250610b13565b60156127e38361322e565b60166040516020016127f793929190614101565b60405160208183030381529060405292915050565b612814612c31565b601255565b612821612c31565b600f55565b61282e612c31565b600e55565b61283b612c31565b601355565b612848612c31565b6000811161288e5760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610f1f565b600c548161289a610bff565b6128a49190613ee2565b11156128f25760405162461bcd60e51b815260206004820152601760248201527f4d6178696d756d20737570706c792065786365656465640000000000000000006044820152606401610f1f565b610d903382612e88565b612904612c31565b6001600160a01b0381166129695760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610f1f565b610d9081612ea2565b60006001600160e01b0319821663152a902d60e11b1480610b1357506301ffc9a760e01b6001600160e01b0319831614610b13565b6000816001116117e0576000548210156117e05760005b50600082815260046020526040812054908190036129e6576129df83614134565b92506129be565b600160e01b161592915050565b8060005260046000fd5b6daaeb6d7670e522a718067333cd4e3b15610d9057604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015612a6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8e9190613f90565b610d9057604051633b79c77360e21b81526001600160a01b0382166004820152602401610f1f565b610e6582826001613272565b6000612acd82612de7565b6001600160a01b039485169490915081168414612af357612af362a1148160e81b6129f3565b60008281526006602052604090208054612b1f8187335b6001600160a01b039081169116811491141790565b612b4157612b2d8633610a57565b612b4157612b41632ce44b5f60e11b6129f3565b8015612b4c57600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003612bde57600184016000818152600460205260408120549003612bdc576000548114612bdc5760008181526004602052604090208490555b505b6001600160a01b0385168481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a480600003612c2857612c28633a954ecd60e21b6129f3565b50505050505050565b600a546001600160a01b03163314610fed5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610f1f565b610bfa83838360405180602001604052806000815250611694565b6000612cb183612de7565b905080600080612ccf86600090815260066020526040902080549091565b915091508415612d0657612ce4818433612b0a565b612d0657612cf28333610a57565b612d0657612d06632ce44b5f60e11b6129f3565b8015612d1157600082555b6001600160a01b038316600081815260056020526040902080546fffffffffffffffffffffffffffffffff0190554260a01b17600360e01b17600087815260046020526040812091909155600160e11b85169003612d9f57600186016000818152600460205260408120549003612d9d576000548114612d9d5760008181526004602052604090208590555b505b60405186906000906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050600180548101905550505050565b600081600111612e78575060008181526004602052604081205490819003612e65576000548210612e2257612e22636f96cda160e11b6129f3565b5b50600019016000818152600460205260409020548015612e2357600160e01b8116600003612e5057919050565b612e60636f96cda160e11b6129f3565b612e23565b600160e01b8116600003612e7857919050565b6117e0636f96cda160e11b6129f3565b610e65828260405180602001604052806000815250613315565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6060818310612f0d57612f0d631960ccad60e11b6129f3565b6001831015612f1b57600192505b600054808310612f29578092505b60606000612f3687610f96565b85871090810291508115612fe7578187870311612f535786860391505b60405192506001820160051b83016040526000612f6f88611781565b905060008160400151612f80575080515b60005b612f8c8a6130b0565b9250604083015160008114612fa45760009250612fc9565b835115612fb057835192505b8b831860601b612fc9576001820191508a8260051b8801525b5060018a019950888a1480612fdd57508481145b15612f8357855250505b50909695505050505050565b6000826130008584613377565b14949350505050565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b613080848484610c0d565b6001600160a01b0383163b1561177b5761309c848484846133bc565b61177b5761177b6368d2bf6b60e11b6129f3565b604080516080810182526000808252602082018190529181018290526060810191909152600082815260046020526040902054610b1390604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b6060816000036131555750506040805180820190915260018152600360fc1b602082015290565b8160005b811561317f578061316981613f17565b91506131789050600a83613dab565b9150613159565b6000816001600160401b03811115613199576131996136dd565b6040519080825280601f01601f1916602001820160405280156131c3576020820181803683370190505b5090505b841561101b576131d8600183613fc9565b91506131e5600a8661414b565b6131f0906030613ee2565b60f81b81838151811061320557613205613ecc565b60200101906001600160f81b031916908160001a905350613227600a86613dab565b94506131c7565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806132485750819003601f19909101908152919050565b600061327d83610eb5565b90508180156132955750336001600160a01b03821614155b156132b8576132a48133610a57565b6132b8576132b86367d9dca160e11b6129f3565b60008381526006602052604080822080546001600160a01b0319166001600160a01b0388811691821790925591518693918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b61331f838361349e565b6001600160a01b0383163b15610bfa576000548281035b61334960008683806001019450866133bc565b61335d5761335d6368d2bf6b60e11b6129f3565b818110613336578160005414610f8257610f8260006129f3565b600081815b8451811015610ead576133a88286838151811061339b5761339b613ecc565b602002602001015161355d565b9150806133b481613f17565b91505061337c565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906133f190339089908890889060040161415f565b6020604051808303816000875af192505050801561342c575060408051601f3d908101601f191682019092526134299181019061419c565b60015b613481573d80801561345a576040519150601f19603f3d011682016040523d82523d6000602084013e61345f565b606091505b508051600003613479576134796368d2bf6b60e11b6129f3565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b60008054908290036134ba576134ba63b562e8dd60e01b6129f3565b60008181526004602090815260408083206001600160a01b0387164260a01b6001881460e11b1781179091558084526005909252822080546801000000000000000186020190559081900361351857613518622e076360e81b6129f3565b818301825b808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a481816001019150810361351d575060005550505050565b6000818310613579576000828152602084905260409020613588565b60008381526020839052604090205b9392505050565b6001600160e01b031981168114610d9057600080fd5b6000602082840312156135b757600080fd5b81356135888161358f565b60005b838110156135dd5781810151838201526020016135c5565b50506000910152565b600081518084526135fe8160208601602086016135c2565b601f01601f19169290920160200192915050565b60208152600061358860208301846135e6565b60006020828403121561363757600080fd5b5035919050565b80356001600160a01b03811681146117e057600080fd5b6000806040838503121561366857600080fd5b6136718361363e565b946020939093013593505050565b60008060006060848603121561369457600080fd5b61369d8461363e565b92506136ab6020850161363e565b9150604084013590509250925092565b600080604083850312156136ce57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561371b5761371b6136dd565b604052919050565b60006001600160401b0383111561373c5761373c6136dd565b61374f601f8401601f19166020016136f3565b905082815283838301111561376357600080fd5b828260208301376000602084830101529392505050565b60006020828403121561378c57600080fd5b81356001600160401b038111156137a257600080fd5b8201601f810184136137b357600080fd5b61101b84823560208401613723565b60008083601f8401126137d457600080fd5b5081356001600160401b038111156137eb57600080fd5b6020830191508360208260051b8501011115610d1057600080fd5b6000806020838503121561381957600080fd5b82356001600160401b0381111561382f57600080fd5b61383b858286016137c2565b90969095509350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b81811015612fe7576138b2838551613847565b928401926080929092019160010161389f565b600080600080604085870312156138db57600080fd5b84356001600160401b03808211156138f257600080fd5b6138fe888389016137c2565b9096509450602087013591508082111561391757600080fd5b50613924878288016137c2565b95989497509550505050565b60006020828403121561394257600080fd5b6135888261363e565b6020808252825182820181905260009190848201906040850190845b81811015612fe757835183529284019291840191600101613967565b6000806040838503121561399657600080fd5b823591506139a66020840161363e565b90509250929050565b60006001600160401b038211156139c8576139c86136dd565b5060051b60200190565b600082601f8301126139e357600080fd5b813560206139f86139f3836139af565b6136f3565b82815260059290921b84018101918181019086841115613a1757600080fd5b8286015b84811015613a325780358352918301918301613a1b565b509695505050505050565b60008060408385031215613a5057600080fd5b82356001600160401b03811115613a6657600080fd5b613a72858286016139d2565b95602094909401359450505050565b600080600060608486031215613a9657600080fd5b613a9f8461363e565b95602085013595506040909401359392505050565b8015158114610d9057600080fd5b60008060408385031215613ad557600080fd5b613ade8361363e565b91506020830135613aee81613ab4565b809150509250929050565b60008060008060808587031215613b0f57600080fd5b613b188561363e565b9350613b266020860161363e565b92506040850135915060608501356001600160401b03811115613b4857600080fd5b8501601f81018713613b5957600080fd5b613b6887823560208401613723565b91505092959194509250565b600080600060408486031215613b8957600080fd5b83356001600160401b03811115613b9f57600080fd5b613bab868287016137c2565b909790965060209590950135949350505050565b60808101610b138284613847565b600082601f830112613bde57600080fd5b81356020613bee6139f3836139af565b82815260059290921b84018101918181019086841115613c0d57600080fd5b8286015b84811015613a325780356001600160401b03811115613c305760008081fd5b613c3e8986838b01016139d2565b845250918301918301613c11565b60008060408385031215613c5f57600080fd5b82356001600160401b0380821115613c7657600080fd5b818501915085601f830112613c8a57600080fd5b81356020613c9a6139f3836139af565b82815260059290921b84018101918181019089841115613cb957600080fd5b948201945b83861015613cd757853582529482019490820190613cbe565b96505086013592505080821115613ced57600080fd5b50613cfa85828601613bcd565b9150509250929050565b60008060408385031215613d1757600080fd5b613d208361363e565b91506139a66020840161363e565b600181811c90821680613d4257607f821691505b602082108103613d6257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610b1357610b13613d68565b634e487b7160e01b600052601260045260246000fd5b600082613dba57613dba613d95565b500490565b601f821115610bfa57600081815260208120601f850160051c81016020861015613de65750805b601f850160051c820191505b81811015613e0557828155600101613df2565b505050505050565b81516001600160401b03811115613e2657613e266136dd565b613e3a81613e348454613d2e565b84613dbf565b602080601f831160018114613e6f5760008415613e575750858301515b600019600386901b1c1916600185901b178555613e05565b600085815260208120601f198616915b82811015613e9e57888601518255948401946001909101908401613e7f565b5085821015613ebc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b80820180821115610b1357610b13613d68565b60208082526008908201526714dbdb19081bdd5d60c21b604082015260600190565b600060018201613f2957613f29613d68565b5060010190565b60208082526027908201527f5075626c6963204d696e74206973207475726e6564206f666620617420746865604082015266081b5bdb595b9d60ca1b606082015260800190565b600060208284031215613f8957600080fd5b5051919050565b600060208284031215613fa257600080fd5b815161358881613ab4565b60008251613fbf8184602087016135c2565b9190910192915050565b81810381811115610b1357610b13613d68565b6020808252601490820152734e6f207265776172647320617661696c61626c6560601b604082015260600190565b6020808252601d908201527f496e73756666696369656e7420636f6e74726163742062616c616e6365000000604082015260600190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252600f908201526e1d1c985b9cd9995c8819985a5b1959608a1b604082015260600190565b6000815461409b81613d2e565b600182811680156140b357600181146140c8576140f7565b60ff19841687528215158302870194506140f7565b8560005260208060002060005b858110156140ee5781548a8201529084019082016140d5565b50505082870194505b5050505092915050565b600061410d828661408e565b845161411d8183602089016135c2565b6141298183018661408e565b979650505050505050565b60008161414357614143613d68565b506000190190565b60008261415a5761415a613d95565b500690565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614192908301846135e6565b9695505050505050565b6000602082840312156141ae57600080fd5b81516135888161358f56fea264697066735822122064cf98b541b8f0f60915dc6d6967c13088b7687cca145cc44dec204eeafad33564736f6c63430008130033697066733a2f2f516d6634673848566f75794361373876506a526a554e574872674241466868706d6661654d7439317369474c4c542f

Deployed Bytecode

0x6080604052600436106103ad5760003560e01c806391333f83116101e7578063c23dc68f1161010d578063e268e4d3116100a0578063efdc77881161006f578063efdc778814610a85578063f2fde38b14610aa5578063fbe641d114610ac5578063ffd4fa0614610af257600080fd5b8063e268e4d3146109e6578063e38a2f6f14610a06578063e3e8421314610a1c578063e985e9c514610a3c57600080fd5b8063cc02b870116100dc578063cc02b8701461097a578063d6492d8114610990578063d9190a90146109a6578063df341bf6146109c657600080fd5b8063c23dc68f146108f7578063c3dfbcd714610924578063c87b56dd14610944578063ca8512471461096457600080fd5b8063a0712d6811610185578063b600ab2211610154578063b600ab22146108a6578063b88d4fde146108bb578063c002d23d146108ce578063c204642c146108e457600080fd5b8063a0712d6814610839578063a22cb4651461084c578063a258fd2d1461086c578063ad3e31b71461088657600080fd5b80639674dd9f116101c15780639674dd9f146107ae57806397db21f5146107e657806399a2557a146107f95780639cd3cb5d1461081957600080fd5b806391333f831461076357806391b7f5ed1461077957806395d89b411461079957600080fd5b80635503a0e8116102d757806370a082311161026a5780637e6f9a03116102395780637e6f9a03146106d85780638462151c146106f85780638ccc51df146107255780638da5cb5b1461074557600080fd5b806370a0823114610677578063715018a61461069757806379395c7b146106ac5780637bd209a3146106c257600080fd5b80636352211e116102a65780636352211e1461060257806366fa216f1461062257806367e4f9a8146106355780636c0360eb1461066257600080fd5b80635503a0e81461058a57806355f804b31461059f5780635bbb2177146105bf5780635dbdda69146105ec57600080fd5b806323b872dd1161034f5780633ccfd60b1161031e5780633ccfd60b1461052d57806341f434341461053557806342842e0e1461055757806342966c681461056a57600080fd5b806323b872dd146104af5780632a55205a146104c25780632c7c02531461050157806332cb6b0c1461051757600080fd5b8063095ea7b31161038b578063095ea7b3146104415780630f2cdd6c1461045657806314cf47011461047a57806318160ddd1461049a57600080fd5b806301ffc9a7146103b257806306fdde03146103e7578063081812fc14610409575b600080fd5b3480156103be57600080fd5b506103d26103cd3660046135a5565b610b08565b60405190151581526020015b60405180910390f35b3480156103f357600080fd5b506103fc610b19565b6040516103de9190613612565b34801561041557600080fd5b50610429610424366004613625565b610bab565b6040516001600160a01b0390911681526020016103de565b61045461044f366004613655565b610be6565b005b34801561046257600080fd5b5061046c600e5481565b6040519081526020016103de565b34801561048657600080fd5b50601454610429906001600160a01b031681565b3480156104a657600080fd5b5061046c610bff565b6104546104bd36600461367f565b610c0d565b3480156104ce57600080fd5b506104e26104dd3660046136bb565b610c69565b604080516001600160a01b0390931683526020830191909152016103de565b34801561050d57600080fd5b5061046c601a5481565b34801561052357600080fd5b5061046c600c5481565b610454610d17565b34801561054157600080fd5b506104296daaeb6d7670e522a718067333cd4e81565b61045461056536600461367f565b610d93565b34801561057657600080fd5b50610454610585366004613625565b610db8565b34801561059657600080fd5b506103fc610dc3565b3480156105ab57600080fd5b506104546105ba36600461377a565b610e51565b3480156105cb57600080fd5b506105df6105da366004613806565b610e69565b6040516103de9190613883565b3480156105f857600080fd5b5061046c60135481565b34801561060e57600080fd5b5061042961061d366004613625565b610eb5565b6104546106303660046138c5565b610ec0565b34801561064157600080fd5b5061046c610650366004613930565b601e6020526000908152604090205481565b34801561066e57600080fd5b506103fc610f89565b34801561068357600080fd5b5061046c610692366004613930565b610f96565b3480156106a357600080fd5b50610454610fdb565b3480156106b857600080fd5b5061046c60115481565b3480156106ce57600080fd5b5061046c60105481565b3480156106e457600080fd5b506104546106f3366004613625565b610fef565b34801561070457600080fd5b50610718610713366004613930565b610ffc565b6040516103de919061394b565b34801561073157600080fd5b50610454610740366004613625565b611023565b34801561075157600080fd5b50600a546001600160a01b0316610429565b34801561076f57600080fd5b5061046c600f5481565b34801561078557600080fd5b50610454610794366004613625565b611030565b3480156107a557600080fd5b506103fc61103d565b3480156107ba57600080fd5b5061046c6107c9366004613983565b601d60209081526000928352604080842090915290825290205481565b6104546107f4366004613a3d565b61104c565b34801561080557600080fd5b50610718610814366004613a81565b611300565b34801561082557600080fd5b50610454610834366004613930565b61130d565b610454610847366004613625565b611431565b34801561085857600080fd5b50610454610867366004613ac2565b611657565b34801561087857600080fd5b50601c546103d29060ff1681565b34801561089257600080fd5b506104546108a1366004613625565b61166b565b3480156108b257600080fd5b50610454611678565b6104546108c9366004613af9565b611694565b3480156108da57600080fd5b5061046c600d5481565b6104546108f2366004613b74565b6116f2565b34801561090357600080fd5b50610917610912366004613625565b611781565b6040516103de9190613bbf565b34801561093057600080fd5b5061045461093f366004613c4c565b6117e5565b34801561095057600080fd5b506103fc61095f366004613625565b612737565b34801561097057600080fd5b5061046c60125481565b34801561098657600080fd5b5061046c60175481565b34801561099c57600080fd5b5061046c601b5481565b3480156109b257600080fd5b506104546109c1366004613625565b61280c565b3480156109d257600080fd5b506104546109e1366004613625565b612819565b3480156109f257600080fd5b50610454610a01366004613625565b612826565b348015610a1257600080fd5b5061046c60195481565b348015610a2857600080fd5b50610454610a37366004613625565b612833565b348015610a4857600080fd5b506103d2610a57366004613d04565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610a9157600080fd5b50610454610aa0366004613625565b612840565b348015610ab157600080fd5b50610454610ac0366004613930565b6128fc565b348015610ad157600080fd5b5061046c610ae0366004613930565b601f6020526000908152604090205481565b348015610afe57600080fd5b5061046c60185481565b6000610b1382612972565b92915050565b606060028054610b2890613d2e565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5490613d2e565b8015610ba15780601f10610b7657610100808354040283529160200191610ba1565b820191906000526020600020905b815481529060010190602001808311610b8457829003601f168201915b5050505050905090565b6000610bb6826129a7565b610bca57610bca6333d1c03960e21b6129f3565b506000908152600660205260409020546001600160a01b031690565b81610bf0816129fd565b610bfa8383612ab6565b505050565b600154600054036000190190565b826001600160a01b0381163314610c2757610c27336129fd565b610c32848484612ac2565b506000908152601d602090815260408083206001600160a01b03958616845290915280822042908190559290931681529190912055565b60008281526009602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610cde5750604080518082019091526008546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610cfd906001600160601b031687613d7e565b610d079190613dab565b91519350909150505b9250929050565b610d1f612c31565b6000610d33600a546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610d7d576040519150601f19603f3d011682016040523d82523d6000602084013e610d82565b606091505b5050905080610d9057600080fd5b50565b826001600160a01b0381163314610dad57610dad336129fd565b610c32848484612c8b565b610d90816001612ca6565b60168054610dd090613d2e565b80601f0160208091040260200160405190810160405280929190818152602001828054610dfc90613d2e565b8015610e495780601f10610e1e57610100808354040283529160200191610e49565b820191906000526020600020905b815481529060010190602001808311610e2c57829003601f168201915b505050505081565b610e59612c31565b6015610e658282613e0d565b5050565b60408051828152600583901b8082016020019092526060915b8015610ead57601f1980820191860101356000610e9e82611781565b8484016020015250610e829050565b509392505050565b6000610b1382612de7565b610ec8612c31565b60005b83811015610f8257600c54838383818110610ee857610ee8613ecc565b90506020020135610ef7610bff565b610f019190613ee2565b1115610f285760405162461bcd60e51b8152600401610f1f90613ef5565b60405180910390fd5b610f70858583818110610f3d57610f3d613ecc565b9050602002016020810190610f529190613930565b848484818110610f6457610f64613ecc565b90506020020135612e88565b80610f7a81613f17565b915050610ecb565b5050505050565b60158054610dd090613d2e565b60006001600160a01b038216610fb657610fb66323d3ad8160e21b6129f3565b506001600160a01b03166000908152600560205260409020546001600160401b031690565b610fe3612c31565b610fed6000612ea2565b565b610ff7612c31565b601055565b6000546060906001908282821461101b57611018858484612ef4565b90505b949350505050565b61102b612c31565b601155565b611038612c31565b600d55565b606060038054610b2890613d2e565b601b546040516bffffffffffffffffffffffff193360601b16602082015261108e91849160340160405160208183030381529060405280519060200120612ff3565b6110da5760405162461bcd60e51b815260206004820152601760248201527f4e6f7420612070617274206f6620416c6c6f776c6973740000000000000000006044820152606401610f1f565b601c5460ff166110fc5760405162461bcd60e51b8152600401610f1f90613f30565b600e54336000908152601f602052604090205461111a908390613ee2565b11156111685760405162461bcd60e51b815260206004820152601d60248201527f4d6178206c696d6974207065722077616c6c65742072656163686564210000006044820152606401610f1f565b600c5481611174610bff565b61117e9190613ee2565b111561119c5760405162461bcd60e51b8152600401610f1f90613ef5565b6000811180156111ae5750600e548111155b6111ec5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420416d6f756e742160881b6044820152606401610f1f565b80600d546111fa9190613d7e565b3410156112495760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f7567682065746865722070726f7669646564210000000000006044820152606401610f1f565b60015b8181116112975760008161125e610bff565b6112689190613ee2565b6000908152601d602090815260408083203384529091529020429055508061128f81613f17565b91505061124c565b50336000908152601f6020526040812080548392906112b7908490613ee2565b909155506112c790503382612e88565b60405181815233907f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe9060200160405180910390a25050565b606061101b848484612ef4565b611315612c31565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561135c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113809190613f77565b9050600081116113c05760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc8185b5bdd5b9d60aa1b6044820152606401610f1f565b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303816000875af115801561140d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfa9190613f90565b600e54336000908152601f602052604090205461144f908390613ee2565b111561149d5760405162461bcd60e51b815260206004820152601d60248201527f4d6178206c696d6974207065722077616c6c65742072656163686564210000006044820152606401610f1f565b600c54816114a9610bff565b6114b39190613ee2565b11156114d15760405162461bcd60e51b8152600401610f1f90613ef5565b601c5460ff16156114f45760405162461bcd60e51b8152600401610f1f90613f30565b6000811180156115065750600e548111155b6115445760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420416d6f756e742160881b6044820152606401610f1f565b80600d546115529190613d7e565b3410156115a15760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f7567682065746865722070726f7669646564210000000000006044820152606401610f1f565b60015b8181116115ef576000816115b6610bff565b6115c09190613ee2565b6000908152601d60209081526040808320338452909152902042905550806115e781613f17565b9150506115a4565b50336000908152601f60205260408120805483929061160f908490613ee2565b9091555061161f90503382612e88565b60405181815233907f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe9060200160405180910390a250565b81611661816129fd565b610bfa8383613009565b611673612c31565b601b55565b611680612c31565b601c805460ff19811660ff90911615179055565b836001600160a01b03811633146116ae576116ae336129fd565b6116ba85858585613075565b50506000908152601d602090815260408083206001600160a01b03958616845290915280822042908190559290931681529190912055565b6116fa612c31565b600c5481611706610bff565b6117109190613ee2565b111561172e5760405162461bcd60e51b8152600401610f1f90613ef5565b60005b8281101561177b5761176984848381811061174e5761174e613ecc565b90506020020160208101906117639190613930565b83612e88565b8061177381613f17565b915050611731565b50505050565b604080516080810182526000808252602082018190529181018290526060810191909152600182106117e0576000548210156117e0575b6000828152600460205260409020546117d757600019909101906117b8565b610b13826130b0565b919050565b6000805b83518110156126ed57600061181685838151811061180957611809613ecc565b602002602001015161312e565b905060008160405160200161182b9190613fad565b604051602081830303815290604052805190602001209050600085848151811061185757611857613ecc565b60200260200101519050336001600160a01b031661188d88868151811061188057611880613ecc565b6020026020010151610eb5565b6001600160a01b0316146118ef5760405162461bcd60e51b8152602060048201526024808201527f596f7520617265206e6f7420746865206f776e6572206f66207468697320746f60448201526335b2b71760e11b6064820152608401610f1f565b6118fc8160175484612ff3565b15611c69576000601d600089878151811061191957611919613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b0316815260200190815260200160002054905042601354826119649190613ee2565b11611c67576013546000906119798342613fc9565b6119839190613dab565b9050600081116119a55760405162461bcd60e51b8152600401610f1f90613fdc565b600081600f546119b59190613d7e565b90506119c18189613ee2565b600b546040516370a0823160e01b815230600482015291995082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015611a0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a329190613f77565b1015611a3d57600080fd5b336000908152601e602052604081208054839290611a5c908490613ee2565b9091555050601354611a6e9083613d7e565b601d60008c8a81518110611a8457611a84613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b031681526020019081526020016000206000828254611acc9190613ee2565b9091555050600b546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015611b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3d9190613f77565b1015611b5b5760405162461bcd60e51b8152600401610f1f9061400a565b600b5460405163095ea7b360e01b8152306004820152602481018390526001600160a01b039091169063095ea7b3906044016020604051808303816000875af1158015611bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd09190613f90565b50600b546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611c0590309033908690600401614041565b6020604051808303816000875af1158015611c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c489190613f90565b611c645760405162461bcd60e51b8152600401610f1f90614065565b50505b505b611c768160185484612ff3565b15611fe3576000601d6000898781518110611c9357611c93613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b031681526020019081526020016000205490504260135482611cde9190613ee2565b11611fe157601354600090611cf38342613fc9565b611cfd9190613dab565b905060008111611d1f5760405162461bcd60e51b8152600401610f1f90613fdc565b600081601054611d2f9190613d7e565b9050611d3b8189613ee2565b600b546040516370a0823160e01b815230600482015291995082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190613f77565b1015611db757600080fd5b336000908152601e602052604081208054839290611dd6908490613ee2565b9091555050601354611de89083613d7e565b601d60008c8a81518110611dfe57611dfe613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b031681526020019081526020016000206000828254611e469190613ee2565b9091555050600b546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015611e93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb79190613f77565b1015611ed55760405162461bcd60e51b8152600401610f1f9061400a565b600b5460405163095ea7b360e01b8152306004820152602481018390526001600160a01b039091169063095ea7b3906044016020604051808303816000875af1158015611f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4a9190613f90565b50600b546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611f7f90309033908690600401614041565b6020604051808303816000875af1158015611f9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc29190613f90565b611fde5760405162461bcd60e51b8152600401610f1f90614065565b50505b505b611ff08160195484612ff3565b1561235d576000601d600089878151811061200d5761200d613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b0316815260200190815260200160002054905042601354826120589190613ee2565b1161235b5760135460009061206d8342613fc9565b6120779190613dab565b9050600081116120995760405162461bcd60e51b8152600401610f1f90613fdc565b6000816011546120a99190613d7e565b90506120b58189613ee2565b600b546040516370a0823160e01b815230600482015291995082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015612102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121269190613f77565b101561213157600080fd5b336000908152601e602052604081208054839290612150908490613ee2565b90915550506013546121629083613d7e565b601d60008c8a8151811061217857612178613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b0316815260200190815260200160002060008282546121c09190613ee2565b9091555050600b546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa15801561220d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122319190613f77565b101561224f5760405162461bcd60e51b8152600401610f1f9061400a565b600b5460405163095ea7b360e01b8152306004820152602481018390526001600160a01b039091169063095ea7b3906044016020604051808303816000875af11580156122a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c49190613f90565b50600b546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906122f990309033908690600401614041565b6020604051808303816000875af1158015612318573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233c9190613f90565b6123585760405162461bcd60e51b8152600401610f1f90614065565b50505b505b61236a81601a5484612ff3565b156126d7576000601d600089878151811061238757612387613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b0316815260200190815260200160002054905042601354826123d29190613ee2565b116126d5576013546000906123e78342613fc9565b6123f19190613dab565b9050600081116124135760405162461bcd60e51b8152600401610f1f90613fdc565b6000816012546124239190613d7e565b905061242f8189613ee2565b600b546040516370a0823160e01b815230600482015291995082916001600160a01b03909116906370a0823190602401602060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a09190613f77565b10156124ab57600080fd5b336000908152601e6020526040812080548392906124ca908490613ee2565b90915550506013546124dc9083613d7e565b601d60008c8a815181106124f2576124f2613ecc565b602002602001015181526020019081526020016000206000336001600160a01b03166001600160a01b03168152602001908152602001600020600082825461253a9190613ee2565b9091555050600b546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612587573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ab9190613f77565b10156125c95760405162461bcd60e51b8152600401610f1f9061400a565b600b5460405163095ea7b360e01b8152306004820152602481018390526001600160a01b039091169063095ea7b3906044016020604051808303816000875af115801561261a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061263e9190613f90565b50600b546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061267390309033908690600401614041565b6020604051808303816000875af1158015612692573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b69190613f90565b6126d25760405162461bcd60e51b8152600401610f1f90614065565b50505b505b50505080806126e590613f17565b9150506117e9565b5060008111610bfa5760405162461bcd60e51b815260206004820152601660248201527543616e6e6f7420636c61696d2030207265776172647360501b6044820152606401610f1f565b6060612742826129a7565b6127ad5760405162461bcd60e51b815260206004820152603660248201527f4572723a20455243373231414d65746164617461202d20555249207175657279604482015275103337b9103737b732bc34b9ba32b73a103a37b5b2b760511b6064820152608401610f1f565b6000601580546127bc90613d2e565b9050116127d85760405180602001604052806000815250610b13565b60156127e38361322e565b60166040516020016127f793929190614101565b60405160208183030381529060405292915050565b612814612c31565b601255565b612821612c31565b600f55565b61282e612c31565b600e55565b61283b612c31565b601355565b612848612c31565b6000811161288e5760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610f1f565b600c548161289a610bff565b6128a49190613ee2565b11156128f25760405162461bcd60e51b815260206004820152601760248201527f4d6178696d756d20737570706c792065786365656465640000000000000000006044820152606401610f1f565b610d903382612e88565b612904612c31565b6001600160a01b0381166129695760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610f1f565b610d9081612ea2565b60006001600160e01b0319821663152a902d60e11b1480610b1357506301ffc9a760e01b6001600160e01b0319831614610b13565b6000816001116117e0576000548210156117e05760005b50600082815260046020526040812054908190036129e6576129df83614134565b92506129be565b600160e01b161592915050565b8060005260046000fd5b6daaeb6d7670e522a718067333cd4e3b15610d9057604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015612a6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8e9190613f90565b610d9057604051633b79c77360e21b81526001600160a01b0382166004820152602401610f1f565b610e6582826001613272565b6000612acd82612de7565b6001600160a01b039485169490915081168414612af357612af362a1148160e81b6129f3565b60008281526006602052604090208054612b1f8187335b6001600160a01b039081169116811491141790565b612b4157612b2d8633610a57565b612b4157612b41632ce44b5f60e11b6129f3565b8015612b4c57600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003612bde57600184016000818152600460205260408120549003612bdc576000548114612bdc5760008181526004602052604090208490555b505b6001600160a01b0385168481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a480600003612c2857612c28633a954ecd60e21b6129f3565b50505050505050565b600a546001600160a01b03163314610fed5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610f1f565b610bfa83838360405180602001604052806000815250611694565b6000612cb183612de7565b905080600080612ccf86600090815260066020526040902080549091565b915091508415612d0657612ce4818433612b0a565b612d0657612cf28333610a57565b612d0657612d06632ce44b5f60e11b6129f3565b8015612d1157600082555b6001600160a01b038316600081815260056020526040902080546fffffffffffffffffffffffffffffffff0190554260a01b17600360e01b17600087815260046020526040812091909155600160e11b85169003612d9f57600186016000818152600460205260408120549003612d9d576000548114612d9d5760008181526004602052604090208590555b505b60405186906000906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050600180548101905550505050565b600081600111612e78575060008181526004602052604081205490819003612e65576000548210612e2257612e22636f96cda160e11b6129f3565b5b50600019016000818152600460205260409020548015612e2357600160e01b8116600003612e5057919050565b612e60636f96cda160e11b6129f3565b612e23565b600160e01b8116600003612e7857919050565b6117e0636f96cda160e11b6129f3565b610e65828260405180602001604052806000815250613315565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6060818310612f0d57612f0d631960ccad60e11b6129f3565b6001831015612f1b57600192505b600054808310612f29578092505b60606000612f3687610f96565b85871090810291508115612fe7578187870311612f535786860391505b60405192506001820160051b83016040526000612f6f88611781565b905060008160400151612f80575080515b60005b612f8c8a6130b0565b9250604083015160008114612fa45760009250612fc9565b835115612fb057835192505b8b831860601b612fc9576001820191508a8260051b8801525b5060018a019950888a1480612fdd57508481145b15612f8357855250505b50909695505050505050565b6000826130008584613377565b14949350505050565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b613080848484610c0d565b6001600160a01b0383163b1561177b5761309c848484846133bc565b61177b5761177b6368d2bf6b60e11b6129f3565b604080516080810182526000808252602082018190529181018290526060810191909152600082815260046020526040902054610b1390604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b6060816000036131555750506040805180820190915260018152600360fc1b602082015290565b8160005b811561317f578061316981613f17565b91506131789050600a83613dab565b9150613159565b6000816001600160401b03811115613199576131996136dd565b6040519080825280601f01601f1916602001820160405280156131c3576020820181803683370190505b5090505b841561101b576131d8600183613fc9565b91506131e5600a8661414b565b6131f0906030613ee2565b60f81b81838151811061320557613205613ecc565b60200101906001600160f81b031916908160001a905350613227600a86613dab565b94506131c7565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806132485750819003601f19909101908152919050565b600061327d83610eb5565b90508180156132955750336001600160a01b03821614155b156132b8576132a48133610a57565b6132b8576132b86367d9dca160e11b6129f3565b60008381526006602052604080822080546001600160a01b0319166001600160a01b0388811691821790925591518693918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b61331f838361349e565b6001600160a01b0383163b15610bfa576000548281035b61334960008683806001019450866133bc565b61335d5761335d6368d2bf6b60e11b6129f3565b818110613336578160005414610f8257610f8260006129f3565b600081815b8451811015610ead576133a88286838151811061339b5761339b613ecc565b602002602001015161355d565b9150806133b481613f17565b91505061337c565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906133f190339089908890889060040161415f565b6020604051808303816000875af192505050801561342c575060408051601f3d908101601f191682019092526134299181019061419c565b60015b613481573d80801561345a576040519150601f19603f3d011682016040523d82523d6000602084013e61345f565b606091505b508051600003613479576134796368d2bf6b60e11b6129f3565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b60008054908290036134ba576134ba63b562e8dd60e01b6129f3565b60008181526004602090815260408083206001600160a01b0387164260a01b6001881460e11b1781179091558084526005909252822080546801000000000000000186020190559081900361351857613518622e076360e81b6129f3565b818301825b808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a481816001019150810361351d575060005550505050565b6000818310613579576000828152602084905260409020613588565b60008381526020839052604090205b9392505050565b6001600160e01b031981168114610d9057600080fd5b6000602082840312156135b757600080fd5b81356135888161358f565b60005b838110156135dd5781810151838201526020016135c5565b50506000910152565b600081518084526135fe8160208601602086016135c2565b601f01601f19169290920160200192915050565b60208152600061358860208301846135e6565b60006020828403121561363757600080fd5b5035919050565b80356001600160a01b03811681146117e057600080fd5b6000806040838503121561366857600080fd5b6136718361363e565b946020939093013593505050565b60008060006060848603121561369457600080fd5b61369d8461363e565b92506136ab6020850161363e565b9150604084013590509250925092565b600080604083850312156136ce57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561371b5761371b6136dd565b604052919050565b60006001600160401b0383111561373c5761373c6136dd565b61374f601f8401601f19166020016136f3565b905082815283838301111561376357600080fd5b828260208301376000602084830101529392505050565b60006020828403121561378c57600080fd5b81356001600160401b038111156137a257600080fd5b8201601f810184136137b357600080fd5b61101b84823560208401613723565b60008083601f8401126137d457600080fd5b5081356001600160401b038111156137eb57600080fd5b6020830191508360208260051b8501011115610d1057600080fd5b6000806020838503121561381957600080fd5b82356001600160401b0381111561382f57600080fd5b61383b858286016137c2565b90969095509350505050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6020808252825182820181905260009190848201906040850190845b81811015612fe7576138b2838551613847565b928401926080929092019160010161389f565b600080600080604085870312156138db57600080fd5b84356001600160401b03808211156138f257600080fd5b6138fe888389016137c2565b9096509450602087013591508082111561391757600080fd5b50613924878288016137c2565b95989497509550505050565b60006020828403121561394257600080fd5b6135888261363e565b6020808252825182820181905260009190848201906040850190845b81811015612fe757835183529284019291840191600101613967565b6000806040838503121561399657600080fd5b823591506139a66020840161363e565b90509250929050565b60006001600160401b038211156139c8576139c86136dd565b5060051b60200190565b600082601f8301126139e357600080fd5b813560206139f86139f3836139af565b6136f3565b82815260059290921b84018101918181019086841115613a1757600080fd5b8286015b84811015613a325780358352918301918301613a1b565b509695505050505050565b60008060408385031215613a5057600080fd5b82356001600160401b03811115613a6657600080fd5b613a72858286016139d2565b95602094909401359450505050565b600080600060608486031215613a9657600080fd5b613a9f8461363e565b95602085013595506040909401359392505050565b8015158114610d9057600080fd5b60008060408385031215613ad557600080fd5b613ade8361363e565b91506020830135613aee81613ab4565b809150509250929050565b60008060008060808587031215613b0f57600080fd5b613b188561363e565b9350613b266020860161363e565b92506040850135915060608501356001600160401b03811115613b4857600080fd5b8501601f81018713613b5957600080fd5b613b6887823560208401613723565b91505092959194509250565b600080600060408486031215613b8957600080fd5b83356001600160401b03811115613b9f57600080fd5b613bab868287016137c2565b909790965060209590950135949350505050565b60808101610b138284613847565b600082601f830112613bde57600080fd5b81356020613bee6139f3836139af565b82815260059290921b84018101918181019086841115613c0d57600080fd5b8286015b84811015613a325780356001600160401b03811115613c305760008081fd5b613c3e8986838b01016139d2565b845250918301918301613c11565b60008060408385031215613c5f57600080fd5b82356001600160401b0380821115613c7657600080fd5b818501915085601f830112613c8a57600080fd5b81356020613c9a6139f3836139af565b82815260059290921b84018101918181019089841115613cb957600080fd5b948201945b83861015613cd757853582529482019490820190613cbe565b96505086013592505080821115613ced57600080fd5b50613cfa85828601613bcd565b9150509250929050565b60008060408385031215613d1757600080fd5b613d208361363e565b91506139a66020840161363e565b600181811c90821680613d4257607f821691505b602082108103613d6257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610b1357610b13613d68565b634e487b7160e01b600052601260045260246000fd5b600082613dba57613dba613d95565b500490565b601f821115610bfa57600081815260208120601f850160051c81016020861015613de65750805b601f850160051c820191505b81811015613e0557828155600101613df2565b505050505050565b81516001600160401b03811115613e2657613e266136dd565b613e3a81613e348454613d2e565b84613dbf565b602080601f831160018114613e6f5760008415613e575750858301515b600019600386901b1c1916600185901b178555613e05565b600085815260208120601f198616915b82811015613e9e57888601518255948401946001909101908401613e7f565b5085821015613ebc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b80820180821115610b1357610b13613d68565b60208082526008908201526714dbdb19081bdd5d60c21b604082015260600190565b600060018201613f2957613f29613d68565b5060010190565b60208082526027908201527f5075626c6963204d696e74206973207475726e6564206f666620617420746865604082015266081b5bdb595b9d60ca1b606082015260800190565b600060208284031215613f8957600080fd5b5051919050565b600060208284031215613fa257600080fd5b815161358881613ab4565b60008251613fbf8184602087016135c2565b9190910192915050565b81810381811115610b1357610b13613d68565b6020808252601490820152734e6f207265776172647320617661696c61626c6560601b604082015260600190565b6020808252601d908201527f496e73756666696369656e7420636f6e74726163742062616c616e6365000000604082015260600190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020808252600f908201526e1d1c985b9cd9995c8819985a5b1959608a1b604082015260600190565b6000815461409b81613d2e565b600182811680156140b357600181146140c8576140f7565b60ff19841687528215158302870194506140f7565b8560005260208060002060005b858110156140ee5781548a8201529084019082016140d5565b50505082870194505b5050505092915050565b600061410d828661408e565b845161411d8183602089016135c2565b6141298183018661408e565b979650505050505050565b60008161414357614143613d68565b506000190190565b60008261415a5761415a613d95565b500690565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614192908301846135e6565b9695505050505050565b6000602082840312156141ae57600080fd5b81516135888161358f56fea264697066735822122064cf98b541b8f0f60915dc6d6967c13088b7687cca145cc44dec204eeafad33564736f6c63430008130033

Deployed Bytecode Sourcemap

105446:16338:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;121550:231;;;;;;;;;;-1:-1:-1;121550:231:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;121550:231:0;;;;;;;;56593:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;64136:290::-;;;;;;;;;;-1:-1:-1;64136:290:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:1;;;1679:51;;1667:2;1652:18;64136:290:0;1533:203:1;119626:225:0;;;;;;:::i;:::-;;:::i;:::-;;105686:33;;;;;;;;;;;;;;;;;;;2324:25:1;;;2312:2;2297:18;105686:33:0;2178:177:1;106003:75:0;;;;;;;;;;-1:-1:-1;106003:75:0;;;;-1:-1:-1;;;;;106003:75:0;;;52157:323;;;;;;;;;;;;;:::i;120034:340::-;;;;;;:::i;:::-;;:::i;10119:438::-;;;;;;;;;;-1:-1:-1;10119:438:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3138:32:1;;;3120:51;;3202:2;3187:18;;3180:34;;;;3093:18;10119:438:0;2946:274:1;106573:109:0;;;;;;;;;;;;;;;;105612:25;;;;;;;;;;;;;;;;117186:335;;;:::i;20313:143::-;;;;;;;;;;;;12729:42;20313:143;;120561:348;;;;;;:::i;:::-;;:::i;104812:94::-;;;;;;;;;;-1:-1:-1;104812:94:0;;;;;:::i;:::-;;:::i;106183:33::-;;;;;;;;;;;;;:::i;118080:104::-;;;;;;;;;;-1:-1:-1;118080:104:0;;;;;:::i;:::-;;:::i;96750:1163::-;;;;;;;;;;-1:-1:-1;96750:1163:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;105948:39::-;;;;;;;;;;;;;;;;58092:202;;;;;;;;;;-1:-1:-1;58092:202:0;;;;;:::i;:::-;;:::i;116071:324::-;;;;;;:::i;:::-;;:::i;106924:50::-;;;;;;;;;;-1:-1:-1;106924:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;106087:89;;;;;;;;;;;;;:::i;53341:292::-;;;;;;;;;;-1:-1:-1;53341:292:0;;;;;:::i;:::-;;:::i;26548:103::-;;;;;;;;;;;;;:::i;105836:45::-;;;;;;;;;;;;;;;;105781;;;;;;;;;;;;;;;;118542:116;;;;;;;;;;-1:-1:-1;118542:116:0;;;;;:::i;:::-;;:::i;98971:375::-;;;;;;;;;;-1:-1:-1;98971:375:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;118666:116::-;;;;;;;;;;-1:-1:-1;118666:116:0;;;;;:::i;:::-;;:::i;25900:87::-;;;;;;;;;;-1:-1:-1;25973:6:0;;-1:-1:-1;;;;;25973:6:0;25900:87;;105726:45;;;;;;;;;;;;;;;;117877:89;;;;;;;;;;-1:-1:-1;117877:89:0;;;;;:::i;:::-;;:::i;56769:104::-;;;;;;;;;;;;;:::i;106847:70::-;;;;;;;;;;-1:-1:-1;106847:70:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;108180:1127;;;;;;:::i;:::-;;:::i;98301:223::-;;;;;;;;;;-1:-1:-1;98301:223:0;;;;;:::i;:::-;;:::i;117529:232::-;;;;;;;;;;-1:-1:-1;117529:232:0;;;;;:::i;:::-;;:::i;107338:834::-;;;;;;:::i;:::-;;:::i;119221:227::-;;;;;;;;;;-1:-1:-1;119221:227:0;;;;;:::i;:::-;;:::i;106805:33::-;;;;;;;;;;-1:-1:-1;106805:33:0;;;;;;;;118300:110;;;;;;;;;;-1:-1:-1;118300:110:0;;;;;:::i;:::-;;:::i;117974:98::-;;;;;;;;;;;;;:::i;121096:382::-;;;;;;:::i;:::-;;:::i;105644:35::-;;;;;;;;;;;;;;;;115768:295;;;;;;:::i;:::-;;:::i;95995:596::-;;;;;;;;;;-1:-1:-1;95995:596:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;109315:6445::-;;;;;;;;;;-1:-1:-1;109315:6445:0;;;;;:::i;:::-;;:::i;116695:483::-;;;;;;;;;;-1:-1:-1;116695:483:0;;;;;:::i;:::-;;:::i;105891:45::-;;;;;;;;;;;;;;;;106225:109;;;;;;;;;;;;;;;;106691:105;;;;;;;;;;;;;;;;118790:116;;;;;;;;;;-1:-1:-1;118790:116:0;;;;;:::i;:::-;;:::i;118418:::-;;;;;;;;;;-1:-1:-1;118418:116:0;;;;;:::i;:::-;;:::i;118192:100::-;;;;;;;;;;-1:-1:-1;118192:100:0;;;;;:::i;:::-;;:::i;106457:109::-;;;;;;;;;;;;;;;;118914:111;;;;;;;;;;-1:-1:-1;118914:111:0;;;;;:::i;:::-;;:::i;65189:214::-;;;;;;;;;;-1:-1:-1;65189:214:0;;;;;:::i;:::-;-1:-1:-1;;;;;65360:25:0;;;65331:4;65360:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;65189:214;116403:284;;;;;;;;;;-1:-1:-1;116403:284:0;;;;;:::i;:::-;;:::i;26806:201::-;;;;;;;;;;-1:-1:-1;26806:201:0;;;;;:::i;:::-;;:::i;106981:52::-;;;;;;;;;;-1:-1:-1;106981:52:0;;;;;:::i;:::-;;;;;;;;;;;;;;106341:109;;;;;;;;;;;;;;;;121550:231;121708:4;121737:36;121761:11;121737:23;:36::i;:::-;121730:43;121550:231;-1:-1:-1;;121550:231:0:o;56593:100::-;56647:13;56680:5;56673:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56593:100;:::o;64136:290::-;64257:7;64287:16;64295:7;64287;:16::i;:::-;64282:86;;64318:50;-1:-1:-1;;;64318:7:0;:50::i;:::-;-1:-1:-1;64388:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;64388:30:0;;64136:290::o;119626:225::-;119785:8;22095:30;22116:8;22095:20;:30::i;:::-;119811:32:::1;119825:8;119835:7;119811:13;:32::i;:::-;119626:225:::0;;;:::o;52157:323::-;107321:1;52431:12;52218:7;52415:13;:28;-1:-1:-1;;52415:46:0;;52157:323::o;120034:340::-;120196:4;-1:-1:-1;;;;;21821:18:0;;21829:10;21821:18;21817:83;;21856:32;21877:10;21856:20;:32::i;:::-;120213:37:::1;120232:4;120238:2;120242:7;120213:18;:37::i;:::-;-1:-1:-1::0;120261:24:0::1;::::0;;;:15:::1;:24;::::0;;;;;;;-1:-1:-1;;;;;120261:30:0;;::::1;::::0;;;;;;;;120294:15:::1;120261:48:::0;;;;120320:28;;;::::1;::::0;;;;;;:46;120034:340::o;10119:438::-;10214:7;10272:26;;;:17;:26;;;;;;;;10243:55;;;;;;;;;-1:-1:-1;;;;;10243:55:0;;;;;-1:-1:-1;;;10243:55:0;;;-1:-1:-1;;;;;10243:55:0;;;;;;;;10214:7;;10311:92;;-1:-1:-1;10362:29:0;;;;;;;;;10372:19;10362:29;-1:-1:-1;;;;;10362:29:0;;;;-1:-1:-1;;;10362:29:0;;-1:-1:-1;;;;;10362:29:0;;;;;10311:92;10452:23;;;;10415:21;;10923:5;;10440:35;;-1:-1:-1;;;;;10440:35:0;:9;:35;:::i;:::-;10439:57;;;;:::i;:::-;10517:16;;;-1:-1:-1;10415:81:0;;-1:-1:-1;;10119:438:0;;;;;;:::o;117186:335::-;25786:13;:11;:13::i;:::-;117333:7:::1;117354;25973:6:::0;;-1:-1:-1;;;;;25973:6:0;;25900:87;117354:7:::1;-1:-1:-1::0;;;;;117346:21:0::1;117375;117346:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;117332:69;;;117420:2;117412:11;;;::::0;::::1;;117231:290;117186:335::o:0;120561:348::-;120727:4;-1:-1:-1;;;;;21821:18:0;;21829:10;21821:18;21817:83;;21856:32;21877:10;21856:20;:32::i;:::-;120744:41:::1;120767:4;120773:2;120777:7;120744:22;:41::i;104812:94::-:0;104878:20;104884:7;104893:4;104878:5;:20::i;106183:33::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;118080:104::-;25786:13;:11;:13::i;:::-;118155:7:::1;:21;118165:11:::0;118155:7;:21:::1;:::i;:::-;;118080:104:::0;:::o;96750:1163::-;97108:4;97102:11;;97161:21;;;97313:1;97309:9;;;97368:29;;;97388:4;97368:29;97355:43;;;96894:23;;97419:459;97426:6;;97419:459;;-1:-1:-1;;97512:12:0;;;;97566:23;;;97553:37;97449:15;97653:28;97553:37;97653:19;:28::i;:::-;97811:29;;;97831:4;97811:29;97804:48;-1:-1:-1;97419:459:0;;-1:-1:-1;97419:459:0;;-1:-1:-1;97895:10:0;96750:1163;-1:-1:-1;;;96750:1163:0:o;58092:202::-;58209:7;58257:27;58276:7;58257:18;:27::i;116071:324::-;25786:13;:11;:13::i;:::-;116222:9:::1;116217:171;116237:14:::0;;::::1;116217:171;;;116310:10;;116297:6;;116304:1;116297:9;;;;;;;:::i;:::-;;;;;;;116281:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:39;;116273:60;;;;-1:-1:-1::0;;;116273:60:0::1;;;;;;;:::i;:::-;;;;;;;;;116348:28;116358:3;;116362:1;116358:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;116366;;116373:1;116366:9;;;;;;;:::i;:::-;;;;;;;116348;:28::i;:::-;116253:3:::0;::::1;::::0;::::1;:::i;:::-;;;;116217:171;;;;116071:324:::0;;;;:::o;106087:89::-;;;;;;;:::i;53341:292::-;53458:7;-1:-1:-1;;;;;53487:19:0;;53483:69;;53508:44;-1:-1:-1;;;53508:7:0;:44::i;:::-;-1:-1:-1;;;;;;53570:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;53570:55:0;;53341:292::o;26548:103::-;25786:13;:11;:13::i;:::-;26613:30:::1;26640:1;26613:18;:30::i;:::-;26548:103::o:0;118542:116::-;25786:13;:11;:13::i;:::-;118620:20:::1;:30:::0;118542:116::o;98971:375::-;99128:13;51926;99094:16;;107321:1;;99094:16;99250:13;;;99246:66;;99276:36;99293:5;99300;99307:4;99276:16;:36::i;:::-;99265:47;;99246:66;99330:8;98971:375;-1:-1:-1;;;;98971:375:0:o;118666:116::-;25786:13;:11;:13::i;:::-;118744:20:::1;:30:::0;118666:116::o;117877:89::-;25786:13;:11;:13::i;:::-;117939:10:::1;:19:::0;117877:89::o;56769:104::-;56825:13;56858:7;56851:14;;;;;:::i;108180:1127::-;108383:12;;108424:28;;-1:-1:-1;;108441:10:0;18982:2:1;18978:15;18974:53;108424:28:0;;;18962:66:1;108316:152:0;;108353:11;;19044:12:1;;108424:28:0;;;;;;;;;;;;108414:39;;;;;;108316:18;:152::i;:::-;108294:225;;;;-1:-1:-1;;;108294:225:0;;19269:2:1;108294:225:0;;;19251:21:1;19308:2;19288:18;;;19281:30;19347:25;19327:18;;;19320:53;19390:18;;108294:225:0;19067:347:1;108294:225:0;108538:14;;;;108530:66;;;;-1:-1:-1;;;108530:66:0;;;;;;;:::i;:::-;108672:14;;108647:10;108629:29;;;;:17;:29;;;;;;:39;;108661:7;;108629:39;:::i;:::-;:57;;108607:136;;;;-1:-1:-1;;;108607:136:0;;20029:2:1;108607:136:0;;;20011:21:1;20068:2;20048:18;;;20041:30;20107:31;20087:18;;;20080:59;20156:18;;108607:136:0;19827:353:1;108607:136:0;108789:10;;108778:7;108762:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:37;;108754:58;;;;-1:-1:-1;;;108754:58:0;;;;;;;:::i;:::-;108841:1;108831:7;:11;:40;;;;;108857:14;;108846:7;:25;;108831:40;108823:68;;;;-1:-1:-1;;;108823:68:0;;20387:2:1;108823:68:0;;;20369:21:1;20426:2;20406:18;;;20399:30;-1:-1:-1;;;20445:18:1;;;20438:45;20500:18;;108823:68:0;20185:339:1;108823:68:0;108946:7;108933:10;;:20;;;;:::i;:::-;108920:9;:33;;108912:72;;;;-1:-1:-1;;;108912:72:0;;20731:2:1;108912:72:0;;;20713:21:1;20770:2;20750:18;;;20743:30;20809:28;20789:18;;;20782:56;20855:18;;108912:72:0;20529:350:1;108912:72:0;109014:1;108997:166;109022:7;109017:1;:12;108997:166;;109051:13;109083:1;109067:13;:11;:13::i;:::-;:17;;;;:::i;:::-;109099:22;;;;:15;:22;;;;;;;;109122:10;109099:34;;;;;;;109136:15;109099:52;;-1:-1:-1;109031:3:0;;;;:::i;:::-;;;;108997:166;;;-1:-1:-1;109193:10:0;109175:29;;;;:17;:29;;;;;:40;;109208:7;;109175:29;:40;;109208:7;;109175:40;:::i;:::-;;;;-1:-1:-1;109226:30:0;;-1:-1:-1;109236:10:0;109248:7;109226:9;:30::i;:::-;109272:27;;2324:25:1;;;109279:10:0;;109272:27;;2312:2:1;2297:18;109272:27:0;;;;;;;108180:1127;;:::o;98301:223::-;98444:16;98480:36;98497:5;98504;98511:4;98480:16;:36::i;117529:232::-;25786:13;:11;:13::i;:::-;117615:38:::1;::::0;-1:-1:-1;;;117615:38:0;;117647:4:::1;117615:38;::::0;::::1;1679:51:1::0;117597:15:0::1;::::0;-1:-1:-1;;;;;117615:23:0;::::1;::::0;::::1;::::0;1652:18:1;;117615:38:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;117597:56;;117682:1;117672:7;:11;117664:35;;;::::0;-1:-1:-1;;;117664:35:0;;21275:2:1;117664:35:0::1;::::0;::::1;21257:21:1::0;21314:2;21294:18;;;21287:30;-1:-1:-1;;;21333:18:1;;;21326:41;21384:18;;117664:35:0::1;21073:335:1::0;117664:35:0::1;117710:43;::::0;-1:-1:-1;;;117710:43:0;;117733:10:::1;117710:43;::::0;::::1;3120:51:1::0;3187:18;;;3180:34;;;-1:-1:-1;;;;;117710:22:0;::::1;::::0;::::1;::::0;3093:18:1;;117710:43:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;107338:834::-:0;107462:14;;107437:10;107419:29;;;;:17;:29;;;;;;:39;;107451:7;;107419:39;:::i;:::-;:57;;107397:136;;;;-1:-1:-1;;;107397:136:0;;20029:2:1;107397:136:0;;;20011:21:1;20068:2;20048:18;;;20041:30;20107:31;20087:18;;;20080:59;20156:18;;107397:136:0;19827:353:1;107397:136:0;107579:10;;107568:7;107552:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:37;;107544:58;;;;-1:-1:-1;;;107544:58:0;;;;;;;:::i;:::-;107622:14;;;;107621:15;107613:67;;;;-1:-1:-1;;;107613:67:0;;;;;;;:::i;:::-;107709:1;107699:7;:11;:40;;;;;107725:14;;107714:7;:25;;107699:40;107691:68;;;;-1:-1:-1;;;107691:68:0;;20387:2:1;107691:68:0;;;20369:21:1;20426:2;20406:18;;;20399:30;-1:-1:-1;;;20445:18:1;;;20438:45;20500:18;;107691:68:0;20185:339:1;107691:68:0;107811:7;107798:10;;:20;;;;:::i;:::-;107785:9;:33;;107777:72;;;;-1:-1:-1;;;107777:72:0;;20731:2:1;107777:72:0;;;20713:21:1;20770:2;20750:18;;;20743:30;20809:28;20789:18;;;20782:56;20855:18;;107777:72:0;20529:350:1;107777:72:0;107879:1;107862:166;107887:7;107882:1;:12;107862:166;;107916:13;107948:1;107932:13;:11;:13::i;:::-;:17;;;;:::i;:::-;107964:22;;;;:15;:22;;;;;;;;107987:10;107964:34;;;;;;;108001:15;107964:52;;-1:-1:-1;107896:3:0;;;;:::i;:::-;;;;107862:166;;;-1:-1:-1;108058:10:0;108040:29;;;;:17;:29;;;;;:40;;108073:7;;108040:29;:40;;108073:7;;108040:40;:::i;:::-;;;;-1:-1:-1;108091:30:0;;-1:-1:-1;108101:10:0;108113:7;108091:9;:30::i;:::-;108137:27;;2324:25:1;;;108144:10:0;;108137:27;;2312:2:1;2297:18;108137:27:0;;;;;;;107338:834;:::o;119221:227::-;119371:8;22095:30;22116:8;22095:20;:30::i;:::-;119397:43:::1;119421:8;119431;119397:23;:43::i;118300:110::-:0;25786:13;:11;:13::i;:::-;118376:12:::1;:26:::0;118300:110::o;117974:98::-;25786:13;:11;:13::i;:::-;118050:14:::1;::::0;;-1:-1:-1;;118032:32:0;::::1;118050:14;::::0;;::::1;118049:15;118032:32;::::0;;117974:98::o;121096:382::-;121290:4;-1:-1:-1;;;;;21821:18:0;;21829:10;21821:18;21817:83;;21856:32;21877:10;21856:20;:32::i;:::-;121307:47:::1;121330:4;121336:2;121340:7;121349:4;121307:22;:47::i;:::-;-1:-1:-1::0;;121365:24:0::1;::::0;;;:15:::1;:24;::::0;;;;;;;-1:-1:-1;;;;;121365:30:0;;::::1;::::0;;;;;;;;121398:15:::1;121365:48:::0;;;;121424:28;;;::::1;::::0;;;;;;:46;121096:382::o;115768:295::-;25786:13;:11;:13::i;:::-;115929:10:::1;;115919:6;115903:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:36;;115895:57;;;;-1:-1:-1::0;;;115895:57:0::1;;;;;;;:::i;:::-;115968:9;115963:93;115983:14:::0;;::::1;115963:93;;;116019:25;116029:3;;116033:1;116029:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;116037;116019:9;:25::i;:::-;115999:3:::0;::::1;::::0;::::1;:::i;:::-;;;;115963:93;;;;115768:295:::0;;;:::o;95995:596::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107321:1:0;96202:7;:26;96198:375;;51899:7;51926:13;96253:7;:24;96249:309;;;96436:51;59288:4;59317:24;;;:17;:24;;;;;;96436:51;;-1:-1:-1;;96478:9:0;;;;96436:51;;;96517:21;96530:7;96517:12;:21::i;96249:309::-;95995:596;;;:::o;109315:6445::-;109443:20;109483:9;109478:6213;109502:11;:18;109498:1;:22;109478:6213;;;109542:25;109570:32;109587:11;109599:1;109587:14;;;;;;;;:::i;:::-;;;;;;;109570:16;:32::i;:::-;109542:60;;109617:12;109659:11;109642:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;109632:40;;;;;;109617:55;;109687:29;109719:11;109731:1;109719:14;;;;;;;;:::i;:::-;;;;;;;109687:46;;109801:10;-1:-1:-1;;;;;109774:37:0;:23;109782:11;109794:1;109782:14;;;;;;;;:::i;:::-;;;;;;;109774:7;:23::i;:::-;-1:-1:-1;;;;;109774:37:0;;109748:135;;;;-1:-1:-1;;;109748:135:0;;22159:2:1;109748:135:0;;;22141:21:1;22198:2;22178:18;;;22171:30;22237:34;22217:18;;;22210:62;-1:-1:-1;;;22288:18:1;;;22281:34;22332:19;;109748:135:0;21957:400:1;109748:135:0;109904:56;109923:12;109937:16;;109955:4;109904:18;:56::i;:::-;109900:1433;;;109981:22;110006:15;:31;110022:11;110034:1;110022:14;;;;;;;;:::i;:::-;;;;;;;110006:31;;;;;;;;;;;:83;110060:10;-1:-1:-1;;;;;110006:83:0;-1:-1:-1;;;;;110006:83:0;;;;;;;;;;;;;109981:108;;110148:15;110129;;110112:14;:32;;;;:::i;:::-;:51;110108:1210;;110271:15;;110188:18;;110210:32;110228:14;110210:15;:32;:::i;:::-;110209:77;;;;:::i;:::-;110188:98;;110330:1;110317:10;:14;110309:47;;;;-1:-1:-1;;;110309:47:0;;;;;;;:::i;:::-;110379:14;110419:10;110396:20;;:33;;;;:::i;:::-;110379:50;-1:-1:-1;110452:22:0;110379:50;110452:22;;:::i;:::-;110505:9;;:34;;-1:-1:-1;;;110505:34:0;;110533:4;110505:34;;;1679:51:1;110452:22:0;;-1:-1:-1;110543:6:0;;-1:-1:-1;;;;;110505:9:0;;;;:19;;1652:18:1;;110505:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;110497:53;;;;;;110589:10;110573:27;;;;:15;:27;;;;;:37;;110604:6;;110573:27;:37;;110604:6;;110573:37;:::i;:::-;;;;-1:-1:-1;;110743:15:0;;110705:53;;:10;:53;:::i;:::-;110633:15;:31;110649:11;110661:1;110649:14;;;;;;;;:::i;:::-;;;;;;;110633:31;;;;;;;;;;;:43;110665:10;-1:-1:-1;;;;;110633:43:0;-1:-1:-1;;;;;110633:43:0;;;;;;;;;;;;;:125;;;;;;;:::i;:::-;;;;-1:-1:-1;;110815:9:0;;:34;;-1:-1:-1;;;110815:34:0;;110843:4;110815:34;;;1679:51:1;110853:6:0;;-1:-1:-1;;;;;110815:9:0;;:19;;1652:18:1;;110815:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;110781:159;;;;-1:-1:-1;;;110781:159:0;;;;;;;:::i;:::-;110963:9;;:40;;-1:-1:-1;;;110963:40:0;;110989:4;110963:40;;;3120:51:1;3187:18;;;3180:34;;;-1:-1:-1;;;;;110963:9:0;;;;:17;;3093:18:1;;110963:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;111060:9:0;;:171;;-1:-1:-1;;;111060:171:0;;-1:-1:-1;;;;;111060:9:0;;;;:22;;:171;;111121:4;;111157:10;;111198:6;;111060:171;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;111026:272;;;;-1:-1:-1;;;111026:272:0;;;;;;;:::i;:::-;110165:1153;;110108:1210;109962:1371;109900:1433;111353:56;111372:12;111386:16;;111404:4;111353:18;:56::i;:::-;111349:1433;;;111430:22;111455:15;:31;111471:11;111483:1;111471:14;;;;;;;;:::i;:::-;;;;;;;111455:31;;;;;;;;;;;:83;111509:10;-1:-1:-1;;;;;111455:83:0;-1:-1:-1;;;;;111455:83:0;;;;;;;;;;;;;111430:108;;111597:15;111578;;111561:14;:32;;;;:::i;:::-;:51;111557:1210;;111720:15;;111637:18;;111659:32;111677:14;111659:15;:32;:::i;:::-;111658:77;;;;:::i;:::-;111637:98;;111779:1;111766:10;:14;111758:47;;;;-1:-1:-1;;;111758:47:0;;;;;;;:::i;:::-;111828:14;111868:10;111845:20;;:33;;;;:::i;:::-;111828:50;-1:-1:-1;111901:22:0;111828:50;111901:22;;:::i;:::-;111954:9;;:34;;-1:-1:-1;;;111954:34:0;;111982:4;111954:34;;;1679:51:1;111901:22:0;;-1:-1:-1;111992:6:0;;-1:-1:-1;;;;;111954:9:0;;;;:19;;1652:18:1;;111954:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;111946:53;;;;;;112038:10;112022:27;;;;:15;:27;;;;;:37;;112053:6;;112022:27;:37;;112053:6;;112022:37;:::i;:::-;;;;-1:-1:-1;;112192:15:0;;112154:53;;:10;:53;:::i;:::-;112082:15;:31;112098:11;112110:1;112098:14;;;;;;;;:::i;:::-;;;;;;;112082:31;;;;;;;;;;;:43;112114:10;-1:-1:-1;;;;;112082:43:0;-1:-1:-1;;;;;112082:43:0;;;;;;;;;;;;;:125;;;;;;;:::i;:::-;;;;-1:-1:-1;;112264:9:0;;:34;;-1:-1:-1;;;112264:34:0;;112292:4;112264:34;;;1679:51:1;112302:6:0;;-1:-1:-1;;;;;112264:9:0;;:19;;1652:18:1;;112264:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;112230:159;;;;-1:-1:-1;;;112230:159:0;;;;;;;:::i;:::-;112412:9;;:40;;-1:-1:-1;;;112412:40:0;;112438:4;112412:40;;;3120:51:1;3187:18;;;3180:34;;;-1:-1:-1;;;;;112412:9:0;;;;:17;;3093:18:1;;112412:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;112509:9:0;;:171;;-1:-1:-1;;;112509:171:0;;-1:-1:-1;;;;;112509:9:0;;;;:22;;:171;;112570:4;;112606:10;;112647:6;;112509:171;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;112475:272;;;;-1:-1:-1;;;112475:272:0;;;;;;;:::i;:::-;111614:1153;;111557:1210;111411:1371;111349:1433;112802:56;112821:12;112835:16;;112853:4;112802:18;:56::i;:::-;112798:1433;;;112879:22;112904:15;:31;112920:11;112932:1;112920:14;;;;;;;;:::i;:::-;;;;;;;112904:31;;;;;;;;;;;:83;112958:10;-1:-1:-1;;;;;112904:83:0;-1:-1:-1;;;;;112904:83:0;;;;;;;;;;;;;112879:108;;113046:15;113027;;113010:14;:32;;;;:::i;:::-;:51;113006:1210;;113169:15;;113086:18;;113108:32;113126:14;113108:15;:32;:::i;:::-;113107:77;;;;:::i;:::-;113086:98;;113228:1;113215:10;:14;113207:47;;;;-1:-1:-1;;;113207:47:0;;;;;;;:::i;:::-;113277:14;113317:10;113294:20;;:33;;;;:::i;:::-;113277:50;-1:-1:-1;113350:22:0;113277:50;113350:22;;:::i;:::-;113403:9;;:34;;-1:-1:-1;;;113403:34:0;;113431:4;113403:34;;;1679:51:1;113350:22:0;;-1:-1:-1;113441:6:0;;-1:-1:-1;;;;;113403:9:0;;;;:19;;1652:18:1;;113403:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;113395:53;;;;;;113487:10;113471:27;;;;:15;:27;;;;;:37;;113502:6;;113471:27;:37;;113502:6;;113471:37;:::i;:::-;;;;-1:-1:-1;;113641:15:0;;113603:53;;:10;:53;:::i;:::-;113531:15;:31;113547:11;113559:1;113547:14;;;;;;;;:::i;:::-;;;;;;;113531:31;;;;;;;;;;;:43;113563:10;-1:-1:-1;;;;;113531:43:0;-1:-1:-1;;;;;113531:43:0;;;;;;;;;;;;;:125;;;;;;;:::i;:::-;;;;-1:-1:-1;;113713:9:0;;:34;;-1:-1:-1;;;113713:34:0;;113741:4;113713:34;;;1679:51:1;113751:6:0;;-1:-1:-1;;;;;113713:9:0;;:19;;1652:18:1;;113713:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;113679:159;;;;-1:-1:-1;;;113679:159:0;;;;;;;:::i;:::-;113861:9;;:40;;-1:-1:-1;;;113861:40:0;;113887:4;113861:40;;;3120:51:1;3187:18;;;3180:34;;;-1:-1:-1;;;;;113861:9:0;;;;:17;;3093:18:1;;113861:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;113958:9:0;;:171;;-1:-1:-1;;;113958:171:0;;-1:-1:-1;;;;;113958:9:0;;;;:22;;:171;;114019:4;;114055:10;;114096:6;;113958:171;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113924:272;;;;-1:-1:-1;;;113924:272:0;;;;;;;:::i;:::-;113063:1153;;113006:1210;112860:1371;112798:1433;114251:56;114270:12;114284:16;;114302:4;114251:18;:56::i;:::-;114247:1433;;;114328:22;114353:15;:31;114369:11;114381:1;114369:14;;;;;;;;:::i;:::-;;;;;;;114353:31;;;;;;;;;;;:83;114407:10;-1:-1:-1;;;;;114353:83:0;-1:-1:-1;;;;;114353:83:0;;;;;;;;;;;;;114328:108;;114495:15;114476;;114459:14;:32;;;;:::i;:::-;:51;114455:1210;;114618:15;;114535:18;;114557:32;114575:14;114557:15;:32;:::i;:::-;114556:77;;;;:::i;:::-;114535:98;;114677:1;114664:10;:14;114656:47;;;;-1:-1:-1;;;114656:47:0;;;;;;;:::i;:::-;114726:14;114766:10;114743:20;;:33;;;;:::i;:::-;114726:50;-1:-1:-1;114799:22:0;114726:50;114799:22;;:::i;:::-;114852:9;;:34;;-1:-1:-1;;;114852:34:0;;114880:4;114852:34;;;1679:51:1;114799:22:0;;-1:-1:-1;114890:6:0;;-1:-1:-1;;;;;114852:9:0;;;;:19;;1652:18:1;;114852:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;114844:53;;;;;;114936:10;114920:27;;;;:15;:27;;;;;:37;;114951:6;;114920:27;:37;;114951:6;;114920:37;:::i;:::-;;;;-1:-1:-1;;115090:15:0;;115052:53;;:10;:53;:::i;:::-;114980:15;:31;114996:11;115008:1;114996:14;;;;;;;;:::i;:::-;;;;;;;114980:31;;;;;;;;;;;:43;115012:10;-1:-1:-1;;;;;114980:43:0;-1:-1:-1;;;;;114980:43:0;;;;;;;;;;;;;:125;;;;;;;:::i;:::-;;;;-1:-1:-1;;115162:9:0;;:34;;-1:-1:-1;;;115162:34:0;;115190:4;115162:34;;;1679:51:1;115200:6:0;;-1:-1:-1;;;;;115162:9:0;;:19;;1652:18:1;;115162:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;115128:159;;;;-1:-1:-1;;;115128:159:0;;;;;;;:::i;:::-;115310:9;;:40;;-1:-1:-1;;;115310:40:0;;115336:4;115310:40;;;3120:51:1;3187:18;;;3180:34;;;-1:-1:-1;;;;;115310:9:0;;;;:17;;3093:18:1;;115310:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;115407:9:0;;:171;;-1:-1:-1;;;115407:171:0;;-1:-1:-1;;;;;115407:9:0;;;;:22;;:171;;115468:4;;115504:10;;115545:6;;115407:171;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115373:272;;;;-1:-1:-1;;;115373:272:0;;;;;;;:::i;:::-;114512:1153;;114455:1210;114309:1371;114247:1433;109527:6164;;;109522:3;;;;;:::i;:::-;;;;109478:6213;;;;115724:1;115709:12;:16;115701:51;;;;-1:-1:-1;;;115701:51:0;;24128:2:1;115701:51:0;;;24110:21:1;24167:2;24147:18;;;24140:30;-1:-1:-1;;;24186:18:1;;;24179:52;24248:18;;115701:51:0;23926:346:1;116695:483:0;116815:13;116868:16;116876:7;116868;:16::i;:::-;116846:120;;;;-1:-1:-1;;;116846:120:0;;24479:2:1;116846:120:0;;;24461:21:1;24518:2;24498:18;;;24491:30;24557:34;24537:18;;;24530:62;-1:-1:-1;;;24608:18:1;;;24601:52;24670:19;;116846:120:0;24277:418:1;116846:120:0;117023:1;117005:7;116999:21;;;;;:::i;:::-;;;:25;:171;;;;;;;;;;;;;;;;;117090:7;117099:18;117109:7;117099:9;:18::i;:::-;117119:9;117073:56;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;116979:191;116695:483;-1:-1:-1;;116695:483:0:o;118790:116::-;25786:13;:11;:13::i;:::-;118868:20:::1;:30:::0;118790:116::o;118418:::-;25786:13;:11;:13::i;:::-;118496:20:::1;:30:::0;118418:116::o;118192:100::-;25786:13;:11;:13::i;:::-;118261:14:::1;:23:::0;118192:100::o;118914:111::-;25786:13;:11;:13::i;:::-;118990:15:::1;:27:::0;118914:111::o;116403:284::-;25786:13;:11;:13::i;:::-;116490:1:::1;116479:8;:12;116471:44;;;::::0;-1:-1:-1;;;116471:44:0;;26103:2:1;116471:44:0::1;::::0;::::1;26085:21:1::0;26142:2;26122:18;;;26115:30;-1:-1:-1;;;26161:18:1;;;26154:49;26220:18;;116471:44:0::1;25901:343:1::0;116471:44:0::1;116576:10;;116564:8;116548:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;;116526:111;;;::::0;-1:-1:-1;;;116526:111:0;;26451:2:1;116526:111:0::1;::::0;::::1;26433:21:1::0;26490:2;26470:18;;;26463:30;26529:25;26509:18;;;26502:53;26572:18;;116526:111:0::1;26249:347:1::0;116526:111:0::1;116648:31;116658:10;116670:8;116648:9;:31::i;26806:201::-:0;25786:13;:11;:13::i;:::-;-1:-1:-1;;;;;26895:22:0;::::1;26887:73;;;::::0;-1:-1:-1;;;26887:73:0;;26803:2:1;26887:73:0::1;::::0;::::1;26785:21:1::0;26842:2;26822:18;;;26815:30;26881:34;26861:18;;;26854:62;-1:-1:-1;;;26932:18:1;;;26925:36;26978:19;;26887:73:0::1;26601:402:1::0;26887:73:0::1;26971:28;26990:8;26971:18;:28::i;9849:215::-:0;9951:4;-1:-1:-1;;;;;;9975:41:0;;-1:-1:-1;;;9975:41:0;;:81;;-1:-1:-1;;;;;;;;;;7406:40:0;;;10020:36;7297:157;65661:409;65762:11;65814:7;107321:1;65795:26;65791:272;;65852:13;;65842:7;:23;65838:214;;;65886:14;65919:60;-1:-1:-1;65936:26:0;;;;:17;:26;;;;;;;65926:42;;;65919:60;;65970:9;;;:::i;:::-;;;65919:60;;;-1:-1:-1;;;66007:24:0;:29;;65661:409;-1:-1:-1;;65661:409:0:o;92486:165::-;92587:13;92581:4;92574:27;92628:4;92622;92615:18;22238:647;12729:42;22429:45;:49;22425:453;;22728:67;;-1:-1:-1;;;22728:67:0;;22779:4;22728:67;;;27361:34:1;-1:-1:-1;;;;;27431:15:1;;27411:18;;;27404:43;12729:42:0;;22728;;27296:18:1;;22728:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22723:144;;22823:28;;-1:-1:-1;;;22823:28:0;;-1:-1:-1;;;;;1697:32:1;;22823:28:0;;;1679:51:1;1652:18;;22823:28:0;1533:203:1;63812:165:0;63942:27;63951:2;63955:7;63964:4;63942:8;:27::i;68056:3701::-;68198:27;68228;68247:7;68228:18;:27::i;:::-;-1:-1:-1;;;;;68383:22:0;;;;68198:57;;-1:-1:-1;68443:45:0;;;;68439:108;;68503:44;-1:-1:-1;;;68503:7:0;:44::i;:::-;68575:27;67164:24;;;:15;:24;;;;;67392:26;;68803:134;67392:26;68880:4;90513:10;68903:19;-1:-1:-1;;;;;66638:32:0;;;66482:28;;66767:20;;66789:30;;66764:56;;66179:659;68803:134;68784:296;;68967:43;68984:4;90513:10;65189:214;:::i;68967:43::-;68962:118;;69029:51;-1:-1:-1;;;69029:7:0;:51::i;:::-;69229:15;69226:160;;;69369:1;69348:19;69341:30;69226:160;-1:-1:-1;;;;;69766:24:0;;;;;;;:18;:24;;;;;;69764:26;;-1:-1:-1;;69764:26:0;;;69835:22;;;;;;;;;69833:24;;-1:-1:-1;69833:24:0;;;62868:11;62843:23;62839:41;62791:112;-1:-1:-1;;;62791:112:0;70128:26;;;;:17;:26;;;;;:196;;;;-1:-1:-1;;;70444:47:0;;:52;;70440:627;;70549:1;70539:11;;70517:19;70672:30;;;:17;:30;;;;;;:35;;70668:384;;70810:13;;70795:11;:28;70791:242;;70957:30;;;;:17;:30;;;;;:52;;;70791:242;70498:569;70440:627;-1:-1:-1;;;;;71199:20:0;;71579:7;71199:20;71509:4;71451:25;71180:16;;71316:299;71640:8;71652:1;71640:13;71636:58;;71655:39;-1:-1:-1;;;71655:7:0;:39::i;:::-;68187:3570;;;;68056:3701;;;:::o;26065:132::-;25973:6;;-1:-1:-1;;;;;25973:6:0;90513:10;26129:23;26121:68;;;;-1:-1:-1;;;26121:68:0;;27660:2:1;26121:68:0;;;27642:21:1;;;27679:18;;;27672:30;27738:34;27718:18;;;27711:62;27790:18;;26121:68:0;27458:356:1;71853:193:0;71999:39;72016:4;72022:2;72026:7;71999:39;;;;;;;;;;;;:16;:39::i;84718:3283::-;84798:27;84828;84847:7;84828:18;:27::i;:::-;84798:57;-1:-1:-1;84798:57:0;84868:12;;85027:35;85054:7;67053:27;67164:24;;;:15;:24;;;;;67392:26;;67164:24;;66951:485;85027:35;84933:129;;;;85079:13;85075:460;;;85218:150;85265:15;85303:4;90513:10;85330:19;90426:105;85218:150;85195:328;;85406:43;85423:4;90513:10;65189:214;:::i;85406:43::-;85401:122;;85472:51;-1:-1:-1;;;85472:7:0;:51::i;:::-;85691:15;85688:160;;;85831:1;85810:19;85803:30;85688:160;-1:-1:-1;;;;;86450:24:0;;;;;;:18;:24;;;;;:60;;86478:32;86450:60;;;62868:11;62843:23;62839:41;62791:112;-1:-1:-1;;;62791:112:0;86748:26;;;;:17;:26;;;;;:226;;;;-1:-1:-1;;;87094:47:0;;:52;;87090:627;;87199:1;87189:11;;87167:19;87322:30;;;:17;:30;;;;;;:35;;87318:384;;87460:13;;87445:11;:28;87441:242;;87607:30;;;;:17;:30;;;;;:52;;;87441:242;87148:569;87090:627;87745:35;;87772:7;;87768:1;;-1:-1:-1;;;;;87745:35:0;;;;;87768:1;;87745:35;-1:-1:-1;;87968:12:0;:14;;;;;;-1:-1:-1;;;;84718:3283:0:o;59745:2065::-;59839:14;59894:7;107321:1;59875:26;59871:1874;;-1:-1:-1;59927:26:0;;;;:17;:26;;;;;;;60053:11;;;60049:1313;;60100:13;;60089:7;:24;60085:98;;60136:47;-1:-1:-1;;;60136:7:0;:47::i;:::-;60740:607;-1:-1:-1;;;60836:9:0;60818:28;;;;:17;:28;;;;;;60892:25;;60740:607;60892:25;-1:-1:-1;;;60944:6:0;:24;60972:1;60944:29;60940:48;;59745:2065;;;:::o;60940:48::-;61280:47;-1:-1:-1;;;61280:7:0;:47::i;:::-;60740:607;;60049:1313;-1:-1:-1;;;61689:6:0;:24;61717:1;61689:29;61685:48;;59745:2065;;;:::o;61685:48::-;61755:47;-1:-1:-1;;;61755:7:0;:47::i;82741:112::-;82818:27;82828:2;82832:8;82818:27;;;;;;;;;;;;:9;:27::i;27167:191::-;27260:6;;;-1:-1:-1;;;;;27277:17:0;;;-1:-1:-1;;;;;;27277:17:0;;;;;;;27310:40;;27260:6;;;27277:17;27260:6;;27310:40;;27241:16;;27310:40;27230:128;27167:191;:::o;99602:4531::-;99728:16;99795:4;99786:5;:13;99782:54;;99801:35;-1:-1:-1;;;99801:7:0;:35::i;:::-;107321:1;99914:5;:23;99910:87;;;107321:1;99958:23;;99910:87;100011:17;51926:13;100115:17;;;100111:74;;100160:9;100153:16;;100111:74;100199:25;100239;100267:16;100277:5;100267:9;:16::i;:::-;100317:12;;;100477:35;;;;-1:-1:-1;100545:22:0;;100541:3544;;100767:17;100758:5;100751:4;:12;:33;100747:114;;100836:5;100829:4;:12;100809:32;;100747:114;100983:4;100977:11;100965:23;;101287:1;101268:17;101264:25;101261:1;101257:33;101247:8;101243:48;101212:4;101179:135;101489:31;101523:26;101543:5;101523:19;:26::i;:::-;101489:60;;101568:25;101865:9;:16;;;101860:100;;-1:-1:-1;101926:14:0;;101860:100;101978:19;102168:1753;102206:19;102219:5;102206:12;:19::i;:::-;102194:31;;102312:4;102301:9;102297:20;102291:27;102409:1;102404:1016;;;;103741:1;103720:22;;102284:1485;;102404:1016;102687:9;102681:16;102678:123;;;102760:9;102754:16;102733:37;;102678:123;103092:5;103073:17;103069:29;103065:2;103061:38;103051:342;;103168:1;103155:11;103151:19;103136:34;;103322:5;103270:11;103267:1;103263:19;103253:8;103249:34;103204:158;103051:342;102284:1485;103815:1;103808:5;103804:13;103795:22;;103878:4;103869:5;:13;:49;;;;103901:17;103886:11;:32;103869:49;103867:52;102168:1753;;104022:29;;-1:-1:-1;;100541:3544:0;-1:-1:-1;104106:8:0;;99602:4531;-1:-1:-1;;;;;;99602:4531:0:o;28640:156::-;28731:4;28784;28755:25;28768:5;28775:4;28755:12;:25::i;:::-;:33;;28640:156;-1:-1:-1;;;;28640:156:0:o;64766:266::-;90513:10;64893:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;64893:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;64893:60:0;;;;;;;;;;64969:55;;540:41:1;;;64893:49:0;;90513:10;64969:55;;513:18:1;64969:55:0;;;;;;;64766:266;;:::o;72644:416::-;72819:31;72832:4;72838:2;72842:7;72819:12;:31::i;:::-;-1:-1:-1;;;;;72865:14:0;;;:19;72861:192;;72904:56;72935:4;72941:2;72945:7;72954:5;72904:30;:56::i;:::-;72899:154;;72981:56;-1:-1:-1;;;72981:7:0;:56::i;58786:202::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58955:24:0;;;;:17;:24;;;;;;58936:44;;-1:-1:-1;;;;;;;;;;;;;62051:41:0;;;;48159:3;62137:33;;;-1:-1:-1;;;;;62103:68:0;-1:-1:-1;;;62103:68:0;-1:-1:-1;;;62201:24:0;;:29;;-1:-1:-1;;;62182:48:0;;;;48680:3;62270:28;;;;-1:-1:-1;;;62241:58:0;-1:-1:-1;61909:398:0;463:723;519:13;740:5;749:1;740:10;736:53;;-1:-1:-1;;767:10:0;;;;;;;;;;;;-1:-1:-1;;;767:10:0;;;;;463:723::o;736:53::-;814:5;799:12;855:78;862:9;;855:78;;888:8;;;;:::i;:::-;;-1:-1:-1;911:10:0;;-1:-1:-1;919:2:0;911:10;;:::i;:::-;;;855:78;;;943:19;975:6;-1:-1:-1;;;;;965:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;965:17:0;;943:39;;993:154;1000:10;;993:154;;1027:11;1037:1;1027:11;;:::i;:::-;;-1:-1:-1;1096:10:0;1104:2;1096:5;:10;:::i;:::-;1083:24;;:2;:24;:::i;:::-;1070:39;;1053:6;1060;1053:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;1053:56:0;;;;;;;;-1:-1:-1;1124:11:0;1133:2;1124:11;;:::i;:::-;;;993:154;;90633:1786;90734:17;91173:4;91166;91160:11;91156:22;91265:1;91259:4;91252:15;91340:4;91337:1;91333:12;91326:19;;;91422:1;91417:3;91410:14;91526:3;91765:5;91747:428;91813:1;91808:3;91804:11;91797:18;;91984:2;91978:4;91974:13;91970:2;91966:22;91961:3;91953:36;92078:2;92068:13;;92135:25;91747:428;92135:25;-1:-1:-1;92205:13:0;;;-1:-1:-1;;92320:14:0;;;92382:19;;;92320:14;90633:1786;-1:-1:-1;90633:1786:0:o;83659:474::-;83788:13;83804:16;83812:7;83804;:16::i;:::-;83788:32;;83837:13;:45;;;;-1:-1:-1;90513:10:0;-1:-1:-1;;;;;83854:28:0;;;;83837:45;83833:201;;;83902:44;83919:5;90513:10;65189:214;:::i;83902:44::-;83897:137;;83967:51;-1:-1:-1;;;83967:7:0;:51::i;:::-;84046:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;84046:35:0;-1:-1:-1;;;;;84046:35:0;;;;;;;;;84097:28;;84046:24;;84097:28;;;;;;;83777:356;83659:474;;;:::o;81702:955::-;81833:19;81839:2;81843:8;81833:5;:19::i;:::-;-1:-1:-1;;;;;81894:14:0;;;:19;81890:749;;81934:11;81948:13;81996:14;;;82029:489;82086:205;82155:1;82188:2;82221:7;;;;;;82259:5;82086:30;:205::i;:::-;82055:423;;82342:112;-1:-1:-1;;;82342:7:0;:112::i;:::-;82513:3;82505:5;:11;82029:489;;82600:3;82583:13;;:20;82579:44;;82605:18;82620:1;82605:7;:18::i;29439:296::-;29522:7;29565:4;29522:7;29580:118;29604:5;:12;29600:1;:16;29580:118;;;29653:33;29663:12;29677:5;29683:1;29677:8;;;;;;;;:::i;:::-;;;;;;;29653:9;:33::i;:::-;29638:48;-1:-1:-1;29618:3:0;;;;:::i;:::-;;;;29580:118;;75144:806;75341:171;;-1:-1:-1;;;75341:171:0;;75307:4;;-1:-1:-1;;;;;75341:45:0;;;;;:171;;90513:10;;75443:4;;75466:7;;75492:5;;75341:171;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75341:171:0;;;;;;;;-1:-1:-1;;75341:171:0;;;;;;;;;;;;:::i;:::-;;;75324:619;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75726:6;:13;75743:1;75726:18;75722:115;;75765:56;-1:-1:-1;;;75765:7:0;:56::i;:::-;75909:6;75903:13;75894:6;75890:2;75886:15;75879:38;75324:619;-1:-1:-1;;;;;;75585:81:0;-1:-1:-1;;;75585:81:0;;-1:-1:-1;75144:806:0;;;;;;:::o;76412:2360::-;76485:20;76508:13;;;76536;;;76532:53;;76551:34;-1:-1:-1;;;76551:7:0;:34::i;:::-;77098:31;;;;:17;:31;;;;;;;;-1:-1:-1;;;;;62659:28:0;;62868:11;62843:23;62839:41;63358:1;63345:15;;63319:24;63315:46;62836:52;62791:112;;77098:194;;;77510:22;;;:18;:22;;;;;:105;;77582:32;77553:62;;77510:105;;;62659:28;77805:13;;;77801:54;;77820:35;-1:-1:-1;;;77820:7:0;:35::i;:::-;77886:23;;;:12;77971:676;78390:7;78346:8;78301:1;78235:25;78172:1;78107;78076:358;78642:3;78629:9;;;;;;:16;77971:676;;-1:-1:-1;78663:13:0;:19;-1:-1:-1;119626:225:0;;;:::o;36643:149::-;36706:7;36737:1;36733;:5;:51;;36868:13;36962:15;;;36998:4;36991:15;;;37045:4;37029:21;;36733:51;;;36868:13;36962:15;;;36998:4;36991:15;;;37045:4;37029:21;;36741:20;36726:58;36643:149;-1:-1:-1;;;36643:149:0:o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:1;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:1;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:1:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:1;;1348:180;-1:-1:-1;1348:180:1:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:1;;1848:42;;1838:70;;1904:1;1901;1894:12;1919:254;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:1:o;2360:328::-;2437:6;2445;2453;2506:2;2494:9;2485:7;2481:23;2477:32;2474:52;;;2522:1;2519;2512:12;2474:52;2545:29;2564:9;2545:29;:::i;:::-;2535:39;;2593:38;2627:2;2616:9;2612:18;2593:38;:::i;:::-;2583:48;;2678:2;2667:9;2663:18;2650:32;2640:42;;2360:328;;;;;:::o;2693:248::-;2761:6;2769;2822:2;2810:9;2801:7;2797:23;2793:32;2790:52;;;2838:1;2835;2828:12;2790:52;-1:-1:-1;;2861:23:1;;;2931:2;2916:18;;;2903:32;;-1:-1:-1;2693:248:1:o;3646:127::-;3707:10;3702:3;3698:20;3695:1;3688:31;3738:4;3735:1;3728:15;3762:4;3759:1;3752:15;3778:275;3849:2;3843:9;3914:2;3895:13;;-1:-1:-1;;3891:27:1;3879:40;;-1:-1:-1;;;;;3934:34:1;;3970:22;;;3931:62;3928:88;;;3996:18;;:::i;:::-;4032:2;4025:22;3778:275;;-1:-1:-1;3778:275:1:o;4058:407::-;4123:5;-1:-1:-1;;;;;4149:6:1;4146:30;4143:56;;;4179:18;;:::i;:::-;4217:57;4262:2;4241:15;;-1:-1:-1;;4237:29:1;4268:4;4233:40;4217:57;:::i;:::-;4208:66;;4297:6;4290:5;4283:21;4337:3;4328:6;4323:3;4319:16;4316:25;4313:45;;;4354:1;4351;4344:12;4313:45;4403:6;4398:3;4391:4;4384:5;4380:16;4367:43;4457:1;4450:4;4441:6;4434:5;4430:18;4426:29;4419:40;4058:407;;;;;:::o;4470:451::-;4539:6;4592:2;4580:9;4571:7;4567:23;4563:32;4560:52;;;4608:1;4605;4598:12;4560:52;4648:9;4635:23;-1:-1:-1;;;;;4673:6:1;4670:30;4667:50;;;4713:1;4710;4703:12;4667:50;4736:22;;4789:4;4781:13;;4777:27;-1:-1:-1;4767:55:1;;4818:1;4815;4808:12;4767:55;4841:74;4907:7;4902:2;4889:16;4884:2;4880;4876:11;4841:74;:::i;4926:367::-;4989:8;4999:6;5053:3;5046:4;5038:6;5034:17;5030:27;5020:55;;5071:1;5068;5061:12;5020:55;-1:-1:-1;5094:20:1;;-1:-1:-1;;;;;5126:30:1;;5123:50;;;5169:1;5166;5159:12;5123:50;5206:4;5198:6;5194:17;5182:29;;5266:3;5259:4;5249:6;5246:1;5242:14;5234:6;5230:27;5226:38;5223:47;5220:67;;;5283:1;5280;5273:12;5298:437;5384:6;5392;5445:2;5433:9;5424:7;5420:23;5416:32;5413:52;;;5461:1;5458;5451:12;5413:52;5501:9;5488:23;-1:-1:-1;;;;;5526:6:1;5523:30;5520:50;;;5566:1;5563;5556:12;5520:50;5605:70;5667:7;5658:6;5647:9;5643:22;5605:70;:::i;:::-;5694:8;;5579:96;;-1:-1:-1;5298:437:1;-1:-1:-1;;;;5298:437:1:o;5740:349::-;5824:12;;-1:-1:-1;;;;;5820:38:1;5808:51;;5912:4;5901:16;;;5895:23;-1:-1:-1;;;;;5891:48:1;5875:14;;;5868:72;6003:4;5992:16;;;5986:23;5979:31;5972:39;5956:14;;;5949:63;6065:4;6054:16;;;6048:23;6073:8;6044:38;6028:14;;6021:62;5740:349::o;6094:724::-;6329:2;6381:21;;;6451:13;;6354:18;;;6473:22;;;6300:4;;6329:2;6552:15;;;;6526:2;6511:18;;;6300:4;6595:197;6609:6;6606:1;6603:13;6595:197;;;6658:52;6706:3;6697:6;6691:13;6658:52;:::i;:::-;6767:15;;;;6739:4;6730:14;;;;;6631:1;6624:9;6595:197;;6823:773;6945:6;6953;6961;6969;7022:2;7010:9;7001:7;6997:23;6993:32;6990:52;;;7038:1;7035;7028:12;6990:52;7078:9;7065:23;-1:-1:-1;;;;;7148:2:1;7140:6;7137:14;7134:34;;;7164:1;7161;7154:12;7134:34;7203:70;7265:7;7256:6;7245:9;7241:22;7203:70;:::i;:::-;7292:8;;-1:-1:-1;7177:96:1;-1:-1:-1;7380:2:1;7365:18;;7352:32;;-1:-1:-1;7396:16:1;;;7393:36;;;7425:1;7422;7415:12;7393:36;;7464:72;7528:7;7517:8;7506:9;7502:24;7464:72;:::i;:::-;6823:773;;;;-1:-1:-1;7555:8:1;-1:-1:-1;;;;6823:773:1:o;7601:186::-;7660:6;7713:2;7701:9;7692:7;7688:23;7684:32;7681:52;;;7729:1;7726;7719:12;7681:52;7752:29;7771:9;7752:29;:::i;7792:632::-;7963:2;8015:21;;;8085:13;;7988:18;;;8107:22;;;7934:4;;7963:2;8186:15;;;;8160:2;8145:18;;;7934:4;8229:169;8243:6;8240:1;8237:13;8229:169;;;8304:13;;8292:26;;8373:15;;;;8338:12;;;;8265:1;8258:9;8229:169;;8429:254;8497:6;8505;8558:2;8546:9;8537:7;8533:23;8529:32;8526:52;;;8574:1;8571;8564:12;8526:52;8610:9;8597:23;8587:33;;8639:38;8673:2;8662:9;8658:18;8639:38;:::i;:::-;8629:48;;8429:254;;;;;:::o;8688:183::-;8748:4;-1:-1:-1;;;;;8773:6:1;8770:30;8767:56;;;8803:18;;:::i;:::-;-1:-1:-1;8848:1:1;8844:14;8860:4;8840:25;;8688:183::o;8876:662::-;8930:5;8983:3;8976:4;8968:6;8964:17;8960:27;8950:55;;9001:1;8998;8991:12;8950:55;9037:6;9024:20;9063:4;9087:60;9103:43;9143:2;9103:43;:::i;:::-;9087:60;:::i;:::-;9181:15;;;9267:1;9263:10;;;;9251:23;;9247:32;;;9212:12;;;;9291:15;;;9288:35;;;9319:1;9316;9309:12;9288:35;9355:2;9347:6;9343:15;9367:142;9383:6;9378:3;9375:15;9367:142;;;9449:17;;9437:30;;9487:12;;;;9400;;9367:142;;;-1:-1:-1;9527:5:1;8876:662;-1:-1:-1;;;;;;8876:662:1:o;9543:416::-;9636:6;9644;9697:2;9685:9;9676:7;9672:23;9668:32;9665:52;;;9713:1;9710;9703:12;9665:52;9753:9;9740:23;-1:-1:-1;;;;;9778:6:1;9775:30;9772:50;;;9818:1;9815;9808:12;9772:50;9841:61;9894:7;9885:6;9874:9;9870:22;9841:61;:::i;:::-;9831:71;9949:2;9934:18;;;;9921:32;;-1:-1:-1;;;;9543:416:1:o;9964:322::-;10041:6;10049;10057;10110:2;10098:9;10089:7;10085:23;10081:32;10078:52;;;10126:1;10123;10116:12;10078:52;10149:29;10168:9;10149:29;:::i;:::-;10139:39;10225:2;10210:18;;10197:32;;-1:-1:-1;10276:2:1;10261:18;;;10248:32;;9964:322;-1:-1:-1;;;9964:322:1:o;10291:118::-;10377:5;10370:13;10363:21;10356:5;10353:32;10343:60;;10399:1;10396;10389:12;10414:315;10479:6;10487;10540:2;10528:9;10519:7;10515:23;10511:32;10508:52;;;10556:1;10553;10546:12;10508:52;10579:29;10598:9;10579:29;:::i;:::-;10569:39;;10658:2;10647:9;10643:18;10630:32;10671:28;10693:5;10671:28;:::i;:::-;10718:5;10708:15;;;10414:315;;;;;:::o;10919:667::-;11014:6;11022;11030;11038;11091:3;11079:9;11070:7;11066:23;11062:33;11059:53;;;11108:1;11105;11098:12;11059:53;11131:29;11150:9;11131:29;:::i;:::-;11121:39;;11179:38;11213:2;11202:9;11198:18;11179:38;:::i;:::-;11169:48;;11264:2;11253:9;11249:18;11236:32;11226:42;;11319:2;11308:9;11304:18;11291:32;-1:-1:-1;;;;;11338:6:1;11335:30;11332:50;;;11378:1;11375;11368:12;11332:50;11401:22;;11454:4;11446:13;;11442:27;-1:-1:-1;11432:55:1;;11483:1;11480;11473:12;11432:55;11506:74;11572:7;11567:2;11554:16;11549:2;11545;11541:11;11506:74;:::i;:::-;11496:84;;;10919:667;;;;;;;:::o;11591:505::-;11686:6;11694;11702;11755:2;11743:9;11734:7;11730:23;11726:32;11723:52;;;11771:1;11768;11761:12;11723:52;11811:9;11798:23;-1:-1:-1;;;;;11836:6:1;11833:30;11830:50;;;11876:1;11873;11866:12;11830:50;11915:70;11977:7;11968:6;11957:9;11953:22;11915:70;:::i;:::-;12004:8;;11889:96;;-1:-1:-1;12086:2:1;12071:18;;;;12058:32;;11591:505;-1:-1:-1;;;;11591:505:1:o;12101:268::-;12299:3;12284:19;;12312:51;12288:9;12345:6;12312:51;:::i;12374:910::-;12438:5;12491:3;12484:4;12476:6;12472:17;12468:27;12458:55;;12509:1;12506;12499:12;12458:55;12545:6;12532:20;12571:4;12595:60;12611:43;12651:2;12611:43;:::i;12595:60::-;12689:15;;;12775:1;12771:10;;;;12759:23;;12755:32;;;12720:12;;;;12799:15;;;12796:35;;;12827:1;12824;12817:12;12796:35;12863:2;12855:6;12851:15;12875:380;12891:6;12886:3;12883:15;12875:380;;;12977:3;12964:17;-1:-1:-1;;;;;13000:11:1;12997:35;12994:125;;;13073:1;13102:2;13098;13091:14;12994:125;13144:68;13208:3;13203:2;13189:11;13181:6;13177:24;13173:33;13144:68;:::i;:::-;13132:81;;-1:-1:-1;13233:12:1;;;;12908;;12875:380;;13289:1175;13432:6;13440;13493:2;13481:9;13472:7;13468:23;13464:32;13461:52;;;13509:1;13506;13499:12;13461:52;13549:9;13536:23;-1:-1:-1;;;;;13619:2:1;13611:6;13608:14;13605:34;;;13635:1;13632;13625:12;13605:34;13673:6;13662:9;13658:22;13648:32;;13718:7;13711:4;13707:2;13703:13;13699:27;13689:55;;13740:1;13737;13730:12;13689:55;13776:2;13763:16;13798:4;13822:60;13838:43;13878:2;13838:43;:::i;13822:60::-;13916:15;;;13998:1;13994:10;;;;13986:19;;13982:28;;;13947:12;;;;14022:19;;;14019:39;;;14054:1;14051;14044:12;14019:39;14078:11;;;;14098:142;14114:6;14109:3;14106:15;14098:142;;;14180:17;;14168:30;;14131:12;;;;14218;;;;14098:142;;;14259:5;-1:-1:-1;;14302:18:1;;14289:32;;-1:-1:-1;;14333:16:1;;;14330:36;;;14362:1;14359;14352:12;14330:36;;14385:73;14450:7;14439:8;14428:9;14424:24;14385:73;:::i;:::-;14375:83;;;13289:1175;;;;;:::o;14469:260::-;14537:6;14545;14598:2;14586:9;14577:7;14573:23;14569:32;14566:52;;;14614:1;14611;14604:12;14566:52;14637:29;14656:9;14637:29;:::i;:::-;14627:39;;14685:38;14719:2;14708:9;14704:18;14685:38;:::i;14734:380::-;14813:1;14809:12;;;;14856;;;14877:61;;14931:4;14923:6;14919:17;14909:27;;14877:61;14984:2;14976:6;14973:14;14953:18;14950:38;14947:161;;15030:10;15025:3;15021:20;15018:1;15011:31;15065:4;15062:1;15055:15;15093:4;15090:1;15083:15;14947:161;;14734:380;;;:::o;15119:127::-;15180:10;15175:3;15171:20;15168:1;15161:31;15211:4;15208:1;15201:15;15235:4;15232:1;15225:15;15251:168;15324:9;;;15355;;15372:15;;;15366:22;;15352:37;15342:71;;15393:18;;:::i;15424:127::-;15485:10;15480:3;15476:20;15473:1;15466:31;15516:4;15513:1;15506:15;15540:4;15537:1;15530:15;15556:120;15596:1;15622;15612:35;;15627:18;;:::i;:::-;-1:-1:-1;15661:9:1;;15556:120::o;16017:545::-;16119:2;16114:3;16111:11;16108:448;;;16155:1;16180:5;16176:2;16169:17;16225:4;16221:2;16211:19;16295:2;16283:10;16279:19;16276:1;16272:27;16266:4;16262:38;16331:4;16319:10;16316:20;16313:47;;;-1:-1:-1;16354:4:1;16313:47;16409:2;16404:3;16400:12;16397:1;16393:20;16387:4;16383:31;16373:41;;16464:82;16482:2;16475:5;16472:13;16464:82;;;16527:17;;;16508:1;16497:13;16464:82;;;16468:3;;;16017:545;;;:::o;16738:1352::-;16864:3;16858:10;-1:-1:-1;;;;;16883:6:1;16880:30;16877:56;;;16913:18;;:::i;:::-;16942:97;17032:6;16992:38;17024:4;17018:11;16992:38;:::i;:::-;16986:4;16942:97;:::i;:::-;17094:4;;17158:2;17147:14;;17175:1;17170:663;;;;17877:1;17894:6;17891:89;;;-1:-1:-1;17946:19:1;;;17940:26;17891:89;-1:-1:-1;;16695:1:1;16691:11;;;16687:24;16683:29;16673:40;16719:1;16715:11;;;16670:57;17993:81;;17140:944;;17170:663;15964:1;15957:14;;;16001:4;15988:18;;-1:-1:-1;;17206:20:1;;;17324:236;17338:7;17335:1;17332:14;17324:236;;;17427:19;;;17421:26;17406:42;;17519:27;;;;17487:1;17475:14;;;;17354:19;;17324:236;;;17328:3;17588:6;17579:7;17576:19;17573:201;;;17649:19;;;17643:26;-1:-1:-1;;17732:1:1;17728:14;;;17744:3;17724:24;17720:37;17716:42;17701:58;17686:74;;17573:201;-1:-1:-1;;;;;17820:1:1;17804:14;;;17800:22;17787:36;;-1:-1:-1;16738:1352:1:o;18095:127::-;18156:10;18151:3;18147:20;18144:1;18137:31;18187:4;18184:1;18177:15;18211:4;18208:1;18201:15;18227:125;18292:9;;;18313:10;;;18310:36;;;18326:18;;:::i;18357:331::-;18559:2;18541:21;;;18598:1;18578:18;;;18571:29;-1:-1:-1;;;18631:2:1;18616:18;;18609:38;18679:2;18664:18;;18357:331::o;18693:135::-;18732:3;18753:17;;;18750:43;;18773:18;;:::i;:::-;-1:-1:-1;18820:1:1;18809:13;;18693:135::o;19419:403::-;19621:2;19603:21;;;19660:2;19640:18;;;19633:30;19699:34;19694:2;19679:18;;19672:62;-1:-1:-1;;;19765:2:1;19750:18;;19743:37;19812:3;19797:19;;19419:403::o;20884:184::-;20954:6;21007:2;20995:9;20986:7;20982:23;20978:32;20975:52;;;21023:1;21020;21013:12;20975:52;-1:-1:-1;21046:16:1;;20884:184;-1:-1:-1;20884:184:1:o;21413:245::-;21480:6;21533:2;21521:9;21512:7;21508:23;21504:32;21501:52;;;21549:1;21546;21539:12;21501:52;21581:9;21575:16;21600:28;21622:5;21600:28;:::i;21663:289::-;21794:3;21832:6;21826:13;21848:66;21907:6;21902:3;21895:4;21887:6;21883:17;21848:66;:::i;:::-;21930:16;;;;;21663:289;-1:-1:-1;;21663:289:1:o;22362:128::-;22429:9;;;22450:11;;;22447:37;;;22464:18;;:::i;22495:344::-;22697:2;22679:21;;;22736:2;22716:18;;;22709:30;-1:-1:-1;;;22770:2:1;22755:18;;22748:50;22830:2;22815:18;;22495:344::o;22844:353::-;23046:2;23028:21;;;23085:2;23065:18;;;23058:30;23124:31;23119:2;23104:18;;23097:59;23188:2;23173:18;;22844:353::o;23202:375::-;-1:-1:-1;;;;;23460:15:1;;;23442:34;;23512:15;;;;23507:2;23492:18;;23485:43;23559:2;23544:18;;23537:34;;;;23392:2;23377:18;;23202:375::o;23582:339::-;23784:2;23766:21;;;23823:2;23803:18;;;23796:30;-1:-1:-1;;;23857:2:1;23842:18;;23835:45;23912:2;23897:18;;23582:339::o;24700:722::-;24750:3;24791:5;24785:12;24820:36;24846:9;24820:36;:::i;:::-;24875:1;24892:18;;;24919:133;;;;25066:1;25061:355;;;;24885:531;;24919:133;-1:-1:-1;;24952:24:1;;24940:37;;25025:14;;25018:22;25006:35;;24997:45;;;-1:-1:-1;24919:133:1;;25061:355;25092:5;25089:1;25082:16;25121:4;25166:2;25163:1;25153:16;25191:1;25205:165;25219:6;25216:1;25213:13;25205:165;;;25297:14;;25284:11;;;25277:35;25340:16;;;;25234:10;;25205:165;;;25209:3;;;25399:6;25394:3;25390:16;25383:23;;24885:531;;;;;24700:722;;;;:::o;25427:469::-;25648:3;25676:38;25710:3;25702:6;25676:38;:::i;:::-;25743:6;25737:13;25759:65;25817:6;25813:2;25806:4;25798:6;25794:17;25759:65;:::i;:::-;25840:50;25882:6;25878:2;25874:15;25866:6;25840:50;:::i;:::-;25833:57;25427:469;-1:-1:-1;;;;;;;25427:469:1:o;27008:136::-;27047:3;27075:5;27065:39;;27084:18;;:::i;:::-;-1:-1:-1;;;27120:18:1;;27008:136::o;27819:112::-;27851:1;27877;27867:35;;27882:18;;:::i;:::-;-1:-1:-1;27916:9:1;;27819:112::o;27936:489::-;-1:-1:-1;;;;;28205:15:1;;;28187:34;;28257:15;;28252:2;28237:18;;28230:43;28304:2;28289:18;;28282:34;;;28352:3;28347:2;28332:18;;28325:31;;;28130:4;;28373:46;;28399:19;;28391:6;28373:46;:::i;:::-;28365:54;27936:489;-1:-1:-1;;;;;;27936:489:1:o;28430:249::-;28499:6;28552:2;28540:9;28531:7;28527:23;28523:32;28520:52;;;28568:1;28565;28558:12;28520:52;28600:9;28594:16;28619:30;28643:5;28619:30;:::i

Swarm Source

ipfs://64cf98b541b8f0f60915dc6d6967c13088b7687cca145cc44dec204eeafad335
Loading...
Loading
Loading...
Loading
[ 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.