ERC-1155
Overview
Max Total Supply
10,000 SUN
Holders
34
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
ERC_X
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-02-26 */ /** *Submitted for verification at Etherscan.io on 2024-02-26 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @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); } /** * @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); } /** * @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); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } /** * @dev Interface that must be implemented by smart contracts in order to receive * ERC-1155 token transfers. */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the value of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. * * WARNING: This function can potentially allow a reentrancy attack when transferring tokens * to an untrusted contract, when invoking {onERC1155Received} on the receiver. * Ensure to follow the checks-effects-interactions pattern and consider employing * reentrancy guards when interacting with untrusted contracts. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `value` amount. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * WARNING: This function can potentially allow a reentrancy attack when transferring tokens * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver. * Ensure to follow the checks-effects-interactions pattern and consider employing * reentrancy guards when interacting with untrusted contracts. * * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments. * * Requirements: * * - `ids` and `values` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external; } /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. */ interface IERC1155MetadataURI is IERC1155 { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); } /** * @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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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 address zero. * * 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); } /** * @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); } /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; 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_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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); } } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } } /// @notice Library for bit twiddling and boolean operations. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol) /// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html) library LibBit { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* BIT TWIDDLING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Find last set. /// Returns the index of the most significant bit of `x`, /// counting from the least significant bit position. /// If `x` is zero, returns 256. function fls(uint256 x) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x))) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) r := or(r, shl(4, lt(0xffff, shr(r, x)))) r := or(r, shl(3, lt(0xff, shr(r, x)))) // forgefmt: disable-next-item r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)), 0x0706060506020504060203020504030106050205030304010505030400000000)) } } /// @dev Count leading zeros. /// Returns the number of zeros preceding the most significant one bit. /// If `x` is zero, returns 256. function clz(uint256 x) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) r := or(r, shl(4, lt(0xffff, shr(r, x)))) r := or(r, shl(3, lt(0xff, shr(r, x)))) // forgefmt: disable-next-item r := add(xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)), 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff)), iszero(x)) } } /// @dev Find first set. /// Returns the index of the least significant bit of `x`, /// counting from the least significant bit position. /// If `x` is zero, returns 256. /// Equivalent to `ctz` (count trailing zeros), which gives /// the number of zeros following the least significant one bit. function ffs(uint256 x) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Isolate the least significant bit. let b := and(x, add(not(x), 1)) r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, b))) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, b)))) r := or(r, shl(5, lt(0xffffffff, shr(r, b)))) // For the remaining 32 bits, use a De Bruijn lookup. // forgefmt: disable-next-item r := or(r, byte(and(div(0xd76453e0, shr(r, b)), 0x1f), 0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405)) } } /// @dev Returns the number of set bits in `x`. function popCount(uint256 x) internal pure returns (uint256 c) { /// @solidity memory-safe-assembly assembly { let max := not(0) let isMax := eq(x, max) x := sub(x, and(shr(1, x), div(max, 3))) x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5))) x := and(add(x, shr(4, x)), div(max, 17)) c := or(shl(8, isMax), shr(248, mul(x, div(max, 255)))) } } /// @dev Returns whether `x` is a power of 2. function isPo2(uint256 x) internal pure returns (bool result) { /// @solidity memory-safe-assembly assembly { // Equivalent to `x && !(x & (x - 1))`. result := iszero(add(and(x, sub(x, 1)), iszero(x))) } } /// @dev Returns `x` reversed at the bit level. function reverseBits(uint256 x) internal pure returns (uint256 r) { uint256 m0 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; uint256 m1 = m0 ^ (m0 << 2); uint256 m2 = m1 ^ (m1 << 1); r = reverseBytes(x); r = (m2 & (r >> 1)) | ((m2 & r) << 1); r = (m1 & (r >> 2)) | ((m1 & r) << 2); r = (m0 & (r >> 4)) | ((m0 & r) << 4); } /// @dev Returns `x` reversed at the byte level. function reverseBytes(uint256 x) internal pure returns (uint256 r) { unchecked { // Computing masks on-the-fly reduces bytecode size by about 200 bytes. uint256 m0 = 0x100000000000000000000000000000001 * (~toUint(x == 0) >> 192); uint256 m1 = m0 ^ (m0 << 32); uint256 m2 = m1 ^ (m1 << 16); uint256 m3 = m2 ^ (m2 << 8); r = (m3 & (x >> 8)) | ((m3 & x) << 8); r = (m2 & (r >> 16)) | ((m2 & r) << 16); r = (m1 & (r >> 32)) | ((m1 & r) << 32); r = (m0 & (r >> 64)) | ((m0 & r) << 64); r = (r >> 128) | (r << 128); } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* BOOLEAN OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // A Solidity bool on the stack or memory is represented as a 256-bit word. // Non-zero values are true, zero is false. // A clean bool is either 0 (false) or 1 (true) under the hood. // Usually, if not always, the bool result of a regular Solidity expression, // or the argument of a public/external function will be a clean bool. // You can usually use the raw variants for more performance. // If uncertain, test (best with exact compiler settings). // Or use the non-raw variants (compiler can sometimes optimize out the double `iszero`s). /// @dev Returns `x & y`. Inputs must be clean. function rawAnd(bool x, bool y) internal pure returns (bool z) { /// @solidity memory-safe-assembly assembly { z := and(x, y) } } /// @dev Returns `x & y`. function and(bool x, bool y) internal pure returns (bool z) { /// @solidity memory-safe-assembly assembly { z := and(iszero(iszero(x)), iszero(iszero(y))) } } /// @dev Returns `x | y`. Inputs must be clean. function rawOr(bool x, bool y) internal pure returns (bool z) { /// @solidity memory-safe-assembly assembly { z := or(x, y) } } /// @dev Returns `x | y`. function or(bool x, bool y) internal pure returns (bool z) { /// @solidity memory-safe-assembly assembly { z := or(iszero(iszero(x)), iszero(iszero(y))) } } /// @dev Returns 1 if `b` is true, else 0. Input must be clean. function rawToUint(bool b) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { z := b } } /// @dev Returns 1 if `b` is true, else 0. function toUint(bool b) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { z := iszero(iszero(b)) } } } /// @notice Library for storage of packed unsigned booleans. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBitmap.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibBitmap.sol) /// @author Modified from Solidity-Bits (https://github.com/estarriolvetch/solidity-bits/blob/main/contracts/BitMaps.sol) library LibBitmap { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The constant returned when a bitmap scan does not find a result. uint256 internal constant NOT_FOUND = type(uint256).max; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STRUCTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev A bitmap in storage. struct Bitmap { mapping(uint256 => uint256) map; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the boolean value of the bit at `index` in `bitmap`. function get(Bitmap storage bitmap, uint256 index) internal view returns (bool isSet) { // It is better to set `isSet` to either 0 or 1, than zero vs non-zero. // Both cost the same amount of gas, but the former allows the returned value // to be reused without cleaning the upper bits. uint256 b = (bitmap.map[index >> 8] >> (index & 0xff)) & 1; /// @solidity memory-safe-assembly assembly { isSet := b } } /// @dev Updates the bit at `index` in `bitmap` to true. function set(Bitmap storage bitmap, uint256 index) internal { bitmap.map[index >> 8] |= (1 << (index & 0xff)); } /// @dev Updates the bit at `index` in `bitmap` to false. function unset(Bitmap storage bitmap, uint256 index) internal { bitmap.map[index >> 8] &= ~(1 << (index & 0xff)); } /// @dev Flips the bit at `index` in `bitmap`. /// Returns the boolean result of the flipped bit. function toggle(Bitmap storage bitmap, uint256 index) internal returns (bool newIsSet) { /// @solidity memory-safe-assembly assembly { mstore(0x20, bitmap.slot) mstore(0x00, shr(8, index)) let storageSlot := keccak256(0x00, 0x40) let shift := and(index, 0xff) let storageValue := xor(sload(storageSlot), shl(shift, 1)) // It makes sense to return the `newIsSet`, // as it allow us to skip an additional warm `sload`, // and it costs minimal gas (about 15), // which may be optimized away if the returned value is unused. newIsSet := and(1, shr(shift, storageValue)) sstore(storageSlot, storageValue) } } /// @dev Updates the bit at `index` in `bitmap` to `shouldSet`. function setTo(Bitmap storage bitmap, uint256 index, bool shouldSet) internal { /// @solidity memory-safe-assembly assembly { mstore(0x20, bitmap.slot) mstore(0x00, shr(8, index)) let storageSlot := keccak256(0x00, 0x40) let storageValue := sload(storageSlot) let shift := and(index, 0xff) sstore( storageSlot, // Unsets the bit at `shift` via `and`, then sets its new value via `or`. or(and(storageValue, not(shl(shift, 1))), shl(shift, iszero(iszero(shouldSet)))) ) } } /// @dev Consecutively sets `amount` of bits starting from the bit at `start`. function setBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let max := not(0) let shift := and(start, 0xff) mstore(0x20, bitmap.slot) mstore(0x00, shr(8, start)) if iszero(lt(add(shift, amount), 257)) { let storageSlot := keccak256(0x00, 0x40) sstore(storageSlot, or(sload(storageSlot), shl(shift, max))) let bucket := add(mload(0x00), 1) let bucketEnd := add(mload(0x00), shr(8, add(amount, shift))) amount := and(add(amount, shift), 0xff) shift := 0 for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } { mstore(0x00, bucket) sstore(keccak256(0x00, 0x40), max) } mstore(0x00, bucket) } let storageSlot := keccak256(0x00, 0x40) sstore(storageSlot, or(sload(storageSlot), shl(shift, shr(sub(256, amount), max)))) } } /// @dev Consecutively unsets `amount` of bits starting from the bit at `start`. function unsetBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let shift := and(start, 0xff) mstore(0x20, bitmap.slot) mstore(0x00, shr(8, start)) if iszero(lt(add(shift, amount), 257)) { let storageSlot := keccak256(0x00, 0x40) sstore(storageSlot, and(sload(storageSlot), not(shl(shift, not(0))))) let bucket := add(mload(0x00), 1) let bucketEnd := add(mload(0x00), shr(8, add(amount, shift))) amount := and(add(amount, shift), 0xff) shift := 0 for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } { mstore(0x00, bucket) sstore(keccak256(0x00, 0x40), 0) } mstore(0x00, bucket) } let storageSlot := keccak256(0x00, 0x40) sstore( storageSlot, and(sload(storageSlot), not(shl(shift, shr(sub(256, amount), not(0))))) ) } } /// @dev Returns number of set bits within a range by /// scanning `amount` of bits starting from the bit at `start`. function popCount(Bitmap storage bitmap, uint256 start, uint256 amount) internal view returns (uint256 count) { unchecked { uint256 bucket = start >> 8; uint256 shift = start & 0xff; if (!(amount + shift < 257)) { count = LibBit.popCount(bitmap.map[bucket] >> shift); uint256 bucketEnd = bucket + ((amount + shift) >> 8); amount = (amount + shift) & 0xff; shift = 0; for (++bucket; bucket != bucketEnd; ++bucket) { count += LibBit.popCount(bitmap.map[bucket]); } } count += LibBit.popCount((bitmap.map[bucket] >> shift) << (256 - amount)); } } /// @dev Returns the index of the most significant set bit before the bit at `before`. /// If no set bit is found, returns `NOT_FOUND`. function findLastSet(Bitmap storage bitmap, uint256 before) internal view returns (uint256 setBitIndex) { uint256 bucket; uint256 bucketBits; /// @solidity memory-safe-assembly assembly { setBitIndex := not(0) bucket := shr(8, before) mstore(0x00, bucket) mstore(0x20, bitmap.slot) let offset := and(0xff, not(before)) // `256 - (255 & before) - 1`. bucketBits := shr(offset, shl(offset, sload(keccak256(0x00, 0x40)))) if iszero(or(bucketBits, iszero(bucket))) { for {} 1 {} { bucket := add(bucket, setBitIndex) // `sub(bucket, 1)`. mstore(0x00, bucket) bucketBits := sload(keccak256(0x00, 0x40)) if or(bucketBits, iszero(bucket)) { break } } } } if (bucketBits != 0) { setBitIndex = (bucket << 8) | LibBit.fls(bucketBits); /// @solidity memory-safe-assembly assembly { setBitIndex := or(setBitIndex, sub(0, gt(setBitIndex, before))) } } } } interface IERCX { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * 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(); /** * Cannot burn from the zero address. */ error BurnFromZeroAddress(); /** * Cannot burn from the address that doesn't owne the token. */ error BurnFromNonOwnerAddress(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from` or the `amount` is not 1. */ error TransferFromIncorrectOwnerOrInvalidAmount(); /** * Cannot safely transfer to a contract that does not implement the * ERC1155Receiver interface. */ error TransferToNonERC1155ReceiverImplementer(); error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The length of input arraies is not matching. */ error InputLengthMistmatch(); // Contract has been re-entered during safe transfer error Reentrance(); function isOwnerOf(address account, uint256 id) external view returns(bool); } abstract contract ERC721Receiver is IERC721Receiver { function onERC721Received( address, address, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC721Receiver.onERC721Received.selector; } } contract ERCX is Context, ERC165, IERC1155, IERC1155MetadataURI, IERCX, IERC20Metadata, IERC20Errors, Ownable { using Address for address; using LibBitmap for LibBitmap.Bitmap; error InvalidQueryRange(); event WhitelistEnabled(address indexed wallet); event WhitelistDisabled(address indexed wallet); event URIUpdated(); event TransfersDelayUpdated(bool status); event MaxWalletUpdated(uint256 max); // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // Mapping from accout to owned tokens mapping(address => LibBitmap.Bitmap) internal _owned; // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json string private _uri; // The next token ID to be minted. uint256 private _currentIndex; // NFT Approval mapping(uint256 => address) public getApproved; //Token balances mapping(address => uint256) internal _balances; //Token allowances mapping(address account => mapping(address spender => uint256)) private _allowances; // Token name string public name; // Token symbol string public symbol; // Decimals for supply uint8 public immutable decimals; // Total ERC20 supply uint256 public immutable totalSupply; // Tokens Per NFT uint256 public immutable decimalFactor; uint256 public immutable tokensPerNFT; // Don't mint for these wallets mapping(address => bool) public whitelist; // Easy Launch - auto-whitelist first transfer which is probably the LP uint256 public easyLaunch = 1; /** * @dev See {_setURI}. */ constructor(string memory uri_, string memory _name, string memory _symbol, uint8 _decimals, uint256 _totalNativeSupply, uint256 _tokensPerNFT) Ownable(msg.sender) { _setURI(uri_); _currentIndex = _startTokenId(); name = _name; symbol = _symbol; decimals = _decimals; decimalFactor = 10 ** decimals; tokensPerNFT = _tokensPerNFT * decimalFactor; totalSupply = _totalNativeSupply * decimalFactor; whitelist[msg.sender] = true; whitelist[0xbEA9C94fB1E2748D8e002d1913FA58593C381EA5] = true; whitelist[0xE592427A0AEce92De3Edee1F18E0157C05861564] = true; _balances[msg.sender] = totalSupply; emit Transfer(address(0), msg.sender, totalSupply); } /** @notice Initialization function to set pairs / etc * saving gas by avoiding mint / burn on unnecessary targets. * Burns held NFTs if entering whitelist mode. */ function setWhitelist(address target, bool state) public virtual onlyOwner { require(whitelist[target] != state, "No change to status"); if(state) { uint256 bal = balanceOf(target,0,_nextTokenId()); if(bal > 0) _burnBatch(target, bal); emit WhitelistEnabled(target); } else { uint256 bal = balanceOf(target); uint256 tokens_to_mint = bal / tokensPerNFT; if(tokens_to_mint > 0) _mintWithoutCheck(target, tokens_to_mint); emit WhitelistDisabled(target); } whitelist[target] = state; } /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal pure virtual returns (uint256) { return 1; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view returns (uint256) { return _currentIndex; } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view returns (uint256) { return _nextTokenId() - _startTokenId(); } /** * @dev Returns true if the account owns the `id` token. */ function isOwnerOf(address account, uint256 id) public view virtual override returns(bool) { return _owned[account].get(id); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155).interfaceId || interfaceId == type(IERC1155MetadataURI).interfaceId || interfaceId == type(IERCX).interfaceId || interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f || // ERC165 interface ID for ERC721Metadata. super.supportsInterface(interfaceId); } /** * @dev See {IERC1155MetadataURI-uri}. * * This implementation returns the same URI for *all* token types. It relies * on the token type ID substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * Clients calling this function must replace the `\{id\}` substring with the * actual token type ID. */ function uri(uint256) public view virtual override returns (string memory) { return _uri; } /** * @dev Returns the number of tokens owned by `owner`. */ function balanceOf(address owner) public view virtual returns (uint256) { return _balances[owner]; } /** * @dev Returns the number of nfts owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * Requirements: * * - `start < stop` */ function balanceOf(address owner, uint256 start, uint256 stop) public view virtual returns (uint256) { return _owned[owner].popCount(start, stop - start); } /** * @dev See {IERC1155-balanceOf}. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { if(account == address(0)) { revert BalanceQueryForZeroAddress(); } if(_owned[account].get(id)) { return 1; } else { return 0; } } /** * @dev See {IERC1155-balanceOfBatch}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual override returns (uint256[] memory) { if(accounts.length != ids.length) { revert InputLengthMistmatch(); } uint256[] memory batchBalances = new uint256[](accounts.length); for (uint256 i = 0; i < accounts.length; ++i) { batchBalances[i] = balanceOf(accounts[i], ids[i]); } return batchBalances; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return _operatorApprovals[account][operator]; } /** * @dev See {IERC1155-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { if(from == _msgSender() || isApprovedForAll(from, _msgSender())){ _safeTransferFrom(from, to, id, amount, data, true); } else { revert TransferCallerNotOwnerNorApproved(); } } /** * @dev See {IERC1155-safeBatchTransferFrom}. */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { if(!(from == _msgSender() || isApprovedForAll(from, _msgSender()))) { revert TransferCallerNotOwnerNorApproved(); } _safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - `amount` cannot be zero. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data, bool check ) internal virtual { if(to == address(0)) { revert TransferToZeroAddress(); } address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); _beforeTokenTransfer(operator, from, to, ids); if(amount == 1 && _owned[from].get(id)) { _owned[from].unset(id); _owned[to].set(id); _transfer(from, to, tokensPerNFT, false); } else { revert TransferFromIncorrectOwnerOrInvalidAmount(); } uint256 toMasked; uint256 fromMasked; assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) fromMasked := and(from, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. fromMasked, // `from`. toMasked, // `to`. amount // `tokenId`. ) } emit TransferSingle(operator, from, to, id, amount); _afterTokenTransfer(operator, from, to, ids); if(check) { uint256 end = _nextTokenId(); _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); if (_nextTokenId() != end) revert Reentrance(); } } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { if(ids.length != amounts.length) { revert InputLengthMistmatch(); } if(to == address(0)) { revert TransferToZeroAddress(); } address operator = _msgSender(); _beforeTokenTransfer(operator, from, to, ids); for (uint256 i = 0; i < ids.length; ++i) { uint256 id = ids[i]; uint256 amount = amounts[i]; if(amount == 1 && _owned[from].get(id)) { _owned[from].unset(id); _owned[to].set(id); } else { revert TransferFromIncorrectOwnerOrInvalidAmount(); } } _transfer(from, to, tokensPerNFT * ids.length, false); uint256 toMasked; uint256 fromMasked; uint256 end = ids.length + 1; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. fromMasked := and(from, _BITMASK_ADDRESS) toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. fromMasked, // `from`. toMasked, // `to`. mload(add(ids, 0x20)) // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let arrayId := 2 } iszero(eq(arrayId, end)) { arrayId := add(arrayId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, toMasked, mload(add(ids, mul(0x20, arrayId)))) } } emit TransferBatch(operator, from, to, ids, amounts); _afterTokenTransfer(operator, from, to, ids); uint256 tokID = _nextTokenId(); _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); if (_nextTokenId() != tokID) revert Reentrance(); } /** * @dev Sets a new URI for all token types, by relying on the token type ID * substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * By this mechanism, any occurrence of the `\{id\}` substring in either the * URI or any of the amounts in the JSON file at said URI will be replaced by * clients with the token type ID. * * For example, the `https://token-cdn-domain/\{id\}.json` URI would be * interpreted by clients as * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` * for token type ID 0x4cce0. * * See {uri}. * * Because these URIs cannot be meaningfully represented by the {URI} event, * this function emits no events. */ function _setURI(string memory newuri) internal virtual { _uri = newuri; } /** * @dev Creates `amount` tokens, and assigns them to `to`. * * Emits a {TransferBatch} event. * * Requirements: * * - `to` cannot be the zero address. * - `amount` cannot be zero. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _mint( address to, uint256 amount, bytes memory data ) internal virtual { (uint256[] memory ids, uint256[] memory amounts) = _mintWithoutCheck(to, amount); uint256 end = _nextTokenId(); _doSafeBatchTransferAcceptanceCheck(_msgSender(), address(0), to, ids, amounts, data); if (_nextTokenId() != end) revert Reentrance(); } function _mintWithoutCheck( address to, uint256 amount ) internal virtual returns(uint256[] memory ids, uint256[] memory amounts) { if(to == address(0)) { revert MintToZeroAddress(); } if(amount == 0) { revert MintZeroQuantity(); } address operator = _msgSender(); ids = new uint256[](amount); amounts = new uint256[](amount); uint256 startTokenId = _nextTokenId(); unchecked { require(type(uint256).max - amount >= startTokenId, "Minting limits reached"); for(uint256 i = 0; i < amount; i++) { ids[i] = startTokenId + i; amounts[i] = 1; } } _beforeTokenTransfer(operator, address(0), to, ids); _owned[to].setBatch(startTokenId, amount); _currentIndex += amount; uint256 toMasked; uint256 end = startTokenId + amount; assembly { toMasked := and(to, _BITMASK_ADDRESS) log4( 0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, startTokenId ) for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } emit TransferBatch(operator, address(0), to, ids, amounts); _afterTokenTransfer(operator, address(0), to, ids); } /** * @dev Destroys token of token type `id` from `from` * * Emits a {TransferSingle} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have the token of token type `id`. */ function _burn( address from, uint256 id ) internal virtual { if(from == address(0)){ revert BurnFromZeroAddress(); } address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); _beforeTokenTransfer(operator, from, address(0), ids); if(!_owned[from].get(id)) { revert BurnFromNonOwnerAddress(); } _owned[from].unset(id); uint256 fromMasked; assembly { fromMasked := and(from, _BITMASK_ADDRESS) log4( 0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, 0, id ) } emit TransferSingle(operator, from, address(0), id, 1); _afterTokenTransfer(operator, from, address(0), ids); } /** * @dev Destroys tokens of token types in `ids` from `from` * * Emits a {TransferBatch} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have the token of token types in `ids`. */ function _burnBatch( address from, uint256[] memory ids ) internal virtual { if(from == address(0)){ revert BurnFromZeroAddress(); } address operator = _msgSender(); uint256[] memory amounts = new uint256[](ids.length); _beforeTokenTransfer(operator, from, address(0), ids); unchecked { for(uint256 i = 0; i < ids.length; i++) { amounts[i] = 1; uint256 id = ids[i]; if(!_owned[from].get(id)) { revert BurnFromNonOwnerAddress(); } _owned[from].unset(id); } } uint256 fromMasked; uint256 end = ids.length + 1; assembly { fromMasked := and(from, _BITMASK_ADDRESS) log4( 0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, 0, mload(add(ids, 0x20)) ) for { let arrayId := 2 } iszero(eq(arrayId, end)) { arrayId := add(arrayId, 1) } { log4(0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, 0, mload(add(ids, mul(0x20, arrayId)))) } } emit TransferBatch(operator, from, address(0), ids, amounts); _afterTokenTransfer(operator, from, address(0), ids); } function _burnBatch( address from, uint256 amount ) internal virtual { if(from == address(0)){ revert BurnFromZeroAddress(); } address operator = _msgSender(); uint256 searchFrom = _nextTokenId(); uint256[] memory amounts = new uint256[](amount); uint256[] memory ids = new uint256[](amount); unchecked { for(uint256 i = 0; i < amount; i++) { amounts[i] = 1; uint256 id = _owned[from].findLastSet(searchFrom); if(id == LibBitmap.NOT_FOUND) revert BurnFromNonOwnerAddress(); ids[i] = id; _owned[from].unset(id); searchFrom = id; } } //technically after, but we didn't have the IDs then _beforeTokenTransfer(operator, from, address(0), ids); uint256 fromMasked; uint256 end = amount + 1; assembly { fromMasked := and(from, _BITMASK_ADDRESS) log4( 0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, 0, mload(add(ids, 0x20)) ) for { let arrayId := 2 } iszero(eq(arrayId, end)) { arrayId := add(arrayId, 1) } { log4(0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, 0, mload(add(ids, mul(0x20, arrayId)))) } } if(amount == 1) emit TransferSingle(operator, from, address(0), ids[0], 1); else emit TransferBatch(operator, from, address(0), ids, amounts); _afterTokenTransfer(operator, from, address(0), ids); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC1155: setting approval status for self"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Hook that is called before any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `ids` and `amounts` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `id` and `amount` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids ) internal virtual {} function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.code.length > 0) { if (IERC165(to).supportsInterface(type(IERC1155).interfaceId)) { try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { if (response != IERC1155Receiver.onERC1155Received.selector) { revert TransferToNonERC1155ReceiverImplementer(); } } catch Error(string memory reason) { revert(reason); } catch { revert TransferToNonERC1155ReceiverImplementer(); } } else { try ERC721Receiver(to).onERC721Received(operator, from, id, data) returns (bytes4 response) { if (response != ERC721Receiver.onERC721Received.selector) { revert TransferToNonERC721ReceiverImplementer(); } } catch Error(string memory reason) { revert(reason); } catch { revert TransferToNonERC721ReceiverImplementer(); } } } } function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.code.length > 0) { try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response ) { if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { revert TransferToNonERC1155ReceiverImplementer(); } } catch Error(string memory reason) { revert(reason); } catch { revert TransferToNonERC1155ReceiverImplementer(); } } } function _asSingletonArray(uint256 element) private pure returns (uint256[] memory array) { array = new uint256[](1); array[0] = element; } function transfer(address to, uint256 value) public virtual returns (bool) { address owner = msg.sender; _transfer(owner, to, value, true); return true; } function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 value) public virtual returns (bool) { address owner = msg.sender; if (value < _nextTokenId() && value > 0) { if(!isOwnerOf(owner, value)) { revert ERC20InvalidSender(owner); } getApproved[value] = spender; emit Approval(owner, spender, value); } else { _approve(owner, spender, value); } return true; } /// @notice Function for mixed transfers /// @dev This function assumes id / native if amount less than or equal to current max id function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { if (value < _nextTokenId()) { if(!_owned[from].get(value)) { revert ERC20InvalidSpender(from); } if ( msg.sender != from && !isApprovedForAll(from, msg.sender) && msg.sender != getApproved[value] ) { revert ERC20InvalidSpender(msg.sender); } delete getApproved[value]; _safeTransferFrom(from, to, value, 1, "", false); } else { _spendAllowance(from, msg.sender, value); _transfer(from, to, value, true); } return true; } function _transfer(address from, address to, uint256 value, bool mint) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value, mint); } function _update(address from, address to, uint256 value, bool mint) internal virtual { uint256 fromBalance = _balances[from]; uint256 toBalance = _balances[to]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } //No need to adjust balances when transfer is to self, prevent self NFT-grind if(from != to) { unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] = toBalance + value; } if(mint) { // Skip burn for certain addresses to save gas bool wlf = whitelist[from]; if (!wlf) { uint256 tokens_to_burn = (fromBalance / tokensPerNFT) - ((fromBalance - value) / tokensPerNFT); if(tokens_to_burn > 0) _burnBatch(from, tokens_to_burn); } // Skip minting for certain addresses to save gas if (!whitelist[to]) { if(easyLaunch == 1 && wlf && from == owner()) { //auto-initialize first (assumed) LP whitelist[to] = true; easyLaunch = 2; } else { uint256 tokens_to_mint = ((toBalance + value) / tokensPerNFT) - (toBalance / tokensPerNFT); if(tokens_to_mint > 0) _mintWithoutCheck(to, tokens_to_mint); } } } } emit Transfer(from, to, value); } function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } /** * @dev Returns an array of token IDs owned by `owner`, * in the range [`start`, `stop`) * (i.e. `start <= tokenId < stop`). * * This function allows for tokens to be queried if the collection * grows too big for a single call of {ERC1155DelataQueryable-tokensOfOwner}. * * Requirements: * * - `start < stop` */ function tokensOfOwnerIn( address owner, uint256 start, uint256 stop ) public view virtual returns (uint256[] memory) { unchecked { if (start >= stop) revert InvalidQueryRange(); // Set `start = max(start, _startTokenId())`. if (start < _startTokenId()) { start = _startTokenId(); } // Set `stop = min(stop, stopLimit)`. uint256 stopLimit = _nextTokenId(); if (stop > stopLimit) { stop = stopLimit; } uint256 tokenIdsLength; if(start < stop) { tokenIdsLength = balanceOf(owner, start, stop); } else { tokenIdsLength = 0; } uint256[] memory tokenIds = new uint256[](tokenIdsLength); LibBitmap.Bitmap storage bmap = _owned[owner]; for ((uint256 i, uint256 tokenIdsIdx) = (start, 0); tokenIdsIdx != tokenIdsLength; ++i) { if(bmap.get(i) ) { tokenIds[tokenIdsIdx++] = i; } } return tokenIds; } } /** * @dev Returns an array of token IDs owned by `owner`. * * This function scans the ownership mapping and is O(`totalSupply`) in complexity. * It is meant to be called off-chain. * * See {ERC1155DeltaQueryable-tokensOfOwnerIn} for splitting the scan into * multiple smaller scans if the collection is large enough to cause * an out-of-gas error (10K collections should be fine). */ function tokensOfOwner(address owner) public view virtual returns (uint256[] memory) { if(_totalMinted() == 0) { return new uint256[](0); } return tokensOfOwnerIn(owner, _startTokenId(), _nextTokenId()); } } contract ERC_X is ERCX { using Strings for uint256; string public dataURI; string public baseTokenURI; uint8 private constant _decimals = 18; uint256 private constant _totalTokens = 10000; uint256 private constant _tokensPerNFT = 1; string private constant _name = "SUN"; string private constant _ticker = "SUN"; // Snipe reduction tools uint256 public maxWallet; bool public transferDelay = true; mapping (address => uint256) private delayTimer; constructor() ERCX("", _name, _ticker, _decimals, _totalTokens, _tokensPerNFT) { dataURI = "https://raw.githubusercontent.com/venusgalstar/SUNERC404V2/master/"; maxWallet = (_totalTokens * 10 ** _decimals) * 2 / 100; } function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids ) internal override { if(!whitelist[to]) { require(_balances[to] <= maxWallet, "Transfer exceeds maximum wallet"); if (transferDelay) { require(delayTimer[tx.origin] < block.number,"Only one transfer per block allowed."); delayTimer[tx.origin] = block.number; require(address(to).code.length == 0 && address(tx.origin).code.length == 0, "Contract trading restricted at launch"); } } super._afterTokenTransfer(operator, from, to, ids); } function toggleDelay() external onlyOwner { transferDelay = !transferDelay; emit TransfersDelayUpdated(transferDelay); } function setMaxWallet(uint256 percent) external onlyOwner { require(percent > 0, "Cannot disable normal trading"); maxWallet = totalSupply * percent / 100; emit MaxWalletUpdated(totalSupply * percent / 100); } function setDataURI(string memory _dataURI) public onlyOwner { dataURI = _dataURI; emit URIUpdated(); } function setTokenURI(string memory _tokenURI) public onlyOwner { baseTokenURI = _tokenURI; emit URIUpdated(); } function setURI(string memory newuri) external onlyOwner { _setURI(newuri); emit URIUpdated(); } function tokenURI(uint256 id) public view returns (string memory) { if(id >= _nextTokenId()) revert InputLengthMistmatch(); if (bytes(super.uri(id)).length > 0) return super.uri(id); if (bytes(baseTokenURI).length > 0) return string(abi.encodePacked(baseTokenURI, id.toString())); else { uint8 seed = uint8(bytes1(keccak256(abi.encodePacked(id)))); string memory image = ""; string memory color = ""; string memory description = ""; if (seed <= 63) { image = "photo_5080192175496604674_y.jpg"; color = "Diamond"; description = "Legendary NFTs powered by ERC1155. The Diamond NFTs are meticulously sunned by industry elites and crafted with unparalleled precision, representing the zenith of luxury and digital artistry."; } else if (seed <= 127) { image = "photo_5080192175496604675_y.jpg"; color = "Gold"; description = "Prestigious NFTs powered by ERC1155. The gold NFTs are carefully sunned by expert collectors and meticulously crafted with golden excellence, symbolizing the pinnacle of digital rarity and exclusivity."; } else if (seed <= 191) { image = "photo_5080192175496604676_y.jpg"; color = "Silver"; description = "Refined NFTs powered by ERC1155. The silver NFTs are sunned by seasoned enthusiasts, adding an extra layer of sophistication to your portfolio."; } else { image = "photo_5080192175496604677_y.jpg"; color = "Bronze"; description = "Entry level NFTs powered by ERC1155. The silver NFTs are sunned by aspiring collectors and meticulously crafted for accessibility."; } string memory jsonPreImage = string(abi.encodePacked('{"name": "SUN #', id.toString(), '","description":"', description, '","external_url":"https://www.solarflare.lol","image":"', dataURI, image)); return string(abi.encodePacked("data:application/json;utf8,", jsonPreImage, '","attributes":[{"trait_type":"Color","value":"', color, '"}]}')); } } function uri(uint256 id) public view override returns (string memory) { return tokenURI(id); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"BurnFromNonOwnerAddress","type":"error"},{"inputs":[],"name":"BurnFromZeroAddress","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"InputLengthMistmatch","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"Reentrance","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwnerOrInvalidAmount","type":"error"},{"inputs":[],"name":"TransferToNonERC1155ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","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":false,"internalType":"uint256","name":"max","type":"uint256"}],"name":"MaxWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"TransfersDelayUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[],"name":"URIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"WhitelistDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"WhitelistEnabled","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"easyLaunch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"isOwnerOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_dataURI","type":"string"}],"name":"setDataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"percent","type":"uint256"}],"name":"setMaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensPerNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferDelay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101006040526001600b819055600f805460ff1916909117905534801562000025575f80fd5b5060408051602080820183525f82528251808401845260038082526229aaa760e91b82840181905285518087019096529085529184019190915290916012612710600133806200008e57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b620000998162000227565b50620000a58662000276565b60016004556008620000b8868262000328565b506009620000c7858262000328565b5060ff83166080819052620000de90600a620004ff565b60c0819052620000ef908262000516565b60e05260c05162000101908362000516565b60a0819052335f818152600a602090815260408083208054600160ff1991821681179092557f38c11ccaa7ff6fbfb3e0e5a96eec33b5d02d14e967e918a27f97965cb46a63b880548216831790557f16524bb5246388b5dcb21861b419f272266fd97bee9ac3e1ee73280386a76111805490911690911790556006825280832085905551938452919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050505050506040518060800160405280604281526020016200415b60429139600c90620001e6908262000328565b506064620001f76012600a620004ff565b620002059061271062000516565b6200021290600262000516565b6200021e919062000530565b600e5562000550565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600362000284828262000328565b5050565b634e487b7160e01b5f52604160045260245ffd5b600181811c90821680620002b157607f821691505b602082108103620002d057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000323575f81815260208120601f850160051c81016020861015620002fe5750805b601f850160051c820191505b818110156200031f578281556001016200030a565b5050505b505050565b81516001600160401b0381111562000344576200034462000288565b6200035c816200035584546200029c565b84620002d6565b602080601f83116001811462000392575f84156200037a5750858301515b5f19600386901b1c1916600185901b1785556200031f565b5f85815260208120601f198616915b82811015620003c257888601518255948401946001909101908401620003a1565b5085821015620003e057878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52601160045260245ffd5b600181815b808511156200044457815f1904821115620004285762000428620003f0565b808516156200043657918102915b93841c939080029062000409565b509250929050565b5f826200045c57506001620004f9565b816200046a57505f620004f9565b81600181146200048357600281146200048e57620004ae565b6001915050620004f9565b60ff841115620004a257620004a2620003f0565b50506001821b620004f9565b5060208310610133831016604e8410600b8410161715620004d3575081810a620004f9565b620004df838362000404565b805f1904821115620004f557620004f5620003f0565b0290505b92915050565b5f6200050f60ff8416836200044c565b9392505050565b8082028115828204841417620004f957620004f9620003f0565b5f826200054b57634e487b7160e01b5f52601260045260245ffd5b500490565b60805160a05160c05160e051613b98620005c35f395f818161041401528181610ced015281816115640152818161193f015281816128120152818161284a0152818161290a015261293101525f61044e01525f818161032d01528181610de60152610e4001525f6103a00152613b985ff3fe608060405234801561000f575f80fd5b506004361061023e575f3560e01c806370a0823111610135578063c5b8f772116100b4578063e985e9c511610079578063e985e9c5146105a8578063f242432a146105e3578063f28ca1dd146105f6578063f2fde38b146105fe578063f8b45b0514610611575f80fd5b8063c5b8f7721461052f578063c87b56dd14610542578063d547cfb714610555578063dd62ed3e1461055d578063e0df5b6f14610595575f80fd5b806399a2557a116100fa57806399a2557a146104cb5780639b19251a146104de578063a014e6e214610500578063a22cb46514610509578063a9059cbb1461051c575f80fd5b806370a0823114610470578063715018a6146104985780638462151c146104a05780638da5cb5b146104b357806395d89b41146104c3575f80fd5b806323b872dd116101c15780634eabf2c6116101865780634eabf2c6146103f457806353d6fd59146103fc5780635afcc2f51461040f5780635d0044ca146104365780636d6a6a4d14610449575f80fd5b806323b872dd146103625780632d760d57146103755780632eb2c2d614610388578063313ce5671461039b5780634e1273f4146103d4575f80fd5b8063095ea7b311610207578063095ea7b3146102f55780630a702e8d146103085780630e89341c1461031557806318160ddd1461032857806318d217c31461034f575f80fd5b8062fdd58e1461024257806301ffc9a71461026857806302fe53051461028b57806306fdde03146102a0578063081812fc146102b5575b5f80fd5b610255610250366004612d83565b61061a565b6040519081526020015b60405180910390f35b61027b610276366004612dc0565b610686565b604051901515815260200161025f565b61029e610299366004612e75565b610726565b005b6102a8610762565b60405161025f9190612f06565b6102dd6102c3366004612f18565b60056020525f90815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161025f565b61027b610303366004612d83565b6107ee565b600f5461027b9060ff1681565b6102a8610323366004612f18565b6108be565b6102557f000000000000000000000000000000000000000000000000000000000000000081565b61029e61035d366004612e75565b6108c9565b61027b610370366004612f2f565b610909565b610255610383366004612f68565b610a45565b61029e610396366004613046565b610a7a565b6103c27f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161025f565b6103e76103e23660046130e8565b610ac7565b60405161025f91906131e5565b61029e610bad565b61029e61040a366004613204565b610c02565b6102557f000000000000000000000000000000000000000000000000000000000000000081565b61029e610444366004612f18565b610d87565b6102557f000000000000000000000000000000000000000000000000000000000000000081565b61025561047e366004613239565b6001600160a01b03165f9081526006602052604090205490565b61029e610e82565b6103e76104ae366004613239565b610e95565b5f546001600160a01b03166102dd565b6102a8610ec6565b6103e76104d9366004612f68565b610ed3565b61027b6104ec366004613239565b600a6020525f908152604090205460ff1681565b610255600b5481565b61029e610517366004613204565b610fff565b61027b61052a366004612d83565b61100e565b61027b61053d366004612d83565b61101d565b6102a8610550366004612f18565b611052565b6102a861138f565b61025561056b366004613252565b6001600160a01b039182165f90815260076020908152604080832093909416825291909152205490565b61029e6105a3366004612e75565b61139c565b61027b6105b6366004613252565b6001600160a01b039182165f90815260026020908152604080832093909416825291909152205460ff1690565b61029e6105f1366004613283565b6113b0565b6102a86113fe565b61029e61060c366004613239565b61140b565b610255600e5481565b5f6001600160a01b038316610642576040516323d3ad8160e21b815260040160405180910390fd5b6001600160a01b0383165f908152600160208181526040808420600887901c85529091529091205460ff84161c161561067d57506001610680565b505f5b92915050565b5f6001600160e01b03198216636cdb3d1360e11b14806106b657506001600160e01b031982166303a24d0760e21b145b806106d157506001600160e01b031982166362dc7bb960e11b145b806106ec57506380ac58cd60e01b6001600160e01b03198316145b806107075750635b5e139f60e01b6001600160e01b03198316145b8061068057506301ffc9a760e01b6001600160e01b0319831614610680565b61072e611448565b61073781611474565b6040517f21bb7eb2be3a3563f9f1a320ebf802250ef46d44df8d42f1596e09117f626489905f90a150565b6008805461076f906132e2565b80601f016020809104026020016040519081016040528092919081815260200182805461079b906132e2565b80156107e65780601f106107bd576101008083540402835291602001916107e6565b820191905f5260205f20905b8154815290600101906020018083116107c957829003601f168201915b505050505081565b5f336107f960045490565b8310801561080657505f83115b156108a957610815818461101d565b61084257604051634b637e8f60e11b81526001600160a01b03821660048201526024015b60405180910390fd5b5f8381526005602090815260409182902080546001600160a01b0319166001600160a01b038881169182179092559251868152908416917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a36108b4565b6108b4818585611480565b5060019392505050565b606061068082611052565b6108d1611448565b600c6108dd828261335f565b506040517f21bb7eb2be3a3563f9f1a320ebf802250ef46d44df8d42f1596e09117f626489905f90a150565b5f61091360045490565b821015610a2d576001600160a01b0384165f908152600160208181526040808420600887901c85529091529091205460ff84161c1661097057604051634a1406b160e11b81526001600160a01b0385166004820152602401610839565b336001600160a01b038516148015906109ac57506001600160a01b0384165f90815260026020908152604080832033845290915290205460ff16155b80156109ce57505f828152600560205260409020546001600160a01b03163314155b156109ee57604051634a1406b160e11b8152336004820152602401610839565b5f82815260056020908152604080832080546001600160a01b031916905580519182019052818152610a2891869186918691600191611492565b6108b4565b610a3884338461168b565b6108b48484846001611706565b5f610a7283610a54818561342e565b6001600160a01b0387165f9081526001602052604090209190611764565b949350505050565b6001600160a01b038516331480610a965750610a9685336105b6565b610ab357604051632ce44b5f60e11b815260040160405180910390fd5b610ac08585858585611802565b5050505050565b60608151835114610aeb57604051637801f4e960e01b815260040160405180910390fd5b5f83516001600160401b03811115610b0557610b05612ddb565b604051908082528060200260200182016040528015610b2e578160200160208202803683370190505b5090505f5b8451811015610ba557610b78858281518110610b5157610b51613441565b6020026020010151858381518110610b6b57610b6b613441565b602002602001015161061a565b828281518110610b8a57610b8a613441565b6020908102919091010152610b9e81613455565b9050610b33565b509392505050565b610bb5611448565b600f805460ff8082161560ff1990921682179092556040519116151581527fea63aac68e0a18e1731accb41e3c0c386ddcf31edaf96d7aebbaf1ac05cafab59060200160405180910390a1565b610c0a611448565b6001600160a01b0382165f908152600a602052604090205481151560ff909116151503610c6f5760405162461bcd60e51b81526020600482015260136024820152724e6f206368616e676520746f2073746174757360681b6044820152606401610839565b8015610ccf575f610c84835f61038360045490565b90508015610c9657610c968382611a83565b6040516001600160a01b038416907f7f93a45f70dde0bd08c45d334f84774f8aaa04a8b7c8349cf2837646445984db905f90a250610d5d565b6001600160a01b0382165f9081526006602052604081205490610d127f00000000000000000000000000000000000000000000000000000000000000008361346d565b90508015610d2757610d248482611d5d565b50505b6040516001600160a01b038516907fc0e106cf568e50698fdbde1eff56f5a5c966cc7958e37e276918e9e4ccdf8cd4905f90a250505b6001600160a01b03919091165f908152600a60205260409020805460ff1916911515919091179055565b610d8f611448565b5f8111610dde5760405162461bcd60e51b815260206004820152601d60248201527f43616e6e6f742064697361626c65206e6f726d616c2074726164696e670000006044820152606401610839565b6064610e0a827f000000000000000000000000000000000000000000000000000000000000000061348c565b610e14919061346d565b600e557f12528a3c61e0f3b2d6fc707a9fc58b1af86e252cad0d7f4c154ebeabb162dace6064610e64837f000000000000000000000000000000000000000000000000000000000000000061348c565b610e6e919061346d565b60405190815260200160405180910390a150565b610e8a611448565b610e935f611fd8565b565b6060610e9f612027565b5f03610eb8575050604080515f81526020810190915290565b610680826001600454610ed3565b6009805461076f906132e2565b6060818310610ef557604051631960ccad60e11b815260040160405180910390fd5b6001831015610f0357600192505b5f610f0d60045490565b905080831115610f1b578092505b5f83851015610f3657610f2f868686610a45565b9050610f39565b505f5b5f816001600160401b03811115610f5257610f52612ddb565b604051908082528060200260200182016040528015610f7b578160200160208202803683370190505b506001600160a01b0388165f90815260016020526040812091925087905b848114610ff157600882901c5f9081526020849052604090205460ff83161c60011615610fe65781848280600101935081518110610fd957610fd9613441565b6020026020010181815250505b816001019150610f99565b509198975050505050505050565b61100a33838361203c565b5050565b5f336108b48185856001611706565b6001600160a01b0382165f908152600160208181526040808420600886901c855290915282205460ff84161c165b9392505050565b606061105d60045490565b821061107c57604051637801f4e960e01b815260040160405180910390fd5b5f6110868361211b565b511115611096576106808261211b565b5f600d80546110a4906132e2565b905011156110de57600d6110b7836121ad565b6040516020016110c8929190613512565b6040516020818303038152906040529050919050565b5f826040516020016110f291815260200190565b60408051601f19818403018152828252805160209182012083820183525f808552835180840185528181528451938401909452825260f81c9350603f84116111ae576040518060400160405280601f81526020017f70686f746f5f353038303139323137353439363630343637345f792e6a706700815250925060405180604001604052806007815260200166111a585b5bdb9960ca1b81525091506040518060e0016040528060bf8152602001613a1560bf9139905061132a565b607f8460ff1611611231576040518060400160405280601f81526020017f70686f746f5f353038303139323137353439363630343637355f792e6a70670081525092506040518060400160405280600481526020016311dbdb1960e21b815250915060405180610100016040528060c9815260200161392c60c99139905061132a565b60bf8460ff16116112b5576040518060400160405280601f81526020017f70686f746f5f353038303139323137353439363630343637365f792e6a70670081525092506040518060400160405280600681526020016529b4b63b32b960d11b81525091506040518060c00160405280608f8152602001613ad4608f9139905061132a565b6040518060400160405280601f81526020017f70686f746f5f353038303139323137353439363630343637375f792e6a70670081525092506040518060400160405280600681526020016542726f6e7a6560d01b81525091506040518060c00160405280608281526020016138aa6082913990505b5f611334876121ad565b82600c8660405160200161134b9493929190613536565b6040516020818303038152906040529050808360405160200161136f92919061360c565b60405160208183030381529060405295505050505050919050565b919050565b600d805461076f906132e2565b6113a4611448565b600d6108dd828261335f565b6001600160a01b0385163314806113cc57506113cc85336105b6565b156113e5576113e085858585856001611492565b610ac0565b604051632ce44b5f60e11b815260040160405180910390fd5b600c805461076f906132e2565b611413611448565b6001600160a01b03811661143c57604051631e4fbdf760e01b81525f6004820152602401610839565b61144581611fd8565b50565b5f546001600160a01b03163314610e935760405163118cdaa760e01b8152336004820152602401610839565b600361100a828261335f565b61148d838383600161223c565b505050565b6001600160a01b0385166114b957604051633a954ecd60e21b815260040160405180910390fd5b335f6114c48661230e565b905084600114801561150057506001600160a01b0388165f90815260016020818152604080842060088b901c85529091529091205460ff88161c165b1561158e576001600160a01b038881165f90815260016020818152604080842060088c901c808652908352818520805460ff8e1686901b8019909116909155958d1685529282528084209284529190528120805490921790915561158990899089907f000000000000000000000000000000000000000000000000000000000000000090611706565b6115a7565b6040516337dbad3d60e01b815260040160405180910390fd5b6001600160a01b038781169089168682825f805160206139f58339815191525f80a4886001600160a01b03168a6001600160a01b0316856001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b8b604051611621929190918252602082015260400190565b60405180910390a4611635848b8b86612354565b841561167f575f61164560045490565b9050611655858c8c8c8c8c6124d7565b8061165f60045490565b1461167d5760405163c07c7e1360e01b815260040160405180910390fd5b505b50505050505050505050565b6001600160a01b038381165f908152600760209081526040808320938616835292905220545f19811461170057818110156116f257604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610839565b61170084848484035f61223c565b50505050565b6001600160a01b03841661172f57604051634b637e8f60e11b81525f6004820152602401610839565b6001600160a01b0383166117585760405163ec442f0560e01b81525f6004820152602401610839565b6117008484848461274b565b5f600883901c60ff8416610101848201106117d6575f8281526020879052604090205461179290821c6129c9565b930160ff811693925060018201915f9160081c015b8083146117d4575f838152602088905260409020546117c5906129c9565b840193508260010192506117a7565b505b5f828152602087905260409020546117f690821c6101008690031b6129c9565b90920195945050505050565b815183511461182457604051637801f4e960e01b815260040160405180910390fd5b6001600160a01b03841661184b57604051633a954ecd60e21b815260040160405180910390fd5b335f5b8451811015611935575f85828151811061186a5761186a613441565b602002602001015190505f85838151811061188757611887613441565b602002602001015190508060011480156118cb57506001600160a01b0389165f908152600160208181526040808420600887901c85529091529091205460ff84161c165b1561158e57506001600160a01b038881165f908152600160208181526040808420600887901c808652908352818520805460ff90981685901b80199098169055948c16845291815281832093835292909252208054909117905561192e81613455565b905061184e565b5061196e868686517f0000000000000000000000000000000000000000000000000000000000000000611968919061348c565b5f611706565b5f805f8651600161197f91906136b5565b90506001600160a01b03891691506001600160a01b0388169250602087015183835f805160206139f58339815191525f80a460025b8181146119dd578060200288015184845f805160206139f58339815191525f80a46001016119b4565b50876001600160a01b0316896001600160a01b0316856001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8a8a604051611a2d9291906136c8565b60405180910390a4611a41848a8a8a612354565b5f611a4b60045490565b9050611a5b858b8b8b8b8b612a78565b80611a6560045490565b1461167f5760405163c07c7e1360e01b815260040160405180910390fd5b6001600160a01b038216611aaa5760405163b817eee760e01b815260040160405180910390fd5b60045433905f836001600160401b03811115611ac857611ac8612ddb565b604051908082528060200260200182016040528015611af1578160200160208202803683370190505b5090505f846001600160401b03811115611b0d57611b0d612ddb565b604051908082528060200260200182016040528015611b36578160200160208202803683370190505b5090505f5b85811015611c07576001838281518110611b5757611b57613441565b6020908102919091018101919091526001600160a01b0388165f908152600190915260408120611b879086612b33565b90505f198103611baa5760405163851f838b60e01b815260040160405180910390fd5b80838381518110611bbd57611bbd613441565b6020908102919091018101919091526001600160a01b0389165f90815260018083526040808320600886901c8452909352919020805460ff841683901b1916905590945001611b3b565b505f80611c158760016136b5565b90506001600160a01b038816915060208301515f835f805160206139f58339815191525f80a460025b818114611c6757806020028401515f845f805160206139f58339815191525f80a4600101611c3e565b5086600103611cef575f6001600160a01b0316886001600160a01b0316876001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62865f81518110611cc157611cc1613441565b60200260200101516001604051611ce2929190918252602082015260400190565b60405180910390a4611d47565b5f6001600160a01b0316886001600160a01b0316876001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8688604051611d3e9291906136c8565b60405180910390a45b611d5386895f86612354565b5050505050505050565b6060806001600160a01b038416611d8657604051622e076360e81b815260040160405180910390fd5b825f03611da65760405163b562e8dd60e01b815260040160405180910390fd5b33836001600160401b03811115611dbf57611dbf612ddb565b604051908082528060200260200182016040528015611de8578160200160208202803683370190505b509250836001600160401b03811115611e0357611e03612ddb565b604051908082528060200260200182016040528015611e2c578160200160208202803683370190505b5091505f611e3960045490565b905080855f19031015611e875760405162461bcd60e51b8152602060048201526016602482015275135a5b9d1a5b99c81b1a5b5a5d1cc81c995858da195960521b6044820152606401610839565b5f5b85811015611ed957808201858281518110611ea657611ea6613441565b6020026020010181815250506001848281518110611ec657611ec6613441565b6020908102919091010152600101611e89565b506001600160a01b0386165f908152600160205260409020611efc908287612c20565b8460045f828254611f0d91906136b5565b909155505f905080611f1f87846136b5565b90506001600160a01b038816915082825f5f805160206139f58339815191525f80a4600183015b818114611f695780835f5f805160206139f58339815191525f80a4600101611f46565b50876001600160a01b03165f6001600160a01b0316856001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8989604051611fb99291906136c8565b60405180910390a4611fcd845f8a89612354565b505050509250929050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f6001600454612037919061342e565b905090565b816001600160a01b0316836001600160a01b0316036120af5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608401610839565b6001600160a01b038381165f81815260026020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60606003805461212a906132e2565b80601f0160208091040260200160405190810160405280929190818152602001828054612156906132e2565b80156121a15780601f10612178576101008083540402835291602001916121a1565b820191905f5260205f20905b81548152906001019060200180831161218457829003601f168201915b50505050509050919050565b60605f6121b983612c96565b60010190505f816001600160401b038111156121d7576121d7612ddb565b6040519080825280601f01601f191660200182016040528015612201576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461220b57509392505050565b6001600160a01b0384166122655760405163e602df0560e01b81525f6004820152602401610839565b6001600160a01b03831661228e57604051634a1406b160e11b81525f6004820152602401610839565b6001600160a01b038085165f908152600760209081526040808320938716835292905220829055801561170057826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161230091815260200190565b60405180910390a350505050565b6040805160018082528183019092526060916020808301908036833701905050905081815f8151811061234357612343613441565b602002602001018181525050919050565b6001600160a01b0382165f908152600a602052604090205460ff166124d257600e546001600160a01b0383165f9081526006602052604090205411156123dc5760405162461bcd60e51b815260206004820152601f60248201527f5472616e736665722065786365656473206d6178696d756d2077616c6c6574006044820152606401610839565b600f5460ff16156124d257325f9081526010602052604090205443116124505760405162461bcd60e51b8152602060048201526024808201527f4f6e6c79206f6e65207472616e736665722070657220626c6f636b20616c6c6f6044820152633bb2b21760e11b6064820152608401610839565b325f9081526010602052604090204390556001600160a01b0382163b1580156124785750323b155b6124d25760405162461bcd60e51b815260206004820152602560248201527f436f6e74726163742074726164696e672072657374726963746564206174206c6044820152640c2eadcc6d60db1b6064820152608401610839565b611700565b6001600160a01b0384163b15612743576040516301ffc9a760e01b8152636cdb3d1360e11b60048201526001600160a01b038516906301ffc9a790602401602060405180830381865afa158015612530573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061255491906136f5565b1561265e5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e619061258d9089908990889088908890600401613710565b6020604051808303815f875af19250505080156125c7575060408051601f3d908101601f191682019092526125c491810190613754565b60015b612627576125d361376f565b806308c379a00361260c57506125e7613788565b806125f2575061260e565b8060405162461bcd60e51b81526004016108399190612f06565b505b604051639c05499b60e01b815260040160405180910390fd5b6001600160e01b0319811663f23a6e6160e01b1461265857604051639c05499b60e01b815260040160405180910390fd5b50612743565b604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612690908990899088908790600401613810565b6020604051808303815f875af19250505080156126ca575060408051601f3d908101601f191682019092526126c791810190613754565b60015b612710576126d661376f565b806308c379a0036126f557506126ea613788565b806125f257506126f7565b505b6040516368d2bf6b60e11b815260040160405180910390fd5b6001600160e01b03198116630a85bd0160e11b14612741576040516368d2bf6b60e11b815260040160405180910390fd5b505b505050505050565b6001600160a01b038085165f90815260066020526040808220549286168252902054838210156127a75760405163391434e360e21b81526001600160a01b03871660048201526024810183905260448101859052606401610839565b846001600160a01b0316866001600160a01b031614612987576001600160a01b038087165f90815260066020526040808220878603905591871681522081850190558215612987576001600160a01b0386165f908152600a602052604090205460ff168061288d575f7f000000000000000000000000000000000000000000000000000000000000000061283b878661342e565b612845919061346d565b61286f7f00000000000000000000000000000000000000000000000000000000000000008661346d565b612879919061342e565b9050801561288b5761288b8882611a83565b505b6001600160a01b0386165f908152600a602052604090205460ff1661298557600b5460011480156128bb5750805b80156128d357505f546001600160a01b038881169116145b15612904576001600160a01b0386165f908152600a60205260409020805460ff191660011790556002600b55612985565b5f61292f7f00000000000000000000000000000000000000000000000000000000000000008461346d565b7f000000000000000000000000000000000000000000000000000000000000000061295a88866136b5565b612964919061346d565b61296e919061342e565b90508015612983576129808782611d5d565b50505b505b505b846001600160a01b0316866001600160a01b03165f805160206139f5833981519152866040516129b991815260200190565b60405180910390a3505050505050565b7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c168203600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c5f199190911460081b1790565b6001600160a01b0384163b156127435760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190612abc908990899088908890889060040161384c565b6020604051808303815f875af1925050508015612af6575060408051601f3d908101601f19168201909252612af391810190613754565b60015b612b02576125d361376f565b6001600160e01b0319811663bc197c8160e01b1461274157604051639c05499b60e01b815260040160405180910390fd5b600881901c5f818152602084905260409020545f19919060ff84191690811b901c81158117612b73575b5081015f81815260409020548115811715612b5d575b8015612c1857612c09817f0706060506020504060203020504030106050205030304010505030400000000601f6f8421084210842108cc6318c6db6d54be831560081b6fffffffffffffffffffffffffffffffff851160071b1784811c6001600160401b031060061b1784811c63ffffffff1060051b1784811c61ffff1060041b1784811c60ff1060031b1793841c1c161a1790565b600883901b178481115f031792505b505092915050565b5f1960ff8316846020528360081c5f5261010183820110612c7c575f805160408220805485851b1790559390910160ff811693600181019160081c015b808214612c7857815f528360405f2055600182019150612c5d565b505f525b60405f208284610100031c821b8154178155505050505050565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310612cd45772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612d00576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612d1e57662386f26fc10000830492506010015b6305f5e1008310612d36576305f5e100830492506008015b6127108310612d4a57612710830492506004015b60648310612d5c576064830492506002015b600a83106106805760010192915050565b80356001600160a01b038116811461138a575f80fd5b5f8060408385031215612d94575f80fd5b612d9d83612d6d565b946020939093013593505050565b6001600160e01b031981168114611445575f80fd5b5f60208284031215612dd0575f80fd5b813561104b81612dab565b634e487b7160e01b5f52604160045260245ffd5b601f8201601f191681016001600160401b0381118282101715612e1457612e14612ddb565b6040525050565b5f6001600160401b03831115612e3357612e33612ddb565b604051612e4a601f8501601f191660200182612def565b809150838152848484011115612e5e575f80fd5b838360208301375f60208583010152509392505050565b5f60208284031215612e85575f80fd5b81356001600160401b03811115612e9a575f80fd5b8201601f81018413612eaa575f80fd5b610a7284823560208401612e1b565b5f5b83811015612ed3578181015183820152602001612ebb565b50505f910152565b5f8151808452612ef2816020860160208601612eb9565b601f01601f19169290920160200192915050565b602081525f61104b6020830184612edb565b5f60208284031215612f28575f80fd5b5035919050565b5f805f60608486031215612f41575f80fd5b612f4a84612d6d565b9250612f5860208501612d6d565b9150604084013590509250925092565b5f805f60608486031215612f7a575f80fd5b612f8384612d6d565b95602085013595506040909401359392505050565b5f6001600160401b03821115612fb057612fb0612ddb565b5060051b60200190565b5f82601f830112612fc9575f80fd5b81356020612fd682612f98565b604051612fe38282612def565b83815260059390931b8501820192828101915086841115613002575f80fd5b8286015b8481101561301d5780358352918301918301613006565b509695505050505050565b5f82601f830112613037575f80fd5b61104b83833560208501612e1b565b5f805f805f60a0868803121561305a575f80fd5b61306386612d6d565b945061307160208701612d6d565b935060408601356001600160401b038082111561308c575f80fd5b61309889838a01612fba565b945060608801359150808211156130ad575f80fd5b6130b989838a01612fba565b935060808801359150808211156130ce575f80fd5b506130db88828901613028565b9150509295509295909350565b5f80604083850312156130f9575f80fd5b82356001600160401b038082111561310f575f80fd5b818501915085601f830112613122575f80fd5b8135602061312f82612f98565b60405161313c8282612def565b83815260059390931b850182019282810191508984111561315b575f80fd5b948201945b838610156131805761317186612d6d565b82529482019490820190613160565b96505086013592505080821115613195575f80fd5b506131a285828601612fba565b9150509250929050565b5f8151808452602080850194508084015f5b838110156131da578151875295820195908201906001016131be565b509495945050505050565b602081525f61104b60208301846131ac565b8015158114611445575f80fd5b5f8060408385031215613215575f80fd5b61321e83612d6d565b9150602083013561322e816131f7565b809150509250929050565b5f60208284031215613249575f80fd5b61104b82612d6d565b5f8060408385031215613263575f80fd5b61326c83612d6d565b915061327a60208401612d6d565b90509250929050565b5f805f805f60a08688031215613297575f80fd5b6132a086612d6d565b94506132ae60208701612d6d565b9350604086013592506060860135915060808601356001600160401b038111156132d6575f80fd5b6130db88828901613028565b600181811c908216806132f657607f821691505b60208210810361331457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561148d575f81815260208120601f850160051c810160208610156133405750805b601f850160051c820191505b818110156127435782815560010161334c565b81516001600160401b0381111561337857613378612ddb565b61338c8161338684546132e2565b8461331a565b602080601f8311600181146133bf575f84156133a85750858301515b5f19600386901b1c1916600185901b178555612743565b5f85815260208120601f198616915b828110156133ed578886015182559484019460019091019084016133ce565b508582101561340a57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52601160045260245ffd5b818103818111156106805761068061341a565b634e487b7160e01b5f52603260045260245ffd5b5f600182016134665761346661341a565b5060010190565b5f8261348757634e487b7160e01b5f52601260045260245ffd5b500490565b80820281158282048414176106805761068061341a565b5f81546134af816132e2565b600182811680156134c757600181146134dc57613508565b60ff1984168752821515830287019450613508565b855f526020805f205f5b858110156134ff5781548a8201529084019082016134e6565b50505082870194505b5050505092915050565b5f61351d82856134a3565b835161352d818360208801612eb9565b01949350505050565b6e7b226e616d65223a202253554e202360881b815284515f9061356081600f850160208a01612eb9565b701116113232b9b1b934b83a34b7b7111d1160791b600f918401918201528551613591816020808501908a01612eb9565b7f222c2265787465726e616c5f75726c223a2268747470733a2f2f7777772e736f602092909101918201527f6c6172666c6172652e6c6f6c222c22696d616765223a2200000000000000000060408201526135ef60578201866134a3565b90508351613601818360208801612eb9565b019695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c000000000081525f835161364381601b850160208801612eb9565b7f222c2261747472696275746573223a5b7b2274726169745f74797065223a2243601b918401918201526e37b637b91116113b30b63ab2911d1160891b603b820152835161369881604a840160208801612eb9565b63227d5d7d60e01b604a9290910191820152604e01949350505050565b808201808211156106805761068061341a565b604081525f6136da60408301856131ac565b82810360208401526136ec81856131ac565b95945050505050565b5f60208284031215613705575f80fd5b815161104b816131f7565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190525f9061374990830184612edb565b979650505050505050565b5f60208284031215613764575f80fd5b815161104b81612dab565b5f60033d11156137855760045f803e505f5160e01c5b90565b5f60443d10156137955790565b6040516003193d81016004833e81513d6001600160401b0381602484011181841117156137c457505050505090565b82850191508151818111156137dc5750505050505090565b843d87010160208285010111156137f65750505050505090565b61380560208286010187612def565b509095945050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f9061384290830184612edb565b9695505050505050565b6001600160a01b0386811682528516602082015260a0604082018190525f90613877908301866131ac565b828103606084015261388981866131ac565b9050828103608084015261389d8185612edb565b9897505050505050505056fe456e747279206c6576656c204e46547320706f776572656420627920455243313135352e205468652073696c766572204e465473206172652073756e6e6564206279206173706972696e6720636f6c6c6563746f727320616e64206d65746963756c6f75736c79206372616674656420666f72206163636573736962696c6974792e50726573746967696f7573204e46547320706f776572656420627920455243313135352e2054686520676f6c64204e46547320617265206361726566756c6c792073756e6e65642062792065787065727420636f6c6c6563746f727320616e64206d65746963756c6f75736c792063726166746564207769746820676f6c64656e20657863656c6c656e63652c2073796d626f6c697a696e67207468652070696e6e61636c65206f66206469676974616c2072617269747920616e64206578636c757369766974792eddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef4c6567656e64617279204e46547320706f776572656420627920455243313135352e20546865204469616d6f6e64204e46547320617265206d65746963756c6f75736c792073756e6e656420627920696e64757374727920656c6974657320616e642063726166746564207769746820756e706172616c6c656c656420707265636973696f6e2c20726570726573656e74696e6720746865207a656e697468206f66206c757875727920616e64206469676974616c2061727469737472792e526566696e6564204e46547320706f776572656420627920455243313135352e205468652073696c766572204e465473206172652073756e6e656420627920736561736f6e656420656e7468757369617374732c20616464696e6720616e206578747261206c61796572206f6620736f706869737469636174696f6e20746f20796f757220706f7274666f6c696f2ea264697066735822122033846d8f18b9e81ed13c5ff6685615735cb957e35478c0ff3cb0c5155466c5d764736f6c6343000814003368747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f76656e757367616c737461722f53554e45524334303456322f6d61737465722f
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061023e575f3560e01c806370a0823111610135578063c5b8f772116100b4578063e985e9c511610079578063e985e9c5146105a8578063f242432a146105e3578063f28ca1dd146105f6578063f2fde38b146105fe578063f8b45b0514610611575f80fd5b8063c5b8f7721461052f578063c87b56dd14610542578063d547cfb714610555578063dd62ed3e1461055d578063e0df5b6f14610595575f80fd5b806399a2557a116100fa57806399a2557a146104cb5780639b19251a146104de578063a014e6e214610500578063a22cb46514610509578063a9059cbb1461051c575f80fd5b806370a0823114610470578063715018a6146104985780638462151c146104a05780638da5cb5b146104b357806395d89b41146104c3575f80fd5b806323b872dd116101c15780634eabf2c6116101865780634eabf2c6146103f457806353d6fd59146103fc5780635afcc2f51461040f5780635d0044ca146104365780636d6a6a4d14610449575f80fd5b806323b872dd146103625780632d760d57146103755780632eb2c2d614610388578063313ce5671461039b5780634e1273f4146103d4575f80fd5b8063095ea7b311610207578063095ea7b3146102f55780630a702e8d146103085780630e89341c1461031557806318160ddd1461032857806318d217c31461034f575f80fd5b8062fdd58e1461024257806301ffc9a71461026857806302fe53051461028b57806306fdde03146102a0578063081812fc146102b5575b5f80fd5b610255610250366004612d83565b61061a565b6040519081526020015b60405180910390f35b61027b610276366004612dc0565b610686565b604051901515815260200161025f565b61029e610299366004612e75565b610726565b005b6102a8610762565b60405161025f9190612f06565b6102dd6102c3366004612f18565b60056020525f90815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161025f565b61027b610303366004612d83565b6107ee565b600f5461027b9060ff1681565b6102a8610323366004612f18565b6108be565b6102557f00000000000000000000000000000000000000000000021e19e0c9bab240000081565b61029e61035d366004612e75565b6108c9565b61027b610370366004612f2f565b610909565b610255610383366004612f68565b610a45565b61029e610396366004613046565b610a7a565b6103c27f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161025f565b6103e76103e23660046130e8565b610ac7565b60405161025f91906131e5565b61029e610bad565b61029e61040a366004613204565b610c02565b6102557f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b61029e610444366004612f18565b610d87565b6102557f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b61025561047e366004613239565b6001600160a01b03165f9081526006602052604090205490565b61029e610e82565b6103e76104ae366004613239565b610e95565b5f546001600160a01b03166102dd565b6102a8610ec6565b6103e76104d9366004612f68565b610ed3565b61027b6104ec366004613239565b600a6020525f908152604090205460ff1681565b610255600b5481565b61029e610517366004613204565b610fff565b61027b61052a366004612d83565b61100e565b61027b61053d366004612d83565b61101d565b6102a8610550366004612f18565b611052565b6102a861138f565b61025561056b366004613252565b6001600160a01b039182165f90815260076020908152604080832093909416825291909152205490565b61029e6105a3366004612e75565b61139c565b61027b6105b6366004613252565b6001600160a01b039182165f90815260026020908152604080832093909416825291909152205460ff1690565b61029e6105f1366004613283565b6113b0565b6102a86113fe565b61029e61060c366004613239565b61140b565b610255600e5481565b5f6001600160a01b038316610642576040516323d3ad8160e21b815260040160405180910390fd5b6001600160a01b0383165f908152600160208181526040808420600887901c85529091529091205460ff84161c161561067d57506001610680565b505f5b92915050565b5f6001600160e01b03198216636cdb3d1360e11b14806106b657506001600160e01b031982166303a24d0760e21b145b806106d157506001600160e01b031982166362dc7bb960e11b145b806106ec57506380ac58cd60e01b6001600160e01b03198316145b806107075750635b5e139f60e01b6001600160e01b03198316145b8061068057506301ffc9a760e01b6001600160e01b0319831614610680565b61072e611448565b61073781611474565b6040517f21bb7eb2be3a3563f9f1a320ebf802250ef46d44df8d42f1596e09117f626489905f90a150565b6008805461076f906132e2565b80601f016020809104026020016040519081016040528092919081815260200182805461079b906132e2565b80156107e65780601f106107bd576101008083540402835291602001916107e6565b820191905f5260205f20905b8154815290600101906020018083116107c957829003601f168201915b505050505081565b5f336107f960045490565b8310801561080657505f83115b156108a957610815818461101d565b61084257604051634b637e8f60e11b81526001600160a01b03821660048201526024015b60405180910390fd5b5f8381526005602090815260409182902080546001600160a01b0319166001600160a01b038881169182179092559251868152908416917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a36108b4565b6108b4818585611480565b5060019392505050565b606061068082611052565b6108d1611448565b600c6108dd828261335f565b506040517f21bb7eb2be3a3563f9f1a320ebf802250ef46d44df8d42f1596e09117f626489905f90a150565b5f61091360045490565b821015610a2d576001600160a01b0384165f908152600160208181526040808420600887901c85529091529091205460ff84161c1661097057604051634a1406b160e11b81526001600160a01b0385166004820152602401610839565b336001600160a01b038516148015906109ac57506001600160a01b0384165f90815260026020908152604080832033845290915290205460ff16155b80156109ce57505f828152600560205260409020546001600160a01b03163314155b156109ee57604051634a1406b160e11b8152336004820152602401610839565b5f82815260056020908152604080832080546001600160a01b031916905580519182019052818152610a2891869186918691600191611492565b6108b4565b610a3884338461168b565b6108b48484846001611706565b5f610a7283610a54818561342e565b6001600160a01b0387165f9081526001602052604090209190611764565b949350505050565b6001600160a01b038516331480610a965750610a9685336105b6565b610ab357604051632ce44b5f60e11b815260040160405180910390fd5b610ac08585858585611802565b5050505050565b60608151835114610aeb57604051637801f4e960e01b815260040160405180910390fd5b5f83516001600160401b03811115610b0557610b05612ddb565b604051908082528060200260200182016040528015610b2e578160200160208202803683370190505b5090505f5b8451811015610ba557610b78858281518110610b5157610b51613441565b6020026020010151858381518110610b6b57610b6b613441565b602002602001015161061a565b828281518110610b8a57610b8a613441565b6020908102919091010152610b9e81613455565b9050610b33565b509392505050565b610bb5611448565b600f805460ff8082161560ff1990921682179092556040519116151581527fea63aac68e0a18e1731accb41e3c0c386ddcf31edaf96d7aebbaf1ac05cafab59060200160405180910390a1565b610c0a611448565b6001600160a01b0382165f908152600a602052604090205481151560ff909116151503610c6f5760405162461bcd60e51b81526020600482015260136024820152724e6f206368616e676520746f2073746174757360681b6044820152606401610839565b8015610ccf575f610c84835f61038360045490565b90508015610c9657610c968382611a83565b6040516001600160a01b038416907f7f93a45f70dde0bd08c45d334f84774f8aaa04a8b7c8349cf2837646445984db905f90a250610d5d565b6001600160a01b0382165f9081526006602052604081205490610d127f0000000000000000000000000000000000000000000000000de0b6b3a76400008361346d565b90508015610d2757610d248482611d5d565b50505b6040516001600160a01b038516907fc0e106cf568e50698fdbde1eff56f5a5c966cc7958e37e276918e9e4ccdf8cd4905f90a250505b6001600160a01b03919091165f908152600a60205260409020805460ff1916911515919091179055565b610d8f611448565b5f8111610dde5760405162461bcd60e51b815260206004820152601d60248201527f43616e6e6f742064697361626c65206e6f726d616c2074726164696e670000006044820152606401610839565b6064610e0a827f00000000000000000000000000000000000000000000021e19e0c9bab240000061348c565b610e14919061346d565b600e557f12528a3c61e0f3b2d6fc707a9fc58b1af86e252cad0d7f4c154ebeabb162dace6064610e64837f00000000000000000000000000000000000000000000021e19e0c9bab240000061348c565b610e6e919061346d565b60405190815260200160405180910390a150565b610e8a611448565b610e935f611fd8565b565b6060610e9f612027565b5f03610eb8575050604080515f81526020810190915290565b610680826001600454610ed3565b6009805461076f906132e2565b6060818310610ef557604051631960ccad60e11b815260040160405180910390fd5b6001831015610f0357600192505b5f610f0d60045490565b905080831115610f1b578092505b5f83851015610f3657610f2f868686610a45565b9050610f39565b505f5b5f816001600160401b03811115610f5257610f52612ddb565b604051908082528060200260200182016040528015610f7b578160200160208202803683370190505b506001600160a01b0388165f90815260016020526040812091925087905b848114610ff157600882901c5f9081526020849052604090205460ff83161c60011615610fe65781848280600101935081518110610fd957610fd9613441565b6020026020010181815250505b816001019150610f99565b509198975050505050505050565b61100a33838361203c565b5050565b5f336108b48185856001611706565b6001600160a01b0382165f908152600160208181526040808420600886901c855290915282205460ff84161c165b9392505050565b606061105d60045490565b821061107c57604051637801f4e960e01b815260040160405180910390fd5b5f6110868361211b565b511115611096576106808261211b565b5f600d80546110a4906132e2565b905011156110de57600d6110b7836121ad565b6040516020016110c8929190613512565b6040516020818303038152906040529050919050565b5f826040516020016110f291815260200190565b60408051601f19818403018152828252805160209182012083820183525f808552835180840185528181528451938401909452825260f81c9350603f84116111ae576040518060400160405280601f81526020017f70686f746f5f353038303139323137353439363630343637345f792e6a706700815250925060405180604001604052806007815260200166111a585b5bdb9960ca1b81525091506040518060e0016040528060bf8152602001613a1560bf9139905061132a565b607f8460ff1611611231576040518060400160405280601f81526020017f70686f746f5f353038303139323137353439363630343637355f792e6a70670081525092506040518060400160405280600481526020016311dbdb1960e21b815250915060405180610100016040528060c9815260200161392c60c99139905061132a565b60bf8460ff16116112b5576040518060400160405280601f81526020017f70686f746f5f353038303139323137353439363630343637365f792e6a70670081525092506040518060400160405280600681526020016529b4b63b32b960d11b81525091506040518060c00160405280608f8152602001613ad4608f9139905061132a565b6040518060400160405280601f81526020017f70686f746f5f353038303139323137353439363630343637375f792e6a70670081525092506040518060400160405280600681526020016542726f6e7a6560d01b81525091506040518060c00160405280608281526020016138aa6082913990505b5f611334876121ad565b82600c8660405160200161134b9493929190613536565b6040516020818303038152906040529050808360405160200161136f92919061360c565b60405160208183030381529060405295505050505050919050565b919050565b600d805461076f906132e2565b6113a4611448565b600d6108dd828261335f565b6001600160a01b0385163314806113cc57506113cc85336105b6565b156113e5576113e085858585856001611492565b610ac0565b604051632ce44b5f60e11b815260040160405180910390fd5b600c805461076f906132e2565b611413611448565b6001600160a01b03811661143c57604051631e4fbdf760e01b81525f6004820152602401610839565b61144581611fd8565b50565b5f546001600160a01b03163314610e935760405163118cdaa760e01b8152336004820152602401610839565b600361100a828261335f565b61148d838383600161223c565b505050565b6001600160a01b0385166114b957604051633a954ecd60e21b815260040160405180910390fd5b335f6114c48661230e565b905084600114801561150057506001600160a01b0388165f90815260016020818152604080842060088b901c85529091529091205460ff88161c165b1561158e576001600160a01b038881165f90815260016020818152604080842060088c901c808652908352818520805460ff8e1686901b8019909116909155958d1685529282528084209284529190528120805490921790915561158990899089907f0000000000000000000000000000000000000000000000000de0b6b3a764000090611706565b6115a7565b6040516337dbad3d60e01b815260040160405180910390fd5b6001600160a01b038781169089168682825f805160206139f58339815191525f80a4886001600160a01b03168a6001600160a01b0316856001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b8b604051611621929190918252602082015260400190565b60405180910390a4611635848b8b86612354565b841561167f575f61164560045490565b9050611655858c8c8c8c8c6124d7565b8061165f60045490565b1461167d5760405163c07c7e1360e01b815260040160405180910390fd5b505b50505050505050505050565b6001600160a01b038381165f908152600760209081526040808320938616835292905220545f19811461170057818110156116f257604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610839565b61170084848484035f61223c565b50505050565b6001600160a01b03841661172f57604051634b637e8f60e11b81525f6004820152602401610839565b6001600160a01b0383166117585760405163ec442f0560e01b81525f6004820152602401610839565b6117008484848461274b565b5f600883901c60ff8416610101848201106117d6575f8281526020879052604090205461179290821c6129c9565b930160ff811693925060018201915f9160081c015b8083146117d4575f838152602088905260409020546117c5906129c9565b840193508260010192506117a7565b505b5f828152602087905260409020546117f690821c6101008690031b6129c9565b90920195945050505050565b815183511461182457604051637801f4e960e01b815260040160405180910390fd5b6001600160a01b03841661184b57604051633a954ecd60e21b815260040160405180910390fd5b335f5b8451811015611935575f85828151811061186a5761186a613441565b602002602001015190505f85838151811061188757611887613441565b602002602001015190508060011480156118cb57506001600160a01b0389165f908152600160208181526040808420600887901c85529091529091205460ff84161c165b1561158e57506001600160a01b038881165f908152600160208181526040808420600887901c808652908352818520805460ff90981685901b80199098169055948c16845291815281832093835292909252208054909117905561192e81613455565b905061184e565b5061196e868686517f0000000000000000000000000000000000000000000000000de0b6b3a7640000611968919061348c565b5f611706565b5f805f8651600161197f91906136b5565b90506001600160a01b03891691506001600160a01b0388169250602087015183835f805160206139f58339815191525f80a460025b8181146119dd578060200288015184845f805160206139f58339815191525f80a46001016119b4565b50876001600160a01b0316896001600160a01b0316856001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8a8a604051611a2d9291906136c8565b60405180910390a4611a41848a8a8a612354565b5f611a4b60045490565b9050611a5b858b8b8b8b8b612a78565b80611a6560045490565b1461167f5760405163c07c7e1360e01b815260040160405180910390fd5b6001600160a01b038216611aaa5760405163b817eee760e01b815260040160405180910390fd5b60045433905f836001600160401b03811115611ac857611ac8612ddb565b604051908082528060200260200182016040528015611af1578160200160208202803683370190505b5090505f846001600160401b03811115611b0d57611b0d612ddb565b604051908082528060200260200182016040528015611b36578160200160208202803683370190505b5090505f5b85811015611c07576001838281518110611b5757611b57613441565b6020908102919091018101919091526001600160a01b0388165f908152600190915260408120611b879086612b33565b90505f198103611baa5760405163851f838b60e01b815260040160405180910390fd5b80838381518110611bbd57611bbd613441565b6020908102919091018101919091526001600160a01b0389165f90815260018083526040808320600886901c8452909352919020805460ff841683901b1916905590945001611b3b565b505f80611c158760016136b5565b90506001600160a01b038816915060208301515f835f805160206139f58339815191525f80a460025b818114611c6757806020028401515f845f805160206139f58339815191525f80a4600101611c3e565b5086600103611cef575f6001600160a01b0316886001600160a01b0316876001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62865f81518110611cc157611cc1613441565b60200260200101516001604051611ce2929190918252602082015260400190565b60405180910390a4611d47565b5f6001600160a01b0316886001600160a01b0316876001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8688604051611d3e9291906136c8565b60405180910390a45b611d5386895f86612354565b5050505050505050565b6060806001600160a01b038416611d8657604051622e076360e81b815260040160405180910390fd5b825f03611da65760405163b562e8dd60e01b815260040160405180910390fd5b33836001600160401b03811115611dbf57611dbf612ddb565b604051908082528060200260200182016040528015611de8578160200160208202803683370190505b509250836001600160401b03811115611e0357611e03612ddb565b604051908082528060200260200182016040528015611e2c578160200160208202803683370190505b5091505f611e3960045490565b905080855f19031015611e875760405162461bcd60e51b8152602060048201526016602482015275135a5b9d1a5b99c81b1a5b5a5d1cc81c995858da195960521b6044820152606401610839565b5f5b85811015611ed957808201858281518110611ea657611ea6613441565b6020026020010181815250506001848281518110611ec657611ec6613441565b6020908102919091010152600101611e89565b506001600160a01b0386165f908152600160205260409020611efc908287612c20565b8460045f828254611f0d91906136b5565b909155505f905080611f1f87846136b5565b90506001600160a01b038816915082825f5f805160206139f58339815191525f80a4600183015b818114611f695780835f5f805160206139f58339815191525f80a4600101611f46565b50876001600160a01b03165f6001600160a01b0316856001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8989604051611fb99291906136c8565b60405180910390a4611fcd845f8a89612354565b505050509250929050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f6001600454612037919061342e565b905090565b816001600160a01b0316836001600160a01b0316036120af5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608401610839565b6001600160a01b038381165f81815260026020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60606003805461212a906132e2565b80601f0160208091040260200160405190810160405280929190818152602001828054612156906132e2565b80156121a15780601f10612178576101008083540402835291602001916121a1565b820191905f5260205f20905b81548152906001019060200180831161218457829003601f168201915b50505050509050919050565b60605f6121b983612c96565b60010190505f816001600160401b038111156121d7576121d7612ddb565b6040519080825280601f01601f191660200182016040528015612201576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461220b57509392505050565b6001600160a01b0384166122655760405163e602df0560e01b81525f6004820152602401610839565b6001600160a01b03831661228e57604051634a1406b160e11b81525f6004820152602401610839565b6001600160a01b038085165f908152600760209081526040808320938716835292905220829055801561170057826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161230091815260200190565b60405180910390a350505050565b6040805160018082528183019092526060916020808301908036833701905050905081815f8151811061234357612343613441565b602002602001018181525050919050565b6001600160a01b0382165f908152600a602052604090205460ff166124d257600e546001600160a01b0383165f9081526006602052604090205411156123dc5760405162461bcd60e51b815260206004820152601f60248201527f5472616e736665722065786365656473206d6178696d756d2077616c6c6574006044820152606401610839565b600f5460ff16156124d257325f9081526010602052604090205443116124505760405162461bcd60e51b8152602060048201526024808201527f4f6e6c79206f6e65207472616e736665722070657220626c6f636b20616c6c6f6044820152633bb2b21760e11b6064820152608401610839565b325f9081526010602052604090204390556001600160a01b0382163b1580156124785750323b155b6124d25760405162461bcd60e51b815260206004820152602560248201527f436f6e74726163742074726164696e672072657374726963746564206174206c6044820152640c2eadcc6d60db1b6064820152608401610839565b611700565b6001600160a01b0384163b15612743576040516301ffc9a760e01b8152636cdb3d1360e11b60048201526001600160a01b038516906301ffc9a790602401602060405180830381865afa158015612530573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061255491906136f5565b1561265e5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e619061258d9089908990889088908890600401613710565b6020604051808303815f875af19250505080156125c7575060408051601f3d908101601f191682019092526125c491810190613754565b60015b612627576125d361376f565b806308c379a00361260c57506125e7613788565b806125f2575061260e565b8060405162461bcd60e51b81526004016108399190612f06565b505b604051639c05499b60e01b815260040160405180910390fd5b6001600160e01b0319811663f23a6e6160e01b1461265857604051639c05499b60e01b815260040160405180910390fd5b50612743565b604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612690908990899088908790600401613810565b6020604051808303815f875af19250505080156126ca575060408051601f3d908101601f191682019092526126c791810190613754565b60015b612710576126d661376f565b806308c379a0036126f557506126ea613788565b806125f257506126f7565b505b6040516368d2bf6b60e11b815260040160405180910390fd5b6001600160e01b03198116630a85bd0160e11b14612741576040516368d2bf6b60e11b815260040160405180910390fd5b505b505050505050565b6001600160a01b038085165f90815260066020526040808220549286168252902054838210156127a75760405163391434e360e21b81526001600160a01b03871660048201526024810183905260448101859052606401610839565b846001600160a01b0316866001600160a01b031614612987576001600160a01b038087165f90815260066020526040808220878603905591871681522081850190558215612987576001600160a01b0386165f908152600a602052604090205460ff168061288d575f7f0000000000000000000000000000000000000000000000000de0b6b3a764000061283b878661342e565b612845919061346d565b61286f7f0000000000000000000000000000000000000000000000000de0b6b3a76400008661346d565b612879919061342e565b9050801561288b5761288b8882611a83565b505b6001600160a01b0386165f908152600a602052604090205460ff1661298557600b5460011480156128bb5750805b80156128d357505f546001600160a01b038881169116145b15612904576001600160a01b0386165f908152600a60205260409020805460ff191660011790556002600b55612985565b5f61292f7f0000000000000000000000000000000000000000000000000de0b6b3a76400008461346d565b7f0000000000000000000000000000000000000000000000000de0b6b3a764000061295a88866136b5565b612964919061346d565b61296e919061342e565b90508015612983576129808782611d5d565b50505b505b505b846001600160a01b0316866001600160a01b03165f805160206139f5833981519152866040516129b991815260200190565b60405180910390a3505050505050565b7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c168203600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c5f199190911460081b1790565b6001600160a01b0384163b156127435760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190612abc908990899088908890889060040161384c565b6020604051808303815f875af1925050508015612af6575060408051601f3d908101601f19168201909252612af391810190613754565b60015b612b02576125d361376f565b6001600160e01b0319811663bc197c8160e01b1461274157604051639c05499b60e01b815260040160405180910390fd5b600881901c5f818152602084905260409020545f19919060ff84191690811b901c81158117612b73575b5081015f81815260409020548115811715612b5d575b8015612c1857612c09817f0706060506020504060203020504030106050205030304010505030400000000601f6f8421084210842108cc6318c6db6d54be831560081b6fffffffffffffffffffffffffffffffff851160071b1784811c6001600160401b031060061b1784811c63ffffffff1060051b1784811c61ffff1060041b1784811c60ff1060031b1793841c1c161a1790565b600883901b178481115f031792505b505092915050565b5f1960ff8316846020528360081c5f5261010183820110612c7c575f805160408220805485851b1790559390910160ff811693600181019160081c015b808214612c7857815f528360405f2055600182019150612c5d565b505f525b60405f208284610100031c821b8154178155505050505050565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310612cd45772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612d00576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612d1e57662386f26fc10000830492506010015b6305f5e1008310612d36576305f5e100830492506008015b6127108310612d4a57612710830492506004015b60648310612d5c576064830492506002015b600a83106106805760010192915050565b80356001600160a01b038116811461138a575f80fd5b5f8060408385031215612d94575f80fd5b612d9d83612d6d565b946020939093013593505050565b6001600160e01b031981168114611445575f80fd5b5f60208284031215612dd0575f80fd5b813561104b81612dab565b634e487b7160e01b5f52604160045260245ffd5b601f8201601f191681016001600160401b0381118282101715612e1457612e14612ddb565b6040525050565b5f6001600160401b03831115612e3357612e33612ddb565b604051612e4a601f8501601f191660200182612def565b809150838152848484011115612e5e575f80fd5b838360208301375f60208583010152509392505050565b5f60208284031215612e85575f80fd5b81356001600160401b03811115612e9a575f80fd5b8201601f81018413612eaa575f80fd5b610a7284823560208401612e1b565b5f5b83811015612ed3578181015183820152602001612ebb565b50505f910152565b5f8151808452612ef2816020860160208601612eb9565b601f01601f19169290920160200192915050565b602081525f61104b6020830184612edb565b5f60208284031215612f28575f80fd5b5035919050565b5f805f60608486031215612f41575f80fd5b612f4a84612d6d565b9250612f5860208501612d6d565b9150604084013590509250925092565b5f805f60608486031215612f7a575f80fd5b612f8384612d6d565b95602085013595506040909401359392505050565b5f6001600160401b03821115612fb057612fb0612ddb565b5060051b60200190565b5f82601f830112612fc9575f80fd5b81356020612fd682612f98565b604051612fe38282612def565b83815260059390931b8501820192828101915086841115613002575f80fd5b8286015b8481101561301d5780358352918301918301613006565b509695505050505050565b5f82601f830112613037575f80fd5b61104b83833560208501612e1b565b5f805f805f60a0868803121561305a575f80fd5b61306386612d6d565b945061307160208701612d6d565b935060408601356001600160401b038082111561308c575f80fd5b61309889838a01612fba565b945060608801359150808211156130ad575f80fd5b6130b989838a01612fba565b935060808801359150808211156130ce575f80fd5b506130db88828901613028565b9150509295509295909350565b5f80604083850312156130f9575f80fd5b82356001600160401b038082111561310f575f80fd5b818501915085601f830112613122575f80fd5b8135602061312f82612f98565b60405161313c8282612def565b83815260059390931b850182019282810191508984111561315b575f80fd5b948201945b838610156131805761317186612d6d565b82529482019490820190613160565b96505086013592505080821115613195575f80fd5b506131a285828601612fba565b9150509250929050565b5f8151808452602080850194508084015f5b838110156131da578151875295820195908201906001016131be565b509495945050505050565b602081525f61104b60208301846131ac565b8015158114611445575f80fd5b5f8060408385031215613215575f80fd5b61321e83612d6d565b9150602083013561322e816131f7565b809150509250929050565b5f60208284031215613249575f80fd5b61104b82612d6d565b5f8060408385031215613263575f80fd5b61326c83612d6d565b915061327a60208401612d6d565b90509250929050565b5f805f805f60a08688031215613297575f80fd5b6132a086612d6d565b94506132ae60208701612d6d565b9350604086013592506060860135915060808601356001600160401b038111156132d6575f80fd5b6130db88828901613028565b600181811c908216806132f657607f821691505b60208210810361331457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561148d575f81815260208120601f850160051c810160208610156133405750805b601f850160051c820191505b818110156127435782815560010161334c565b81516001600160401b0381111561337857613378612ddb565b61338c8161338684546132e2565b8461331a565b602080601f8311600181146133bf575f84156133a85750858301515b5f19600386901b1c1916600185901b178555612743565b5f85815260208120601f198616915b828110156133ed578886015182559484019460019091019084016133ce565b508582101561340a57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52601160045260245ffd5b818103818111156106805761068061341a565b634e487b7160e01b5f52603260045260245ffd5b5f600182016134665761346661341a565b5060010190565b5f8261348757634e487b7160e01b5f52601260045260245ffd5b500490565b80820281158282048414176106805761068061341a565b5f81546134af816132e2565b600182811680156134c757600181146134dc57613508565b60ff1984168752821515830287019450613508565b855f526020805f205f5b858110156134ff5781548a8201529084019082016134e6565b50505082870194505b5050505092915050565b5f61351d82856134a3565b835161352d818360208801612eb9565b01949350505050565b6e7b226e616d65223a202253554e202360881b815284515f9061356081600f850160208a01612eb9565b701116113232b9b1b934b83a34b7b7111d1160791b600f918401918201528551613591816020808501908a01612eb9565b7f222c2265787465726e616c5f75726c223a2268747470733a2f2f7777772e736f602092909101918201527f6c6172666c6172652e6c6f6c222c22696d616765223a2200000000000000000060408201526135ef60578201866134a3565b90508351613601818360208801612eb9565b019695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c000000000081525f835161364381601b850160208801612eb9565b7f222c2261747472696275746573223a5b7b2274726169745f74797065223a2243601b918401918201526e37b637b91116113b30b63ab2911d1160891b603b820152835161369881604a840160208801612eb9565b63227d5d7d60e01b604a9290910191820152604e01949350505050565b808201808211156106805761068061341a565b604081525f6136da60408301856131ac565b82810360208401526136ec81856131ac565b95945050505050565b5f60208284031215613705575f80fd5b815161104b816131f7565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190525f9061374990830184612edb565b979650505050505050565b5f60208284031215613764575f80fd5b815161104b81612dab565b5f60033d11156137855760045f803e505f5160e01c5b90565b5f60443d10156137955790565b6040516003193d81016004833e81513d6001600160401b0381602484011181841117156137c457505050505090565b82850191508151818111156137dc5750505050505090565b843d87010160208285010111156137f65750505050505090565b61380560208286010187612def565b509095945050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f9061384290830184612edb565b9695505050505050565b6001600160a01b0386811682528516602082015260a0604082018190525f90613877908301866131ac565b828103606084015261388981866131ac565b9050828103608084015261389d8185612edb565b9897505050505050505056fe456e747279206c6576656c204e46547320706f776572656420627920455243313135352e205468652073696c766572204e465473206172652073756e6e6564206279206173706972696e6720636f6c6c6563746f727320616e64206d65746963756c6f75736c79206372616674656420666f72206163636573736962696c6974792e50726573746967696f7573204e46547320706f776572656420627920455243313135352e2054686520676f6c64204e46547320617265206361726566756c6c792073756e6e65642062792065787065727420636f6c6c6563746f727320616e64206d65746963756c6f75736c792063726166746564207769746820676f6c64656e20657863656c6c656e63652c2073796d626f6c697a696e67207468652070696e6e61636c65206f66206469676974616c2072617269747920616e64206578636c757369766974792eddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef4c6567656e64617279204e46547320706f776572656420627920455243313135352e20546865204469616d6f6e64204e46547320617265206d65746963756c6f75736c792073756e6e656420627920696e64757374727920656c6974657320616e642063726166746564207769746820756e706172616c6c656c656420707265636973696f6e2c20726570726573656e74696e6720746865207a656e697468206f66206c757875727920616e64206469676974616c2061727469737472792e526566696e6564204e46547320706f776572656420627920455243313135352e205468652073696c766572204e465473206172652073756e6e656420627920736561736f6e656420656e7468757369617374732c20616464696e6720616e206578747261206c61796572206f6620736f706869737469636174696f6e20746f20796f757220706f7274666f6c696f2ea264697066735822122033846d8f18b9e81ed13c5ff6685615735cb957e35478c0ff3cb0c5155466c5d764736f6c63430008140033
Deployed Bytecode Sourcemap
108695:4687:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80075:318;;;;;;:::i;:::-;;:::i;:::-;;;597:25:1;;;585:2;570:18;80075:318:0;;;;;;;;78283:527;;;;;;:::i;:::-;;:::i;:::-;;;1184:14:1;;1177:22;1159:41;;1147:2;1132:18;78283:527:0;1019:187:1;110866:119:0;;;;;;:::i;:::-;;:::i;:::-;;75164:18;;;:::i;:::-;;;;;;;:::i;74893:46::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;74893:46:0;;;;;;-1:-1:-1;;;;;3632:32:1;;;3614:51;;3602:2;3587:18;74893:46:0;3468:203:1;101629:483:0;;;;;;:::i;:::-;;:::i;109122:32::-;;;;;;;;;113271:108;;;;;;:::i;:::-;;:::i;75336:36::-;;;;;110590:126;;;;;;:::i;:::-;;:::i;102261:770::-;;;;;;:::i;:::-;;:::i;79754:170::-;;;;;;:::i;:::-;;:::i;82116:418::-;;;;;;:::i;:::-;;:::i;75269:31::-;;;;;;;;6599:4:1;6587:17;;;6569:36;;6557:2;6542:18;75269:31:0;6427:184:1;80559:530:0;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;110190:143::-;;;:::i;76703:660::-;;;;;;:::i;:::-;;:::i;75449:37::-;;;;;110341:241;;;;;;:::i;:::-;;:::i;75404:38::-;;;;;79412:114;;;;;;:::i;:::-;-1:-1:-1;;;;;79502:16:0;79475:7;79502:16;;;:9;:16;;;;;;;79412:114;48028:103;;;:::i;108438:250::-;;;;;;:::i;:::-;;:::i;47353:87::-;47399:7;47426:6;-1:-1:-1;;;;;47426:6:0;47353:87;;75212:20;;;:::i;106722:1264::-;;;;;;:::i;:::-;;:::i;75532:41::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;75659:29;;;;;;81162:155;;;;;;:::i;:::-;;:::i;101285:186::-;;;;;;:::i;:::-;;:::i;78071:140::-;;;;;;:::i;:::-;;:::i;110993:2270::-;;;;;;:::i;:::-;;:::i;108785:26::-;;;:::i;101479:142::-;;;;;;:::i;:::-;-1:-1:-1;;;;;101586:18:0;;;101559:7;101586:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;101479:142;110724:134;;;;;;:::i;:::-;;:::i;81389:168::-;;;;;;:::i;:::-;-1:-1:-1;;;;;81512:27:0;;;81488:4;81512:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;81389:168;81629:410;;;;;;:::i;:::-;;:::i;108757:21::-;;;:::i;48286:220::-;;;;;;:::i;:::-;;:::i;109091:24::-;;;;;;80075:318;80161:7;-1:-1:-1;;;;;80184:21:0;;80181:88;;80229:28;;-1:-1:-1;;;80229:28:0;;;;;;;;;;;80181:88;-1:-1:-1;;;;;80282:15:0;;;;;;:6;:15;;;;;;;;64806:1;64797:10;;;64786:22;;;;;;;;;64821:4;64813:12;;64786:40;64785:46;80279:104;;;-1:-1:-1;80329:1:0;80322:8;;80279:104;-1:-1:-1;80370:1:0;80279:104;80075:318;;;;:::o;78283:527::-;78385:4;-1:-1:-1;;;;;;78422:41:0;;-1:-1:-1;;;78422:41:0;;:110;;-1:-1:-1;;;;;;;78480:52:0;;-1:-1:-1;;;78480:52:0;78422:110;:165;;;-1:-1:-1;;;;;;;78549:38:0;;-1:-1:-1;;;78549:38:0;78422:165;:207;;;-1:-1:-1;;;;;;;;;;78604:25:0;;;78422:207;:284;;;-1:-1:-1;;;;;;;;;;78681:25:0;;;78422:284;:380;;;-1:-1:-1;;;;;;;;;;2462:40:0;;;78766:36;2362:148;110866:119;47239:13;:11;:13::i;:::-;110934:15:::1;110942:6;110934:7;:15::i;:::-;110965:12;::::0;::::1;::::0;;;::::1;110866:119:::0;:::o;75164:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;101629:483::-;101702:4;101735:10;101768:14;77750:13;;;77676:95;101768:14;101760:5;:22;:35;;;;;101794:1;101786:5;:9;101760:35;101756:327;;;101818:23;101828:5;101835;101818:9;:23::i;:::-;101814:96;;101869:25;;-1:-1:-1;;;101869:25:0;;-1:-1:-1;;;;;3632:32:1;;101869:25:0;;;3614:51:1;3587:18;;101869:25:0;;;;;;;;101814:96;101926:18;;;;:11;:18;;;;;;;;;:28;;-1:-1:-1;;;;;;101926:28:0;-1:-1:-1;;;;;101926:28:0;;;;;;;;;101976:31;;597:25:1;;;101976:31:0;;;;;;570:18:1;101976:31:0;;;;;;;101756:327;;;102040:31;102049:5;102056:7;102065:5;102040:8;:31::i;:::-;-1:-1:-1;102100:4:0;;101629:483;-1:-1:-1;;;101629:483:0:o;113271:108::-;113326:13;113359:12;113368:2;113359:8;:12::i;110590:126::-;47239:13;:11;:13::i;:::-;110662:7:::1;:18;110672:8:::0;110662:7;:18:::1;:::i;:::-;-1:-1:-1::0;110696:12:0::1;::::0;::::1;::::0;;;::::1;110590:126:::0;:::o;102261:770::-;102348:4;102377:14;77750:13;;;77676:95;102377:14;102369:5;:22;102365:637;;;-1:-1:-1;;;;;102412:12:0;;;;;;:6;:12;;;;;;;;64806:1;64797:10;;;64786:22;;;;;;;;;64821:4;64813:12;;64786:40;64785:46;102408:96;;102463:25;;-1:-1:-1;;;102463:25:0;;-1:-1:-1;;;;;3632:32:1;;102463:25:0;;;3614:51:1;3587:18;;102463:25:0;3468:203:1;102408:96:0;102546:10;-1:-1:-1;;;;;102546:18:0;;;;;;:74;;-1:-1:-1;;;;;;81512:27:0;;81488:4;81512:27;;;:18;:27;;;;;;;;102609:10;81512:37;;;;;;;;;;102585:35;102546:74;:127;;;;-1:-1:-1;102655:18:0;;;;:11;:18;;;;;;-1:-1:-1;;;;;102655:18:0;102641:10;:32;;102546:127;102524:238;;;102715:31;;-1:-1:-1;;;102715:31:0;;102735:10;102715:31;;;3614:51:1;3587:18;;102715:31:0;3468:203:1;102524:238:0;102785:18;;;;:11;:18;;;;;;;;102778:25;;-1:-1:-1;;;;;;102778:25:0;;;102820:48;;;;;;;;;;;;102838:4;;102844:2;;102797:5;;102778:25;;102820:17;:48::i;:::-;102365:637;;;102903:40;102919:4;102925:10;102937:5;102903:15;:40::i;:::-;102958:32;102968:4;102974:2;102978:5;102985:4;102958:9;:32::i;79754:170::-;79846:7;79873:43;79896:5;79903:12;79896:5;79903:4;:12;:::i;:::-;-1:-1:-1;;;;;79873:13:0;;;;;;:6;:13;;;;;;:43;:22;:43::i;:::-;79866:50;79754:170;-1:-1:-1;;;;79754:170:0:o;82116:418::-;-1:-1:-1;;;;;82332:20:0;;45599:10;82332:20;;:60;;-1:-1:-1;82356:36:0;82373:4;45599:10;81389:168;:::i;82356:36::-;82327:137;;82417:35;;-1:-1:-1;;;82417:35:0;;;;;;;;;;;82327:137;82474:52;82497:4;82503:2;82507:3;82512:7;82521:4;82474:22;:52::i;:::-;82116:418;;;;;:::o;80559:530::-;80715:16;80771:3;:10;80752:8;:15;:29;80749:90;;80805:22;;-1:-1:-1;;;80805:22:0;;;;;;;;;;;80749:90;80851:30;80898:8;:15;-1:-1:-1;;;;;80884:30:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80884:30:0;;80851:63;;80932:9;80927:122;80951:8;:15;80947:1;:19;80927:122;;;81007:30;81017:8;81026:1;81017:11;;;;;;;;:::i;:::-;;;;;;;81030:3;81034:1;81030:6;;;;;;;;:::i;:::-;;;;;;;81007:9;:30::i;:::-;80988:13;81002:1;80988:16;;;;;;;;:::i;:::-;;;;;;;;;;:49;80968:3;;;:::i;:::-;;;80927:122;;;-1:-1:-1;81068:13:0;80559:530;-1:-1:-1;;;80559:530:0:o;110190:143::-;47239:13;:11;:13::i;:::-;110260::::1;::::0;;::::1;::::0;;::::1;110259:14;-1:-1:-1::0;;110243:30:0;;::::1;::::0;::::1;::::0;;;110289:36:::1;::::0;110311:13;;1184:14:1;1177:22;1159:41;;110289:36:0::1;::::0;1147:2:1;1132:18;110289:36:0::1;;;;;;;110190:143::o:0;76703:660::-;47239:13;:11;:13::i;:::-;-1:-1:-1;;;;;76797:17:0;::::1;;::::0;;;:9:::1;:17;::::0;;;;;:26;::::1;;:17;::::0;;::::1;:26;;::::0;76789:58:::1;;;::::0;-1:-1:-1;;;76789:58:0;;13373:2:1;76789:58:0::1;::::0;::::1;13355:21:1::0;13412:2;13392:18;;;13385:30;-1:-1:-1;;;13431:18:1;;;13424:49;13490:18;;76789:58:0::1;13171:343:1::0;76789:58:0::1;76863:5;76860:460;;;76885:11;76899:34;76909:6;76916:1;76918:14;77750:13:::0;;;77676:95;76899:34:::1;76885:48:::0;-1:-1:-1;76951:7:0;;76948:53:::1;;76978:23;76989:6;76997:3;76978:10;:23::i;:::-;77021:24;::::0;-1:-1:-1;;;;;77021:24:0;::::1;::::0;::::1;::::0;;;::::1;76870:187;76860:460;;;-1:-1:-1::0;;;;;79502:16:0;;77078:11:::1;79502:16:::0;;;:9;:16;;;;;;;77149:18:::1;77155:12;79502:16:::0;77149:18:::1;:::i;:::-;77124:43:::0;-1:-1:-1;77185:18:0;;77182:81:::1;;77222:41;77240:6;77248:14;77222:17;:41::i;:::-;;;77182:81;77283:25;::::0;-1:-1:-1;;;;;77283:25:0;::::1;::::0;::::1;::::0;;;::::1;77063:257;;76860:460;-1:-1:-1::0;;;;;77330:17:0;;;::::1;;::::0;;;:9:::1;:17;::::0;;;;:25;;-1:-1:-1;;77330:25:0::1;::::0;::::1;;::::0;;;::::1;::::0;;76703:660::o;110341:241::-;47239:13;:11;:13::i;:::-;110428:1:::1;110418:7;:11;110410:53;;;::::0;-1:-1:-1;;;110410:53:0;;14075:2:1;110410:53:0::1;::::0;::::1;14057:21:1::0;14114:2;14094:18;;;14087:30;14153:31;14133:18;;;14126:59;14202:18;;110410:53:0::1;13873:353:1::0;110410:53:0::1;110510:3;110486:21;110500:7:::0;110486:11:::1;:21;:::i;:::-;:27;;;;:::i;:::-;110474:9;:39:::0;110529:45:::1;110570:3;110546:21;110560:7:::0;110546:11:::1;:21;:::i;:::-;:27;;;;:::i;:::-;110529:45;::::0;597:25:1;;;585:2;570:18;110529:45:0::1;;;;;;;110341:241:::0;:::o;48028:103::-;47239:13;:11;:13::i;:::-;48093:30:::1;48120:1;48093:18;:30::i;:::-;48028:103::o:0;108438:250::-;108505:16;108537:14;:12;:14::i;:::-;108555:1;108537:19;108534:74;;-1:-1:-1;;108580:16:0;;;108594:1;108580:16;;;;;;;;;108438:250::o;108534:74::-;108625:55;108641:5;77588:1;77750:13;;106722:1264;:::i;75212:20::-;;;;;;;:::i;106722:1264::-;106854:16;106921:4;106912:5;:13;106908:45;;106934:19;;-1:-1:-1;;;106934:19:0;;;;;;;;;;;106908:45;77588:1;107059:5;:23;107055:87;;;77588:1;107103:23;;107055:87;107221:17;107241:14;77750:13;;;77676:95;107241:14;107221:34;;107281:9;107274:4;:16;107270:73;;;107318:9;107311:16;;107270:73;107359:22;107407:4;107399:5;:12;107396:157;;;107449:29;107459:5;107466;107473:4;107449:9;:29::i;:::-;107432:46;;107396:157;;;-1:-1:-1;107536:1:0;107396:157;107581:25;107623:14;-1:-1:-1;;;;;107609:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;107609:29:0;-1:-1:-1;;;;;;107687:13:0;;107655:29;107687:13;;;:6;:13;;;;;107581:57;;-1:-1:-1;107770:5:0;;107729:209;107796:14;107781:11;:29;107729:209;;64806:1;64797:10;;;64524;64786:22;;;;;;;;;;;64821:4;64813:12;;64786:40;64830:1;64785:46;107836:87;;;107902:1;107876:8;107885:13;;;;;;107876:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;107836:87;107812:3;;;;;107729:209;;;-1:-1:-1;107959:8:0;;106722:1264;-1:-1:-1;;;;;;;;106722:1264:0:o;81162:155::-;81257:52;45599:10;81290:8;81300;81257:18;:52::i;:::-;81162:155;;:::o;101285:186::-;101354:4;101387:10;101408:33;101387:10;101425:2;101429:5;101436:4;101408:9;:33::i;78071:140::-;-1:-1:-1;;;;;78180:15:0;;78156:4;78180:15;;;:6;:15;;;;;;;;64806:1;64797:10;;;64786:22;;;;;;;;64821:4;64813:12;;64786:40;64785:46;78180:23;78173:30;78071:140;-1:-1:-1;;;78071:140:0:o;110993:2270::-;111044:13;111079:14;77750:13;;;77676:95;111079:14;111073:2;:20;111070:54;;111102:22;;-1:-1:-1;;;111102:22:0;;;;;;;;;;;111070:54;111171:1;111147:13;111157:2;111147:9;:13::i;:::-;111141:27;:31;111137:70;;;111194:13;111204:2;111194:9;:13::i;111137:70::-;111251:1;111228:12;111222:26;;;;;:::i;:::-;;;:30;111218:2038;;;111298:12;111312:13;:2;:11;:13::i;:::-;111281:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;111267:60;;110993:2270;;;:::o;111218:2038::-;111358:10;111411:2;111394:20;;;;;;15654:19:1;;15698:2;15689:12;;15525:182;111394:20:0;;;;-1:-1:-1;;111394:20:0;;;;;;;;;111384:31;;111394:20;111384:31;;;;111434:24;;;;;:19;:24;;;111473;;;;;;;;;;111512:30;;;;;;;;;;111371:46;;;-1:-1:-1;111571:2:0;111563:10;;111559:1316;;111594:41;;;;;;;;;;;;;;;;;;;111654:17;;;;;;;;;;;;;-1:-1:-1;;;111654:17:0;;;;;111690:207;;;;;;;;;;;;;;;;;;;111559:1316;;;111931:3;111923:4;:11;;;111919:956;;111955:41;;;;;;;;;;;;;;;;;;;112015:14;;;;;;;;;;;;;-1:-1:-1;;;112015:14:0;;;;;112048:217;;;;;;;;;;;;;;;;;;;111919:956;;;112299:3;112291:4;:11;;;112287:588;;112323:41;;;;;;;;;;;;;;;;;;;112383:16;;;;;;;;;;;;;-1:-1:-1;;;112383:16:0;;;;;112418:159;;;;;;;;;;;;;;;;;;;112287:588;;;112618:41;;;;;;;;;;;;;;;;;;;112678:16;;;;;;;;;;;;;-1:-1:-1;;;112678:16:0;;;;;112713:146;;;;;;;;;;;;;;;;;;;112287:588;112891:26;112963:13;:2;:11;:13::i;:::-;112999:11;113071:7;113080:5;112927:159;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;112891:196;;113164:12;113229:5;113116:127;;;;;;;;;:::i;:::-;;;;;;;;;;;;;113102:142;;;;;;;110993:2270;;;:::o;111218:2038::-;110993:2270;;;:::o;108785:26::-;;;;;;;:::i;110724:134::-;47239:13;:11;:13::i;:::-;110798:12:::1;:24;110813:9:::0;110798:12;:24:::1;:::i;81629:410::-:0;-1:-1:-1;;;;;81818:20:0;;45599:10;81818:20;;:60;;-1:-1:-1;81842:36:0;81859:4;45599:10;81389:168;:::i;81842:36::-;81815:217;;;81894:51;81912:4;81918:2;81922;81926:6;81934:4;81940;81894:17;:51::i;:::-;81815:217;;;81985:35;;-1:-1:-1;;;81985:35:0;;;;;;;;;;;108757:21;;;;;;;:::i;48286:220::-;47239:13;:11;:13::i;:::-;-1:-1:-1;;;;;48371:22:0;::::1;48367:93;;48417:31;::::0;-1:-1:-1;;;48417:31:0;;48445:1:::1;48417:31;::::0;::::1;3614:51:1::0;3587:18;;48417:31:0::1;3468:203:1::0;48367:93:0::1;48470:28;48489:8;48470:18;:28::i;:::-;48286:220:::0;:::o;47518:166::-;47399:7;47426:6;-1:-1:-1;;;;;47426:6:0;45599:10;47578:23;47574:103;;47625:40;;-1:-1:-1;;;47625:40:0;;45599:10;47625:40;;;3614:51:1;3587:18;;47625:40:0;3468:203:1;88818:88:0;88885:4;:13;88892:6;88885:4;:13;:::i;105252:130::-;105337:37;105346:5;105353:7;105362:5;105369:4;105337:8;:37::i;:::-;105252:130;;;:::o;83033:1707::-;-1:-1:-1;;;;;83237:16:0;;83234:78;;83277:23;;-1:-1:-1;;;83277:23:0;;;;;;;;;;;83234:78;45599:10;83324:16;83389:21;83407:2;83389:17;:21::i;:::-;83366:44;;83484:6;83494:1;83484:11;:35;;;;-1:-1:-1;;;;;;83499:12:0;;;;;;:6;:12;;;;;;;;64806:1;64797:10;;;64786:22;;;;;;;;;64821:4;64813:12;;64786:40;64785:46;83499:20;83481:260;;;-1:-1:-1;;;;;83536:12:0;;;;;;;:6;:12;;;;;;;;65298:1;65289:10;;;65278:22;;;;;;;;;:48;;65320:4;65312:12;;65306:19;;;65304:22;;65278:48;;;;;;83573:10;;;;;;;;;;;65079:22;;;;;;;;:47;;;;;;;;83606:40;;83536:12;;83573:10;;83626:12;;83606:9;:40::i;:::-;83481:260;;;83686:43;;-1:-1:-1;;;83686:43:0;;;;;;;;;;;83481:260;-1:-1:-1;;;;;83939:25:0;;;;83992:27;;84345:6;83939:25;83992:27;-1:-1:-1;;;;;;;;;;;83753:16:0;;84076:304;84439:2;-1:-1:-1;;;;;84408:46:0;84433:4;-1:-1:-1;;;;;84408:46:0;84423:8;-1:-1:-1;;;;;84408:46:0;;84443:2;84447:6;84408:46;;;;;;18455:25:1;;;18511:2;18496:18;;18489:34;18443:2;18428:18;;18281:248;84408:46:0;;;;;;;;84467:44;84487:8;84497:4;84503:2;84507:3;84467:19;:44::i;:::-;84527:5;84524:209;;;84549:11;84563:14;77750:13;;;77676:95;84563:14;84549:28;;84592:68;84623:8;84633:4;84639:2;84643;84647:6;84655:4;84592:30;:68::i;:::-;84697:3;84679:14;77750:13;;;77676:95;84679:14;:21;84675:46;;84709:12;;-1:-1:-1;;;84709:12:0;;;;;;;;;;;84675:46;84534:199;84524:209;83223:1517;;;;83033:1707;;;;;;:::o;105841:487::-;-1:-1:-1;;;;;101586:18:0;;;105941:24;101586:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;106008:37:0;;106004:317;;106085:5;106066:16;:24;106062:132;;;106118:60;;-1:-1:-1;;;106118:60:0;;-1:-1:-1;;;;;18754:32:1;;106118:60:0;;;18736:51:1;18803:18;;;18796:34;;;18846:18;;;18839:34;;;18709:18;;106118:60:0;18534:345:1;106062:132:0;106237:57;106246:5;106253:7;106281:5;106262:16;:24;106288:5;106237:8;:57::i;:::-;105930:398;105841:487;;;:::o;103039:325::-;-1:-1:-1;;;;;103134:18:0;;103130:88;;103176:30;;-1:-1:-1;;;103176:30:0;;103203:1;103176:30;;;3614:51:1;3587:18;;103176:30:0;3468:203:1;103130:88:0;-1:-1:-1;;;;;103232:16:0;;103228:88;;103272:32;;-1:-1:-1;;;103272:32:0;;103301:1;103272:32;;;3614:51:1;3587:18;;103272:32:0;3468:203:1;103228:88:0;103326:30;103334:4;103340:2;103344:5;103351:4;103326:7;:30::i;69549:786::-;69671:13;69753:1;69744:10;;;69793:4;69785:12;;69835:3;69818:14;;;:20;69812:417;;69884:10;:18;;;;;;;;;;;69868:44;;69884:27;;69868:15;:44::i;:::-;69962:14;;70030:4;70011:23;;;69962:14;-1:-1:-1;70086:8:0;;;;69931:17;;69981:1;69961:21;69951:32;70081:133;70106:9;70096:6;:19;70081:133;;70175:10;:18;;;;;;;;;;;70159:35;;:15;:35::i;:::-;70150:44;;;;70117:8;;;;;70081:133;;;69841:388;69812:417;70269:10;:18;;;;;;;;;;;70252:64;;70269:27;;70302:3;:12;;;70268:47;70252:15;:64::i;:::-;70243:73;;;;69549:786;-1:-1:-1;;;;;69549:786:0:o;85098:2876::-;85320:7;:14;85306:3;:10;:28;85303:89;;85358:22;;-1:-1:-1;;;85358:22:0;;;;;;;;;;;85303:89;-1:-1:-1;;;;;85407:16:0;;85404:78;;85447:23;;-1:-1:-1;;;85447:23:0;;;;;;;;;;;85404:78;45599:10;85492:16;85594:370;85618:3;:10;85614:1;:14;85594:370;;;85650:10;85663:3;85667:1;85663:6;;;;;;;;:::i;:::-;;;;;;;85650:19;;85684:14;85701:7;85709:1;85701:10;;;;;;;;:::i;:::-;;;;;;;85684:27;;85731:6;85741:1;85731:11;:35;;;;-1:-1:-1;;;;;;85746:12:0;;;;;;:6;:12;;;;;;;;64806:1;64797:10;;;64786:22;;;;;;;;;64821:4;64813:12;;64786:40;64785:46;85746:20;85728:225;;;-1:-1:-1;;;;;;85787:12:0;;;;;;;:6;:12;;;;;;;;65298:1;65289:10;;;65278:22;;;;;;;;;:48;;65320:4;65312:12;;;65306:19;;;65304:22;;65278:48;;;;;85828:10;;;;;;;;;;;65079:22;;;;;;;;:47;;;;;;;85630:3;;;:::i;:::-;;;85594:370;;;;85974:53;85984:4;85990:2;86009:3;:10;85994:12;:25;;;;:::i;:::-;86021:5;85974:9;:53::i;:::-;86040:16;86067:18;86096:11;86110:3;:10;86123:1;86110:14;;;;:::i;:::-;86096:28;;-1:-1:-1;;;;;86607:4:0;86603:27;86589:41;;-1:-1:-1;;;;;86660:2:0;86656:25;86644:37;;87022:4;87017:3;87013:14;87007:21;86971:8;86931:10;-1:-1:-1;;;;;;;;;;;86818:1:0;86761;86738:319;87345:1;87307:336;87381:3;87372:7;87369:16;87307:336;;87617:7;87611:4;87607:18;87602:3;87598:28;87592:35;87582:8;87570:10;-1:-1:-1;;;;;;;;;;;87540:1:0;87537;87532:96;87430:1;87417:15;87307:336;;;87311:50;87701:2;-1:-1:-1;;;;;87671:47:0;87695:4;-1:-1:-1;;;;;87671:47:0;87685:8;-1:-1:-1;;;;;87671:47:0;;87705:3;87710:7;87671:47;;;;;;;:::i;:::-;;;;;;;;87731:44;87751:8;87761:4;87767:2;87771:3;87731:19;:44::i;:::-;87791:13;87807:14;77750:13;;;77676:95;87807:14;87791:30;;87832:75;87868:8;87878:4;87884:2;87888:3;87893:7;87902:4;87832:35;:75::i;:::-;87940:5;87922:14;77750:13;;;77676:95;87922:14;:23;87918:48;;87954:12;;-1:-1:-1;;;87954:12:0;;;;;;;;;;;94378:1816;-1:-1:-1;;;;;94484:18:0;;94481:77;;94525:21;;-1:-1:-1;;;94525:21:0;;;;;;;;;;;94481:77;77750:13;;45599:10;;94662:24;94703:6;-1:-1:-1;;;;;94689:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;94689:21:0;;94662:48;;94721:20;94758:6;-1:-1:-1;;;;;94744:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;94744:21:0;;94721:44;;94807:9;94803:339;94826:6;94822:1;:10;94803:339;;;94871:1;94858:7;94866:1;94858:10;;;;;;;;:::i;:::-;;;;;;;;;;;:14;;;;-1:-1:-1;;;;;94904:12:0;;94891:10;94904:12;;;:6;:12;;;;;;:36;;94929:10;94904:24;:36::i;:::-;94891:49;;-1:-1:-1;;94962:2:0;:25;94959:62;;94996:25;;-1:-1:-1;;;94996:25:0;;;;;;;;;;;94959:62;95049:2;95040:3;95044:1;95040:6;;;;;;;;:::i;:::-;;;;;;;;;;;:11;;;;-1:-1:-1;;;;;95070:12:0;;;;;;:6;:12;;;;;;;65298:1;65289:10;;;65278:22;;;;;;;;:48;;65320:4;65312:12;;65306:19;;;65304:22;65278:48;;;65289:10;;-1:-1:-1;94834:3:0;94803:339;;;;95293:18;;95336:10;:6;95345:1;95336:10;:::i;:::-;95322:24;;-1:-1:-1;;;;;95401:4:0;95397:27;95383:41;;95609:4;95604:3;95600:14;95594:21;95574:1;95545:10;-1:-1:-1;;;;;;;;;;;95481:1:0;95461;95438:192;95684:1;95646:264;95720:3;95711:7;95708:16;95646:264;;95884:7;95878:4;95874:18;95869:3;95865:28;95859:35;95856:1;95844:10;-1:-1:-1;;;;;;;;;;;95814:1:0;95811;95806:89;95769:1;95756:15;95646:264;;;95650:50;95936:6;95946:1;95936:11;95933:176;;96006:1;-1:-1:-1;;;;;95967:53:0;95992:4;-1:-1:-1;;;;;95967:53:0;95982:8;-1:-1:-1;;;;;95967:53:0;;96010:3;96014:1;96010:6;;;;;;;;:::i;:::-;;;;;;;96018:1;95967:53;;;;;;18455:25:1;;;18511:2;18496:18;;18489:34;18443:2;18428:18;;18281:248;95967:53:0;;;;;;;;95933:176;;;96092:1;-1:-1:-1;;;;;96054:55:0;96078:4;-1:-1:-1;;;;;96054:55:0;96068:8;-1:-1:-1;;;;;96054:55:0;;96096:3;96101:7;96054:55;;;;;;;:::i;:::-;;;;;;;;95933:176;96132:52;96152:8;96162:4;96176:1;96180:3;96132:19;:52::i;:::-;94470:1724;;;;;;94378:1816;;:::o;89721:1687::-;89826:20;;-1:-1:-1;;;;;89890:16:0;;89887:74;;89930:19;;-1:-1:-1;;;89930:19:0;;;;;;;;;;;89887:74;89974:6;89984:1;89974:11;89971:68;;90009:18;;-1:-1:-1;;;90009:18:0;;;;;;;;;;;89971:68;45599:10;90115:6;-1:-1:-1;;;;;90101:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90101:21:0;;90095:27;;90157:6;-1:-1:-1;;;;;90143:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90143:21:0;;90133:31;;90175:20;90198:14;77750:13;;;77676:95;90198:14;90175:37;;90288:12;90278:6;-1:-1:-1;;90258:26:0;:42;;90250:77;;;;-1:-1:-1;;;90250:77:0;;19947:2:1;90250:77:0;;;19929:21:1;19986:2;19966:18;;;19959:30;-1:-1:-1;;;20005:18:1;;;19998:52;20067:18;;90250:77:0;19745:346:1;90250:77:0;90346:9;90342:129;90365:6;90361:1;:10;90342:129;;;90421:1;90406:12;:16;90397:3;90401:1;90397:6;;;;;;;;:::i;:::-;;;;;;:25;;;;;90454:1;90441:7;90449:1;90441:10;;;;;;;;:::i;:::-;;;;;;;;;;:14;90373:3;;90342:129;;;;-1:-1:-1;;;;;90566:10:0;;;;;;:6;:10;;;;;:41;;90586:12;90600:6;90566:19;:41::i;:::-;90635:6;90618:13;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;90654:16:0;;-1:-1:-1;90654:16:0;90695:21;90710:6;90695:12;:21;:::i;:::-;90681:35;;-1:-1:-1;;;;;90769:2:0;90765:25;90753:37;;90958:12;90931:8;90911:1;-1:-1:-1;;;;;;;;;;;90847:1:0;90827;90804:181;91057:1;91043:12;91039:20;91001:253;91094:3;91085:7;91082:16;91001:253;;91231:7;91221:8;91218:1;-1:-1:-1;;;;;;;;;;;91188:1:0;91185;91180:59;91143:1;91130:15;91001:253;;;91005:69;91318:2;-1:-1:-1;;;;;91282:53:0;91314:1;-1:-1:-1;;;;;91282:53:0;91296:8;-1:-1:-1;;;;;91282:53:0;;91322:3;91327:7;91282:53;;;;;;;:::i;:::-;;;;;;;;91348:50;91368:8;91386:1;91390:2;91394:3;91348:19;:50::i;:::-;89874:1534;;;;89721:1687;;;;;:::o;48666:191::-;48740:16;48759:6;;-1:-1:-1;;;;;48776:17:0;;;-1:-1:-1;;;;;;48776:17:0;;;;;;48809:40;;48759:6;;;;;;;48809:40;;48740:16;48809:40;48729:128;48666:191;:::o;77869:114::-;77916:7;77588:1;77750:13;;77943:32;;;;:::i;:::-;77936:39;;77869:114;:::o;96340:331::-;96495:8;-1:-1:-1;;;;;96486:17:0;:5;-1:-1:-1;;;;;96486:17:0;;96478:71;;;;-1:-1:-1;;;96478:71:0;;20298:2:1;96478:71:0;;;20280:21:1;20337:2;20317:18;;;20310:30;20376:34;20356:18;;;20349:62;-1:-1:-1;;;20427:18:1;;;20420:39;20476:19;;96478:71:0;20096:405:1;96478:71:0;-1:-1:-1;;;;;96560:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;96560:46:0;;;;;;;;;;96622:41;;1159::1;;;96622::0;;1132:18:1;96622:41:0;;;;;;;96340:331;;;:::o;79221:105::-;79281:13;79314:4;79307:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79221:105;;;:::o;42444:718::-;42500:13;42551:14;42568:17;42579:5;42568:10;:17::i;:::-;42588:1;42568:21;42551:38;;42604:20;42638:6;-1:-1:-1;;;;;42627:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42627:18:0;-1:-1:-1;42604:41:0;-1:-1:-1;42769:28:0;;;42785:2;42769:28;42826:290;-1:-1:-1;;42858:5:0;-1:-1:-1;;;42995:2:0;42984:14;;42979:32;42858:5;42966:46;43058:2;43049:11;;;-1:-1:-1;43079:21:0;42826:290;43079:21;-1:-1:-1;43137:6:0;42444:718;-1:-1:-1;;;42444:718:0:o;105390:443::-;-1:-1:-1;;;;;105503:19:0;;105499:91;;105546:32;;-1:-1:-1;;;105546:32:0;;105575:1;105546:32;;;3614:51:1;3587:18;;105546:32:0;3468:203:1;105499:91:0;-1:-1:-1;;;;;105604:21:0;;105600:92;;105649:31;;-1:-1:-1;;;105649:31:0;;105677:1;105649:31;;;3614:51:1;3587:18;;105649:31:0;3468:203:1;105600:92:0;-1:-1:-1;;;;;105702:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;105748:78;;;;105799:7;-1:-1:-1;;;;;105783:31:0;105792:5;-1:-1:-1;;;;;105783:31:0;;105808:5;105783:31;;;;597:25:1;;585:2;570:18;;451:177;105783:31:0;;;;;;;;105390:443;;;;:::o;101115:162::-;101224:16;;;101238:1;101224:16;;;;;;;;;101181:22;;101224:16;;;;;;;;;;;-1:-1:-1;101224:16:0;101216:24;;101262:7;101251:5;101257:1;101251:8;;;;;;;;:::i;:::-;;;;;;:18;;;;;101115:162;;;:::o;109466:716::-;-1:-1:-1;;;;;109637:13:0;;;;;;:9;:13;;;;;;;;109633:461;;109692:9;;-1:-1:-1;;;;;109675:13:0;;;;;;:9;:13;;;;;;:26;;109667:70;;;;-1:-1:-1;;;109667:70:0;;20708:2:1;109667:70:0;;;20690:21:1;20747:2;20727:18;;;20720:30;20786:33;20766:18;;;20759:61;20837:18;;109667:70:0;20506:355:1;109667:70:0;109756:13;;;;109752:331;;;109809:9;109798:21;;;;:10;:21;;;;;;109822:12;-1:-1:-1;109790:84:0;;;;-1:-1:-1;;;109790:84:0;;21068:2:1;109790:84:0;;;21050:21:1;21107:2;21087:18;;;21080:30;21146:34;21126:18;;;21119:62;-1:-1:-1;;;21197:18:1;;;21190:34;21241:19;;109790:84:0;20866:400:1;109790:84:0;109904:9;109893:21;;;;:10;:21;;;;;109917:12;109893:36;;-1:-1:-1;;;;;109958:23:0;;;:28;:67;;;;-1:-1:-1;109998:9:0;109990:30;:35;109958:67;109950:117;;;;-1:-1:-1;;;109950:117:0;;21473:2:1;109950:117:0;;;21455:21:1;21512:2;21492:18;;;21485:30;21551:34;21531:18;;;21524:62;-1:-1:-1;;;21602:18:1;;;21595:35;21647:19;;109950:117:0;21271:401:1;109950:117:0;110124:50;105841:487;98907:1392;-1:-1:-1;;;;;99122:14:0;;;:18;99118:1174;;99161:57;;-1:-1:-1;;;99161:57:0;;-1:-1:-1;;;99161:57:0;;;21821:52:1;-1:-1:-1;;;;;99161:29:0;;;;;21794:18:1;;99161:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;99157:1124;;;99243:72;;-1:-1:-1;;;99243:72:0;;-1:-1:-1;;;;;99243:38:0;;;;;:72;;99282:8;;99292:4;;99298:2;;99302:6;;99310:4;;99243:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;99243:72:0;;;;;;;;-1:-1:-1;;99243:72:0;;;;;;;;;;;;:::i;:::-;;;99239:495;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;99609:6;99602:14;;-1:-1:-1;;;99602:14:0;;;;;;;;:::i;99239:495::-;;;99673:41;;-1:-1:-1;;;99673:41:0;;;;;;;;;;;99239:495;-1:-1:-1;;;;;;99369:55:0;;-1:-1:-1;;;99369:55:0;99365:160;;99460:41;;-1:-1:-1;;;99460:41:0;;;;;;;;;;;99365:160;99316:228;99157:1124;;;99791:61;;-1:-1:-1;;;99791:61:0;;-1:-1:-1;;;;;99791:35:0;;;;;:61;;99827:8;;99837:4;;99843:2;;99847:4;;99791:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;99791:61:0;;;;;;;;-1:-1:-1;;99791:61:0;;;;;;;;;;;;:::i;:::-;;;99787:479;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;100206:40;;-1:-1:-1;;;100206:40:0;;;;;;;;;;;99787:479;-1:-1:-1;;;;;;99906:52:0;;-1:-1:-1;;;99906:52:0;99902:156;;99994:40;;-1:-1:-1;;;99994:40:0;;;;;;;;;;;99902:156;99853:224;99787:479;98907:1392;;;;;;:::o;103372:1872::-;-1:-1:-1;;;;;103491:15:0;;;103469:19;103491:15;;;:9;:15;;;;;;;103537:13;;;;;;;;103565:19;;;103561:109;;;103608:50;;-1:-1:-1;;;103608:50:0;;-1:-1:-1;;;;;18754:32:1;;103608:50:0;;;18736:51:1;18803:18;;;18796:34;;;18846:18;;;18839:34;;;18709:18;;103608:50:0;18534:345:1;103561:109:0;103780:2;-1:-1:-1;;;;;103772:10:0;:4;-1:-1:-1;;;;;103772:10:0;;103769:1425;;-1:-1:-1;;;;;103908:15:0;;;;;;;:9;:15;;;;;;103926:19;;;103908:37;;104084:13;;;;;;104100:17;;;104084:33;;104149:1034;;;;-1:-1:-1;;;;;104252:15:0;;104241:8;104252:15;;;:9;:15;;;;;;;;;104286:250;;104319:22;104400:12;104377:19;104391:5;104377:11;:19;:::i;:::-;104376:36;;;;:::i;:::-;104345:26;104359:12;104345:11;:26;:::i;:::-;104344:69;;;;:::i;:::-;104319:94;-1:-1:-1;104439:18:0;;104436:80;;104484:32;104495:4;104501:14;104484:10;:32::i;:::-;104296:240;104286:250;-1:-1:-1;;;;;104628:13:0;;;;;;:9;:13;;;;;;;;104623:545;;104669:10;;104683:1;104669:15;:22;;;;;104688:3;104669:22;:41;;;;-1:-1:-1;47399:7:0;47426:6;-1:-1:-1;;;;;104695:15:0;;;47426:6;;104695:15;104669:41;104666:483;;;-1:-1:-1;;;;;104801:13:0;;;;;;:9;:13;;;;;:20;;-1:-1:-1;;104801:20:0;104817:4;104801:20;;;104861:1;104848:10;:14;104666:483;;;104919:22;104984:24;104996:12;104984:9;:24;:::i;:::-;104967:12;104946:17;104958:5;104946:9;:17;:::i;:::-;104945:34;;;;:::i;:::-;104944:65;;;;:::i;:::-;104919:90;-1:-1:-1;105039:18:0;;105036:89;;105088:37;105106:2;105110:14;105088:17;:37::i;:::-;;;105036:89;104892:257;104666:483;104158:1025;104149:1034;105226:2;-1:-1:-1;;;;;105211:25:0;105220:4;-1:-1:-1;;;;;105211:25:0;-1:-1:-1;;;;;;;;;;;105230:5:0;105211:25;;;;597::1;;585:2;570:18;;451:177;105211:25:0;;;;;;;;103458:1786;;103372:1872;;;;:::o;58556:464::-;58920:12;58793:11;58786:1;58782:9;;;58778:27;58771:35;;58858:1;58854:9;;;58865:11;58850:27;;;58829:19;;58825:53;58912:1;58908:9;;;58901:17;58897:36;58986:13;58979:21;58974:3;58970:31;-1:-1:-1;;58742:10:0;;;;58959:1;58955:13;58952:50;;58556:464::o;100307:800::-;-1:-1:-1;;;;;100547:14:0;;;:18;100543:557;;100586:79;;-1:-1:-1;;;100586:79:0;;-1:-1:-1;;;;;100586:43:0;;;;;:79;;100630:8;;100640:4;;100646:3;;100651:7;;100660:4;;100586:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;100586:79:0;;;;;;;;-1:-1:-1;;100586:79:0;;;;;;;;;;;;:::i;:::-;;;100582:507;;;;:::i;:::-;-1:-1:-1;;;;;;100747:60:0;;-1:-1:-1;;;100747:60:0;100743:157;;100839:41;;-1:-1:-1;;;100839:41:0;;;;;;;;;;;70489:1230;70807:1;70803:14;;;70599:19;70831:20;;;70872:4;70865:25;;;71045:4;71029:21;;71023:28;-1:-1:-1;;70773:6:0;70803:14;70922:4;70928:11;;70918:22;71011:41;;;70999:54;;71092:14;;71077:30;;71067:356;;71128:280;-1:-1:-1;71173:24:0;;71247:4;71240:20;;;71318:4;71302:21;;71296:28;71364:14;;71349:30;;71346:43;71128:280;71346:43;71128:280;71448:15;;71444:268;;71510:22;71521:10;56512:66;56436:4;56457:34;56062:9;;56059:1;56055:17;56084:34;56081:41;-1:-1:-1;56078:1:0;56074:49;56052:72;56179:9;;;-1:-1:-1;;;;;56156:33:0;56153:1;56149:41;56143:48;56238:9;;;56226:10;56223:25;56220:1;56216:33;56210:40;56293:9;;;56285:6;56282:21;56279:1;56275:29;56269:36;56346:9;;;56340:4;56337:19;56334:1;56330:27;56324:34;56446:9;;;56442:50;56432:61;56427:152;56421:159;;55910:688;71510:22;71505:1;71495:11;;;71494:38;71661:23;;;71658:1;71654:31;71638:48;;-1:-1:-1;71444:268:0;70625:1094;;70489:1230;;;;:::o;67042:1129::-;67217:1;67213:6;67257:4;67250:5;67246:16;67289:11;67283:4;67276:25;67335:5;67332:1;67328:13;67322:4;67315:27;67389:3;67380:6;67373:5;67369:18;67366:27;67356:646;;67443:4;67433:21;;67449:4;67433:21;;67495:18;;67515:15;;;67492:39;67472:60;;67642:18;;;;67714:4;67690:29;;;-1:-1:-1;67564:19:0;;;67639:1;67635:26;67618:44;67765:184;67790:9;67782:6;67779:21;67765:184;;67867:6;67861:4;67854:20;67926:3;67919:4;67913;67903:21;67896:34;67826:1;67818:6;67814:14;67804:24;;67765:184;;;-1:-1:-1;67974:4:0;67967:20;67356:646;68051:4;68045;68035:21;68146:3;68137:6;68132:3;68128:16;68124:26;68117:5;68113:38;68099:11;68093:18;68090:62;68077:11;68070:83;;;;67042:1129;;;:::o;39005:948::-;39058:7;;-1:-1:-1;;;39136:17:0;;39132:106;;-1:-1:-1;;;39174:17:0;;;-1:-1:-1;39220:2:0;39210:12;39132:106;39265:8;39256:5;:17;39252:106;;39303:8;39294:17;;;-1:-1:-1;39340:2:0;39330:12;39252:106;39385:8;39376:5;:17;39372:106;;39423:8;39414:17;;;-1:-1:-1;39460:2:0;39450:12;39372:106;39505:7;39496:5;:16;39492:103;;39542:7;39533:16;;;-1:-1:-1;39578:1:0;39568:11;39492:103;39622:7;39613:5;:16;39609:103;;39659:7;39650:16;;;-1:-1:-1;39695:1:0;39685:11;39609:103;39739:7;39730:5;:16;39726:103;;39776:7;39767:16;;;-1:-1:-1;39812:1:0;39802:11;39726:103;39856:7;39847:5;:16;39843:68;;39894:1;39884:11;39939:6;39005:948;-1:-1:-1;;39005:948:0:o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;192:254;260:6;268;321:2;309:9;300:7;296:23;292:32;289:52;;;337:1;334;327:12;289:52;360:29;379:9;360:29;:::i;:::-;350:39;436:2;421:18;;;;408:32;;-1:-1:-1;;;192:254:1:o;633:131::-;-1:-1:-1;;;;;;707:32:1;;697:43;;687:71;;754:1;751;744:12;769:245;827:6;880:2;868:9;859:7;855:23;851:32;848:52;;;896:1;893;886:12;848:52;935:9;922:23;954:30;978:5;954:30;:::i;1211:127::-;1272:10;1267:3;1263:20;1260:1;1253:31;1303:4;1300:1;1293:15;1327:4;1324:1;1317:15;1343:249;1453:2;1434:13;;-1:-1:-1;;1430:27:1;1418:40;;-1:-1:-1;;;;;1473:34:1;;1509:22;;;1470:62;1467:88;;;1535:18;;:::i;:::-;1571:2;1564:22;-1:-1:-1;;1343:249:1:o;1597:469::-;1662:5;-1:-1:-1;;;;;1688:6:1;1685:30;1682:56;;;1718:18;;:::i;:::-;1767:2;1761:9;1779:69;1836:2;1815:15;;-1:-1:-1;;1811:29:1;1842:4;1807:40;1761:9;1779:69;:::i;:::-;1866:6;1857:15;;1896:6;1888;1881:22;1936:3;1927:6;1922:3;1918:16;1915:25;1912:45;;;1953:1;1950;1943:12;1912:45;2003:6;1998:3;1991:4;1983:6;1979:17;1966:44;2058:1;2051:4;2042:6;2034;2030:19;2026:30;2019:41;;1597:469;;;;;:::o;2071:451::-;2140:6;2193:2;2181:9;2172:7;2168:23;2164:32;2161:52;;;2209:1;2206;2199:12;2161:52;2249:9;2236:23;-1:-1:-1;;;;;2274:6:1;2271:30;2268:50;;;2314:1;2311;2304:12;2268:50;2337:22;;2390:4;2382:13;;2378:27;-1:-1:-1;2368:55:1;;2419:1;2416;2409:12;2368:55;2442:74;2508:7;2503:2;2490:16;2485:2;2481;2477:11;2442:74;:::i;2527:250::-;2612:1;2622:113;2636:6;2633:1;2630:13;2622:113;;;2712:11;;;2706:18;2693:11;;;2686:39;2658:2;2651:10;2622:113;;;-1:-1:-1;;2769:1:1;2751:16;;2744:27;2527:250::o;2782:271::-;2824:3;2862:5;2856:12;2889:6;2884:3;2877:19;2905:76;2974:6;2967:4;2962:3;2958:14;2951:4;2944:5;2940:16;2905:76;:::i;:::-;3035:2;3014:15;-1:-1:-1;;3010:29:1;3001:39;;;;3042:4;2997:50;;2782:271;-1:-1:-1;;2782:271:1:o;3058:220::-;3207:2;3196:9;3189:21;3170:4;3227:45;3268:2;3257:9;3253:18;3245:6;3227:45;:::i;3283:180::-;3342:6;3395:2;3383:9;3374:7;3370:23;3366:32;3363:52;;;3411:1;3408;3401:12;3363:52;-1:-1:-1;3434:23:1;;3283:180;-1:-1:-1;3283:180:1:o;3676:328::-;3753:6;3761;3769;3822:2;3810:9;3801:7;3797:23;3793:32;3790:52;;;3838:1;3835;3828:12;3790:52;3861:29;3880:9;3861:29;:::i;:::-;3851:39;;3909:38;3943:2;3932:9;3928:18;3909:38;:::i;:::-;3899:48;;3994:2;3983:9;3979:18;3966:32;3956:42;;3676:328;;;;;:::o;4009:322::-;4086:6;4094;4102;4155:2;4143:9;4134:7;4130:23;4126:32;4123:52;;;4171:1;4168;4161:12;4123:52;4194:29;4213:9;4194:29;:::i;:::-;4184:39;4270:2;4255:18;;4242:32;;-1:-1:-1;4321:2:1;4306:18;;;4293:32;;4009:322;-1:-1:-1;;;4009:322:1:o;4336:183::-;4396:4;-1:-1:-1;;;;;4421:6:1;4418:30;4415:56;;;4451:18;;:::i;:::-;-1:-1:-1;4496:1:1;4492:14;4508:4;4488:25;;4336:183::o;4524:724::-;4578:5;4631:3;4624:4;4616:6;4612:17;4608:27;4598:55;;4649:1;4646;4639:12;4598:55;4685:6;4672:20;4711:4;4734:43;4774:2;4734:43;:::i;:::-;4806:2;4800:9;4818:31;4846:2;4838:6;4818:31;:::i;:::-;4884:18;;;4976:1;4972:10;;;;4960:23;;4956:32;;;4918:15;;;;-1:-1:-1;5000:15:1;;;4997:35;;;5028:1;5025;5018:12;4997:35;5064:2;5056:6;5052:15;5076:142;5092:6;5087:3;5084:15;5076:142;;;5158:17;;5146:30;;5196:12;;;;5109;;5076:142;;;-1:-1:-1;5236:6:1;4524:724;-1:-1:-1;;;;;;4524:724:1:o;5253:221::-;5295:5;5348:3;5341:4;5333:6;5329:17;5325:27;5315:55;;5366:1;5363;5356:12;5315:55;5388:80;5464:3;5455:6;5442:20;5435:4;5427:6;5423:17;5388:80;:::i;5479:943::-;5633:6;5641;5649;5657;5665;5718:3;5706:9;5697:7;5693:23;5689:33;5686:53;;;5735:1;5732;5725:12;5686:53;5758:29;5777:9;5758:29;:::i;:::-;5748:39;;5806:38;5840:2;5829:9;5825:18;5806:38;:::i;:::-;5796:48;;5895:2;5884:9;5880:18;5867:32;-1:-1:-1;;;;;5959:2:1;5951:6;5948:14;5945:34;;;5975:1;5972;5965:12;5945:34;5998:61;6051:7;6042:6;6031:9;6027:22;5998:61;:::i;:::-;5988:71;;6112:2;6101:9;6097:18;6084:32;6068:48;;6141:2;6131:8;6128:16;6125:36;;;6157:1;6154;6147:12;6125:36;6180:63;6235:7;6224:8;6213:9;6209:24;6180:63;:::i;:::-;6170:73;;6296:3;6285:9;6281:19;6268:33;6252:49;;6326:2;6316:8;6313:16;6310:36;;;6342:1;6339;6332:12;6310:36;;6365:51;6408:7;6397:8;6386:9;6382:24;6365:51;:::i;:::-;6355:61;;;5479:943;;;;;;;;:::o;6616:1208::-;6734:6;6742;6795:2;6783:9;6774:7;6770:23;6766:32;6763:52;;;6811:1;6808;6801:12;6763:52;6851:9;6838:23;-1:-1:-1;;;;;6921:2:1;6913:6;6910:14;6907:34;;;6937:1;6934;6927:12;6907:34;6975:6;6964:9;6960:22;6950:32;;7020:7;7013:4;7009:2;7005:13;7001:27;6991:55;;7042:1;7039;7032:12;6991:55;7078:2;7065:16;7100:4;7123:43;7163:2;7123:43;:::i;:::-;7195:2;7189:9;7207:31;7235:2;7227:6;7207:31;:::i;:::-;7273:18;;;7361:1;7357:10;;;;7349:19;;7345:28;;;7307:15;;;;-1:-1:-1;7385:19:1;;;7382:39;;;7417:1;7414;7407:12;7382:39;7441:11;;;;7461:148;7477:6;7472:3;7469:15;7461:148;;;7543:23;7562:3;7543:23;:::i;:::-;7531:36;;7494:12;;;;7587;;;;7461:148;;;7628:6;-1:-1:-1;;7672:18:1;;7659:32;;-1:-1:-1;;7703:16:1;;;7700:36;;;7732:1;7729;7722:12;7700:36;;7755:63;7810:7;7799:8;7788:9;7784:24;7755:63;:::i;:::-;7745:73;;;6616:1208;;;;;:::o;7829:435::-;7882:3;7920:5;7914:12;7947:6;7942:3;7935:19;7973:4;8002:2;7997:3;7993:12;7986:19;;8039:2;8032:5;8028:14;8060:1;8070:169;8084:6;8081:1;8078:13;8070:169;;;8145:13;;8133:26;;8179:12;;;;8214:15;;;;8106:1;8099:9;8070:169;;;-1:-1:-1;8255:3:1;;7829:435;-1:-1:-1;;;;;7829:435:1:o;8269:261::-;8448:2;8437:9;8430:21;8411:4;8468:56;8520:2;8509:9;8505:18;8497:6;8468:56;:::i;8535:118::-;8621:5;8614:13;8607:21;8600:5;8597:32;8587:60;;8643:1;8640;8633:12;8658:315;8723:6;8731;8784:2;8772:9;8763:7;8759:23;8755:32;8752:52;;;8800:1;8797;8790:12;8752:52;8823:29;8842:9;8823:29;:::i;:::-;8813:39;;8902:2;8891:9;8887:18;8874:32;8915:28;8937:5;8915:28;:::i;:::-;8962:5;8952:15;;;8658:315;;;;;:::o;8978:186::-;9037:6;9090:2;9078:9;9069:7;9065:23;9061:32;9058:52;;;9106:1;9103;9096:12;9058:52;9129:29;9148:9;9129:29;:::i;9169:260::-;9237:6;9245;9298:2;9286:9;9277:7;9273:23;9269:32;9266:52;;;9314:1;9311;9304:12;9266:52;9337:29;9356:9;9337:29;:::i;:::-;9327:39;;9385:38;9419:2;9408:9;9404:18;9385:38;:::i;:::-;9375:48;;9169:260;;;;;:::o;9434:606::-;9538:6;9546;9554;9562;9570;9623:3;9611:9;9602:7;9598:23;9594:33;9591:53;;;9640:1;9637;9630:12;9591:53;9663:29;9682:9;9663:29;:::i;:::-;9653:39;;9711:38;9745:2;9734:9;9730:18;9711:38;:::i;:::-;9701:48;;9796:2;9785:9;9781:18;9768:32;9758:42;;9847:2;9836:9;9832:18;9819:32;9809:42;;9902:3;9891:9;9887:19;9874:33;-1:-1:-1;;;;;9922:6:1;9919:30;9916:50;;;9962:1;9959;9952:12;9916:50;9985:49;10026:7;10017:6;10006:9;10002:22;9985:49;:::i;10045:380::-;10124:1;10120:12;;;;10167;;;10188:61;;10242:4;10234:6;10230:17;10220:27;;10188:61;10295:2;10287:6;10284:14;10264:18;10261:38;10258:161;;10341:10;10336:3;10332:20;10329:1;10322:31;10376:4;10373:1;10366:15;10404:4;10401:1;10394:15;10258:161;;10045:380;;;:::o;10556:545::-;10658:2;10653:3;10650:11;10647:448;;;10694:1;10719:5;10715:2;10708:17;10764:4;10760:2;10750:19;10834:2;10822:10;10818:19;10815:1;10811:27;10805:4;10801:38;10870:4;10858:10;10855:20;10852:47;;;-1:-1:-1;10893:4:1;10852:47;10948:2;10943:3;10939:12;10936:1;10932:20;10926:4;10922:31;10912:41;;11003:82;11021:2;11014:5;11011:13;11003:82;;;11066:17;;;11047:1;11036:13;11003:82;;11277:1352;11403:3;11397:10;-1:-1:-1;;;;;11422:6:1;11419:30;11416:56;;;11452:18;;:::i;:::-;11481:97;11571:6;11531:38;11563:4;11557:11;11531:38;:::i;:::-;11525:4;11481:97;:::i;:::-;11633:4;;11697:2;11686:14;;11714:1;11709:663;;;;12416:1;12433:6;12430:89;;;-1:-1:-1;12485:19:1;;;12479:26;12430:89;-1:-1:-1;;11234:1:1;11230:11;;;11226:24;11222:29;11212:40;11258:1;11254:11;;;11209:57;12532:81;;11679:944;;11709:663;10503:1;10496:14;;;10540:4;10527:18;;-1:-1:-1;;11745:20:1;;;11863:236;11877:7;11874:1;11871:14;11863:236;;;11966:19;;;11960:26;11945:42;;12058:27;;;;12026:1;12014:14;;;;11893:19;;11863:236;;;11867:3;12127:6;12118:7;12115:19;12112:201;;;12188:19;;;12182:26;-1:-1:-1;;12271:1:1;12267:14;;;12283:3;12263:24;12259:37;12255:42;12240:58;12225:74;;12112:201;-1:-1:-1;;;;;12359:1:1;12343:14;;;12339:22;12326:36;;-1:-1:-1;11277:1352:1:o;12634:127::-;12695:10;12690:3;12686:20;12683:1;12676:31;12726:4;12723:1;12716:15;12750:4;12747:1;12740:15;12766:128;12833:9;;;12854:11;;;12851:37;;;12868:18;;:::i;12899:127::-;12960:10;12955:3;12951:20;12948:1;12941:31;12991:4;12988:1;12981:15;13015:4;13012:1;13005:15;13031:135;13070:3;13091:17;;;13088:43;;13111:18;;:::i;:::-;-1:-1:-1;13158:1:1;13147:13;;13031:135::o;13651:217::-;13691:1;13717;13707:132;;13761:10;13756:3;13752:20;13749:1;13742:31;13796:4;13793:1;13786:15;13824:4;13821:1;13814:15;13707:132;-1:-1:-1;13853:9:1;;13651:217::o;14231:168::-;14304:9;;;14335;;14352:15;;;14346:22;;14332:37;14322:71;;14373:18;;:::i;14404:722::-;14454:3;14495:5;14489:12;14524:36;14550:9;14524:36;:::i;:::-;14579:1;14596:18;;;14623:133;;;;14770:1;14765:355;;;;14589:531;;14623:133;-1:-1:-1;;14656:24:1;;14644:37;;14729:14;;14722:22;14710:35;;14701:45;;;-1:-1:-1;14623:133:1;;14765:355;14796:5;14793:1;14786:16;14825:4;14870:2;14867:1;14857:16;14895:1;14909:165;14923:6;14920:1;14917:13;14909:165;;;15001:14;;14988:11;;;14981:35;15044:16;;;;14938:10;;14909:165;;;14913:3;;;15103:6;15098:3;15094:16;15087:23;;14589:531;;;;;14404:722;;;;:::o;15131:389::-;15307:3;15335:38;15369:3;15361:6;15335:38;:::i;:::-;15402:6;15396:13;15418:65;15476:6;15472:2;15465:4;15457:6;15453:17;15418:65;:::i;:::-;15499:15;;15131:389;-1:-1:-1;;;;15131:389:1:o;15712:1452::-;-1:-1:-1;;;16305:55:1;;16383:13;;16287:3;;16405:75;16383:13;16468:2;16459:12;;16452:4;16440:17;;16405:75;:::i;:::-;-1:-1:-1;;;16539:2:1;16499:16;;;16531:11;;;16524:67;16616:13;;16638:78;16616:13;16700:4;16692:13;;;;16673:17;;16638:78;:::i;:::-;16783:66;16776:4;16735:17;;;;16768:13;;;16761:89;16879:66;16874:2;16866:11;;16859:87;16965:46;17007:2;16999:11;;16991:6;16965:46;:::i;:::-;16955:56;;17042:6;17036:13;17058:67;17116:8;17112:2;17105:4;17097:6;17093:17;17058:67;:::i;:::-;17141:17;;15712:1452;-1:-1:-1;;;;;;15712:1452:1:o;17169:1107::-;17681:29;17676:3;17669:42;17651:3;17740:6;17734:13;17756:75;17824:6;17819:2;17814:3;17810:12;17803:4;17795:6;17791:17;17756:75;:::i;:::-;17895:66;17890:2;17850:16;;;17882:11;;;17875:87;-1:-1:-1;;;17986:2:1;17978:11;;17971:63;18059:13;;18081:76;18059:13;18143:2;18135:11;;18128:4;18116:17;;18081:76;:::i;:::-;-1:-1:-1;;;18217:2:1;18176:17;;;;18209:11;;;18202:41;18267:2;18259:11;;17169:1107;-1:-1:-1;;;;17169:1107:1:o;18884:125::-;18949:9;;;18970:10;;;18967:36;;;18983:18;;:::i;19014:465::-;19271:2;19260:9;19253:21;19234:4;19297:56;19349:2;19338:9;19334:18;19326:6;19297:56;:::i;:::-;19401:9;19393:6;19389:22;19384:2;19373:9;19369:18;19362:50;19429:44;19466:6;19458;19429:44;:::i;:::-;19421:52;19014:465;-1:-1:-1;;;;;19014:465:1:o;21884:245::-;21951:6;22004:2;21992:9;21983:7;21979:23;21975:32;21972:52;;;22020:1;22017;22010:12;21972:52;22052:9;22046:16;22071:28;22093:5;22071:28;:::i;22134:561::-;-1:-1:-1;;;;;22431:15:1;;;22413:34;;22483:15;;22478:2;22463:18;;22456:43;22530:2;22515:18;;22508:34;;;22573:2;22558:18;;22551:34;;;22393:3;22616;22601:19;;22594:32;;;22356:4;;22643:46;;22669:19;;22661:6;22643:46;:::i;:::-;22635:54;22134:561;-1:-1:-1;;;;;;;22134:561:1:o;22700:249::-;22769:6;22822:2;22810:9;22801:7;22797:23;22793:32;22790:52;;;22838:1;22835;22828:12;22790:52;22870:9;22864:16;22889:30;22913:5;22889:30;:::i;22954:179::-;22989:3;23031:1;23013:16;23010:23;23007:120;;;23077:1;23074;23071;23056:23;-1:-1:-1;23114:1:1;23108:8;23103:3;23099:18;23007:120;22954:179;:::o;23138:671::-;23177:3;23219:4;23201:16;23198:26;23195:39;;;23138:671;:::o;23195:39::-;23261:2;23255:9;-1:-1:-1;;23326:16:1;23322:25;;23319:1;23255:9;23298:50;23377:4;23371:11;23401:16;-1:-1:-1;;;;;23507:2:1;23500:4;23492:6;23488:17;23485:25;23480:2;23472:6;23469:14;23466:45;23463:58;;;23514:5;;;;;23138:671;:::o;23463:58::-;23551:6;23545:4;23541:17;23530:28;;23587:3;23581:10;23614:2;23606:6;23603:14;23600:27;;;23620:5;;;;;;23138:671;:::o;23600:27::-;23704:2;23685:16;23679:4;23675:27;23671:36;23664:4;23655:6;23650:3;23646:16;23642:27;23639:69;23636:82;;;23711:5;;;;;;23138:671;:::o;23636:82::-;23727:57;23778:4;23769:6;23761;23757:19;23753:30;23747:4;23727:57;:::i;:::-;-1:-1:-1;23800:3:1;;23138:671;-1:-1:-1;;;;;23138:671:1:o;23814:489::-;-1:-1:-1;;;;;24083:15:1;;;24065:34;;24135:15;;24130:2;24115:18;;24108:43;24182:2;24167:18;;24160:34;;;24230:3;24225:2;24210:18;;24203:31;;;24008:4;;24251:46;;24277:19;;24269:6;24251:46;:::i;:::-;24243:54;23814:489;-1:-1:-1;;;;;;23814:489:1:o;24308:827::-;-1:-1:-1;;;;;24705:15:1;;;24687:34;;24757:15;;24752:2;24737:18;;24730:43;24667:3;24804:2;24789:18;;24782:31;;;24630:4;;24836:57;;24873:19;;24865:6;24836:57;:::i;:::-;24941:9;24933:6;24929:22;24924:2;24913:9;24909:18;24902:50;24975:44;25012:6;25004;24975:44;:::i;:::-;24961:58;;25068:9;25060:6;25056:22;25050:3;25039:9;25035:19;25028:51;25096:33;25122:6;25114;25096:33;:::i;:::-;25088:41;24308:827;-1:-1:-1;;;;;;;;24308:827:1:o
Swarm Source
ipfs://33846d8f18b9e81ed13c5ff6685615735cb957e35478c0ff3cb0c5155466c5d7
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.