ETH Price: $3,261.83 (-0.12%)
Gas: 1 Gwei

Token

Teahouse HighTable VIP (HTVIP)
 

Overview

Max Total Supply

1,242 HTVIP

Holders

463

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
dexmond.eth
Balance
1 HTVIP
0x5A4AF726713147fE3c753F578547C9056317E765
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
HightableVIP

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, BSL 1.1 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-05-18
*/

// SPDX-License-Identifier: BUSL-1.1
// File: contracts/nft/IPFSConvert.sol
// contracts/IPFSConvert.sol

pragma solidity ^0.8.4;

/// @title Hightable IPFSConvert Library
/// @author Teahouse Finance
library IPFSConvert {

    bytes constant private CODE_STRING = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    bytes constant private CIDV0HEAD = "\x00\x04\x28\x0b\x12\x17\x09\x28\x31\x00\x12\x04\x28\x20\x25\x25\x22\x31\x1b\x1d\x39\x29\x09\x26\x1b\x29\x0b\x02\x0a\x18\x25\x22\x24\x1b\x39\x2c\x1d\x39\x07\x06\x29\x25\x13\x15\x2c\x17";

    /**
     * @dev This function converts an 256 bits hash value into IPFS CIDv0 hash string.
     * @param _cidv0 256 bits hash value (not including the 0x12 0x20 signature)
     * @return IPFS CIDv0 hash string (Qm...)
     */
    function cidv0FromBytes32(bytes32 _cidv0) public pure returns (string memory) {
        unchecked {
            // convert to base58
            bytes memory result = new bytes(46);        // 46 is the longest possible base58 result from CIDv0
            uint256 resultLen = 45;
            uint256 number = uint256(_cidv0);
            while(number > 0) {
                uint256 rem = number % 58;
                result[resultLen] = bytes1(uint8(rem));
                resultLen--;
                number = number / 58;
            }

            // add 0x1220 in front of _cidv0
            uint256 i;
            for (i = 0; i < 46; i++) {
                uint8 r = uint8(result[45 - i]) + uint8(CIDV0HEAD[i]);
                if (r >= 58) {
                    result[45 - i] = bytes1(r - 58);
                    result[45 - i - 1] = bytes1(uint8(result[45 - i - 1]) + 1);
                }
                else {
                    result[45 - i] = bytes1(r);
                }
            }

            // convert to characters
            for (i = 0; i < 46; i++) {
                result[i] = CODE_STRING[uint8(result[i])];
            }

            return string(result);
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/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: @openzeppelin/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: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @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`.
     *
     * 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 calldata data
    ) external;

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @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);
}

// File: erc721a/contracts/IERC721A.sol


// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;



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

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

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

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

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

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     * 
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);
}

// File: @chainlink/contracts/src/v0.8/VRFRequestIDBase.sol


pragma solidity ^0.8.0;

contract VRFRequestIDBase {
  /**
   * @notice returns the seed which is actually input to the VRF coordinator
   *
   * @dev To prevent repetition of VRF output due to repetition of the
   * @dev user-supplied seed, that seed is combined in a hash with the
   * @dev user-specific nonce, and the address of the consuming contract. The
   * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in
   * @dev the final seed, but the nonce does protect against repetition in
   * @dev requests which are included in a single block.
   *
   * @param _userSeed VRF seed input provided by user
   * @param _requester Address of the requesting contract
   * @param _nonce User-specific nonce at the time of the request
   */
  function makeVRFInputSeed(
    bytes32 _keyHash,
    uint256 _userSeed,
    address _requester,
    uint256 _nonce
  ) internal pure returns (uint256) {
    return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));
  }

  /**
   * @notice Returns the id for this request
   * @param _keyHash The serviceAgreement ID to be used for this request
   * @param _vRFInputSeed The seed to be passed directly to the VRF
   * @return The id for this request
   *
   * @dev Note that _vRFInputSeed is not the seed passed by the consuming
   * @dev contract, but the one generated by makeVRFInputSeed
   */
  function makeRequestId(bytes32 _keyHash, uint256 _vRFInputSeed) internal pure returns (bytes32) {
    return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));
  }
}

// File: @chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol


pragma solidity ^0.8.0;

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);

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

  function balanceOf(address owner) external view returns (uint256 balance);

  function decimals() external view returns (uint8 decimalPlaces);

  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);

  function increaseApproval(address spender, uint256 subtractedValue) external;

  function name() external view returns (string memory tokenName);

  function symbol() external view returns (string memory tokenSymbol);

  function totalSupply() external view returns (uint256 totalTokensIssued);

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

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  ) external returns (bool success);

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

// File: @chainlink/contracts/src/v0.8/VRFConsumerBase.sol


pragma solidity ^0.8.0;



/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constructor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash), and have told you the minimum LINK
 * @dev price for VRF service. Make sure your contract has sufficient LINK, and
 * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you
 * @dev want to generate randomness from.
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomness method.
 *
 * @dev The randomness argument to fulfillRandomness is the actual random value
 * @dev generated from your seed.
 *
 * @dev The requestId argument is generated from the keyHash and the seed by
 * @dev makeRequestId(keyHash, seed). If your contract could have concurrent
 * @dev requests open, you can use the requestId to track which seed is
 * @dev associated with which randomness. See VRFRequestIDBase.sol for more
 * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.)
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ. (Which is critical to making unpredictable randomness! See the
 * @dev next section.)
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the ultimate input to the VRF is mixed with the block hash of the
 * @dev block in which the request is made, user-provided seeds have no impact
 * @dev on its economic security properties. They are only included for API
 * @dev compatability with previous versions of this contract.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request.
 */
abstract contract VRFConsumerBase is VRFRequestIDBase {
  /**
   * @notice fulfillRandomness handles the VRF response. Your contract must
   * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
   * @notice principles to keep in mind when implementing your fulfillRandomness
   * @notice method.
   *
   * @dev VRFConsumerBase expects its subcontracts to have a method with this
   * @dev signature, and will call it once it has verified the proof
   * @dev associated with the randomness. (It is triggered via a call to
   * @dev rawFulfillRandomness, below.)
   *
   * @param requestId The Id initially returned by requestRandomness
   * @param randomness the VRF output
   */
  function fulfillRandomness(bytes32 requestId, uint256 randomness) internal virtual;

  /**
   * @dev In order to keep backwards compatibility we have kept the user
   * seed field around. We remove the use of it because given that the blockhash
   * enters later, it overrides whatever randomness the used seed provides.
   * Given that it adds no security, and can easily lead to misunderstandings,
   * we have removed it from usage and can now provide a simpler API.
   */
  uint256 private constant USER_SEED_PLACEHOLDER = 0;

  /**
   * @notice requestRandomness initiates a request for VRF output given _seed
   *
   * @dev The fulfillRandomness method receives the output, once it's provided
   * @dev by the Oracle, and verified by the vrfCoordinator.
   *
   * @dev The _keyHash must already be registered with the VRFCoordinator, and
   * @dev the _fee must exceed the fee specified during registration of the
   * @dev _keyHash.
   *
   * @dev The _seed parameter is vestigial, and is kept only for API
   * @dev compatibility with older versions. It can't *hurt* to mix in some of
   * @dev your own randomness, here, but it's not necessary because the VRF
   * @dev oracle will mix the hash of the block containing your request into the
   * @dev VRF seed it ultimately uses.
   *
   * @param _keyHash ID of public key against which randomness is generated
   * @param _fee The amount of LINK to send with the request
   *
   * @return requestId unique ID for this request
   *
   * @dev The returned requestId can be used to distinguish responses to
   * @dev concurrent requests. It is passed as the first argument to
   * @dev fulfillRandomness.
   */
  function requestRandomness(bytes32 _keyHash, uint256 _fee) internal returns (bytes32 requestId) {
    LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));
    // This is the seed passed to VRFCoordinator. The oracle will mix this with
    // the hash of the block containing this request to obtain the seed/input
    // which is finally passed to the VRF cryptographic machinery.
    uint256 vRFSeed = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]);
    // nonces[_keyHash] must stay in sync with
    // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above
    // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).
    // This provides protection against the user repeating their input seed,
    // which would result in a predictable/duplicate output, if multiple such
    // requests appeared in the same block.
    nonces[_keyHash] = nonces[_keyHash] + 1;
    return makeRequestId(_keyHash, vRFSeed);
  }

  LinkTokenInterface internal immutable LINK;
  address private immutable vrfCoordinator;

  // Nonces for each VRF key from which randomness has been requested.
  //
  // Must stay in sync with VRFCoordinator[_keyHash][this]
  mapping(bytes32 => uint256) /* keyHash */ /* nonce */
    private nonces;

  /**
   * @param _vrfCoordinator address of VRFCoordinator contract
   * @param _link address of LINK token contract
   *
   * @dev https://docs.chain.link/docs/link-token-contracts
   */
  constructor(address _vrfCoordinator, address _link) {
    vrfCoordinator = _vrfCoordinator;
    LINK = LinkTokenInterface(_link);
  }

  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
  // the origin of the call
  function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external {
    require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill");
    fulfillRandomness(requestId, randomness);
  }
}

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


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

pragma solidity ^0.8.0;

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

    /**
     * @dev 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++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

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


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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

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

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


// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

// File: @openzeppelin/contracts/utils/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: erc721a/contracts/ERC721A.sol


// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;







/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is Context, ERC165, IERC721A {
    using Address for address;
    using Strings for uint256;

    // The tokenId of the next token to be minted.
    uint256 internal _currentIndex;

    // The number of tokens burned.
    uint256 internal _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 _ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

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

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

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

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

    /**
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startTokenId() times
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberMinted);
    }

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

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

    /**
     * Sets the auxillary 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 {
        _addressData[owner].aux = aux;
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr) if (curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant:
                    // There will always be an ownership that has an address and is not burned
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return _ownershipOf(tokenId).addr;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = ERC721A.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

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

        _approve(to, tokenId, owner);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSender()) revert ApproveToCaller();

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.isContract()) if(!_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

    /**
     * @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 (`_mint`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return _startTokenId() <= tokenId && tokenId < _currentIndex && !_ownerships[tokenId].burned;
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, 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.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.isContract()) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @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.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSender() == from ||
            isApprovedForAll(from, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, from);

        // 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 {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = to;
            currSlot.startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

    /**
     * @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 {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSender() == from ||
                isApprovedForAll(from, _msgSender()) ||
                getApproved(tokenId) == _msgSender());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, from);

        // 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 {
            AddressData storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

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

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

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

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

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


// OpenZeppelin Contracts v4.4.1 (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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        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: contracts/nft/HightableVIP.sol

// contracts/HightableVIP.sol


pragma solidity ^0.8.0;








error TokenSalePhaseBoundaryAlreadySet();
error ReachedMaxSupply();
error TransactionExpired();
error ExceedMaxAllowedMintAmount();
error SignatureAlreadyUsed();
error IncorrectSignature();
error InsufficientPayments();
error NotRevealer();
error TokenIndexOutOfBounds();
error RequestRaffleRandomnessNotAllowed();
error RaffleRandomnessAlreadyRequested();
error InvalidRaffleRegisterTime();
error AlreadyRegistered();
error InvalidPublicMintTime();
error NotRegistered();
error RefundNotAllowed();
error NoRefundQuota();
error UnableToRefundRafflePayment();
error UnableToWithdrawFund();
error RevealNotAllowed();
error RequestRevealNotTokenOwner();
error RevealAlreadyRequested();
error MerkleTreeRootAlreadySet();
error RandomizerAlreadySet();
error MerkleTreeRootNotSet();
error IncorrectRevealIndex();
error TokenAlreadyRevealed();
error MerkleTreeProofFailed();
error IncorrectRevealManyLength();
error CharacterLengthMismatch();
error InvalidCharacterSlice();
error WhitelistMintNotStarted();
error WhitelistMintEnded();


/// @title Hightable VIP NFT
/// @author Teahouse Finance
contract HightableVIP is ERC721A, Ownable, ReentrancyGuard, VRFConsumerBase {
    using ECDSA for bytes32;

    struct GlobalInfo {
        address whitelistSigner;
        address randomizer;
        address revealer;
        uint64 whitelistMintStartTime;
        uint64 whitelistMintEndTime;
        bool allowReveal;
    }

    struct RaffleInfo {
        uint64 registerStartTime;
        uint64 registerEndTime;
        uint32 numberOfBatch;
        uint32 numberOfRegistered;
        uint32 numberOfRefunded;
    }

    struct PublicMintInfo {
        uint64 publicMintStartTime;
        uint64 publicMintStepTime;
        uint64 unlimitMintStartTime;
        uint32 numberOfRaffleMinted;
    }

    struct AddressPublicMintInfo {
        bool raffleRegistered;
        bool raffleRefunded;
        bool raffleMinted;
    }

    struct TokenRevealInfo {
        bytes32 tokenBaseURIHash;
        uint64 index;
        bool revealRequested;
    }

    // Chainlink doc: https://docs.chain.link/docs/vrf-contracts/v1/ 
    bytes32 public vrfKeyHash;
    uint256 public vrfFee;

    GlobalInfo public globalInfo;
    uint256 public maxCollection;
    uint256 public price = 0.5566 ether;
    uint256 public tokenSalePhaseBoundary;
    bytes32 public hashMerkleRoot;
    string public unrevealURI;
    uint256[] public characterSlice;

    uint256 public raffleRandomness;
    uint256 public rafflePrice = 0.05566 ether;
    RaffleInfo public raffleInfo;
    PublicMintInfo public publicMintInfo;
    
    //mapping(bytes32 => bool) public signatureUsed;
    mapping(address => AddressPublicMintInfo) public addressPublicMintInfo;
    mapping(uint256 => TokenRevealInfo) public tokenRevealInfo; 

    event RaffleRegistered(address registeredAddress);
    event RaffleRandomnessRequested(bytes32 requestId);
    event RaffleRandomnessReceived(uint256 randomness);
    event RaffleRefunded(address refundedAddress);
    event RevealRequested(uint256 indexed tokenId);
    event Revealed(uint256 indexed tokenId);


    /// @param _name Name of the NFT
    /// @param _symbol Symbol of the NFT
    /// @param _maxCollection Maximum allowed number of tokens
    constructor(
        string memory _name,
        string memory _symbol,
        uint256 _maxCollection,          // total supply
        address _vrfCoordinator,
        address _linkToken,
        bytes32 _vrfKeyHash,
        uint256 _vrfFee
    ) ERC721A(_name, _symbol) VRFConsumerBase(_vrfCoordinator, _linkToken)
    {
        maxCollection = _maxCollection;

        vrfKeyHash = _vrfKeyHash;
        vrfFee = _vrfFee;
    }


    /// @notice Set VRF parameters
    /// @param _vrfKeyHash VRF Key hash
    /// @param _vrfFee VRF fee in Link
    function setVRFParameters(bytes32 _vrfKeyHash, uint256 _vrfFee) external onlyOwner {
        vrfKeyHash = _vrfKeyHash;
        vrfFee = _vrfFee;
    }


    /// @notice Set token minting price
    /// @param _newPrice New price in wei
    /// @dev Only owner can do this
    function setPrice(uint256 _newPrice) external onlyOwner {
        price = _newPrice;
    }


    /// @notice Set whitelist minting signer address
    /// @param _newWhitelistSigner New signer address
    /// @dev Only owner can do this
    function setWhitelistSigner(address _newWhitelistSigner) external onlyOwner {
        globalInfo.whitelistSigner = _newWhitelistSigner;
    }


    /// @notice set whitelist mint start and end time
    /// @param _whitelistMintStartTime whitelist mint start time
    /// @param _whitelistMintEndTime whitelist mint end time
    /// @dev Only owner can do this
    function setWhitelistMintTime(uint64 _whitelistMintStartTime, uint64 _whitelistMintEndTime) external onlyOwner {
        globalInfo.whitelistMintStartTime = _whitelistMintStartTime;
        globalInfo.whitelistMintEndTime = _whitelistMintEndTime;
    }


    /// @notice set token sale boundary
    /// @param _tokenId boundary tokenId
    /// @dev Only owner can do this
    function setTokenSalePhaseBoundary(uint256 _tokenId) external onlyOwner {
        if (tokenSalePhaseBoundary != 0) revert TokenSalePhaseBoundaryAlreadySet();

        tokenSalePhaseBoundary = _tokenId;
    }


    /// @notice Returns token's sale phase
    /// @param _tokenId TokenId to reveal
    /// @return sale phase
    function getTokenSalePhase(uint256 _tokenId) public view returns (uint256) {
        if (!_exists(_tokenId)) revert URIQueryForNonexistentToken();

        if (_tokenId <= tokenSalePhaseBoundary) {
            return 1;
        }

        return 2;
    }


    /// @notice Set revealer address
    /// @param _newRevealer New revealer address
    /// @dev Only owner can do this
    function setRevealer(address _newRevealer) external onlyOwner {
        globalInfo.revealer = _newRevealer;
    }


    /// @notice Set token URI for unrevealed tokens
    /// @param _newURI New token URI
    /// @dev Only owner can do this
    function setUnrevealURI(string calldata _newURI) external onlyOwner {
        unrevealURI = _newURI;
    }


    /// @notice set Merkle tree root for reveal verfication
    /// @param _hashMerkleRoot Merkle tree root
    /// @dev Only owner can do this
    function setMerkleRoot(bytes32 _hashMerkleRoot) external onlyOwner {
        if (hashMerkleRoot != bytes32(0)) revert MerkleTreeRootAlreadySet();

        hashMerkleRoot = _hashMerkleRoot;
    }


    /// @notice set randomizer address in Polygon before allow reveal
    /// @param _randomizer randomizer address in Polygon
    /// @dev randomizer can be only set once
    /// @dev Only owner can do this
    function setRandomizer(address _randomizer) external onlyOwner {
        if (globalInfo.randomizer != address(0)) revert RandomizerAlreadySet();

        globalInfo.randomizer = _randomizer;
    }


    /// @notice Set whether to allow reveal requests
    /// @param _allowReveal true to allow reveal requests, false to disallow
    /// @dev Only owner can do this
    function setAllowReveal(bool _allowReveal) external onlyOwner {
        globalInfo.allowReveal = _allowReveal;
    }


    /// @notice set raffle parameters
    /// @param _raffleRegisterStartTime raffle register start time
    /// @param _raffleRegisterEndTime raffle register end time
    /// @param _numberOfRaffleBatch number of batch in public minting
    /// @dev Only owner can do this
    function setRaffle(uint64 _raffleRegisterStartTime, uint64 _raffleRegisterEndTime, uint32 _numberOfRaffleBatch) external onlyOwner {
        RaffleInfo storage raffleParameters = raffleInfo;

        raffleParameters.registerStartTime = _raffleRegisterStartTime; 
        raffleParameters.registerEndTime = _raffleRegisterEndTime;
        raffleParameters.numberOfBatch = _numberOfRaffleBatch;
    }


    /// @notice set public mint pramameters
    /// @param _publicMintStartTime public mint start time
    /// @param _publicMintStepTime public mint batch step time
    /// @param _unlimitMintStartTime unlimited public mint start time
    /// @dev Only owner can do this
    function setPublicMintTimeSetting(uint64 _publicMintStartTime, uint64 _publicMintStepTime, uint64 _unlimitMintStartTime) external onlyOwner {
        PublicMintInfo storage publicMintParameters = publicMintInfo;

        publicMintParameters.publicMintStartTime = _publicMintStartTime;
        publicMintParameters.publicMintStepTime = _publicMintStepTime;
        publicMintParameters.unlimitMintStartTime = _unlimitMintStartTime;
    }


    function isAuthorized(address _sender, uint32 _allowAmount, uint64 _expireTime, bytes memory _signature) private view returns (bool) {
        bytes32 hashMsg = keccak256(abi.encodePacked(_sender, _allowAmount, _expireTime));
        bytes32 ethHashMessage = hashMsg.toEthSignedMessageHash();

        return ethHashMessage.recover(_signature) == globalInfo.whitelistSigner;
    }


    /// @notice Whitelist minting
    /// @param _amount Number of tokens to whitelistMint
    /// @param _allowAmount Allowed amount of tokens
    /// @param _expireTime Expiry time
    /// @param _signature The signature signed by the signer address
    /// @dev The caller must obtain a valid signature signed by the signer address from the server
    /// @dev and pays for the correct price to whitelistMint
    /// @dev The resulting token is sent to the caller's address
    function whitelistMint(uint32 _amount, uint32 _allowAmount, uint64 _expireTime, bytes calldata _signature) external payable {
        if (totalSupply() + _amount > maxCollection) revert ReachedMaxSupply();
        if (block.timestamp < globalInfo.whitelistMintStartTime) revert WhitelistMintNotStarted();
        if (block.timestamp > globalInfo.whitelistMintEndTime) revert WhitelistMintEnded();
        if (block.timestamp > _expireTime) revert TransactionExpired();
        if (_numberMinted(msg.sender) + _amount > _allowAmount) revert ExceedMaxAllowedMintAmount();

        // bytes32 sigHash = keccak256(abi.encodePacked(_signature));
        // if (signatureUsed[sigHash]) revert SignatureAlreadyUsed();
        // signatureUsed[sigHash] = true;

        if (!isAuthorized(msg.sender, _allowAmount, _expireTime, _signature)) revert IncorrectSignature();

        uint256 finalPrice = price * _amount;
        if (msg.value < finalPrice) revert InsufficientPayments();
        
        _safeMint(msg.sender, _amount);
    }


    /// @notice Developer minting
    /// @param _amount Number of tokens to mint
    /// @param _to Address to send the tokens to
    /// @dev Only owner can do this
    function devMint(uint256 _amount, address _to) external onlyOwner {
        if (totalSupply() + _amount > maxCollection) revert ReachedMaxSupply();

        _safeMint(_to, _amount);
    }


    /// @notice Public minting
    /// @dev The caller must pay for the correct price to publicMint
    /// @dev After unlimitMintStartTime, anyone can mint without any constraints
    /// @dev and pays for the correct price to publicMint
    /// @dev The resulting token is sent to the caller's address
    function publicMint() external payable {
        if (totalSupply() == maxCollection) revert ReachedMaxSupply();
        if (msg.value < price) revert InsufficientPayments();

        PublicMintInfo storage publicMintParameters = publicMintInfo;
        if (publicMintParameters.unlimitMintStartTime > 0 && block.timestamp >= publicMintParameters.unlimitMintStartTime) {
            _safeMint(msg.sender, 1);

            return;
        }

        AddressPublicMintInfo storage accountInfo = addressPublicMintInfo[msg.sender];
        if (!accountInfo.raffleRegistered) revert NotRegistered();
        if (accountInfo.raffleMinted) revert ExceedMaxAllowedMintAmount();

        uint256 startTime;
        (, startTime) = getAddressBatchInfo(msg.sender);
        
        if (block.timestamp < startTime) revert InvalidPublicMintTime();

        _safeMint(msg.sender, 1);
        publicMintParameters.numberOfRaffleMinted++;
        accountInfo.raffleMinted = true;
    }


    /// @notice pay raffle price to register the raffle
    /// @dev only allow to register in time internal raffleRegisterStartTime to raffleRegisterEndTime
    /// @dev must pay enough ether to register the raffle
    /// @dev cannot register for more than twice
    function registerRaffle() external payable {
        RaffleInfo storage raffleParameters = raffleInfo;
        if (block.timestamp < raffleParameters.registerStartTime || raffleParameters.registerEndTime < block.timestamp) revert InvalidRaffleRegisterTime();
        if (msg.value < rafflePrice) revert InsufficientPayments();

        AddressPublicMintInfo storage accountInfo = addressPublicMintInfo[msg.sender];
        if (accountInfo.raffleRegistered) revert AlreadyRegistered();

        accountInfo.raffleRegistered = true;
        raffleParameters.numberOfRegistered++;

        emit RaffleRegistered(msg.sender);
    }


    /// @notice request for raffle randomness
    /// @dev can only request after raffle register end
    /// @dev Only owner can do this
    function requestRaffleRandomness() external onlyOwner nonReentrant {
        RaffleInfo storage raffleParameters = raffleInfo;
        if (block.timestamp < raffleParameters.registerEndTime) revert RequestRaffleRandomnessNotAllowed();
        if (raffleRandomness != 0) revert RaffleRandomnessAlreadyRequested();

        bytes32 requestId = requestRandomness(vrfKeyHash, vrfFee);

        emit RaffleRandomnessRequested(requestId);
    }


    function fulfillRandomness(bytes32 /*requestId*/, uint256 randomness) internal override {
        raffleRandomness = randomness;

        emit RaffleRandomnessReceived(randomness);
    }


    /// @notice Returns nth batch and start time in public sale of the address
    /// @param _address The query address
    /// @return nth batch of the address
    /// @return public mint start time of the address
    function getAddressBatchInfo(address _address) public view returns (uint256, uint256) {
        RaffleInfo storage raffleParameters = raffleInfo;
        PublicMintInfo storage publicMintParameters = publicMintInfo;

        uint256 order = uint256(bytes32(raffleRandomness) ^ bytes32(uint256(uint160(_address)))) % raffleParameters.numberOfBatch;
        uint256 time = publicMintParameters.publicMintStartTime + publicMintParameters.publicMintStepTime * order;

        return (order + 1, time);
    }


    /// @notice Refund raffle payment
    /// @dev Refund is allowed after sold out
    /// @dev If an address have minted, it cannot refund
    /// @dev If the batch of an address is smaller than the last batch, it cannot refund
    /// @dev Only payer can do this
    function refundRafflePayment() external nonReentrant {
        if (totalSupply() != maxCollection) revert RefundNotAllowed();
        
        AddressPublicMintInfo storage accountInfo = addressPublicMintInfo[msg.sender];
        if (!accountInfo.raffleRegistered || accountInfo.raffleMinted || accountInfo.raffleRefunded) revert NoRefundQuota();

        accountInfo.raffleRefunded = true;
        raffleInfo.numberOfRefunded++;
        (bool success, ) = payable(msg.sender).call{value: rafflePrice}("");
        if (!success) revert UnableToRefundRafflePayment();

        emit RaffleRefunded(msg.sender);
    }


    /// @notice Request to reveal token
    /// @param _tokenId TokenId to reveal
    /// @dev Only token owner can do this
    /// @dev The backend server will scan for tokens requested to be revealed and call "reveal" function to reveal the token
    function requestReveal(uint256 _tokenId) external {
        if (!globalInfo.allowReveal) revert RevealNotAllowed();
        if (ownerOf(_tokenId) != msg.sender) revert RequestRevealNotTokenOwner();
        if (tokenRevealInfo[_tokenId].revealRequested) revert RevealAlreadyRequested();
        if (hashMerkleRoot == bytes32(0)) revert MerkleTreeRootNotSet();

        tokenRevealInfo[_tokenId].revealRequested = true;
        
        emit RevealRequested(_tokenId);
    }


    /// @notice Reveal the token
    /// @param _tokenId TokenId to reveal
    /// @param _tokenBaseURIHash IPFS hash of the metadata for this token
    /// @param _index index of metadata for this token
    /// @param _salt salt of tokenBaseURIHash for this token
    /// @dev Only revealer can do this
    function reveal(uint256 _tokenId, bytes32 _tokenBaseURIHash, uint64 _index, bytes32 _salt, bytes32[] memory _proof) public onlyRevealer {
        if (hashMerkleRoot == bytes32(0)) revert MerkleTreeRootNotSet();
        if (!tokenRevealInfo[_tokenId].revealRequested) revert IncorrectRevealIndex();

        TokenRevealInfo storage tokenInfo = tokenRevealInfo[_tokenId];
        if (tokenInfo.tokenBaseURIHash != 0) revert TokenAlreadyRevealed();

        bytes32 hash = keccak256(abi.encodePacked(_tokenBaseURIHash, uint256(_index), _salt));
        if (!MerkleProof.verify(_proof, hashMerkleRoot, hash)) revert MerkleTreeProofFailed();

        tokenInfo.tokenBaseURIHash = _tokenBaseURIHash;
        tokenInfo.index = _index;

        emit Revealed(_tokenId);
    }


    /// @notice Reveal batch tokens
    /// @param _tokenIds TokenIds to reveal
    /// @param _tokenBaseURIHashes IPFS hashes of the metadata for the tokens
    /// @param _indexes indexes of metadata for the tokens
    /// @param _salts salts of tokenBaseURIHash for the tokens
    function revealMany(uint256[] memory _tokenIds, bytes32[] memory _tokenBaseURIHashes, uint64[] memory _indexes, bytes32[] memory _salts, bytes32[][] memory _prooves) external {
        if (hashMerkleRoot == bytes32(0)) revert MerkleTreeRootNotSet();
        if (_tokenIds.length != _tokenBaseURIHashes.length) revert IncorrectRevealManyLength();
        if (_tokenIds.length != _indexes.length) revert IncorrectRevealManyLength();
        if (_tokenIds.length != _salts.length) revert IncorrectRevealManyLength();
        if (_tokenIds.length != _prooves.length) revert IncorrectRevealManyLength();

        uint256 i;
        uint256 length = _tokenIds.length;
        for (i = 0; i < length; i++) {
            TokenRevealInfo storage tokenInfo = tokenRevealInfo[_tokenIds[i]];
            if (tokenInfo.tokenBaseURIHash == 0) {
                // only calls reveal for those not revealed yet
                // this is to prevent the case where one revealed token will cause the entire batch to revert
                // we only check for "revealed" but not for other situation as the entire batch is supposed to have
                // correct parameters
                reveal(_tokenIds[i], _tokenBaseURIHashes[i], _indexes[i], _salts[i], _prooves[i]);
            }
        }
    }


    /// @notice Returns token URI of a token
    /// @param _tokenId Token Id
    /// @return uri Token URI
    function tokenURI(uint256 _tokenId) public view virtual override returns (string memory uri) {
	    if (!_exists(_tokenId)) revert URIQueryForNonexistentToken();
        
        TokenRevealInfo storage tokenInfo = tokenRevealInfo[_tokenId];
        if (tokenInfo.tokenBaseURIHash == 0) {
            return unrevealURI;
        }
        else {
            bytes32 hash = tokenInfo.tokenBaseURIHash;
            return string(abi.encodePacked("ipfs://", IPFSConvert.cidv0FromBytes32(hash)));
        }
	}


    /// @notice Returns the number of all minted tokens
    /// @return minted Number of all minted tokens
    function totalMinted() external view returns (uint256 minted) {
        return _totalMinted();
    }


    /// @notice Returns the number of all minted tokens from an address
    /// @param _minter Minter address
    /// @return minted Number of all minted tokens from the minter
    function numberMinted(address _minter) external view returns (uint256 minted) {
        return _numberMinted(_minter);
    }


    /// @notice Sets character slice
    /// @param _numberOfCharacter Number of character
    /// @param _characterSlice character slice
    /// @dev Only revealer can do this 
    function setCharacter(uint256 _numberOfCharacter, uint256[] memory _characterSlice) external onlyOwner {
        if (_numberOfCharacter != _characterSlice.length) revert CharacterLengthMismatch();
        if (_characterSlice[_characterSlice.length - 1] != maxCollection) revert InvalidCharacterSlice();

        characterSlice = _characterSlice;
    }


    /// @notice Returns character of a token
    /// @param _tokenId Token Id
    /// @return character Character of a token, starting from 1. Returns 0 if a token is not revealed yet.
    function tokenCharacter(uint256 _tokenId) public view returns (uint256) {
        if (!_exists(_tokenId)) revert URIQueryForNonexistentToken();

        TokenRevealInfo storage tokenInfo = tokenRevealInfo[_tokenId];
        uint256 index = tokenInfo.index;

        if (index == 0) {
            return 0;
        }

        for (uint256 i = 0; i < characterSlice.length; i++) {
            if (characterSlice[i] >= index) {
                return i + 1;
            }
        }
        
        // should not go here
        return 0;
    }


    /// @notice Returns all tokenIds owned by an address
    /// @param _addr The address
    /// @param _startId starting tokenId
    /// @param _endId ending tokenId (inclusive)
    /// @return tokenIds Array of all tokenIds owned by the address
    /// @return endTokenId ending tokenId
    function ownedTokens(address _addr, uint256 _startId, uint256 _endId) external view returns (uint256[] memory tokenIds, uint256 endTokenId) {
        if (_endId == 0) {
            _endId = _currentIndex - 1;
        }

        if (_startId < _startTokenId() || _endId >= _currentIndex) revert TokenIndexOutOfBounds();

        uint256 i;
        uint256 balance = balanceOf(_addr);
        if (balance == 0) {
            return (new uint256[](0), _endId + 1);
        }

        if (balance > 256) {
            balance = 256;
        }

        uint256[] memory results = new uint256[](balance);
        uint256 idx = 0;
        
        address owner = ownerOf(_startId);
        for (i = _startId; i <= _endId; i++) {
            if (_ownerships[i].addr != address(0)) {
                owner = _ownerships[i].addr;
            }

            if (!_ownerships[i].burned && owner == _addr) {
                results[idx] = i;
                idx++;

                if (idx == balance) {
                    if (balance == balanceOf(_addr)) {
                        return (results, _endId + 1);
                    }
                    else {
                        return (results, i + 1);
                    }
                }
            }
        }

        uint256[] memory partialResults = new uint256[](idx);
        for (i = 0; i < idx; i++) {
            partialResults[i] = results[i];
        }        

        return (partialResults, _endId + 1);
    }


    /// @notice Returns all tokenIds that are requested to be revealed but not revealed
    /// @param _startId starting tokenId
    /// @param _endId ending tokenId (inclusive)
    /// @return tokenIds Array of tokenIds that are requested to be revealed but not revealed
    /// @return endTokenId ending tokenId
    function unrevealedTokens(uint256 _startId, uint256 _endId) external view returns (uint256[] memory, uint256) {
        if (_endId == 0) {
            _endId = _currentIndex - 1;
        }

        if (_startId < _startTokenId() || _endId >= _currentIndex) revert TokenIndexOutOfBounds();

        uint256 i;
        uint256[] memory results = new uint256[](256);
        uint256 idx = 0;
        
        for (i = _startId; i <= _endId; i++) {
            TokenRevealInfo storage tokenInfo = tokenRevealInfo[i];
            if (tokenInfo.revealRequested && tokenInfo.tokenBaseURIHash == 0) {
                // reveal requested but not revealed
                results[idx] = i;
                idx++;

                if (idx == 256) {
                    return (results, i + 1);
                }
            }
        }

        uint256[] memory partialResults = new uint256[](idx);
        for (i = 0; i < idx; i++) {
            partialResults[i] = results[i];
        }

        return (partialResults, _endId + 1);
    }


    /// @notice Withdraw funds in the contract
    /// @param _to The address to send the funds to
    /// @dev value will be balance of contract - refund reserved value
    /// @dev Only owner can do this
    function withdraw(address payable _to) external payable onlyOwner nonReentrant {
        PublicMintInfo storage publicMintParameters = publicMintInfo;
        RaffleInfo storage raffleParameters = raffleInfo;

        uint256 value = address(this).balance - rafflePrice * (raffleParameters.numberOfRegistered - publicMintParameters.numberOfRaffleMinted - raffleParameters.numberOfRefunded);
        (bool success, ) = _to.call{value: value}("");
        if (!success) revert UnableToWithdrawFund();
	}


    function _startTokenId() override internal view virtual returns (uint256) {
        // the starting token Id
        return 1;
    }


    modifier onlyRevealer {
        if(msg.sender != globalInfo.revealer) revert NotRevealer();
        _;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_maxCollection","type":"uint256"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_linkToken","type":"address"},{"internalType":"bytes32","name":"_vrfKeyHash","type":"bytes32"},{"internalType":"uint256","name":"_vrfFee","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyRegistered","type":"error"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"CharacterLengthMismatch","type":"error"},{"inputs":[],"name":"ExceedMaxAllowedMintAmount","type":"error"},{"inputs":[],"name":"IncorrectRevealIndex","type":"error"},{"inputs":[],"name":"IncorrectRevealManyLength","type":"error"},{"inputs":[],"name":"IncorrectSignature","type":"error"},{"inputs":[],"name":"InsufficientPayments","type":"error"},{"inputs":[],"name":"InvalidCharacterSlice","type":"error"},{"inputs":[],"name":"InvalidPublicMintTime","type":"error"},{"inputs":[],"name":"InvalidRaffleRegisterTime","type":"error"},{"inputs":[],"name":"MerkleTreeProofFailed","type":"error"},{"inputs":[],"name":"MerkleTreeRootAlreadySet","type":"error"},{"inputs":[],"name":"MerkleTreeRootNotSet","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NoRefundQuota","type":"error"},{"inputs":[],"name":"NotRegistered","type":"error"},{"inputs":[],"name":"NotRevealer","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"RaffleRandomnessAlreadyRequested","type":"error"},{"inputs":[],"name":"RandomizerAlreadySet","type":"error"},{"inputs":[],"name":"ReachedMaxSupply","type":"error"},{"inputs":[],"name":"RefundNotAllowed","type":"error"},{"inputs":[],"name":"RequestRaffleRandomnessNotAllowed","type":"error"},{"inputs":[],"name":"RequestRevealNotTokenOwner","type":"error"},{"inputs":[],"name":"RevealAlreadyRequested","type":"error"},{"inputs":[],"name":"RevealNotAllowed","type":"error"},{"inputs":[],"name":"TokenAlreadyRevealed","type":"error"},{"inputs":[],"name":"TokenIndexOutOfBounds","type":"error"},{"inputs":[],"name":"TokenSalePhaseBoundaryAlreadySet","type":"error"},{"inputs":[],"name":"TransactionExpired","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"},{"inputs":[],"name":"UnableToRefundRafflePayment","type":"error"},{"inputs":[],"name":"UnableToWithdrawFund","type":"error"},{"inputs":[],"name":"WhitelistMintEnded","type":"error"},{"inputs":[],"name":"WhitelistMintNotStarted","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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"RaffleRandomnessReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"RaffleRandomnessRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"refundedAddress","type":"address"}],"name":"RaffleRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"registeredAddress","type":"address"}],"name":"RaffleRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"RevealRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Revealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressPublicMintInfo","outputs":[{"internalType":"bool","name":"raffleRegistered","type":"bool"},{"internalType":"bool","name":"raffleRefunded","type":"bool"},{"internalType":"bool","name":"raffleMinted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"characterSlice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"devMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getAddressBatchInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTokenSalePhase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalInfo","outputs":[{"internalType":"address","name":"whitelistSigner","type":"address"},{"internalType":"address","name":"randomizer","type":"address"},{"internalType":"address","name":"revealer","type":"address"},{"internalType":"uint64","name":"whitelistMintStartTime","type":"uint64"},{"internalType":"uint64","name":"whitelistMintEndTime","type":"uint64"},{"internalType":"bool","name":"allowReveal","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hashMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"maxCollection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"minted","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint256","name":"_startId","type":"uint256"},{"internalType":"uint256","name":"_endId","type":"uint256"}],"name":"ownedTokens","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"endTokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicMintInfo","outputs":[{"internalType":"uint64","name":"publicMintStartTime","type":"uint64"},{"internalType":"uint64","name":"publicMintStepTime","type":"uint64"},{"internalType":"uint64","name":"unlimitMintStartTime","type":"uint64"},{"internalType":"uint32","name":"numberOfRaffleMinted","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"raffleInfo","outputs":[{"internalType":"uint64","name":"registerStartTime","type":"uint64"},{"internalType":"uint64","name":"registerEndTime","type":"uint64"},{"internalType":"uint32","name":"numberOfBatch","type":"uint32"},{"internalType":"uint32","name":"numberOfRegistered","type":"uint32"},{"internalType":"uint32","name":"numberOfRefunded","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rafflePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"raffleRandomness","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refundRafflePayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registerRaffle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestRaffleRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"requestReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes32","name":"_tokenBaseURIHash","type":"bytes32"},{"internalType":"uint64","name":"_index","type":"uint64"},{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bytes32[]","name":"_tokenBaseURIHashes","type":"bytes32[]"},{"internalType":"uint64[]","name":"_indexes","type":"uint64[]"},{"internalType":"bytes32[]","name":"_salts","type":"bytes32[]"},{"internalType":"bytes32[][]","name":"_prooves","type":"bytes32[][]"}],"name":"revealMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_allowReveal","type":"bool"}],"name":"setAllowReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numberOfCharacter","type":"uint256"},{"internalType":"uint256[]","name":"_characterSlice","type":"uint256[]"}],"name":"setCharacter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hashMerkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_publicMintStartTime","type":"uint64"},{"internalType":"uint64","name":"_publicMintStepTime","type":"uint64"},{"internalType":"uint64","name":"_unlimitMintStartTime","type":"uint64"}],"name":"setPublicMintTimeSetting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_raffleRegisterStartTime","type":"uint64"},{"internalType":"uint64","name":"_raffleRegisterEndTime","type":"uint64"},{"internalType":"uint32","name":"_numberOfRaffleBatch","type":"uint32"}],"name":"setRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_randomizer","type":"address"}],"name":"setRandomizer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newRevealer","type":"address"}],"name":"setRevealer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"setTokenSalePhaseBoundary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newURI","type":"string"}],"name":"setUnrevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_vrfKeyHash","type":"bytes32"},{"internalType":"uint256","name":"_vrfFee","type":"uint256"}],"name":"setVRFParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_whitelistMintStartTime","type":"uint64"},{"internalType":"uint64","name":"_whitelistMintEndTime","type":"uint64"}],"name":"setWhitelistMintTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newWhitelistSigner","type":"address"}],"name":"setWhitelistSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenCharacter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenRevealInfo","outputs":[{"internalType":"bytes32","name":"tokenBaseURIHash","type":"bytes32"},{"internalType":"uint64","name":"index","type":"uint64"},{"internalType":"bool","name":"revealRequested","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenSalePhaseBoundary","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"uri","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"minted","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unrevealURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startId","type":"uint256"},{"internalType":"uint256","name":"_endId","type":"uint256"}],"name":"unrevealedTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vrfKeyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_amount","type":"uint32"},{"internalType":"uint32","name":"_allowAmount","type":"uint32"},{"internalType":"uint64","name":"_expireTime","type":"uint64"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

60c06040526707b970c041fb800060125566c5be79a032c0006018553480156200002857600080fd5b506040516200486f3803806200486f8339810160408190526200004b91620002a0565b8383888881600290805190602001906200006792919062000110565b5080516200007d90600390602084019062000110565b50506001600055506200009033620000be565b60016009556001600160a01b0391821660a05216608052601194909455600b555050600c5550620003889050565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200011e906200034c565b90600052602060002090601f0160209004810192826200014257600085556200018d565b82601f106200015d57805160ff19168380011785556200018d565b828001600101855582156200018d579182015b828111156200018d57825182559160200191906001019062000170565b506200019b9291506200019f565b5090565b5b808211156200019b5760008155600101620001a0565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001de57600080fd5b81516001600160401b0380821115620001fb57620001fb620001b6565b604051601f8301601f19908116603f01168101908282118183101715620002265762000226620001b6565b816040528381526020925086838588010111156200024357600080fd5b600091505b8382101562000267578582018301518183018401529082019062000248565b83821115620002795760008385830101525b9695505050505050565b80516001600160a01b03811681146200029b57600080fd5b919050565b600080600080600080600060e0888a031215620002bc57600080fd5b87516001600160401b0380821115620002d457600080fd5b620002e28b838c01620001cc565b985060208a0151915080821115620002f957600080fd5b50620003088a828b01620001cc565b96505060408801519450620003206060890162000283565b9350620003306080890162000283565b925060a0880151915060c0880151905092959891949750929550565b600181811c908216806200036157607f821691505b6020821081036200038257634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a0516144ba620003b5600039600081816121630152612dcb01526000612d9c01526144ba6000f3fe6080604052600436106103b85760003560e01c806357019e34116101f2578063b88d4fde1161010d578063e985e9c5116100a0578063f1955ccc1161006f578063f1955ccc14610c07578063f2fde38b14610c80578063f8d8679414610ca0578063fc3f614714610cb657600080fd5b8063e985e9c514610aeb578063eddad33c14610b34578063edfe2e0f14610b54578063f04b5fa014610b6957600080fd5b8063d0a89b08116100dc578063d0a89b0814610a82578063d338143814610a95578063dc33e68114610ab5578063e11c9a2614610ad557600080fd5b8063b88d4fde14610a0c578063c17c3fe314610a2c578063c87b56dd14610a4c578063c9df912c14610a6c57600080fd5b80638da5cb5b1161018557806397bc411c1161015457806397bc411c1461099d578063a035b1fe146109bd578063a22cb465146109d3578063a2309ff8146109f357600080fd5b80638da5cb5b1461092a57806391b7f5ed1461094857806394985ddd1461096857806395d89b411461098857600080fd5b8063715018a6116101c1578063715018a614610867578063767bcab51461087c5780637cb647591461089c578063818f9156146108bc57600080fd5b806357019e34146107e75780636352211e146108075780636df64c1c1461082757806370a082311461084757600080fd5b8063269b7943116102e25780633d444c591161027557806349a0a50e1161024457806349a0a50e146107665780634ad505161461079457806351cff8d9146107b457806353418fa2146107c757600080fd5b80633d444c59146106f057806340261cdd1461070657806342842e0e146107265780634807856a1461074657600080fd5b8063390a5b9a116102b1578063390a5b9a146106855780633ae5213e1461069b5780633b0b1323146106bb5780633c66a815146106d057600080fd5b8063269b7943146105f0578063285ab8c1146106105780632d1a12f61461064557806337b677df1461066557600080fd5b80631017507d1161035a578063220c19c211610329578063220c19c2146105a057806322fde03a146105a857806323b872dd146105c857806326092b83146105e857600080fd5b80631017507d1461054057806314bf9d171461055657806318160ddd146105765780632126ea811461058b57600080fd5b806306fdde031161039657806306fdde0314610438578063081812fc1461045a578063095ea7b3146104925780630fb5b157146104b257600080fd5b806301ffc9a7146103bd57806302b49315146103f2578063041d443e14610414575b600080fd5b3480156103c957600080fd5b506103dd6103d836600461392a565b610d18565b60405190151581526020015b60405180910390f35b3480156103fe57600080fd5b5061041261040d366004613a22565b610d6a565b005b34801561042057600080fd5b5061042a600b5481565b6040519081526020016103e9565b34801561044457600080fd5b5061044d610e1e565b6040516103e99190613ac0565b34801561046657600080fd5b5061047a610475366004613ad3565b610eb0565b6040516001600160a01b0390911681526020016103e9565b34801561049e57600080fd5b506104126104ad366004613b01565b610ef4565b3480156104be57600080fd5b50601954610502906001600160401b0380821691600160401b81049091169063ffffffff600160801b8204811691600160a01b8104821691600160c01b9091041685565b604080516001600160401b03968716815295909416602086015263ffffffff928316938501939093528116606084015216608082015260a0016103e9565b34801561054c57600080fd5b5061042a600c5481565b34801561056257600080fd5b5061042a610571366004613ad3565b610f75565b34801561058257600080fd5b5061042a610f96565b34801561059757600080fd5b5061044d610fa4565b610412611032565b3480156105b457600080fd5b5061042a6105c3366004613ad3565b61114f565b3480156105d457600080fd5b506104126105e3366004613b2d565b61120b565b610412611216565b3480156105fc57600080fd5b5061041261060b366004613b8a565b61138a565b34801561061c57600080fd5b5061063061062b366004613bcd565b611400565b604080519283526020830191909152016103e9565b34801561065157600080fd5b50610412610660366004613bea565b611486565b34801561067157600080fd5b50610412610680366004613cfb565b6114f3565b34801561069157600080fd5b5061042a60115481565b3480156106a757600080fd5b506104126106b6366004613dcc565b61168d565b3480156106c757600080fd5b506104126116c2565b3480156106dc57600080fd5b506104126106eb366004613dee565b6117bc565b3480156106fc57600080fd5b5061042a60135481565b34801561071257600080fd5b50610412610721366004613ad3565b611928565b34801561073257600080fd5b50610412610741366004613b2d565b611a29565b34801561075257600080fd5b50610412610761366004613ad3565b611a44565b34801561077257600080fd5b50610786610781366004613e4b565b611a94565b6040516103e9929190613e80565b3480156107a057600080fd5b506104126107af366004613ed6565b611d31565b6104126107c2366004613bcd565b611d79565b3480156107d357600080fd5b506104126107e2366004613f07565b611eaa565b3480156107f357600080fd5b50610412610802366004613f41565b611f21565b34801561081357600080fd5b5061047a610822366004613ad3565b611f89565b34801561083357600080fd5b5061042a610842366004613ad3565b611f9b565b34801561085357600080fd5b5061042a610862366004613bcd565b611fdc565b34801561087357600080fd5b5061041261202a565b34801561088857600080fd5b50610412610897366004613bcd565b612060565b3480156108a857600080fd5b506104126108b7366004613ad3565b6120d6565b3480156108c857600080fd5b506109056108d7366004613ad3565b601c60205260009081526040902080546001909101546001600160401b03811690600160401b900460ff1683565b604080519384526001600160401b0390921660208401521515908201526060016103e9565b34801561093657600080fd5b506008546001600160a01b031661047a565b34801561095457600080fd5b50610412610963366004613ad3565b612129565b34801561097457600080fd5b50610412610983366004613dcc565b612158565b34801561099457600080fd5b5061044d6121da565b3480156109a957600080fd5b506104126109b8366004613fb5565b6121e9565b3480156109c957600080fd5b5061042a60125481565b3480156109df57600080fd5b506104126109ee366004613ff6565b61221f565b3480156109ff57600080fd5b506000546000190161042a565b348015610a1857600080fd5b50610412610a2736600461404b565b6122b4565b348015610a3857600080fd5b50610412610a47366004613bcd565b6122fe565b348015610a5857600080fd5b5061044d610a67366004613ad3565b61234a565b348015610a7857600080fd5b5061042a60145481565b610412610a903660046140f4565b6124c4565b348015610aa157600080fd5b50610412610ab0366004613bcd565b61268c565b348015610ac157600080fd5b5061042a610ad0366004613bcd565b6126d8565b348015610ae157600080fd5b5061042a60175481565b348015610af757600080fd5b506103dd610b06366004614169565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610b4057600080fd5b50610786610b4f366004613dcc565b612706565b348015610b6057600080fd5b506104126128ce565b348015610b7557600080fd5b50600d54600e54600f54601054610bbd936001600160a01b0390811693811692908116916001600160401b03600160a01b90920482169181169060ff600160401b9091041686565b604080516001600160a01b039788168152958716602087015293909516928401929092526001600160401b03908116606084015216608082015290151560a082015260c0016103e9565b348015610c1357600080fd5b50601a54610c4a906001600160401b0380821691600160401b8104821691600160801b82041690600160c01b900463ffffffff1684565b604080516001600160401b0395861681529385166020850152919093169082015263ffffffff90911660608201526080016103e9565b348015610c8c57600080fd5b50610412610c9b366004613bcd565b612a64565b348015610cac57600080fd5b5061042a60185481565b348015610cc257600080fd5b50610cf9610cd1366004613bcd565b601b6020526000908152604090205460ff808216916101008104821691620100009091041683565b60408051931515845291151560208401521515908201526060016103e9565b60006001600160e01b031982166380ac58cd60e01b1480610d4957506001600160e01b03198216635b5e139f60e01b145b80610d6457506301ffc9a760e01b6001600160e01b03198316145b92915050565b6008546001600160a01b03163314610d9d5760405162461bcd60e51b8152600401610d9490614197565b60405180910390fd5b80518214610dbe5760405163addbf84b60e01b815260040160405180910390fd5b6011548160018351610dd091906141e2565b81518110610de057610de06141f9565b602002602001015114610e065760405163d93aa98160e01b815260040160405180910390fd5b8051610e19906016906020840190613840565b505050565b606060028054610e2d9061420f565b80601f0160208091040260200160405190810160405280929190818152602001828054610e599061420f565b8015610ea65780601f10610e7b57610100808354040283529160200191610ea6565b820191906000526020600020905b815481529060010190602001808311610e8957829003601f168201915b5050505050905090565b6000610ebb82612afc565b610ed8576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610eff82611f89565b9050806001600160a01b0316836001600160a01b031603610f335760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b03821614610f6a57610f4d8133610b06565b610f6a576040516367d9dca160e11b815260040160405180910390fd5b610e19838383612b35565b60168181548110610f8557600080fd5b600091825260209091200154905081565b600154600054036000190190565b60158054610fb19061420f565b80601f0160208091040260200160405190810160405280929190818152602001828054610fdd9061420f565b801561102a5780601f10610fff5761010080835404028352916020019161102a565b820191906000526020600020905b81548152906001019060200180831161100d57829003601f168201915b505050505081565b601980546001600160401b031642108061105d5750805442600160401b9091046001600160401b0316105b1561107b5760405163015cb63b60e41b815260040160405180910390fd5b60185434101561109e5760405163fa47be2b60e01b815260040160405180910390fd5b336000908152601b60205260409020805460ff16156110d057604051630ea075bf60e21b815260040160405180910390fd5b805460ff19166001178155815463ffffffff600160a01b909104168260146110f783614243565b825463ffffffff9182166101009390930a9283029190920219909116179055506040513381527f633ce1c9388c97d7993f137095f9978b0605881949d6640da48ce48504fcaddd906020015b60405180910390a15050565b600061115a82612afc565b61117757604051630a14c4b560e41b815260040160405180910390fd5b6000828152601c60205260408120600181015490916001600160401b03909116908190036111a9575060009392505050565b60005b6016548110156112005781601682815481106111ca576111ca6141f9565b9060005260206000200154106111ee576111e5816001614266565b95945050505050565b806111f88161427e565b9150506111ac565b506000949350505050565b610e19838383612b91565b601154611221610f96565b0361123f5760405163794bb39b60e01b815260040160405180910390fd5b6012543410156112625760405163fa47be2b60e01b815260040160405180910390fd5b601a8054600160801b90046001600160401b03161580159061129557508054600160801b90046001600160401b03164210155b156112a8576112a5336001612d7e565b50565b336000908152601b60205260409020805460ff166112d95760405163aba4733960e01b815260040160405180910390fd5b805462010000900460ff161561130257604051635c81808d60e11b815260040160405180910390fd5b600061130d33611400565b91505042811115611331576040516320f2db8560e01b815260040160405180910390fd5b61133c336001612d7e565b8254600160c01b900463ffffffff1683601861135783614243565b825463ffffffff9182166101009390930a92830291909202199091161790555050805462ff000019166201000017905550565b6008546001600160a01b031633146113b45760405162461bcd60e51b8152600401610d9490614197565b601a80546001600160401b039485166001600160801b031990911617600160401b938516939093029290921767ffffffffffffffff60801b1916600160801b9190931602919091179055565b6019805460175460009283929091601a91849161143591600160801b900463ffffffff16906001600160a01b03891618614297565b8254909150600090611458908390600160401b90046001600160401b03166142b9565b835461146d91906001600160401b0316614266565b905061147a826001614266565b97909650945050505050565b6008546001600160a01b031633146114b05760405162461bcd60e51b8152600401610d9490614197565b601154826114bc610f96565b6114c69190614266565b11156114e55760405163794bb39b60e01b815260040160405180910390fd5b6114ef8183612d7e565b5050565b60145461151357604051633d39c8eb60e11b815260040160405180910390fd5b835185511461153557604051636726d5d560e11b815260040160405180910390fd5b825185511461155757604051636726d5d560e11b815260040160405180910390fd5b815185511461157957604051636726d5d560e11b815260040160405180910390fd5b805185511461159b57604051636726d5d560e11b815260040160405180910390fd5b84516000905b80821015611684576000601c60008985815181106115c1576115c16141f9565b60200260200101518152602001908152602001600020905080600001546000801b03611671576116718884815181106115fc576115fc6141f9565b6020026020010151888581518110611616576116166141f9565b6020026020010151888681518110611630576116306141f9565b602002602001015188878151811061164a5761164a6141f9565b6020026020010151888881518110611664576116646141f9565b60200260200101516117bc565b508161167c8161427e565b9250506115a1565b50505050505050565b6008546001600160a01b031633146116b75760405162461bcd60e51b8152600401610d9490614197565b600b91909155600c55565b6008546001600160a01b031633146116ec5760405162461bcd60e51b8152600401610d9490614197565b60026009540361170e5760405162461bcd60e51b8152600401610d94906142d8565b600260095560198054600160401b90046001600160401b0316421015611747576040516343698abd60e11b815260040160405180910390fd5b601754156117685760405163a21f7b7f60e01b815260040160405180910390fd5b6000611778600b54600c54612d98565b90507f8a9bace5c88f7bb841bb0d7e705b9afdbf85f3a1693cc681070cb06dcb984fc7816040516117ab91815260200190565b60405180910390a150506001600955565b600f546001600160a01b031633146117e75760405163572b2f3160e01b815260040160405180910390fd5b60145461180757604051633d39c8eb60e11b815260040160405180910390fd5b6000858152601c6020526040902060010154600160401b900460ff1661184057604051633674210b60e01b815260040160405180910390fd5b6000858152601c6020526040902080541561186e576040516305a049a960e41b815260040160405180910390fd5b6040805160208082018890526001600160401b03871682840152606080830187905283518084039091018152608090920190925280519101206014546118b690849083612f1c565b6118d357604051633fec49b760e01b815260040160405180910390fd5b85825560018201805467ffffffffffffffff19166001600160401b03871617905560405187907f15120e52505e619cbf6c2af910d5cf7f9ee1befa55801b078c33e93880b2d60990600090a250505050505050565b601054600160401b900460ff16611952576040516344300a9960e01b815260040160405180910390fd5b3361195c82611f89565b6001600160a01b03161461198357604051634fb693d160e11b815260040160405180910390fd5b6000818152601c6020526040902060010154600160401b900460ff16156119bd57604051633383b7e560e21b815260040160405180910390fd5b6014546119dd57604051633d39c8eb60e11b815260040160405180910390fd5b6000818152601c6020526040808220600101805460ff60401b1916600160401b1790555182917f63e414cbfeae599c8bf0173052f72173257ad08c1c0b49eed829a02a9368395691a250565b610e19838383604051806020016040528060008152506122b4565b6008546001600160a01b03163314611a6e5760405162461bcd60e51b8152600401610d9490614197565b60135415611a8f5760405163e602438d60e01b815260040160405180910390fd5b601355565b6060600082600003611ab2576001600054611aaf91906141e2565b92505b6001841080611ac357506000548310155b15611ae1576040516329c8c00760e21b815260040160405180910390fd5b600080611aed87611fdc565b905080600003611b1c57604080516000815260208101909152611b11866001614266565b935093505050611d29565b610100811115611b2b57506101005b6000816001600160401b03811115611b4557611b4561394e565b604051908082528060200260200182016040528015611b6e578160200160208202803683370190505b509050600080611b7d89611f89565b90508894505b878511611c76576000858152600460205260409020546001600160a01b031615611bc157506000848152600460205260409020546001600160a01b03165b600085815260046020526040902054600160e01b900460ff16158015611bf85750896001600160a01b0316816001600160a01b0316145b15611c645784838381518110611c1057611c106141f9565b602090810291909101015281611c258161427e565b925050838203611c6457611c388a611fdc565b8403611c585782611c4a896001614266565b965096505050505050611d29565b82611c4a866001614266565b84611c6e8161427e565b955050611b83565b6000826001600160401b03811115611c9057611c9061394e565b604051908082528060200260200182016040528015611cb9578160200160208202803683370190505b509050600095505b82861015611d1257838681518110611cdb57611cdb6141f9565b6020026020010151818781518110611cf557611cf56141f9565b602090810291909101015285611d0a8161427e565b965050611cc1565b80611d1e8a6001614266565b975097505050505050505b935093915050565b6008546001600160a01b03163314611d5b5760405162461bcd60e51b8152600401610d9490614197565b60108054911515600160401b0260ff60401b19909216919091179055565b6008546001600160a01b03163314611da35760405162461bcd60e51b8152600401610d9490614197565b600260095403611dc55760405162461bcd60e51b8152600401610d94906142d8565b600260095560198054601a805490929160009163ffffffff600160c01b808404821693611e019391909104821691600160a01b9091041661430f565b611e0b919061430f565b63ffffffff16601854611e1e91906142b9565b611e2890476141e2565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114611e77576040519150601f19603f3d011682016040523d82523d6000602084013e611e7c565b606091505b5050905080611e9e57604051634abd53ef60e11b815260040160405180910390fd5b50506001600955505050565b6008546001600160a01b03163314611ed45760405162461bcd60e51b8152600401610d9490614197565b6019805463ffffffff909216600160801b0263ffffffff60801b196001600160401b03948516600160401b026001600160801b031990941694909516939093179190911792909216179055565b6008546001600160a01b03163314611f4b5760405162461bcd60e51b8152600401610d9490614197565b600f805467ffffffffffffffff60a01b1916600160a01b6001600160401b03948516021790556010805467ffffffffffffffff191691909216179055565b6000611f9482612f32565b5192915050565b6000611fa682612afc565b611fc357604051630a14c4b560e41b815260040160405180910390fd5b6013548211611fd457506001919050565b506002919050565b60006001600160a01b038216612005576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b031633146120545760405162461bcd60e51b8152600401610d9490614197565b61205e6000613054565b565b6008546001600160a01b0316331461208a5760405162461bcd60e51b8152600401610d9490614197565b600e546001600160a01b0316156120b457604051637605a66760e11b815260040160405180910390fd5b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b031633146121005760405162461bcd60e51b8152600401610d9490614197565b6014541561212457604051600162b055f360e01b0319815260040160405180910390fd5b601455565b6008546001600160a01b031633146121535760405162461bcd60e51b8152600401610d9490614197565b601255565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146121d05760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610d94565b6114ef82826130a6565b606060038054610e2d9061420f565b6008546001600160a01b031633146122135760405162461bcd60e51b8152600401610d9490614197565b610e196015838361388b565b336001600160a01b038316036122485760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6122bf848484612b91565b6001600160a01b0383163b156122f8576122db848484846130db565b6122f8576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6008546001600160a01b031633146123285760405162461bcd60e51b8152600401610d9490614197565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b606061235582612afc565b61237257604051630a14c4b560e41b815260040160405180910390fd5b6000828152601c60205260408120805490910361241c57601580546123969061420f565b80601f01602080910402602001604051908101604052809291908181526020018280546123c29061420f565b801561240f5780601f106123e45761010080835404028352916020019161240f565b820191906000526020600020905b8154815290600101906020018083116123f257829003601f168201915b5050505050915050919050565b8054604051638614c2c360e01b81526004810182905273de22f3a62b3cff575f20614f33c0c65adcb9470290638614c2c390602401600060405180830381865af415801561246e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526124969190810190614334565b6040516020016124a691906143a1565b60405160208183030381529060405292505050919050565b50919050565b6011548563ffffffff166124d6610f96565b6124e09190614266565b11156124ff5760405163794bb39b60e01b815260040160405180910390fd5b600f54600160a01b90046001600160401b03164210156125325760405163ef4604b360e01b815260040160405180910390fd5b6010546001600160401b031642111561255e57604051633e17626f60e01b815260040160405180910390fd5b826001600160401b0316421115612588576040516338e5e54b60e21b815260040160405180910390fd5b3360009081526005602052604090205463ffffffff858116916125bd91881690600160401b90046001600160401b0316614266565b11156125dc57604051635c81808d60e11b815260040160405180910390fd5b61261e33858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506131c692505050565b61263b5760405163c1606c2f60e01b815260040160405180910390fd5b60008563ffffffff1660125461265191906142b9565b9050803410156126745760405163fa47be2b60e01b815260040160405180910390fd5b612684338763ffffffff16612d7e565b505050505050565b6008546001600160a01b031633146126b65760405162461bcd60e51b8152600401610d9490614197565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116600090815260056020526040812054600160401b90046001600160401b0316610d64565b606060008260000361272457600160005461272191906141e2565b92505b600184108061273557506000548310155b15612753576040516329c8c00760e21b815260040160405180910390fd5b604080516101008082526120208201909252600091829190602082016120008036833701905050905060008692505b858311612816576000838152601c602052604090206001810154600160401b900460ff1680156127b157508054155b1561280357838383815181106127c9576127c96141f9565b6020908102919091010152816127de8161427e565b925050816101000361280357826127f6856001614266565b95509550505050506128c7565b508261280e8161427e565b935050612782565b6000816001600160401b038111156128305761283061394e565b604051908082528060200260200182016040528015612859578160200160208202803683370190505b509050600093505b818410156128b25782848151811061287b5761287b6141f9565b6020026020010151818581518110612895576128956141f9565b6020908102919091010152836128aa8161427e565b945050612861565b806128be886001614266565b95509550505050505b9250929050565b6002600954036128f05760405162461bcd60e51b8152600401610d94906142d8565b6002600955601154612900610f96565b1461291e5760405163089c998760e01b815260040160405180910390fd5b336000908152601b60205260409020805460ff1615806129455750805462010000900460ff165b8061295657508054610100900460ff165b1561297457604051631124896d60e01b815260040160405180910390fd5b805461ff0019166101001781556019805463ffffffff600160c01b9091041690601861299f83614243565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000336001600160a01b031660185460405160006040518083038185875af1925050503d8060008114612a0d576040519150601f19603f3d011682016040523d82523d6000602084013e612a12565b606091505b5050905080612a34576040516327304f5160e21b815260040160405180910390fd5b6040513381527fcada6d5a24d75e568453894e32683a8a5e6421131f8df496749af47c49a93287906020016117ab565b6008546001600160a01b03163314612a8e5760405162461bcd60e51b8152600401610d9490614197565b6001600160a01b038116612af35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d94565b6112a581613054565b600081600111158015612b10575060005482105b8015610d64575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000612b9c82612f32565b9050836001600160a01b031681600001516001600160a01b031614612bd35760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b0386161480612bf15750612bf18533610b06565b80612c0c575033612c0184610eb0565b6001600160a01b0316145b905080612c2c57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038416612c5357604051633a954ecd60e21b815260040160405180910390fd5b612c5f60008487612b35565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b42909216919091021783558701808452922080549193909116612d33576000548214612d3357805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b6114ef8282604051806020016040528060008152506132b0565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000084866000604051602001612e08929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612e35939291906143d0565b6020604051808303816000875af1158015612e54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e7891906143f7565b506000838152600a6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a090910190925281519183019190912093879052919052612ed4906001614266565b6000858152600a6020526040902055612f148482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b949350505050565b600082612f298584613469565b14949350505050565b6040805160608101825260008082526020820181905291810191909152818060011161303b5760005481101561303b57600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906130395780516001600160a01b031615612fd0579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215613034579392505050565b612fd0565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60178190556040518181527ffd1fb69f924fc6339f4afd97c8dd1188e95739807f6286074e37bdd28562033890602001611143565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290613110903390899088908890600401614414565b6020604051808303816000875af192505050801561314b575060408051601f3d908101601f1916820190925261314891810190614451565b60015b6131a9573d808015613179576040519150601f19603f3d011682016040523d82523d6000602084013e61317e565b606091505b5080516000036131a1576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b604080516bffffffffffffffffffffffff19606087901b1660208201526001600160e01b031960e086901b1660348201526001600160c01b031960c085901b1660388201526000918291016040516020818303038152906040528051906020012090506000613282826040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b600d549091506001600160a01b031661329b82866134dd565b6001600160a01b031614979650505050505050565b6000546001600160a01b0384166132d957604051622e076360e81b815260040160405180910390fd5b826000036132fa5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260056020908152604080832080546001600160801b031981166001600160401b038083168b018116918217600160401b67ffffffffffffffff1990941690921783900481168b01811690920217909155858452600490925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b15613414575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46133dd60008784806001019550876130db565b6133fa576040516368d2bf6b60e11b815260040160405180910390fd5b80821061339257826000541461340f57600080fd5b613459565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210613415575b5060009081556122f89085838684565b600081815b84518110156134d557600085828151811061348b5761348b6141f9565b602002602001015190508083116134b157600083815260208290526040902092506134c2565b600081815260208490526040902092505b50806134cd8161427e565b91505061346e565b509392505050565b60008060006134ec85856134f9565b915091506134d581613564565b600080825160410361352f5760208301516040840151606085015160001a6135238782858561371a565b945094505050506128c7565b8251604003613558576020830151604084015161354d868383613807565b9350935050506128c7565b506000905060026128c7565b60008160048111156135785761357861446e565b036135805750565b60018160048111156135945761359461446e565b036135e15760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610d94565b60028160048111156135f5576135f561446e565b036136425760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610d94565b60038160048111156136565761365661446e565b036136ae5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610d94565b60048160048111156136c2576136c261446e565b036112a55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610d94565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561375157506000905060036137fe565b8460ff16601b1415801561376957508460ff16601c14155b1561377a57506000905060046137fe565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156137ce573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166137f7576000600192509250506137fe565b9150600090505b94509492505050565b6000806001600160ff1b0383168161382460ff86901c601b614266565b90506138328782888561371a565b935093505050935093915050565b82805482825590600052602060002090810192821561387b579160200282015b8281111561387b578251825591602001919060010190613860565b506138879291506138ff565b5090565b8280546138979061420f565b90600052602060002090601f0160209004810192826138b9576000855561387b565b82601f106138d25782800160ff1982351617855561387b565b8280016001018555821561387b579182015b8281111561387b5782358255916020019190600101906138e4565b5b808211156138875760008155600101613900565b6001600160e01b0319811681146112a557600080fd5b60006020828403121561393c57600080fd5b813561394781613914565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561398c5761398c61394e565b604052919050565b60006001600160401b038211156139ad576139ad61394e565b5060051b60200190565b600082601f8301126139c857600080fd5b813560206139dd6139d883613994565b613964565b82815260059290921b840181019181810190868411156139fc57600080fd5b8286015b84811015613a175780358352918301918301613a00565b509695505050505050565b60008060408385031215613a3557600080fd5b8235915060208301356001600160401b03811115613a5257600080fd5b613a5e858286016139b7565b9150509250929050565b60005b83811015613a83578181015183820152602001613a6b565b838111156122f85750506000910152565b60008151808452613aac816020860160208601613a68565b601f01601f19169290920160200192915050565b6020815260006139476020830184613a94565b600060208284031215613ae557600080fd5b5035919050565b6001600160a01b03811681146112a557600080fd5b60008060408385031215613b1457600080fd5b8235613b1f81613aec565b946020939093013593505050565b600080600060608486031215613b4257600080fd5b8335613b4d81613aec565b92506020840135613b5d81613aec565b929592945050506040919091013590565b80356001600160401b0381168114613b8557600080fd5b919050565b600080600060608486031215613b9f57600080fd5b613ba884613b6e565b9250613bb660208501613b6e565b9150613bc460408501613b6e565b90509250925092565b600060208284031215613bdf57600080fd5b813561394781613aec565b60008060408385031215613bfd57600080fd5b823591506020830135613c0f81613aec565b809150509250929050565b600082601f830112613c2b57600080fd5b81356020613c3b6139d883613994565b82815260059290921b84018101918181019086841115613c5a57600080fd5b8286015b84811015613a1757613c6f81613b6e565b8352918301918301613c5e565b600082601f830112613c8d57600080fd5b81356020613c9d6139d883613994565b82815260059290921b84018101918181019086841115613cbc57600080fd5b8286015b84811015613a175780356001600160401b03811115613cdf5760008081fd5b613ced8986838b01016139b7565b845250918301918301613cc0565b600080600080600060a08688031215613d1357600080fd5b85356001600160401b0380821115613d2a57600080fd5b613d3689838a016139b7565b96506020880135915080821115613d4c57600080fd5b613d5889838a016139b7565b95506040880135915080821115613d6e57600080fd5b613d7a89838a01613c1a565b94506060880135915080821115613d9057600080fd5b613d9c89838a016139b7565b93506080880135915080821115613db257600080fd5b50613dbf88828901613c7c565b9150509295509295909350565b60008060408385031215613ddf57600080fd5b50508035926020909101359150565b600080600080600060a08688031215613e0657600080fd5b8535945060208601359350613e1d60408701613b6e565b92506060860135915060808601356001600160401b03811115613e3f57600080fd5b613dbf888289016139b7565b600080600060608486031215613e6057600080fd5b8335613e6b81613aec565b95602085013595506040909401359392505050565b604080825283519082018190526000906020906060840190828701845b82811015613eb957815184529284019290840190600101613e9d565b50505092019290925292915050565b80151581146112a557600080fd5b600060208284031215613ee857600080fd5b813561394781613ec8565b803563ffffffff81168114613b8557600080fd5b600080600060608486031215613f1c57600080fd5b613f2584613b6e565b9250613f3360208501613b6e565b9150613bc460408501613ef3565b60008060408385031215613f5457600080fd5b613f5d83613b6e565b9150613f6b60208401613b6e565b90509250929050565b60008083601f840112613f8657600080fd5b5081356001600160401b03811115613f9d57600080fd5b6020830191508360208285010111156128c757600080fd5b60008060208385031215613fc857600080fd5b82356001600160401b03811115613fde57600080fd5b613fea85828601613f74565b90969095509350505050565b6000806040838503121561400957600080fd5b823561401481613aec565b91506020830135613c0f81613ec8565b60006001600160401b0382111561403d5761403d61394e565b50601f01601f191660200190565b6000806000806080858703121561406157600080fd5b843561406c81613aec565b9350602085013561407c81613aec565b92506040850135915060608501356001600160401b0381111561409e57600080fd5b8501601f810187136140af57600080fd5b80356140bd6139d882614024565b8181528860208385010111156140d257600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060008060006080868803121561410c57600080fd5b61411586613ef3565b945061412360208701613ef3565b935061413160408701613b6e565b925060608601356001600160401b0381111561414c57600080fd5b61415888828901613f74565b969995985093965092949392505050565b6000806040838503121561417c57600080fd5b823561418781613aec565b91506020830135613c0f81613aec565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156141f4576141f46141cc565b500390565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061422357607f821691505b6020821081036124be57634e487b7160e01b600052602260045260246000fd5b600063ffffffff80831681810361425c5761425c6141cc565b6001019392505050565b60008219821115614279576142796141cc565b500190565b600060018201614290576142906141cc565b5060010190565b6000826142b457634e487b7160e01b600052601260045260246000fd5b500690565b60008160001904831182151516156142d3576142d36141cc565b500290565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600063ffffffff8381169083168181101561432c5761432c6141cc565b039392505050565b60006020828403121561434657600080fd5b81516001600160401b0381111561435c57600080fd5b8201601f8101841361436d57600080fd5b805161437b6139d882614024565b81815285602083850101111561439057600080fd5b6111e5826020830160208601613a68565b66697066733a2f2f60c81b8152600082516143c3816007850160208701613a68565b9190910160070192915050565b60018060a01b03841681528260208201526060604082015260006111e56060830184613a94565b60006020828403121561440957600080fd5b815161394781613ec8565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061444790830184613a94565b9695505050505050565b60006020828403121561446357600080fd5b815161394781613914565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220915286e7b8277fbc158efcc38e68723db9664232eec815b42dd3a9de2c32102764736f6c634300080d003300000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000015be000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986caaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af4450000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000016546561686f75736520486967685461626c65205649500000000000000000000000000000000000000000000000000000000000000000000000000000000000054854564950000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103b85760003560e01c806357019e34116101f2578063b88d4fde1161010d578063e985e9c5116100a0578063f1955ccc1161006f578063f1955ccc14610c07578063f2fde38b14610c80578063f8d8679414610ca0578063fc3f614714610cb657600080fd5b8063e985e9c514610aeb578063eddad33c14610b34578063edfe2e0f14610b54578063f04b5fa014610b6957600080fd5b8063d0a89b08116100dc578063d0a89b0814610a82578063d338143814610a95578063dc33e68114610ab5578063e11c9a2614610ad557600080fd5b8063b88d4fde14610a0c578063c17c3fe314610a2c578063c87b56dd14610a4c578063c9df912c14610a6c57600080fd5b80638da5cb5b1161018557806397bc411c1161015457806397bc411c1461099d578063a035b1fe146109bd578063a22cb465146109d3578063a2309ff8146109f357600080fd5b80638da5cb5b1461092a57806391b7f5ed1461094857806394985ddd1461096857806395d89b411461098857600080fd5b8063715018a6116101c1578063715018a614610867578063767bcab51461087c5780637cb647591461089c578063818f9156146108bc57600080fd5b806357019e34146107e75780636352211e146108075780636df64c1c1461082757806370a082311461084757600080fd5b8063269b7943116102e25780633d444c591161027557806349a0a50e1161024457806349a0a50e146107665780634ad505161461079457806351cff8d9146107b457806353418fa2146107c757600080fd5b80633d444c59146106f057806340261cdd1461070657806342842e0e146107265780634807856a1461074657600080fd5b8063390a5b9a116102b1578063390a5b9a146106855780633ae5213e1461069b5780633b0b1323146106bb5780633c66a815146106d057600080fd5b8063269b7943146105f0578063285ab8c1146106105780632d1a12f61461064557806337b677df1461066557600080fd5b80631017507d1161035a578063220c19c211610329578063220c19c2146105a057806322fde03a146105a857806323b872dd146105c857806326092b83146105e857600080fd5b80631017507d1461054057806314bf9d171461055657806318160ddd146105765780632126ea811461058b57600080fd5b806306fdde031161039657806306fdde0314610438578063081812fc1461045a578063095ea7b3146104925780630fb5b157146104b257600080fd5b806301ffc9a7146103bd57806302b49315146103f2578063041d443e14610414575b600080fd5b3480156103c957600080fd5b506103dd6103d836600461392a565b610d18565b60405190151581526020015b60405180910390f35b3480156103fe57600080fd5b5061041261040d366004613a22565b610d6a565b005b34801561042057600080fd5b5061042a600b5481565b6040519081526020016103e9565b34801561044457600080fd5b5061044d610e1e565b6040516103e99190613ac0565b34801561046657600080fd5b5061047a610475366004613ad3565b610eb0565b6040516001600160a01b0390911681526020016103e9565b34801561049e57600080fd5b506104126104ad366004613b01565b610ef4565b3480156104be57600080fd5b50601954610502906001600160401b0380821691600160401b81049091169063ffffffff600160801b8204811691600160a01b8104821691600160c01b9091041685565b604080516001600160401b03968716815295909416602086015263ffffffff928316938501939093528116606084015216608082015260a0016103e9565b34801561054c57600080fd5b5061042a600c5481565b34801561056257600080fd5b5061042a610571366004613ad3565b610f75565b34801561058257600080fd5b5061042a610f96565b34801561059757600080fd5b5061044d610fa4565b610412611032565b3480156105b457600080fd5b5061042a6105c3366004613ad3565b61114f565b3480156105d457600080fd5b506104126105e3366004613b2d565b61120b565b610412611216565b3480156105fc57600080fd5b5061041261060b366004613b8a565b61138a565b34801561061c57600080fd5b5061063061062b366004613bcd565b611400565b604080519283526020830191909152016103e9565b34801561065157600080fd5b50610412610660366004613bea565b611486565b34801561067157600080fd5b50610412610680366004613cfb565b6114f3565b34801561069157600080fd5b5061042a60115481565b3480156106a757600080fd5b506104126106b6366004613dcc565b61168d565b3480156106c757600080fd5b506104126116c2565b3480156106dc57600080fd5b506104126106eb366004613dee565b6117bc565b3480156106fc57600080fd5b5061042a60135481565b34801561071257600080fd5b50610412610721366004613ad3565b611928565b34801561073257600080fd5b50610412610741366004613b2d565b611a29565b34801561075257600080fd5b50610412610761366004613ad3565b611a44565b34801561077257600080fd5b50610786610781366004613e4b565b611a94565b6040516103e9929190613e80565b3480156107a057600080fd5b506104126107af366004613ed6565b611d31565b6104126107c2366004613bcd565b611d79565b3480156107d357600080fd5b506104126107e2366004613f07565b611eaa565b3480156107f357600080fd5b50610412610802366004613f41565b611f21565b34801561081357600080fd5b5061047a610822366004613ad3565b611f89565b34801561083357600080fd5b5061042a610842366004613ad3565b611f9b565b34801561085357600080fd5b5061042a610862366004613bcd565b611fdc565b34801561087357600080fd5b5061041261202a565b34801561088857600080fd5b50610412610897366004613bcd565b612060565b3480156108a857600080fd5b506104126108b7366004613ad3565b6120d6565b3480156108c857600080fd5b506109056108d7366004613ad3565b601c60205260009081526040902080546001909101546001600160401b03811690600160401b900460ff1683565b604080519384526001600160401b0390921660208401521515908201526060016103e9565b34801561093657600080fd5b506008546001600160a01b031661047a565b34801561095457600080fd5b50610412610963366004613ad3565b612129565b34801561097457600080fd5b50610412610983366004613dcc565b612158565b34801561099457600080fd5b5061044d6121da565b3480156109a957600080fd5b506104126109b8366004613fb5565b6121e9565b3480156109c957600080fd5b5061042a60125481565b3480156109df57600080fd5b506104126109ee366004613ff6565b61221f565b3480156109ff57600080fd5b506000546000190161042a565b348015610a1857600080fd5b50610412610a2736600461404b565b6122b4565b348015610a3857600080fd5b50610412610a47366004613bcd565b6122fe565b348015610a5857600080fd5b5061044d610a67366004613ad3565b61234a565b348015610a7857600080fd5b5061042a60145481565b610412610a903660046140f4565b6124c4565b348015610aa157600080fd5b50610412610ab0366004613bcd565b61268c565b348015610ac157600080fd5b5061042a610ad0366004613bcd565b6126d8565b348015610ae157600080fd5b5061042a60175481565b348015610af757600080fd5b506103dd610b06366004614169565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610b4057600080fd5b50610786610b4f366004613dcc565b612706565b348015610b6057600080fd5b506104126128ce565b348015610b7557600080fd5b50600d54600e54600f54601054610bbd936001600160a01b0390811693811692908116916001600160401b03600160a01b90920482169181169060ff600160401b9091041686565b604080516001600160a01b039788168152958716602087015293909516928401929092526001600160401b03908116606084015216608082015290151560a082015260c0016103e9565b348015610c1357600080fd5b50601a54610c4a906001600160401b0380821691600160401b8104821691600160801b82041690600160c01b900463ffffffff1684565b604080516001600160401b0395861681529385166020850152919093169082015263ffffffff90911660608201526080016103e9565b348015610c8c57600080fd5b50610412610c9b366004613bcd565b612a64565b348015610cac57600080fd5b5061042a60185481565b348015610cc257600080fd5b50610cf9610cd1366004613bcd565b601b6020526000908152604090205460ff808216916101008104821691620100009091041683565b60408051931515845291151560208401521515908201526060016103e9565b60006001600160e01b031982166380ac58cd60e01b1480610d4957506001600160e01b03198216635b5e139f60e01b145b80610d6457506301ffc9a760e01b6001600160e01b03198316145b92915050565b6008546001600160a01b03163314610d9d5760405162461bcd60e51b8152600401610d9490614197565b60405180910390fd5b80518214610dbe5760405163addbf84b60e01b815260040160405180910390fd5b6011548160018351610dd091906141e2565b81518110610de057610de06141f9565b602002602001015114610e065760405163d93aa98160e01b815260040160405180910390fd5b8051610e19906016906020840190613840565b505050565b606060028054610e2d9061420f565b80601f0160208091040260200160405190810160405280929190818152602001828054610e599061420f565b8015610ea65780601f10610e7b57610100808354040283529160200191610ea6565b820191906000526020600020905b815481529060010190602001808311610e8957829003601f168201915b5050505050905090565b6000610ebb82612afc565b610ed8576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610eff82611f89565b9050806001600160a01b0316836001600160a01b031603610f335760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b03821614610f6a57610f4d8133610b06565b610f6a576040516367d9dca160e11b815260040160405180910390fd5b610e19838383612b35565b60168181548110610f8557600080fd5b600091825260209091200154905081565b600154600054036000190190565b60158054610fb19061420f565b80601f0160208091040260200160405190810160405280929190818152602001828054610fdd9061420f565b801561102a5780601f10610fff5761010080835404028352916020019161102a565b820191906000526020600020905b81548152906001019060200180831161100d57829003601f168201915b505050505081565b601980546001600160401b031642108061105d5750805442600160401b9091046001600160401b0316105b1561107b5760405163015cb63b60e41b815260040160405180910390fd5b60185434101561109e5760405163fa47be2b60e01b815260040160405180910390fd5b336000908152601b60205260409020805460ff16156110d057604051630ea075bf60e21b815260040160405180910390fd5b805460ff19166001178155815463ffffffff600160a01b909104168260146110f783614243565b825463ffffffff9182166101009390930a9283029190920219909116179055506040513381527f633ce1c9388c97d7993f137095f9978b0605881949d6640da48ce48504fcaddd906020015b60405180910390a15050565b600061115a82612afc565b61117757604051630a14c4b560e41b815260040160405180910390fd5b6000828152601c60205260408120600181015490916001600160401b03909116908190036111a9575060009392505050565b60005b6016548110156112005781601682815481106111ca576111ca6141f9565b9060005260206000200154106111ee576111e5816001614266565b95945050505050565b806111f88161427e565b9150506111ac565b506000949350505050565b610e19838383612b91565b601154611221610f96565b0361123f5760405163794bb39b60e01b815260040160405180910390fd5b6012543410156112625760405163fa47be2b60e01b815260040160405180910390fd5b601a8054600160801b90046001600160401b03161580159061129557508054600160801b90046001600160401b03164210155b156112a8576112a5336001612d7e565b50565b336000908152601b60205260409020805460ff166112d95760405163aba4733960e01b815260040160405180910390fd5b805462010000900460ff161561130257604051635c81808d60e11b815260040160405180910390fd5b600061130d33611400565b91505042811115611331576040516320f2db8560e01b815260040160405180910390fd5b61133c336001612d7e565b8254600160c01b900463ffffffff1683601861135783614243565b825463ffffffff9182166101009390930a92830291909202199091161790555050805462ff000019166201000017905550565b6008546001600160a01b031633146113b45760405162461bcd60e51b8152600401610d9490614197565b601a80546001600160401b039485166001600160801b031990911617600160401b938516939093029290921767ffffffffffffffff60801b1916600160801b9190931602919091179055565b6019805460175460009283929091601a91849161143591600160801b900463ffffffff16906001600160a01b03891618614297565b8254909150600090611458908390600160401b90046001600160401b03166142b9565b835461146d91906001600160401b0316614266565b905061147a826001614266565b97909650945050505050565b6008546001600160a01b031633146114b05760405162461bcd60e51b8152600401610d9490614197565b601154826114bc610f96565b6114c69190614266565b11156114e55760405163794bb39b60e01b815260040160405180910390fd5b6114ef8183612d7e565b5050565b60145461151357604051633d39c8eb60e11b815260040160405180910390fd5b835185511461153557604051636726d5d560e11b815260040160405180910390fd5b825185511461155757604051636726d5d560e11b815260040160405180910390fd5b815185511461157957604051636726d5d560e11b815260040160405180910390fd5b805185511461159b57604051636726d5d560e11b815260040160405180910390fd5b84516000905b80821015611684576000601c60008985815181106115c1576115c16141f9565b60200260200101518152602001908152602001600020905080600001546000801b03611671576116718884815181106115fc576115fc6141f9565b6020026020010151888581518110611616576116166141f9565b6020026020010151888681518110611630576116306141f9565b602002602001015188878151811061164a5761164a6141f9565b6020026020010151888881518110611664576116646141f9565b60200260200101516117bc565b508161167c8161427e565b9250506115a1565b50505050505050565b6008546001600160a01b031633146116b75760405162461bcd60e51b8152600401610d9490614197565b600b91909155600c55565b6008546001600160a01b031633146116ec5760405162461bcd60e51b8152600401610d9490614197565b60026009540361170e5760405162461bcd60e51b8152600401610d94906142d8565b600260095560198054600160401b90046001600160401b0316421015611747576040516343698abd60e11b815260040160405180910390fd5b601754156117685760405163a21f7b7f60e01b815260040160405180910390fd5b6000611778600b54600c54612d98565b90507f8a9bace5c88f7bb841bb0d7e705b9afdbf85f3a1693cc681070cb06dcb984fc7816040516117ab91815260200190565b60405180910390a150506001600955565b600f546001600160a01b031633146117e75760405163572b2f3160e01b815260040160405180910390fd5b60145461180757604051633d39c8eb60e11b815260040160405180910390fd5b6000858152601c6020526040902060010154600160401b900460ff1661184057604051633674210b60e01b815260040160405180910390fd5b6000858152601c6020526040902080541561186e576040516305a049a960e41b815260040160405180910390fd5b6040805160208082018890526001600160401b03871682840152606080830187905283518084039091018152608090920190925280519101206014546118b690849083612f1c565b6118d357604051633fec49b760e01b815260040160405180910390fd5b85825560018201805467ffffffffffffffff19166001600160401b03871617905560405187907f15120e52505e619cbf6c2af910d5cf7f9ee1befa55801b078c33e93880b2d60990600090a250505050505050565b601054600160401b900460ff16611952576040516344300a9960e01b815260040160405180910390fd5b3361195c82611f89565b6001600160a01b03161461198357604051634fb693d160e11b815260040160405180910390fd5b6000818152601c6020526040902060010154600160401b900460ff16156119bd57604051633383b7e560e21b815260040160405180910390fd5b6014546119dd57604051633d39c8eb60e11b815260040160405180910390fd5b6000818152601c6020526040808220600101805460ff60401b1916600160401b1790555182917f63e414cbfeae599c8bf0173052f72173257ad08c1c0b49eed829a02a9368395691a250565b610e19838383604051806020016040528060008152506122b4565b6008546001600160a01b03163314611a6e5760405162461bcd60e51b8152600401610d9490614197565b60135415611a8f5760405163e602438d60e01b815260040160405180910390fd5b601355565b6060600082600003611ab2576001600054611aaf91906141e2565b92505b6001841080611ac357506000548310155b15611ae1576040516329c8c00760e21b815260040160405180910390fd5b600080611aed87611fdc565b905080600003611b1c57604080516000815260208101909152611b11866001614266565b935093505050611d29565b610100811115611b2b57506101005b6000816001600160401b03811115611b4557611b4561394e565b604051908082528060200260200182016040528015611b6e578160200160208202803683370190505b509050600080611b7d89611f89565b90508894505b878511611c76576000858152600460205260409020546001600160a01b031615611bc157506000848152600460205260409020546001600160a01b03165b600085815260046020526040902054600160e01b900460ff16158015611bf85750896001600160a01b0316816001600160a01b0316145b15611c645784838381518110611c1057611c106141f9565b602090810291909101015281611c258161427e565b925050838203611c6457611c388a611fdc565b8403611c585782611c4a896001614266565b965096505050505050611d29565b82611c4a866001614266565b84611c6e8161427e565b955050611b83565b6000826001600160401b03811115611c9057611c9061394e565b604051908082528060200260200182016040528015611cb9578160200160208202803683370190505b509050600095505b82861015611d1257838681518110611cdb57611cdb6141f9565b6020026020010151818781518110611cf557611cf56141f9565b602090810291909101015285611d0a8161427e565b965050611cc1565b80611d1e8a6001614266565b975097505050505050505b935093915050565b6008546001600160a01b03163314611d5b5760405162461bcd60e51b8152600401610d9490614197565b60108054911515600160401b0260ff60401b19909216919091179055565b6008546001600160a01b03163314611da35760405162461bcd60e51b8152600401610d9490614197565b600260095403611dc55760405162461bcd60e51b8152600401610d94906142d8565b600260095560198054601a805490929160009163ffffffff600160c01b808404821693611e019391909104821691600160a01b9091041661430f565b611e0b919061430f565b63ffffffff16601854611e1e91906142b9565b611e2890476141e2565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114611e77576040519150601f19603f3d011682016040523d82523d6000602084013e611e7c565b606091505b5050905080611e9e57604051634abd53ef60e11b815260040160405180910390fd5b50506001600955505050565b6008546001600160a01b03163314611ed45760405162461bcd60e51b8152600401610d9490614197565b6019805463ffffffff909216600160801b0263ffffffff60801b196001600160401b03948516600160401b026001600160801b031990941694909516939093179190911792909216179055565b6008546001600160a01b03163314611f4b5760405162461bcd60e51b8152600401610d9490614197565b600f805467ffffffffffffffff60a01b1916600160a01b6001600160401b03948516021790556010805467ffffffffffffffff191691909216179055565b6000611f9482612f32565b5192915050565b6000611fa682612afc565b611fc357604051630a14c4b560e41b815260040160405180910390fd5b6013548211611fd457506001919050565b506002919050565b60006001600160a01b038216612005576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b031633146120545760405162461bcd60e51b8152600401610d9490614197565b61205e6000613054565b565b6008546001600160a01b0316331461208a5760405162461bcd60e51b8152600401610d9490614197565b600e546001600160a01b0316156120b457604051637605a66760e11b815260040160405180910390fd5b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b031633146121005760405162461bcd60e51b8152600401610d9490614197565b6014541561212457604051600162b055f360e01b0319815260040160405180910390fd5b601455565b6008546001600160a01b031633146121535760405162461bcd60e51b8152600401610d9490614197565b601255565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795216146121d05760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610d94565b6114ef82826130a6565b606060038054610e2d9061420f565b6008546001600160a01b031633146122135760405162461bcd60e51b8152600401610d9490614197565b610e196015838361388b565b336001600160a01b038316036122485760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6122bf848484612b91565b6001600160a01b0383163b156122f8576122db848484846130db565b6122f8576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6008546001600160a01b031633146123285760405162461bcd60e51b8152600401610d9490614197565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b606061235582612afc565b61237257604051630a14c4b560e41b815260040160405180910390fd5b6000828152601c60205260408120805490910361241c57601580546123969061420f565b80601f01602080910402602001604051908101604052809291908181526020018280546123c29061420f565b801561240f5780601f106123e45761010080835404028352916020019161240f565b820191906000526020600020905b8154815290600101906020018083116123f257829003601f168201915b5050505050915050919050565b8054604051638614c2c360e01b81526004810182905273de22f3a62b3cff575f20614f33c0c65adcb9470290638614c2c390602401600060405180830381865af415801561246e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526124969190810190614334565b6040516020016124a691906143a1565b60405160208183030381529060405292505050919050565b50919050565b6011548563ffffffff166124d6610f96565b6124e09190614266565b11156124ff5760405163794bb39b60e01b815260040160405180910390fd5b600f54600160a01b90046001600160401b03164210156125325760405163ef4604b360e01b815260040160405180910390fd5b6010546001600160401b031642111561255e57604051633e17626f60e01b815260040160405180910390fd5b826001600160401b0316421115612588576040516338e5e54b60e21b815260040160405180910390fd5b3360009081526005602052604090205463ffffffff858116916125bd91881690600160401b90046001600160401b0316614266565b11156125dc57604051635c81808d60e11b815260040160405180910390fd5b61261e33858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506131c692505050565b61263b5760405163c1606c2f60e01b815260040160405180910390fd5b60008563ffffffff1660125461265191906142b9565b9050803410156126745760405163fa47be2b60e01b815260040160405180910390fd5b612684338763ffffffff16612d7e565b505050505050565b6008546001600160a01b031633146126b65760405162461bcd60e51b8152600401610d9490614197565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116600090815260056020526040812054600160401b90046001600160401b0316610d64565b606060008260000361272457600160005461272191906141e2565b92505b600184108061273557506000548310155b15612753576040516329c8c00760e21b815260040160405180910390fd5b604080516101008082526120208201909252600091829190602082016120008036833701905050905060008692505b858311612816576000838152601c602052604090206001810154600160401b900460ff1680156127b157508054155b1561280357838383815181106127c9576127c96141f9565b6020908102919091010152816127de8161427e565b925050816101000361280357826127f6856001614266565b95509550505050506128c7565b508261280e8161427e565b935050612782565b6000816001600160401b038111156128305761283061394e565b604051908082528060200260200182016040528015612859578160200160208202803683370190505b509050600093505b818410156128b25782848151811061287b5761287b6141f9565b6020026020010151818581518110612895576128956141f9565b6020908102919091010152836128aa8161427e565b945050612861565b806128be886001614266565b95509550505050505b9250929050565b6002600954036128f05760405162461bcd60e51b8152600401610d94906142d8565b6002600955601154612900610f96565b1461291e5760405163089c998760e01b815260040160405180910390fd5b336000908152601b60205260409020805460ff1615806129455750805462010000900460ff165b8061295657508054610100900460ff165b1561297457604051631124896d60e01b815260040160405180910390fd5b805461ff0019166101001781556019805463ffffffff600160c01b9091041690601861299f83614243565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000336001600160a01b031660185460405160006040518083038185875af1925050503d8060008114612a0d576040519150601f19603f3d011682016040523d82523d6000602084013e612a12565b606091505b5050905080612a34576040516327304f5160e21b815260040160405180910390fd5b6040513381527fcada6d5a24d75e568453894e32683a8a5e6421131f8df496749af47c49a93287906020016117ab565b6008546001600160a01b03163314612a8e5760405162461bcd60e51b8152600401610d9490614197565b6001600160a01b038116612af35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d94565b6112a581613054565b600081600111158015612b10575060005482105b8015610d64575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000612b9c82612f32565b9050836001600160a01b031681600001516001600160a01b031614612bd35760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b0386161480612bf15750612bf18533610b06565b80612c0c575033612c0184610eb0565b6001600160a01b0316145b905080612c2c57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038416612c5357604051633a954ecd60e21b815260040160405180910390fd5b612c5f60008487612b35565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b42909216919091021783558701808452922080549193909116612d33576000548214612d3357805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b6114ef8282604051806020016040528060008152506132b0565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795284866000604051602001612e08929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612e35939291906143d0565b6020604051808303816000875af1158015612e54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e7891906143f7565b506000838152600a6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a090910190925281519183019190912093879052919052612ed4906001614266565b6000858152600a6020526040902055612f148482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b949350505050565b600082612f298584613469565b14949350505050565b6040805160608101825260008082526020820181905291810191909152818060011161303b5760005481101561303b57600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906130395780516001600160a01b031615612fd0579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215613034579392505050565b612fd0565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60178190556040518181527ffd1fb69f924fc6339f4afd97c8dd1188e95739807f6286074e37bdd28562033890602001611143565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290613110903390899088908890600401614414565b6020604051808303816000875af192505050801561314b575060408051601f3d908101601f1916820190925261314891810190614451565b60015b6131a9573d808015613179576040519150601f19603f3d011682016040523d82523d6000602084013e61317e565b606091505b5080516000036131a1576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b604080516bffffffffffffffffffffffff19606087901b1660208201526001600160e01b031960e086901b1660348201526001600160c01b031960c085901b1660388201526000918291016040516020818303038152906040528051906020012090506000613282826040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b600d549091506001600160a01b031661329b82866134dd565b6001600160a01b031614979650505050505050565b6000546001600160a01b0384166132d957604051622e076360e81b815260040160405180910390fd5b826000036132fa5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260056020908152604080832080546001600160801b031981166001600160401b038083168b018116918217600160401b67ffffffffffffffff1990941690921783900481168b01811690920217909155858452600490925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b15613414575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46133dd60008784806001019550876130db565b6133fa576040516368d2bf6b60e11b815260040160405180910390fd5b80821061339257826000541461340f57600080fd5b613459565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210613415575b5060009081556122f89085838684565b600081815b84518110156134d557600085828151811061348b5761348b6141f9565b602002602001015190508083116134b157600083815260208290526040902092506134c2565b600081815260208490526040902092505b50806134cd8161427e565b91505061346e565b509392505050565b60008060006134ec85856134f9565b915091506134d581613564565b600080825160410361352f5760208301516040840151606085015160001a6135238782858561371a565b945094505050506128c7565b8251604003613558576020830151604084015161354d868383613807565b9350935050506128c7565b506000905060026128c7565b60008160048111156135785761357861446e565b036135805750565b60018160048111156135945761359461446e565b036135e15760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610d94565b60028160048111156135f5576135f561446e565b036136425760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610d94565b60038160048111156136565761365661446e565b036136ae5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610d94565b60048160048111156136c2576136c261446e565b036112a55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610d94565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561375157506000905060036137fe565b8460ff16601b1415801561376957508460ff16601c14155b1561377a57506000905060046137fe565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156137ce573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166137f7576000600192509250506137fe565b9150600090505b94509492505050565b6000806001600160ff1b0383168161382460ff86901c601b614266565b90506138328782888561371a565b935093505050935093915050565b82805482825590600052602060002090810192821561387b579160200282015b8281111561387b578251825591602001919060010190613860565b506138879291506138ff565b5090565b8280546138979061420f565b90600052602060002090601f0160209004810192826138b9576000855561387b565b82601f106138d25782800160ff1982351617855561387b565b8280016001018555821561387b579182015b8281111561387b5782358255916020019190600101906138e4565b5b808211156138875760008155600101613900565b6001600160e01b0319811681146112a557600080fd5b60006020828403121561393c57600080fd5b813561394781613914565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561398c5761398c61394e565b604052919050565b60006001600160401b038211156139ad576139ad61394e565b5060051b60200190565b600082601f8301126139c857600080fd5b813560206139dd6139d883613994565b613964565b82815260059290921b840181019181810190868411156139fc57600080fd5b8286015b84811015613a175780358352918301918301613a00565b509695505050505050565b60008060408385031215613a3557600080fd5b8235915060208301356001600160401b03811115613a5257600080fd5b613a5e858286016139b7565b9150509250929050565b60005b83811015613a83578181015183820152602001613a6b565b838111156122f85750506000910152565b60008151808452613aac816020860160208601613a68565b601f01601f19169290920160200192915050565b6020815260006139476020830184613a94565b600060208284031215613ae557600080fd5b5035919050565b6001600160a01b03811681146112a557600080fd5b60008060408385031215613b1457600080fd5b8235613b1f81613aec565b946020939093013593505050565b600080600060608486031215613b4257600080fd5b8335613b4d81613aec565b92506020840135613b5d81613aec565b929592945050506040919091013590565b80356001600160401b0381168114613b8557600080fd5b919050565b600080600060608486031215613b9f57600080fd5b613ba884613b6e565b9250613bb660208501613b6e565b9150613bc460408501613b6e565b90509250925092565b600060208284031215613bdf57600080fd5b813561394781613aec565b60008060408385031215613bfd57600080fd5b823591506020830135613c0f81613aec565b809150509250929050565b600082601f830112613c2b57600080fd5b81356020613c3b6139d883613994565b82815260059290921b84018101918181019086841115613c5a57600080fd5b8286015b84811015613a1757613c6f81613b6e565b8352918301918301613c5e565b600082601f830112613c8d57600080fd5b81356020613c9d6139d883613994565b82815260059290921b84018101918181019086841115613cbc57600080fd5b8286015b84811015613a175780356001600160401b03811115613cdf5760008081fd5b613ced8986838b01016139b7565b845250918301918301613cc0565b600080600080600060a08688031215613d1357600080fd5b85356001600160401b0380821115613d2a57600080fd5b613d3689838a016139b7565b96506020880135915080821115613d4c57600080fd5b613d5889838a016139b7565b95506040880135915080821115613d6e57600080fd5b613d7a89838a01613c1a565b94506060880135915080821115613d9057600080fd5b613d9c89838a016139b7565b93506080880135915080821115613db257600080fd5b50613dbf88828901613c7c565b9150509295509295909350565b60008060408385031215613ddf57600080fd5b50508035926020909101359150565b600080600080600060a08688031215613e0657600080fd5b8535945060208601359350613e1d60408701613b6e565b92506060860135915060808601356001600160401b03811115613e3f57600080fd5b613dbf888289016139b7565b600080600060608486031215613e6057600080fd5b8335613e6b81613aec565b95602085013595506040909401359392505050565b604080825283519082018190526000906020906060840190828701845b82811015613eb957815184529284019290840190600101613e9d565b50505092019290925292915050565b80151581146112a557600080fd5b600060208284031215613ee857600080fd5b813561394781613ec8565b803563ffffffff81168114613b8557600080fd5b600080600060608486031215613f1c57600080fd5b613f2584613b6e565b9250613f3360208501613b6e565b9150613bc460408501613ef3565b60008060408385031215613f5457600080fd5b613f5d83613b6e565b9150613f6b60208401613b6e565b90509250929050565b60008083601f840112613f8657600080fd5b5081356001600160401b03811115613f9d57600080fd5b6020830191508360208285010111156128c757600080fd5b60008060208385031215613fc857600080fd5b82356001600160401b03811115613fde57600080fd5b613fea85828601613f74565b90969095509350505050565b6000806040838503121561400957600080fd5b823561401481613aec565b91506020830135613c0f81613ec8565b60006001600160401b0382111561403d5761403d61394e565b50601f01601f191660200190565b6000806000806080858703121561406157600080fd5b843561406c81613aec565b9350602085013561407c81613aec565b92506040850135915060608501356001600160401b0381111561409e57600080fd5b8501601f810187136140af57600080fd5b80356140bd6139d882614024565b8181528860208385010111156140d257600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060008060006080868803121561410c57600080fd5b61411586613ef3565b945061412360208701613ef3565b935061413160408701613b6e565b925060608601356001600160401b0381111561414c57600080fd5b61415888828901613f74565b969995985093965092949392505050565b6000806040838503121561417c57600080fd5b823561418781613aec565b91506020830135613c0f81613aec565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156141f4576141f46141cc565b500390565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061422357607f821691505b6020821081036124be57634e487b7160e01b600052602260045260246000fd5b600063ffffffff80831681810361425c5761425c6141cc565b6001019392505050565b60008219821115614279576142796141cc565b500190565b600060018201614290576142906141cc565b5060010190565b6000826142b457634e487b7160e01b600052601260045260246000fd5b500690565b60008160001904831182151516156142d3576142d36141cc565b500290565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600063ffffffff8381169083168181101561432c5761432c6141cc565b039392505050565b60006020828403121561434657600080fd5b81516001600160401b0381111561435c57600080fd5b8201601f8101841361436d57600080fd5b805161437b6139d882614024565b81815285602083850101111561439057600080fd5b6111e5826020830160208601613a68565b66697066733a2f2f60c81b8152600082516143c3816007850160208701613a68565b9190910160070192915050565b60018060a01b03841681528260208201526060604082015260006111e56060830184613a94565b60006020828403121561440957600080fd5b815161394781613ec8565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061444790830184613a94565b9695505050505050565b60006020828403121561446357600080fd5b815161394781613914565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220915286e7b8277fbc158efcc38e68723db9664232eec815b42dd3a9de2c32102764736f6c634300080d0033

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

00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000015be000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986caaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af4450000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000016546561686f75736520486967685461626c65205649500000000000000000000000000000000000000000000000000000000000000000000000000000000000054854564950000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): Teahouse HighTable VIP
Arg [1] : _symbol (string): HTVIP
Arg [2] : _maxCollection (uint256): 5566
Arg [3] : _vrfCoordinator (address): 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952
Arg [4] : _linkToken (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [5] : _vrfKeyHash (bytes32): 0xaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445
Arg [6] : _vrfFee (uint256): 2000000000000000000

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 00000000000000000000000000000000000000000000000000000000000015be
Arg [3] : 000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952
Arg [4] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [5] : aa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445
Arg [6] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000016
Arg [8] : 546561686f75736520486967685461626c652056495000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [10] : 4854564950000000000000000000000000000000000000000000000000000000


Libraries Used


Deployed Bytecode Sourcemap

78441:24808:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55853:305;;;;;;;;;;-1:-1:-1;55853:305:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;55853:305:0;;;;;;;;97923:356;;;;;;;;;;-1:-1:-1;97923:356:0;;;;;:::i;:::-;;:::i;:::-;;79509:25;;;;;;;;;;;;;;;;;;;2426::1;;;2414:2;2399:18;79509:25:0;2280:177:1;58968:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;60472:204::-;;;;;;;;;;-1:-1:-1;60472:204:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3562:32:1;;;3544:51;;3532:2;3517:18;60472:204:0;3398:203:1;60034:372:0;;;;;;;;;;-1:-1:-1;60034:372:0;;;;;:::i;:::-;;:::i;79922:28::-;;;;;;;;;;-1:-1:-1;79922:28:0;;;;-1:-1:-1;;;;;79922:28:0;;;;-1:-1:-1;;;79922:28:0;;;;;;;-1:-1:-1;;;79922:28:0;;;;;-1:-1:-1;;;79922:28:0;;;;;-1:-1:-1;;;79922:28:0;;;;;;;;;;-1:-1:-1;;;;;4366:15:1;;;4348:34;;4418:15;;;;4413:2;4398:18;;4391:43;4453:10;4499:15;;;4479:18;;;4472:43;;;;4551:15;;4546:2;4531:18;;4524:43;4604:15;4598:3;4583:19;;4576:44;4298:3;4283:19;79922:28:0;4062:564:1;79541:21:0;;;;;;;;;;;;;;;;79795:31;;;;;;;;;;-1:-1:-1;79795:31:0;;;;;:::i;:::-;;:::i;55093:312::-;;;;;;;;;;;;;:::i;79763:25::-;;;;;;;;;;;;;:::i;90027:639::-;;;:::i;98477:559::-;;;;;;;;;;-1:-1:-1;98477:559:0;;;;;:::i;:::-;;:::i;61337:170::-;;;;;;;;;;-1:-1:-1;61337:170:0;;;;;:::i;:::-;;:::i;88755:993::-;;;:::i;85685:443::-;;;;;;;;;;-1:-1:-1;85685:443:0;;;;;:::i;:::-;;:::i;91693:511::-;;;;;;;;;;-1:-1:-1;91693:511:0;;;;;:::i;:::-;;:::i;:::-;;;;6209:25:1;;;6265:2;6250:18;;6243:34;;;;6182:18;91693:511:0;6035:248:1;88245:191:0;;;;;;;;;;-1:-1:-1;88245:191:0;;;;;:::i;:::-;;:::i;95251:1306::-;;;;;;;;;;-1:-1:-1;95251:1306:0;;;;;:::i;:::-;;:::i;79606:28::-;;;;;;;;;;;;;;;;81246:153;;;;;;;;;;-1:-1:-1;81246:153:0;;;;;:::i;:::-;;:::i;90817:446::-;;;;;;;;;;;;;:::i;94175:781::-;;;;;;;;;;-1:-1:-1;94175:781:0;;;;;:::i;:::-;;:::i;79683:37::-;;;;;;;;;;;;;;;;93374:481;;;;;;;;;;-1:-1:-1;93374:481:0;;;;;:::i;:::-;;:::i;61578:185::-;;;;;;;;;;-1:-1:-1;61578:185:0;;;;;:::i;:::-;;:::i;82536:211::-;;;;;;;;;;-1:-1:-1;82536:211:0;;;;;:::i;:::-;;:::i;99342:1522::-;;;;;;;;;;-1:-1:-1;99342:1522:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;84586:118::-;;;;;;;;;;-1:-1:-1;84586:118:0;;;;;:::i;:::-;;:::i;102472:508::-;;;;;;:::i;:::-;;:::i;84993:405::-;;;;;;;;;;-1:-1:-1;84993:405:0;;;;;:::i;:::-;;:::i;82151:255::-;;;;;;;;;;-1:-1:-1;82151:255:0;;;;;:::i;:::-;;:::i;58776:125::-;;;;;;;;;;-1:-1:-1;58776:125:0;;;;;:::i;:::-;;:::i;82872:262::-;;;;;;;;;;-1:-1:-1;82872:262:0;;;;;:::i;:::-;;:::i;56222:206::-;;;;;;;;;;-1:-1:-1;56222:206:0;;;;;:::i;:::-;;:::i;76380:103::-;;;;;;;;;;;;;:::i;84207:200::-;;;;;;;;;;-1:-1:-1;84207:200:0;;;;;:::i;:::-;;:::i;83787:198::-;;;;;;;;;;-1:-1:-1;83787:198:0;;;;;:::i;:::-;;:::i;80137:58::-;;;;;;;;;;-1:-1:-1;80137:58:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;80137:58:0;;;-1:-1:-1;;;80137:58:0;;;;;;;;;;13259:25:1;;;-1:-1:-1;;;;;13320:31:1;;;13315:2;13300:18;;13293:59;13395:14;13388:22;13368:18;;;13361:50;13247:2;13232:18;80137:58:0;13065:352:1;75729:87:0;;;;;;;;;;-1:-1:-1;75802:6:0;;-1:-1:-1;;;;;75802:6:0;75729:87;;81530:92;;;;;;;;;;-1:-1:-1;81530:92:0;;;;;:::i;:::-;;:::i;34792:210::-;;;;;;;;;;-1:-1:-1;34792:210:0;;;;;:::i;:::-;;:::i;59137:104::-;;;;;;;;;;;;;:::i;83522:108::-;;;;;;;;;;-1:-1:-1;83522:108:0;;;;;:::i;:::-;;:::i;79641:35::-;;;;;;;;;;;;;;;;60748:287;;;;;;;;;;-1:-1:-1;60748:287:0;;;;;:::i;:::-;;:::i;97313:102::-;;;;;;;;;;-1:-1:-1;97359:14:0;55731:13;-1:-1:-1;;55731:31:0;97313:102;;61834:370;;;;;;;;;;-1:-1:-1;61834:370:0;;;;;:::i;:::-;;:::i;83269:115::-;;;;;;;;;;-1:-1:-1;83269:115:0;;;;;:::i;:::-;;:::i;96678:516::-;;;;;;;;;;-1:-1:-1;96678:516:0;;;;;:::i;:::-;;:::i;79727:29::-;;;;;;;;;;;;;;;;87018:1046;;;;;;:::i;:::-;;:::i;81778:143::-;;;;;;;;;;-1:-1:-1;81778:143:0;;;;;:::i;:::-;;:::i;97605:126::-;;;;;;;;;;-1:-1:-1;97605:126:0;;;;;:::i;:::-;;:::i;79835:31::-;;;;;;;;;;;;;;;;61106:164;;;;;;;;;;-1:-1:-1;61106:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;61227:25:0;;;61203:4;61227:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;61106:164;101193:1059;;;;;;;;;;-1:-1:-1;101193:1059:0;;;;;:::i;:::-;;:::i;92485:626::-;;;;;;;;;;;;;:::i;79571:28::-;;;;;;;;;;-1:-1:-1;79571:28:0;;;;;;;;;;-1:-1:-1;;;;;79571:28:0;;;;;;;;;;;-1:-1:-1;;;;;;;;79571:28:0;;;;;;;;;;-1:-1:-1;;;79571:28:0;;;;;;;;;;-1:-1:-1;;;;;17401:15:1;;;17383:34;;17453:15;;;17448:2;17433:18;;17426:43;17505:15;;;;17485:18;;;17478:43;;;;-1:-1:-1;;;;;17594:15:1;;;17589:2;17574:18;;17567:43;17647:15;17641:3;17626:19;;17619:44;17707:14;;17700:22;17363:3;17679:19;;17672:51;17332:3;17317:19;79571:28:0;17068:661:1;79957:36:0;;;;;;;;;;-1:-1:-1;79957:36:0;;;;-1:-1:-1;;;;;79957:36:0;;;;-1:-1:-1;;;79957:36:0;;;;;-1:-1:-1;;;79957:36:0;;;;-1:-1:-1;;;79957:36:0;;;;;;;;;;-1:-1:-1;;;;;18012:15:1;;;17994:34;;18064:15;;;18059:2;18044:18;;18037:43;18116:15;;;;18096:18;;;18089:43;18180:10;18168:23;;;18163:2;18148:18;;18141:51;17944:3;17929:19;79957:36:0;17734:464:1;76638:201:0;;;;;;;;;;-1:-1:-1;76638:201:0;;;;;:::i;:::-;;:::i;79873:42::-;;;;;;;;;;;;;;;;80060:70;;;;;;;;;;-1:-1:-1;80060:70:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18412:14:1;;18405:22;18387:41;;18471:14;;18464:22;18459:2;18444:18;;18437:50;18530:14;18523:22;18503:18;;;18496:50;18375:2;18360:18;80060:70:0;18203:349:1;55853:305:0;55955:4;-1:-1:-1;;;;;;55992:40:0;;-1:-1:-1;;;55992:40:0;;:105;;-1:-1:-1;;;;;;;56049:48:0;;-1:-1:-1;;;56049:48:0;55992:105;:158;;;-1:-1:-1;;;;;;;;;;13498:40:0;;;56114:36;55972:178;55853:305;-1:-1:-1;;55853:305:0:o;97923:356::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;;;;;;;;;98063:15:::1;:22;98041:18;:44;98037:82;;98094:25;;-1:-1:-1::0;;;98094:25:0::1;;;;;;;;;;;98037:82;98181:13;;98134:15;98175:1;98150:15;:22;:26;;;;:::i;:::-;98134:43;;;;;;;;:::i;:::-;;;;;;;:60;98130:96;;98203:23;;-1:-1:-1::0;;;98203:23:0::1;;;;;;;;;;;98130:96;98239:32:::0;;::::1;::::0;:14:::1;::::0;:32:::1;::::0;::::1;::::0;::::1;:::i;:::-;;97923:356:::0;;:::o;58968:100::-;59022:13;59055:5;59048:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58968:100;:::o;60472:204::-;60540:7;60565:16;60573:7;60565;:16::i;:::-;60560:64;;60590:34;;-1:-1:-1;;;60590:34:0;;;;;;;;;;;60560:64;-1:-1:-1;60644:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;60644:24:0;;60472:204::o;60034:372::-;60107:13;60123:24;60139:7;60123:15;:24::i;:::-;60107:40;;60168:5;-1:-1:-1;;;;;60162:11:0;:2;-1:-1:-1;;;;;60162:11:0;;60158:48;;60182:24;;-1:-1:-1;;;60182:24:0;;;;;;;;;;;60158:48;52870:10;-1:-1:-1;;;;;60223:21:0;;;60219:139;;60250:37;60267:5;52870:10;61106:164;:::i;60250:37::-;60246:112;;60311:35;;-1:-1:-1;;;60311:35:0;;;;;;;;;;;60246:112;60370:28;60379:2;60383:7;60392:5;60370:8;:28::i;79795:31::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79795:31:0;:::o;55093:312::-;103116:1;55356:12;55146:7;55340:13;:28;-1:-1:-1;;55340:46:0;;55093:312::o;79763:25::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;90027:639::-;90119:10;90162:34;;-1:-1:-1;;;;;90162:34:0;90144:15;:52;;:106;;-1:-1:-1;90200:32:0;;90235:15;-1:-1:-1;;;90200:32:0;;;-1:-1:-1;;;;;90200:32:0;:50;90144:106;90140:146;;;90259:27;;-1:-1:-1;;;90259:27:0;;;;;;;;;;;90140:146;90313:11;;90301:9;:23;90297:58;;;90333:22;;-1:-1:-1;;;90333:22:0;;;;;;;;;;;90297:58;90434:10;90368:41;90412:33;;;:21;:33;;;;;90460:28;;;;90456:60;;;90497:19;;-1:-1:-1;;;90497:19:0;;;;;;;;;;;90456:60;90529:35;;-1:-1:-1;;90529:35:0;90560:4;90529:35;;;90575:37;;;-1:-1:-1;;;90575:37:0;;;;:16;:35;:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90630:28:0;;90647:10;3544:51:1;;90630:28:0;;3532:2:1;3517:18;90630:28:0;;;;;;;;90070:596;;90027:639::o;98477:559::-;98540:7;98565:17;98573:8;98565:7;:17::i;:::-;98560:60;;98591:29;;-1:-1:-1;;;98591:29:0;;;;;;;;;;;98560:60;98633:33;98669:25;;;:15;:25;;;;;98721:15;;;;98669:25;;-1:-1:-1;;;;;98721:15:0;;;;98753:10;;;98749:51;;-1:-1:-1;98787:1:0;;98477:559;-1:-1:-1;;;98477:559:0:o;98749:51::-;98817:9;98812:157;98836:14;:21;98832:25;;98812:157;;;98904:5;98883:14;98898:1;98883:17;;;;;;;;:::i;:::-;;;;;;;;;:26;98879:79;;98937:5;:1;98941;98937:5;:::i;:::-;98930:12;98477:559;-1:-1:-1;;;;;98477:559:0:o;98879:79::-;98859:3;;;;:::i;:::-;;;;98812:157;;;-1:-1:-1;99027:1:0;;98477:559;-1:-1:-1;;;;98477:559:0:o;61337:170::-;61471:28;61481:4;61487:2;61491:7;61471:9;:28::i;88755:993::-;88826:13;;88809;:11;:13::i;:::-;:30;88805:61;;88848:18;;-1:-1:-1;;;88848:18:0;;;;;;;;;;;88805:61;88893:5;;88881:9;:17;88877:52;;;88907:22;;-1:-1:-1;;;88907:22:0;;;;;;;;;;;88877:52;88988:14;89017:41;;-1:-1:-1;;;89017:41:0;;-1:-1:-1;;;;;89017:41:0;:45;;;;:109;;-1:-1:-1;89085:41:0;;-1:-1:-1;;;89085:41:0;;-1:-1:-1;;;;;89085:41:0;89066:15;:60;;89017:109;89013:189;;;89143:24;89153:10;89165:1;89143:9;:24::i;:::-;89184:7;88755:993::o;89013:189::-;89280:10;89214:41;89258:33;;;:21;:33;;;;;89307:28;;;;89302:57;;89344:15;;-1:-1:-1;;;89344:15:0;;;;;;;;;;;89302:57;89374:24;;;;;;;89370:65;;;89407:28;;-1:-1:-1;;;89407:28:0;;;;;;;;;;;89370:65;89448:17;89492:31;89512:10;89492:19;:31::i;:::-;89476:47;-1:-1:-1;;89548:15:0;:27;-1:-1:-1;89544:63:0;;;89584:23;;-1:-1:-1;;;89584:23:0;;;;;;;;;;;89544:63;89620:24;89630:10;89642:1;89620:9;:24::i;:::-;89655:43;;-1:-1:-1;;;89655:43:0;;;;;:41;:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;89709:31:0;;-1:-1:-1;;89709:31:0;;;;;-1:-1:-1;88755:993:0:o;85685:443::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;85882:14:::1;85909:63:::0;;-1:-1:-1;;;;;85909:63:0;;::::1;-1:-1:-1::0;;;;;;85983:61:0;;;;-1:-1:-1;;;85983:61:0;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;86055:65:0::1;-1:-1:-1::0;;;86055:65:0;;;::::1;;::::0;;;::::1;::::0;;85685:443::o;91693:511::-;91828:10;92013:30;;91954:16;;91761:7;;;;91828:10;;91895:14;;91761:7;;91938:105;;-1:-1:-1;;;92013:30:0;;;;;-1:-1:-1;;;;;91982:26:0;;91946:63;91938:105;:::i;:::-;92112:39;;91922:121;;-1:-1:-1;92054:12:0;;92112:47;;91922:121;;-1:-1:-1;;;92112:39:0;;-1:-1:-1;;;;;92112:39:0;:47;:::i;:::-;92069:40;;:90;;;-1:-1:-1;;;;;92069:40:0;:90;:::i;:::-;92054:105;-1:-1:-1;92180:9:0;:5;92188:1;92180:9;:::i;:::-;92172:24;92191:4;;-1:-1:-1;91693:511:0;-1:-1:-1;;;;;91693:511:0:o;88245:191::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;88352:13:::1;;88342:7;88326:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:39;88322:70;;;88374:18;;-1:-1:-1::0;;;88374:18:0::1;;;;;;;;;;;88322:70;88405:23;88415:3;88420:7;88405:9;:23::i;:::-;88245:191:::0;;:::o;95251:1306::-;95441:14;;95437:63;;95478:22;;-1:-1:-1;;;95478:22:0;;;;;;;;;;;95437:63;95535:19;:26;95515:9;:16;:46;95511:86;;95570:27;;-1:-1:-1;;;95570:27:0;;;;;;;;;;;95511:86;95632:8;:15;95612:9;:16;:35;95608:75;;95656:27;;-1:-1:-1;;;95656:27:0;;;;;;;;;;;95608:75;95718:6;:13;95698:9;:16;:33;95694:73;;95740:27;;-1:-1:-1;;;95740:27:0;;;;;;;;;;;95694:73;95802:8;:15;95782:9;:16;:35;95778:75;;95826:27;;-1:-1:-1;;;95826:27:0;;;;;;;;;;;95778:75;95903:16;;95866:9;;95930:620;95946:6;95942:1;:10;95930:620;;;95974:33;96010:15;:29;96026:9;96036:1;96026:12;;;;;;;;:::i;:::-;;;;;;;96010:29;;;;;;;;;;;95974:65;;96058:9;:26;;;96088:1;96058:31;;;96054:485;;96442:81;96449:9;96459:1;96449:12;;;;;;;;:::i;:::-;;;;;;;96463:19;96483:1;96463:22;;;;;;;;:::i;:::-;;;;;;;96487:8;96496:1;96487:11;;;;;;;;:::i;:::-;;;;;;;96500:6;96507:1;96500:9;;;;;;;;:::i;:::-;;;;;;;96511:8;96520:1;96511:11;;;;;;;;:::i;:::-;;;;;;;96442:6;:81::i;:::-;-1:-1:-1;95954:3:0;;;;:::i;:::-;;;;95930:620;;;95426:1131;;95251:1306;;;;;:::o;81246:153::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;81340:10:::1;:24:::0;;;;81375:6:::1;:16:::0;81246:153::o;90817:446::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;51164:1:::1;51762:7;;:19:::0;51754:63:::1;;;;-1:-1:-1::0;;;51754:63:0::1;;;;;;;:::i;:::-;51164:1;51895:7;:18:::0;90933:10:::2;90976:32:::0;;-1:-1:-1;;;90976:32:0;::::2;-1:-1:-1::0;;;;;90976:32:0::2;90958:15;:50;90954:98;;;91017:35;;-1:-1:-1::0;;;91017:35:0::2;;;;;;;;;;;90954:98;91067:16;::::0;:21;91063:68:::2;;91097:34;;-1:-1:-1::0;;;91097:34:0::2;;;;;;;;;;;91063:68;91144:17;91164:37;91182:10;;91194:6;;91164:17;:37::i;:::-;91144:57;;91219:36;91245:9;91219:36;;;;2426:25:1::0;;2414:2;2399:18;;2280:177;91219:36:0::2;;;;;;;;-1:-1:-1::0;;51120:1:0::1;52074:7;:22:::0;90817:446::o;94175:781::-;103185:19;;-1:-1:-1;;;;;103185:19:0;103171:10;:33;103168:58;;103213:13;;-1:-1:-1;;;103213:13:0;;;;;;;;;;;103168:58;94326:14:::1;::::0;94322:63:::1;;94363:22;;-1:-1:-1::0;;;94363:22:0::1;;;;;;;;;;;94322:63;94401:25;::::0;;;:15:::1;:25;::::0;;;;:41:::1;;::::0;-1:-1:-1;;;94401:41:0;::::1;;;94396:77;;94451:22;;-1:-1:-1::0;;;94451:22:0::1;;;;;;;;;;;94396:77;94486:33;94522:25:::0;;;:15:::1;:25;::::0;;;;94562:26;;:31;94558:66:::1;;94602:22;;-1:-1:-1::0;;;94602:22:0::1;;;;;;;;;;;94558:66;94662:59;::::0;;::::1;::::0;;::::1;21108:19:1::0;;;-1:-1:-1;;;;;94698:15:0;::::1;21143:12:1::0;;;21136:28;21180:12;;;;21173:28;;;94662:59:0;;;;;;;;;;21217:12:1;;;;94662:59:0;;;94652:70;;;::::1;::::0;94765:14:::1;::::0;94738:48:::1;::::0;94757:6;;94652:70;94738:18:::1;:48::i;:::-;94733:85;;94795:23;;-1:-1:-1::0;;;94795:23:0::1;;;;;;;;;;;94733:85;94831:46:::0;;;94888:15:::1;::::0;::::1;:24:::0;;-1:-1:-1;;94888:24:0::1;-1:-1:-1::0;;;;;94888:24:0;::::1;;::::0;;94930:18:::1;::::0;94939:8;;94930:18:::1;::::0;-1:-1:-1;;94930:18:0::1;94311:645;;94175:781:::0;;;;;:::o;93374:481::-;93440:22;;-1:-1:-1;;;93440:22:0;;;;93435:54;;93471:18;;-1:-1:-1;;;93471:18:0;;;;;;;;;;;93435:54;93525:10;93504:17;93512:8;93504:7;:17::i;:::-;-1:-1:-1;;;;;93504:31:0;;93500:72;;93544:28;;-1:-1:-1;;;93544:28:0;;;;;;;;;;;93500:72;93587:25;;;;:15;:25;;;;;:41;;;-1:-1:-1;;;93587:41:0;;;;93583:78;;;93637:24;;-1:-1:-1;;;93637:24:0;;;;;;;;;;;93583:78;93676:14;;93672:63;;93713:22;;-1:-1:-1;;;93713:22:0;;;;;;;;;;;93672:63;93748:25;;;;:15;:25;;;;;;93792:4;93748:41;:48;;-1:-1:-1;;;;93748:48:0;-1:-1:-1;;;93748:48:0;;;93822:25;93764:8;;93822:25;;;93374:481;:::o;61578:185::-;61716:39;61733:4;61739:2;61743:7;61716:39;;;;;;;;;;;;:16;:39::i;82536:211::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;82623:22:::1;::::0;:27;82619:74:::1;;82659:34;;-1:-1:-1::0;;;82659:34:0::1;;;;;;;;;;;82619:74;82706:22;:33:::0;82536:211::o;99342:1522::-;99435:25;99462:18;99497:6;99507:1;99497:11;99493:70;;99550:1;99534:13;;:17;;;;:::i;:::-;99525:26;;99493:70;103116:1;99579:8;:26;:53;;;;99619:13;;99609:6;:23;;99579:53;99575:89;;;99641:23;;-1:-1:-1;;;99641:23:0;;;;;;;;;;;99575:89;99677:9;99697:15;99715:16;99725:5;99715:9;:16::i;:::-;99697:34;;99746:7;99757:1;99746:12;99742:82;;99783:16;;;99797:1;99783:16;;;;;;;;99801:10;:6;99810:1;99801:10;:::i;:::-;99775:37;;;;;;;;99742:82;99850:3;99840:7;:13;99836:59;;;-1:-1:-1;99880:3:0;99836:59;99907:24;99948:7;-1:-1:-1;;;;;99934:22:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;99934:22:0;;99907:49;;99967:11;100003:13;100019:17;100027:8;100019:7;:17::i;:::-;100003:33;;100056:8;100052:12;;100047:596;100071:6;100066:1;:11;100047:596;;100134:1;100103:14;;;:11;:14;;;;;:19;-1:-1:-1;;;;;100103:19:0;:33;100099:101;;-1:-1:-1;100165:14:0;;;;:11;:14;;;;;:19;-1:-1:-1;;;;;100165:19:0;100099:101;100221:14;;;;:11;:14;;;;;:21;-1:-1:-1;;;100221:21:0;;;;100220:22;:40;;;;;100255:5;-1:-1:-1;;;;;100246:14:0;:5;-1:-1:-1;;;;;100246:14:0;;100220:40;100216:416;;;100296:1;100281:7;100289:3;100281:12;;;;;;;;:::i;:::-;;;;;;;;;;:16;100316:5;;;;:::i;:::-;;;;100353:7;100346:3;:14;100342:275;;100400:16;100410:5;100400:9;:16::i;:::-;100389:7;:27;100385:213;;100453:7;100462:10;:6;100471:1;100462:10;:::i;:::-;100445:28;;;;;;;;;;;100385:213;100559:7;100568:5;:1;100572;100568:5;:::i;100385:213::-;100079:3;;;;:::i;:::-;;;;100047:596;;;100655:31;100703:3;-1:-1:-1;;;;;100689:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;100689:18:0;;100655:52;;100727:1;100723:5;;100718:83;100734:3;100730:1;:7;100718:83;;;100779:7;100787:1;100779:10;;;;;;;;:::i;:::-;;;;;;;100759:14;100774:1;100759:17;;;;;;;;:::i;:::-;;;;;;;;;;:30;100739:3;;;;:::i;:::-;;;;100718:83;;;100829:14;100845:10;:6;100854:1;100845:10;:::i;:::-;100821:35;;;;;;;;;;99342:1522;;;;;;;:::o;84586:118::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;84659:22;:37;;;::::1;;-1:-1:-1::0;;;84659:37:0::1;-1:-1:-1::0;;;;84659:37:0;;::::1;::::0;;;::::1;::::0;;84586:118::o;102472:508::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;51164:1:::1;51762:7;;:19:::0;51754:63:::1;;;;-1:-1:-1::0;;;51754:63:0::1;;;;;;;:::i;:::-;51164:1;51895:7;:18:::0;102671:10:::2;102831:33:::0;;102608:14:::2;102787:41:::0;;102608:14;;102671:10;102562:43:::2;::::0;102831:33:::2;-1:-1:-1::0;;;102831:33:0;;::::2;::::0;::::2;::::0;102749:79:::2;::::0;102787:41;;;::::2;::::0;::::2;::::0;-1:-1:-1;;;102749:35:0;;::::2;;:79;:::i;:::-;:115;;;;:::i;:::-;102734:131;;:11;;:131;;;;:::i;:::-;102710:155;::::0;:21:::2;:155;:::i;:::-;102694:171;;102877:12;102895:3;-1:-1:-1::0;;;;;102895:8:0::2;102911:5;102895:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102876:45;;;102937:7;102932:43;;102953:22;;-1:-1:-1::0;;;102953:22:0::2;;;;;;;;;;;102932:43;-1:-1:-1::0;;51120:1:0::1;52074:7;:22:::0;-1:-1:-1;;;102472:508:0:o;84993:405::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;85173:10:::1;85196:61:::0;;85337:53:::1;::::0;;::::1;-1:-1:-1::0;;;85337:53:0::1;-1:-1:-1::0;;;;;;;;;85269:57:0;;::::1;-1:-1:-1::0;;;85269:57:0::1;-1:-1:-1::0;;;;;;85269:57:0;;;85196:61;;;::::1;85269:57:::0;;;;;;;::::1;85337:53:::0;;;::::1;;::::0;;84993:405::o;82151:255::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;82273:33;:59;;-1:-1:-1;;;;82273:59:0::1;-1:-1:-1::0;;;;;;;;82273:59:0;;::::1;;;::::0;;82343:31;:55;;-1:-1:-1;;82343:55:0::1;::::0;;;::::1;;::::0;;82151:255::o;58776:125::-;58840:7;58867:21;58880:7;58867:12;:21::i;:::-;:26;;58776:125;-1:-1:-1;;58776:125:0:o;82872:262::-;82938:7;82963:17;82971:8;82963:7;:17::i;:::-;82958:60;;82989:29;;-1:-1:-1;;;82989:29:0;;;;;;;;;;;82958:60;83047:22;;83035:8;:34;83031:75;;-1:-1:-1;83093:1:0;;82872:262;-1:-1:-1;82872:262:0:o;83031:75::-;-1:-1:-1;83125:1:0;;82872:262;-1:-1:-1;82872:262:0:o;56222:206::-;56286:7;-1:-1:-1;;;;;56310:19:0;;56306:60;;56338:28;;-1:-1:-1;;;56338:28:0;;;;;;;;;;;56306:60;-1:-1:-1;;;;;;56392:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;56392:27:0;;56222:206::o;76380:103::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;76445:30:::1;76472:1;76445:18;:30::i;:::-;76380:103::o:0;84207:200::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;84285:21;;-1:-1:-1;;;;;84285:21:0::1;:35:::0;84281:70:::1;;84329:22;;-1:-1:-1::0;;;84329:22:0::1;;;;;;;;;;;84281:70;84364:21:::0;:35;;-1:-1:-1;;;;;;84364:35:0::1;-1:-1:-1::0;;;;;84364:35:0;;;::::1;::::0;;;::::1;::::0;;84207:200::o;83787:198::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;83869:14:::1;::::0;:28;83865:67:::1;;83906:26;;-1:-1:-1::0;;;;;;83906:26:0::1;;;;;;;;;;;83865:67;83945:14;:32:::0;83787:198::o;81530:92::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;81597:5:::1;:17:::0;81530:92::o;34792:210::-;34885:10;-1:-1:-1;;;;;34899:14:0;34885:28;;34877:72;;;;-1:-1:-1;;;34877:72:0;;21878:2:1;34877:72:0;;;21860:21:1;21917:2;21897:18;;;21890:30;21956:33;21936:18;;;21929:61;22007:18;;34877:72:0;21676:355:1;34877:72:0;34956:40;34974:9;34985:10;34956:17;:40::i;59137:104::-;59193:13;59226:7;59219:14;;;;;:::i;83522:108::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;83601:21:::1;:11;83615:7:::0;;83601:21:::1;:::i;60748:287::-:0;52870:10;-1:-1:-1;;;;;60847:24:0;;;60843:54;;60880:17;;-1:-1:-1;;;60880:17:0;;;;;;;;;;;60843:54;52870:10;60910:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;60910:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;60910:53:0;;;;;;;;;;60979:48;;540:41:1;;;60910:42:0;;52870:10;60979:48;;513:18:1;60979:48:0;;;;;;;60748:287;;:::o;61834:370::-;62001:28;62011:4;62017:2;62021:7;62001:9;:28::i;:::-;-1:-1:-1;;;;;62044:13:0;;3578:19;:23;62040:157;;62065:56;62096:4;62102:2;62106:7;62115:5;62065:30;:56::i;:::-;62061:136;;62145:40;;-1:-1:-1;;;62145:40:0;;;;;;;;;;;62061:136;61834:370;;;;:::o;83269:115::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;83342:19;:34;;-1:-1:-1;;;;;;83342:34:0::1;-1:-1:-1::0;;;;;83342:34:0;;;::::1;::::0;;;::::1;::::0;;83269:115::o;96678:516::-;96752:17;96784;96792:8;96784:7;:17::i;:::-;96779:60;;96810:29;;-1:-1:-1;;;96810:29:0;;;;;;;;;;;96779:60;96860:33;96896:25;;;:15;:25;;;;;96936:26;;96896:25;;96936:31;96932:258;;96991:11;96984:18;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96678:516;;;:::o;96932:258::-;97059:26;;97142:34;;-1:-1:-1;;;97142:34:0;;;;;2426:25:1;;;97142:11:0;;:28;;2399:18:1;;97142:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;97142:34:0;;;;;;;;;;;;:::i;:::-;97114:63;;;;;;;;:::i;:::-;;;;;;;;;;;;;97100:78;;;;96678:516;;;:::o;96932:258::-;96771:423;96678:516;;;:::o;87018:1046::-;87183:13;;87173:7;87157:23;;:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:39;87153:70;;;87205:18;;-1:-1:-1;;;87205:18:0;;;;;;;;;;;87153:70;87256:33;;-1:-1:-1;;;87256:33:0;;-1:-1:-1;;;;;87256:33:0;87238:15;:51;87234:89;;;87298:25;;-1:-1:-1;;;87298:25:0;;;;;;;;;;;87234:89;87356:31;;-1:-1:-1;;;;;87356:31:0;87338:15;:49;87334:82;;;87396:20;;-1:-1:-1;;;87396:20:0;;;;;;;;;;;87334:82;87449:11;-1:-1:-1;;;;;87431:29:0;:15;:29;87427:62;;;87469:20;;-1:-1:-1;;;87469:20:0;;;;;;;;;;;87427:62;87518:10;56571:7;56606:19;;;:12;:19;;;;;:32;87504:50;;;;;:35;;;;;-1:-1:-1;;;56606:32:0;;-1:-1:-1;;;;;56606:32:0;87504:35;:::i;:::-;:50;87500:91;;;87563:28;;-1:-1:-1;;;87563:28:0;;;;;;;;;;;87500:91;87796:63;87809:10;87821:12;87835:11;87848:10;;87796:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;87796:12:0;;-1:-1:-1;;;87796:63:0:i;:::-;87791:97;;87868:20;;-1:-1:-1;;;87868:20:0;;;;;;;;;;;87791:97;87901:18;87930:7;87922:15;;:5;;:15;;;;:::i;:::-;87901:36;;87964:10;87952:9;:22;87948:57;;;87983:22;;-1:-1:-1;;;87983:22:0;;;;;;;;;;;87948:57;88026:30;88036:10;88048:7;88026:30;;:9;:30::i;:::-;87142:922;87018:1046;;;;;:::o;81778:143::-;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;81865:10:::1;:48:::0;;-1:-1:-1;;;;;;81865:48:0::1;-1:-1:-1::0;;;;;81865:48:0;;;::::1;::::0;;;::::1;::::0;;81778:143::o;97605:126::-;-1:-1:-1;;;;;56606:19:0;;97667:14;56606:19;;;:12;:19;;;;;:32;-1:-1:-1;;;56606:32:0;;-1:-1:-1;;;;;56606:32:0;97701:22;56510:137;101193:1059;101276:16;101294:7;101318:6;101328:1;101318:11;101314:70;;101371:1;101355:13;;:17;;;;:::i;:::-;101346:26;;101314:70;103116:1;101400:8;:26;:53;;;;101440:13;;101430:6;:23;;101400:53;101396:89;;;101462:23;;-1:-1:-1;;;101462:23:0;;;;;;;;;;;101396:89;101545:18;;;101559:3;101545:18;;;;;;;;;101498:9;;;;101545:18;;;;;;;;;;;-1:-1:-1;101545:18:0;101518:45;;101574:11;101619:8;101615:12;;101610:429;101634:6;101629:1;:11;101610:429;;101662:33;101698:18;;;:15;:18;;;;;101735:25;;;;-1:-1:-1;;;101735:25:0;;;;:60;;;;-1:-1:-1;101764:26:0;;:31;101735:60;101731:297;;;101885:1;101870:7;101878:3;101870:12;;;;;;;;:::i;:::-;;;;;;;;;;:16;101905:5;;;;:::i;:::-;;;;101935:3;101942;101935:10;101931:82;;101978:7;101987:5;:1;101991;101987:5;:::i;:::-;101970:23;;;;;;;;;;101931:82;-1:-1:-1;101642:3:0;;;;:::i;:::-;;;;101610:429;;;102051:31;102099:3;-1:-1:-1;;;;;102085:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102085:18:0;;102051:52;;102123:1;102119:5;;102114:83;102130:3;102126:1;:7;102114:83;;;102175:7;102183:1;102175:10;;;;;;;;:::i;:::-;;;;;;;102155:14;102170:1;102155:17;;;;;;;;:::i;:::-;;;;;;;;;;:30;102135:3;;;;:::i;:::-;;;;102114:83;;;102217:14;102233:10;:6;102242:1;102233:10;:::i;:::-;102209:35;;;;;;;;101193:1059;;;;;;:::o;92485:626::-;51164:1;51762:7;;:19;51754:63;;;;-1:-1:-1;;;51754:63:0;;;;;;;:::i;:::-;51164:1;51895:7;:18;92570:13:::1;::::0;92553::::1;:11;:13::i;:::-;:30;92549:61;;92592:18;;-1:-1:-1::0;;;92592:18:0::1;;;;;;;;;;;92549:61;92697:10;92631:41;92675:33:::0;;;:21:::1;:33;::::0;;;;92724:28;;::::1;;92723:29;::::0;:57:::1;;-1:-1:-1::0;92756:24:0;;;;::::1;;;92723:57;:87;;;-1:-1:-1::0;92784:26:0;;::::1;::::0;::::1;;;92723:87;92719:115;;;92819:15;;-1:-1:-1::0;;;92819:15:0::1;;;;;;;;;;;92719:115;92847:33:::0;;-1:-1:-1;;92847:33:0::1;;;::::0;;92891:10:::1;:29:::0;;::::1;-1:-1:-1::0;;;92891:29:0;;::::1;;::::0;:27:::1;:29;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;92932:12;92958:10;-1:-1:-1::0;;;;;92950:24:0::1;92982:11;;92950:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92931:67;;;93014:7;93009:50;;93030:29;;-1:-1:-1::0;;;93030:29:0::1;;;;;;;;;;;93009:50;93077:26;::::0;93092:10:::1;3544:51:1::0;;93077:26:0::1;::::0;3532:2:1;3517:18;93077:26:0::1;3398:203:1::0;76638:201:0;75802:6;;-1:-1:-1;;;;;75802:6:0;52870:10;75949:23;75941:68;;;;-1:-1:-1;;;75941:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;76727:22:0;::::1;76719:73;;;::::0;-1:-1:-1;;;76719:73:0;;23497:2:1;76719:73:0::1;::::0;::::1;23479:21:1::0;23536:2;23516:18;;;23509:30;23575:34;23555:18;;;23548:62;-1:-1:-1;;;23626:18:1;;;23619:36;23672:19;;76719:73:0::1;23295:402:1::0;76719:73:0::1;76803:28;76822:8;76803:18;:28::i;62459:174::-:0;62516:4;62559:7;103116:1;62540:26;;:53;;;;;62580:13;;62570:7;:23;62540:53;:85;;;;-1:-1:-1;;62598:20:0;;;;:11;:20;;;;;:27;-1:-1:-1;;;62598:27:0;;;;62597:28;;62459:174::o;71681:196::-;71796:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;71796:29:0;-1:-1:-1;;;;;71796:29:0;;;;;;;;;71841:28;;71796:24;;71841:28;;;;;;;71681:196;;;:::o;66629:2130::-;66744:35;66782:21;66795:7;66782:12;:21::i;:::-;66744:59;;66842:4;-1:-1:-1;;;;;66820:26:0;:13;:18;;;-1:-1:-1;;;;;66820:26:0;;66816:67;;66855:28;;-1:-1:-1;;;66855:28:0;;;;;;;;;;;66816:67;66896:22;52870:10;-1:-1:-1;;;;;66922:20:0;;;;:73;;-1:-1:-1;66959:36:0;66976:4;52870:10;61106:164;:::i;66959:36::-;66922:126;;;-1:-1:-1;52870:10:0;67012:20;67024:7;67012:11;:20::i;:::-;-1:-1:-1;;;;;67012:36:0;;66922:126;66896:153;;67067:17;67062:66;;67093:35;;-1:-1:-1;;;67093:35:0;;;;;;;;;;;67062:66;-1:-1:-1;;;;;67143:16:0;;67139:52;;67168:23;;-1:-1:-1;;;67168:23:0;;;;;;;;;;;67139:52;67312:35;67329:1;67333:7;67342:4;67312:8;:35::i;:::-;-1:-1:-1;;;;;67643:18:0;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;67643:31:0;;;-1:-1:-1;;;;;67643:31:0;;;-1:-1:-1;;67643:31:0;;;;;;;67689:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;67689:29:0;;;;;;;;;;;67769:20;;;:11;:20;;;;;;67804:18;;-1:-1:-1;;;;;;67837:49:0;;;;-1:-1:-1;;;67870:15:0;67837:49;;;;;;;;;;68160:11;;68220:24;;;;;68263:13;;67769:20;;68220:24;;68263:13;68259:384;;68473:13;;68458:11;:28;68454:174;;68511:20;;68580:28;;;;-1:-1:-1;;;;;68554:54:0;-1:-1:-1;;;68554:54:0;-1:-1:-1;;;;;;68554:54:0;;;-1:-1:-1;;;;;68511:20:0;;68554:54;;;;68454:174;67618:1036;;;68690:7;68686:2;-1:-1:-1;;;;;68671:27:0;68680:4;-1:-1:-1;;;;;68671:27:0;;;;;;;;;;;66733:2026;;66629:2130;;;:::o;62717:104::-;62786:27;62796:2;62800:8;62786:27;;;;;;;;;;;;:9;:27::i;32909:1034::-;32986:17;33012:4;-1:-1:-1;;;;;33012:20:0;;33033:14;33049:4;33066:8;31739:1;33055:43;;;;;;;;6209:25:1;;;6265:2;6250:18;;6243:34;6197:2;6182:18;;6035:248;33055:43:0;;;;;;;;;;;;;33012:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;33334:15:0;33417:16;;;:6;:16;;;;;;;;;23233:51;;;;;26017:25:1;;;26058:18;;;26051:34;;;33410:4:0;26101:18:1;;;26094:60;26170:18;;;;26163:34;;;23233:51:0;;;;;;;;;;25989:19:1;;;;23233:51:0;;;23223:62;;;;;;;;;33871:16;;;;;;;:20;;33890:1;33871:20;:::i;:::-;33852:16;;;;:6;:16;;;;;:39;33905:32;33859:8;33929:7;23803:41;;;;;;;26365:19:1;;;;26400:12;;;26393:28;;;;23803:41:0;;;;;;;;;26437:12:1;;;;23803:41:0;;23793:52;;;;;;23683:168;33905:32;33898:39;32909:1034;-1:-1:-1;;;;32909:1034:0:o;36229:190::-;36354:4;36407;36378:25;36391:5;36398:4;36378:12;:25::i;:::-;:33;;36229:190;-1:-1:-1;;;;36229:190:0:o;57603:1111::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;57714:7:0;;103116:1;57763:23;57759:888;;57799:13;;57792:4;:20;57788:859;;;57833:31;57867:17;;;:11;:17;;;;;;;;;57833:51;;;;;;;;;-1:-1:-1;;;;;57833:51:0;;;;-1:-1:-1;;;57833:51:0;;-1:-1:-1;;;;;57833:51:0;;;;;;;;-1:-1:-1;;;57833:51:0;;;;;;;;;;;;;;57903:729;;57953:14;;-1:-1:-1;;;;;57953:28:0;;57949:101;;58017:9;57603:1111;-1:-1:-1;;;57603:1111:0:o;57949:101::-;-1:-1:-1;;;58392:6:0;58437:17;;;;:11;:17;;;;;;;;;58425:29;;;;;;;;;-1:-1:-1;;;;;58425:29:0;;;;;-1:-1:-1;;;58425:29:0;;-1:-1:-1;;;;;58425:29:0;;;;;;;;-1:-1:-1;;;58425:29:0;;;;;;;;;;;;;58485:28;58481:109;;58553:9;57603:1111;-1:-1:-1;;;57603:1111:0:o;58481:109::-;58352:261;;;57814:833;57788:859;58675:31;;-1:-1:-1;;;58675:31:0;;;;;;;;;;;76999:191;77092:6;;;-1:-1:-1;;;;;77109:17:0;;;-1:-1:-1;;;;;;77109:17:0;;;;;;;77142:40;;77092:6;;;77109:17;77092:6;;77142:40;;77073:16;;77142:40;77062:128;76999:191;:::o;91273:190::-;91372:16;:29;;;91419:36;;2426:25:1;;;91419:36:0;;2414:2:1;2399:18;91419:36:0;2280:177:1;72369:667:0;72553:72;;-1:-1:-1;;;72553:72:0;;72532:4;;-1:-1:-1;;;;;72553:36:0;;;;;:72;;52870:10;;72604:4;;72610:7;;72619:5;;72553:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72553:72:0;;;;;;;;-1:-1:-1;;72553:72:0;;;;;;;;;;;;:::i;:::-;;;72549:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72787:6;:13;72804:1;72787:18;72783:235;;72833:40;;-1:-1:-1;;;72833:40:0;;;;;;;;;;;72783:235;72976:6;72970:13;72961:6;72957:2;72953:15;72946:38;72549:480;-1:-1:-1;;;;;;72672:55:0;-1:-1:-1;;;72672:55:0;;-1:-1:-1;72369:667:0;;;;;;:::o;86138:385::-;86310:52;;;-1:-1:-1;;25545:2:1;25541:15;;;25537:53;86310:52:0;;;25525:66:1;-1:-1:-1;;;;;;25647:3:1;25625:16;;;25621:43;25607:12;;;25600:65;-1:-1:-1;;;;;;25721:3:1;25699:16;;;25695:51;25681:12;;;25674:73;86265:4:0;;;;25763:12:1;86310:52:0;;;;;;;;;;;;86300:63;;;;;;86282:81;;86374:22;86399:32;:7;48239:58;;26702:66:1;48239:58:0;;;26690:79:1;26785:12;;;26778:28;;;48106:7:0;;26822:12:1;;48239:58:0;;;;;;;;;;;;48229:69;;;;;;48222:76;;48037:269;;;;86399:32;86489:10;:26;86374:57;;-1:-1:-1;;;;;;86489:26:0;86451:34;86374:57;86474:10;86451:22;:34::i;:::-;-1:-1:-1;;;;;86451:64:0;;;86138:385;-1:-1:-1;;;;;;;86138:385:0:o;63194:1749::-;63317:20;63340:13;-1:-1:-1;;;;;63368:16:0;;63364:48;;63393:19;;-1:-1:-1;;;63393:19:0;;;;;;;;;;;63364:48;63427:8;63439:1;63427:13;63423:44;;63449:18;;-1:-1:-1;;;63449:18:0;;;;;;;;;;;63423:44;-1:-1:-1;;;;;63818:16:0;;;;;;:12;:16;;;;;;;;:44;;-1:-1:-1;;;;;;63877:49:0;;-1:-1:-1;;;;;63818:44:0;;;;;;;63877:49;;;-1:-1:-1;;;;;63818:44:0;;;;;;63877:49;;;;;;;;;;;;;;;;63943:25;;;:11;:25;;;;;;:35;;-1:-1:-1;;;;;;63993:66:0;;;-1:-1:-1;;;64043:15:0;63993:66;;;;;;;;;;;;;63943:25;;64140:23;;;;3578:19;:23;64180:631;;64220:313;64251:38;;64276:12;;-1:-1:-1;;;;;64251:38:0;;;64268:1;;64251:38;;64268:1;;64251:38;64317:69;64356:1;64360:2;64364:14;;;;;;64380:5;64317:30;:69::i;:::-;64312:174;;64422:40;;-1:-1:-1;;;64422:40:0;;;;;;;;;;;64312:174;64528:3;64513:12;:18;64220:313;;64614:12;64597:13;;:29;64593:43;;64628:8;;;64593:43;64180:631;;;64677:119;64708:40;;64733:14;;;;;-1:-1:-1;;;;;64708:40:0;;;64725:1;;64708:40;;64725:1;;64708:40;64791:3;64776:12;:18;64677:119;;64180:631;-1:-1:-1;64825:13:0;:28;;;64875:60;;64908:2;64912:12;64926:8;64875:60;:::i;36780:675::-;36863:7;36906:4;36863:7;36921:497;36945:5;:12;36941:1;:16;36921:497;;;36979:20;37002:5;37008:1;37002:8;;;;;;;;:::i;:::-;;;;;;;36979:31;;37045:12;37029;:28;37025:382;;37531:13;37581:15;;;37617:4;37610:15;;;37664:4;37648:21;;37157:57;;37025:382;;;37531:13;37581:15;;;37617:4;37610:15;;;37664:4;37648:21;;37334:57;;37025:382;-1:-1:-1;36959:3:0;;;;:::i;:::-;;;;36921:497;;;-1:-1:-1;37435:12:0;36780:675;-1:-1:-1;;;36780:675:0:o;44235:231::-;44313:7;44334:17;44353:18;44375:27;44386:4;44392:9;44375:10;:27::i;:::-;44333:69;;;;44413:18;44425:5;44413:11;:18::i;42125:1308::-;42206:7;42215:12;42440:9;:16;42460:2;42440:22;42436:990;;42736:4;42721:20;;42715:27;42786:4;42771:20;;42765:27;42844:4;42829:20;;42823:27;42479:9;42815:36;42887:25;42898:4;42815:36;42715:27;42765;42887:10;:25::i;:::-;42880:32;;;;;;;;;42436:990;42934:9;:16;42954:2;42934:22;42930:496;;43209:4;43194:20;;43188:27;43260:4;43245:20;;43239:27;43302:23;43313:4;43188:27;43239;43302:10;:23::i;:::-;43295:30;;;;;;;;42930:496;-1:-1:-1;43374:1:0;;-1:-1:-1;43378:35:0;43358:56;;40396:643;40474:20;40465:5;:29;;;;;;;;:::i;:::-;;40461:571;;40396:643;:::o;40461:571::-;40572:29;40563:5;:38;;;;;;;;:::i;:::-;;40559:473;;40618:34;;-1:-1:-1;;;40618:34:0;;27179:2:1;40618:34:0;;;27161:21:1;27218:2;27198:18;;;27191:30;27257:26;27237:18;;;27230:54;27301:18;;40618:34:0;26977:348:1;40559:473:0;40683:35;40674:5;:44;;;;;;;;:::i;:::-;;40670:362;;40735:41;;-1:-1:-1;;;40735:41:0;;27532:2:1;40735:41:0;;;27514:21:1;27571:2;27551:18;;;27544:30;27610:33;27590:18;;;27583:61;27661:18;;40735:41:0;27330:355:1;40670:362:0;40807:30;40798:5;:39;;;;;;;;:::i;:::-;;40794:238;;40854:44;;-1:-1:-1;;;40854:44:0;;27892:2:1;40854:44:0;;;27874:21:1;27931:2;27911:18;;;27904:30;27970:34;27950:18;;;27943:62;-1:-1:-1;;;28021:18:1;;;28014:32;28063:19;;40854:44:0;27690:398:1;40794:238:0;40929:30;40920:5;:39;;;;;;;;:::i;:::-;;40916:116;;40976:44;;-1:-1:-1;;;40976:44:0;;28295:2:1;40976:44:0;;;28277:21:1;28334:2;28314:18;;;28307:30;28373:34;28353:18;;;28346:62;-1:-1:-1;;;28424:18:1;;;28417:32;28466:19;;40976:44:0;28093:398:1;45687:1632:0;45818:7;;46752:66;46739:79;;46735:163;;;-1:-1:-1;46851:1:0;;-1:-1:-1;46855:30:0;46835:51;;46735:163;46912:1;:7;;46917:2;46912:7;;:18;;;;;46923:1;:7;;46928:2;46923:7;;46912:18;46908:102;;;-1:-1:-1;46963:1:0;;-1:-1:-1;46967:30:0;46947:51;;46908:102;47124:24;;;47107:14;47124:24;;;;;;;;;28723:25:1;;;28796:4;28784:17;;28764:18;;;28757:45;;;;28818:18;;;28811:34;;;28861:18;;;28854:34;;;47124:24:0;;28695:19:1;;47124:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47124:24:0;;-1:-1:-1;;47124:24:0;;;-1:-1:-1;;;;;;;47163:20:0;;47159:103;;47216:1;47220:29;47200:50;;;;;;;47159:103;47282:6;-1:-1:-1;47290:20:0;;-1:-1:-1;45687:1632:0;;;;;;;;:::o;44729:344::-;44843:7;;-1:-1:-1;;;;;44889:80:0;;44843:7;44996:25;45012:3;44997:18;;;45019:2;44996:25;:::i;:::-;44980:42;;45040:25;45051:4;45057:1;45060;45063;45040:10;:25::i;:::-;45033:32;;;;;;44729:344;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;:::-;384:5;150:245;-1:-1:-1;;;150:245:1:o;592:127::-;653:10;648:3;644:20;641:1;634:31;684:4;681:1;674:15;708:4;705:1;698:15;724:275;795:2;789:9;860:2;841:13;;-1:-1:-1;;837:27:1;825:40;;-1:-1:-1;;;;;880:34:1;;916:22;;;877:62;874:88;;;942:18;;:::i;:::-;978:2;971:22;724:275;;-1:-1:-1;724:275:1:o;1004:183::-;1064:4;-1:-1:-1;;;;;1089:6:1;1086:30;1083:56;;;1119:18;;:::i;:::-;-1:-1:-1;1164:1:1;1160:14;1176:4;1156:25;;1004:183::o;1192:662::-;1246:5;1299:3;1292:4;1284:6;1280:17;1276:27;1266:55;;1317:1;1314;1307:12;1266:55;1353:6;1340:20;1379:4;1403:60;1419:43;1459:2;1419:43;:::i;:::-;1403:60;:::i;:::-;1497:15;;;1583:1;1579:10;;;;1567:23;;1563:32;;;1528:12;;;;1607:15;;;1604:35;;;1635:1;1632;1625:12;1604:35;1671:2;1663:6;1659:15;1683:142;1699:6;1694:3;1691:15;1683:142;;;1765:17;;1753:30;;1803:12;;;;1716;;1683:142;;;-1:-1:-1;1843:5:1;1192:662;-1:-1:-1;;;;;;1192:662:1:o;1859:416::-;1952:6;1960;2013:2;2001:9;1992:7;1988:23;1984:32;1981:52;;;2029:1;2026;2019:12;1981:52;2065:9;2052:23;2042:33;;2126:2;2115:9;2111:18;2098:32;-1:-1:-1;;;;;2145:6:1;2142:30;2139:50;;;2185:1;2182;2175:12;2139:50;2208:61;2261:7;2252:6;2241:9;2237:22;2208:61;:::i;:::-;2198:71;;;1859:416;;;;;:::o;2462:258::-;2534:1;2544:113;2558:6;2555:1;2552:13;2544:113;;;2634:11;;;2628:18;2615:11;;;2608:39;2580:2;2573:10;2544:113;;;2675:6;2672:1;2669:13;2666:48;;;-1:-1:-1;;2710:1:1;2692:16;;2685:27;2462:258::o;2725:::-;2767:3;2805:5;2799:12;2832:6;2827:3;2820:19;2848:63;2904:6;2897:4;2892:3;2888:14;2881:4;2874:5;2870:16;2848:63;:::i;:::-;2965:2;2944:15;-1:-1:-1;;2940:29:1;2931:39;;;;2972:4;2927:50;;2725:258;-1:-1:-1;;2725:258:1:o;2988:220::-;3137:2;3126:9;3119:21;3100:4;3157:45;3198:2;3187:9;3183:18;3175:6;3157:45;:::i;3213:180::-;3272:6;3325:2;3313:9;3304:7;3300:23;3296:32;3293:52;;;3341:1;3338;3331:12;3293:52;-1:-1:-1;3364:23:1;;3213:180;-1:-1:-1;3213:180:1:o;3606:131::-;-1:-1:-1;;;;;3681:31:1;;3671:42;;3661:70;;3727:1;3724;3717:12;3742:315;3810:6;3818;3871:2;3859:9;3850:7;3846:23;3842:32;3839:52;;;3887:1;3884;3877:12;3839:52;3926:9;3913:23;3945:31;3970:5;3945:31;:::i;:::-;3995:5;4047:2;4032:18;;;;4019:32;;-1:-1:-1;;;3742:315:1:o;4813:456::-;4890:6;4898;4906;4959:2;4947:9;4938:7;4934:23;4930:32;4927:52;;;4975:1;4972;4965:12;4927:52;5014:9;5001:23;5033:31;5058:5;5033:31;:::i;:::-;5083:5;-1:-1:-1;5140:2:1;5125:18;;5112:32;5153:33;5112:32;5153:33;:::i;:::-;4813:456;;5205:7;;-1:-1:-1;;;5259:2:1;5244:18;;;;5231:32;;4813:456::o;5274:171::-;5341:20;;-1:-1:-1;;;;;5390:30:1;;5380:41;;5370:69;;5435:1;5432;5425:12;5370:69;5274:171;;;:::o;5450:328::-;5524:6;5532;5540;5593:2;5581:9;5572:7;5568:23;5564:32;5561:52;;;5609:1;5606;5599:12;5561:52;5632:28;5650:9;5632:28;:::i;:::-;5622:38;;5679:37;5712:2;5701:9;5697:18;5679:37;:::i;:::-;5669:47;;5735:37;5768:2;5757:9;5753:18;5735:37;:::i;:::-;5725:47;;5450:328;;;;;:::o;5783:247::-;5842:6;5895:2;5883:9;5874:7;5870:23;5866:32;5863:52;;;5911:1;5908;5901:12;5863:52;5950:9;5937:23;5969:31;5994:5;5969:31;:::i;6288:315::-;6356:6;6364;6417:2;6405:9;6396:7;6392:23;6388:32;6385:52;;;6433:1;6430;6423:12;6385:52;6469:9;6456:23;6446:33;;6529:2;6518:9;6514:18;6501:32;6542:31;6567:5;6542:31;:::i;:::-;6592:5;6582:15;;;6288:315;;;;;:::o;6608:666::-;6661:5;6714:3;6707:4;6699:6;6695:17;6691:27;6681:55;;6732:1;6729;6722:12;6681:55;6768:6;6755:20;6794:4;6818:60;6834:43;6874:2;6834:43;:::i;6818:60::-;6912:15;;;6998:1;6994:10;;;;6982:23;;6978:32;;;6943:12;;;;7022:15;;;7019:35;;;7050:1;7047;7040:12;7019:35;7086:2;7078:6;7074:15;7098:147;7114:6;7109:3;7106:15;7098:147;;;7180:22;7198:3;7180:22;:::i;:::-;7168:35;;7223:12;;;;7131;;7098:147;;7279:910;7343:5;7396:3;7389:4;7381:6;7377:17;7373:27;7363:55;;7414:1;7411;7404:12;7363:55;7450:6;7437:20;7476:4;7500:60;7516:43;7556:2;7516:43;:::i;7500:60::-;7594:15;;;7680:1;7676:10;;;;7664:23;;7660:32;;;7625:12;;;;7704:15;;;7701:35;;;7732:1;7729;7722:12;7701:35;7768:2;7760:6;7756:15;7780:380;7796:6;7791:3;7788:15;7780:380;;;7882:3;7869:17;-1:-1:-1;;;;;7905:11:1;7902:35;7899:125;;;7978:1;8007:2;8003;7996:14;7899:125;8049:68;8113:3;8108:2;8094:11;8086:6;8082:24;8078:33;8049:68;:::i;:::-;8037:81;;-1:-1:-1;8138:12:1;;;;7813;;7780:380;;8194:1308;8438:6;8446;8454;8462;8470;8523:3;8511:9;8502:7;8498:23;8494:33;8491:53;;;8540:1;8537;8530:12;8491:53;8580:9;8567:23;-1:-1:-1;;;;;8650:2:1;8642:6;8639:14;8636:34;;;8666:1;8663;8656:12;8636:34;8689:61;8742:7;8733:6;8722:9;8718:22;8689:61;:::i;:::-;8679:71;;8803:2;8792:9;8788:18;8775:32;8759:48;;8832:2;8822:8;8819:16;8816:36;;;8848:1;8845;8838:12;8816:36;8871:63;8926:7;8915:8;8904:9;8900:24;8871:63;:::i;:::-;8861:73;;8987:2;8976:9;8972:18;8959:32;8943:48;;9016:2;9006:8;9003:16;9000:36;;;9032:1;9029;9022:12;9000:36;9055:62;9109:7;9098:8;9087:9;9083:24;9055:62;:::i;:::-;9045:72;;9170:2;9159:9;9155:18;9142:32;9126:48;;9199:2;9189:8;9186:16;9183:36;;;9215:1;9212;9205:12;9183:36;9238:63;9293:7;9282:8;9271:9;9267:24;9238:63;:::i;:::-;9228:73;;9354:3;9343:9;9339:19;9326:33;9310:49;;9384:2;9374:8;9371:16;9368:36;;;9400:1;9397;9390:12;9368:36;;9423:73;9488:7;9477:8;9466:9;9462:24;9423:73;:::i;:::-;9413:83;;;8194:1308;;;;;;;;:::o;9507:248::-;9575:6;9583;9636:2;9624:9;9615:7;9611:23;9607:32;9604:52;;;9652:1;9649;9642:12;9604:52;-1:-1:-1;;9675:23:1;;;9745:2;9730:18;;;9717:32;;-1:-1:-1;9507:248:1:o;9760:626::-;9879:6;9887;9895;9903;9911;9964:3;9952:9;9943:7;9939:23;9935:33;9932:53;;;9981:1;9978;9971:12;9932:53;10017:9;10004:23;9994:33;;10074:2;10063:9;10059:18;10046:32;10036:42;;10097:37;10130:2;10119:9;10115:18;10097:37;:::i;:::-;10087:47;;10181:2;10170:9;10166:18;10153:32;10143:42;;10236:3;10225:9;10221:19;10208:33;-1:-1:-1;;;;;10256:6:1;10253:30;10250:50;;;10296:1;10293;10286:12;10250:50;10319:61;10372:7;10363:6;10352:9;10348:22;10319:61;:::i;10391:383::-;10468:6;10476;10484;10537:2;10525:9;10516:7;10512:23;10508:32;10505:52;;;10553:1;10550;10543:12;10505:52;10592:9;10579:23;10611:31;10636:5;10611:31;:::i;:::-;10661:5;10713:2;10698:18;;10685:32;;-1:-1:-1;10764:2:1;10749:18;;;10736:32;;10391:383;-1:-1:-1;;;10391:383:1:o;10779:705::-;10997:2;11009:21;;;11079:13;;10982:18;;;11101:22;;;10949:4;;11176;;11154:2;11139:18;;;11203:15;;;10949:4;11246:169;11260:6;11257:1;11254:13;11246:169;;;11321:13;;11309:26;;11355:12;;;;11390:15;;;;11282:1;11275:9;11246:169;;;-1:-1:-1;;;11451:18:1;;11444:34;;;;11432:3;10779:705;-1:-1:-1;;10779:705:1:o;11489:118::-;11575:5;11568:13;11561:21;11554:5;11551:32;11541:60;;11597:1;11594;11587:12;11612:241;11668:6;11721:2;11709:9;11700:7;11696:23;11692:32;11689:52;;;11737:1;11734;11727:12;11689:52;11776:9;11763:23;11795:28;11817:5;11795:28;:::i;12118:163::-;12185:20;;12245:10;12234:22;;12224:33;;12214:61;;12271:1;12268;12261:12;12286:328;12360:6;12368;12376;12429:2;12417:9;12408:7;12404:23;12400:32;12397:52;;;12445:1;12442;12435:12;12397:52;12468:28;12486:9;12468:28;:::i;:::-;12458:38;;12515:37;12548:2;12537:9;12533:18;12515:37;:::i;:::-;12505:47;;12571:37;12604:2;12593:9;12589:18;12571:37;:::i;12619:256::-;12685:6;12693;12746:2;12734:9;12725:7;12721:23;12717:32;12714:52;;;12762:1;12759;12752:12;12714:52;12785:28;12803:9;12785:28;:::i;:::-;12775:38;;12832:37;12865:2;12854:9;12850:18;12832:37;:::i;:::-;12822:47;;12619:256;;;;;:::o;13422:348::-;13474:8;13484:6;13538:3;13531:4;13523:6;13519:17;13515:27;13505:55;;13556:1;13553;13546:12;13505:55;-1:-1:-1;13579:20:1;;-1:-1:-1;;;;;13611:30:1;;13608:50;;;13654:1;13651;13644:12;13608:50;13691:4;13683:6;13679:17;13667:29;;13743:3;13736:4;13727:6;13719;13715:19;13711:30;13708:39;13705:59;;;13760:1;13757;13750:12;13775:411;13846:6;13854;13907:2;13895:9;13886:7;13882:23;13878:32;13875:52;;;13923:1;13920;13913:12;13875:52;13963:9;13950:23;-1:-1:-1;;;;;13988:6:1;13985:30;13982:50;;;14028:1;14025;14018:12;13982:50;14067:59;14118:7;14109:6;14098:9;14094:22;14067:59;:::i;:::-;14145:8;;14041:85;;-1:-1:-1;13775:411:1;-1:-1:-1;;;;13775:411:1:o;14191:382::-;14256:6;14264;14317:2;14305:9;14296:7;14292:23;14288:32;14285:52;;;14333:1;14330;14323:12;14285:52;14372:9;14359:23;14391:31;14416:5;14391:31;:::i;:::-;14441:5;-1:-1:-1;14498:2:1;14483:18;;14470:32;14511:30;14470:32;14511:30;:::i;14578:186::-;14626:4;-1:-1:-1;;;;;14651:6:1;14648:30;14645:56;;;14681:18;;:::i;:::-;-1:-1:-1;14747:2:1;14726:15;-1:-1:-1;;14722:29:1;14753:4;14718:40;;14578:186::o;14769:1016::-;14864:6;14872;14880;14888;14941:3;14929:9;14920:7;14916:23;14912:33;14909:53;;;14958:1;14955;14948:12;14909:53;14997:9;14984:23;15016:31;15041:5;15016:31;:::i;:::-;15066:5;-1:-1:-1;15123:2:1;15108:18;;15095:32;15136:33;15095:32;15136:33;:::i;:::-;15188:7;-1:-1:-1;15242:2:1;15227:18;;15214:32;;-1:-1:-1;15297:2:1;15282:18;;15269:32;-1:-1:-1;;;;;15313:30:1;;15310:50;;;15356:1;15353;15346:12;15310:50;15379:22;;15432:4;15424:13;;15420:27;-1:-1:-1;15410:55:1;;15461:1;15458;15451:12;15410:55;15497:2;15484:16;15522:48;15538:31;15566:2;15538:31;:::i;15522:48::-;15593:2;15586:5;15579:17;15633:7;15628:2;15623;15619;15615:11;15611:20;15608:33;15605:53;;;15654:1;15651;15644:12;15605:53;15709:2;15704;15700;15696:11;15691:2;15684:5;15680:14;15667:45;15753:1;15748:2;15743;15736:5;15732:14;15728:23;15721:34;15774:5;15764:15;;;;;14769:1016;;;;;;;:::o;15790:627::-;15884:6;15892;15900;15908;15916;15969:3;15957:9;15948:7;15944:23;15940:33;15937:53;;;15986:1;15983;15976:12;15937:53;16009:28;16027:9;16009:28;:::i;:::-;15999:38;;16056:37;16089:2;16078:9;16074:18;16056:37;:::i;:::-;16046:47;;16112:37;16145:2;16134:9;16130:18;16112:37;:::i;:::-;16102:47;;16200:2;16189:9;16185:18;16172:32;-1:-1:-1;;;;;16219:6:1;16216:30;16213:50;;;16259:1;16256;16249:12;16213:50;16298:59;16349:7;16340:6;16329:9;16325:22;16298:59;:::i;:::-;15790:627;;;;-1:-1:-1;15790:627:1;;-1:-1:-1;16376:8:1;;16272:85;15790:627;-1:-1:-1;;;15790:627:1:o;16422:388::-;16490:6;16498;16551:2;16539:9;16530:7;16526:23;16522:32;16519:52;;;16567:1;16564;16557:12;16519:52;16606:9;16593:23;16625:31;16650:5;16625:31;:::i;:::-;16675:5;-1:-1:-1;16732:2:1;16717:18;;16704:32;16745:33;16704:32;16745:33;:::i;18557:356::-;18759:2;18741:21;;;18778:18;;;18771:30;18837:34;18832:2;18817:18;;18810:62;18904:2;18889:18;;18557:356::o;18918:127::-;18979:10;18974:3;18970:20;18967:1;18960:31;19010:4;19007:1;19000:15;19034:4;19031:1;19024:15;19050:125;19090:4;19118:1;19115;19112:8;19109:34;;;19123:18;;:::i;:::-;-1:-1:-1;19160:9:1;;19050:125::o;19180:127::-;19241:10;19236:3;19232:20;19229:1;19222:31;19272:4;19269:1;19262:15;19296:4;19293:1;19286:15;19312:380;19391:1;19387:12;;;;19434;;;19455:61;;19509:4;19501:6;19497:17;19487:27;;19455:61;19562:2;19554:6;19551:14;19531:18;19528:38;19525:161;;19608:10;19603:3;19599:20;19596:1;19589:31;19643:4;19640:1;19633:15;19671:4;19668:1;19661:15;19697:201;19735:3;19763:10;19808:2;19801:5;19797:14;19835:2;19826:7;19823:15;19820:41;;19841:18;;:::i;:::-;19890:1;19877:15;;19697:201;-1:-1:-1;;;19697:201:1:o;19903:128::-;19943:3;19974:1;19970:6;19967:1;19964:13;19961:39;;;19980:18;;:::i;:::-;-1:-1:-1;20016:9:1;;19903:128::o;20036:135::-;20075:3;20096:17;;;20093:43;;20116:18;;:::i;:::-;-1:-1:-1;20163:1:1;20152:13;;20036:135::o;20176:209::-;20208:1;20234;20224:132;;20278:10;20273:3;20269:20;20266:1;20259:31;20313:4;20310:1;20303:15;20341:4;20338:1;20331:15;20224:132;-1:-1:-1;20370:9:1;;20176:209::o;20390:168::-;20430:7;20496:1;20492;20488:6;20484:14;20481:1;20478:21;20473:1;20466:9;20459:17;20455:45;20452:71;;;20503:18;;:::i;:::-;-1:-1:-1;20543:9:1;;20390:168::o;20563:355::-;20765:2;20747:21;;;20804:2;20784:18;;;20777:30;20843:33;20838:2;20823:18;;20816:61;20909:2;20894:18;;20563:355::o;21240:221::-;21279:4;21308:10;21368;;;;21338;;21390:12;;;21387:38;;;21405:18;;:::i;:::-;21442:13;;21240:221;-1:-1:-1;;;21240:221:1:o;22226:635::-;22306:6;22359:2;22347:9;22338:7;22334:23;22330:32;22327:52;;;22375:1;22372;22365:12;22327:52;22408:9;22402:16;-1:-1:-1;;;;;22433:6:1;22430:30;22427:50;;;22473:1;22470;22463:12;22427:50;22496:22;;22549:4;22541:13;;22537:27;-1:-1:-1;22527:55:1;;22578:1;22575;22568:12;22527:55;22607:2;22601:9;22632:48;22648:31;22676:2;22648:31;:::i;22632:48::-;22703:2;22696:5;22689:17;22743:7;22738:2;22733;22729;22725:11;22721:20;22718:33;22715:53;;;22764:1;22761;22754:12;22715:53;22777:54;22828:2;22823;22816:5;22812:14;22807:2;22803;22799:11;22777:54;:::i;22866:424::-;-1:-1:-1;;;23123:3:1;23116:22;23098:3;23167:6;23161:13;23183:61;23237:6;23233:1;23228:3;23224:11;23217:4;23209:6;23205:17;23183:61;:::i;:::-;23264:16;;;;23282:1;23260:24;;22866:424;-1:-1:-1;;22866:424:1:o;23955:386::-;24187:1;24183;24178:3;24174:11;24170:19;24162:6;24158:32;24147:9;24140:51;24227:6;24222:2;24211:9;24207:18;24200:34;24270:2;24265;24254:9;24250:18;24243:30;24121:4;24290:45;24331:2;24320:9;24316:18;24308:6;24290:45;:::i;24346:245::-;24413:6;24466:2;24454:9;24445:7;24441:23;24437:32;24434:52;;;24482:1;24479;24472:12;24434:52;24514:9;24508:16;24533:28;24555:5;24533:28;:::i;24596:489::-;-1:-1:-1;;;;;24865:15:1;;;24847:34;;24917:15;;24912:2;24897:18;;24890:43;24964:2;24949:18;;24942:34;;;25012:3;25007:2;24992:18;;24985:31;;;24790:4;;25033:46;;25059:19;;25051:6;25033:46;:::i;:::-;25025:54;24596:489;-1:-1:-1;;;;;;24596:489:1:o;25090:249::-;25159:6;25212:2;25200:9;25191:7;25187:23;25183:32;25180:52;;;25228:1;25225;25218:12;25180:52;25260:9;25254:16;25279:30;25303:5;25279:30;:::i;26845:127::-;26906:10;26901:3;26897:20;26894:1;26887:31;26937:4;26934:1;26927:15;26961:4;26958:1;26951:15

Swarm Source

ipfs://915286e7b8277fbc158efcc38e68723db9664232eec815b42dd3a9de2c321027
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.