ERC-721
Overview
Max Total Supply
1,000 0O
Holders
236
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 0OLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
OxOwls
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-03-06 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @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 up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (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; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 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. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); 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 (rounding == Rounding.Up && 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 down. * * 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * 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 10, 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 + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { 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), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @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) { 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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/IERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) { if (_startTokenId() <= tokenId) { packed = _packedOwnerships[tokenId]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // If the data at the starting slot does not exist, start the scan. if (packed == 0) { if (tokenId >= _currentIndex) revert OwnerQueryForNonexistentToken(); // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `tokenId` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. for (;;) { unchecked { packed = _packedOwnerships[--tokenId]; } if (packed == 0) continue; return packed; } } // Otherwise, the data exists and is not burned. We can skip the scan. // This is possible because we have already achieved the target condition. // This saves 2143 gas on transfers of initialized tokens. return packed; } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}. * * Requirements: * * - The caller must own the token or be an approved operator. */ function approve(address to, uint256 tokenId) public payable virtual override { _approve(to, tokenId, true); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Equivalent to `_approve(to, tokenId, false)`. */ function _approve(address to, uint256 tokenId) internal virtual { _approve(to, tokenId, false); } /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - `tokenId` must exist. * * Emits an {Approval} event. */ function _approve( address to, uint256 tokenId, bool approvalCheck ) internal virtual { address owner = ownerOf(tokenId); if (approvalCheck) if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: NFT project/0xOwl/0xOwl.sol pragma solidity ^0.8.4; contract OxOwls is ERC721A, Ownable { using Strings for uint256; string public baseExtension = ".json"; uint256 OnceMintSOperation = 10; uint256 MAX_SUPPLY = 1000; uint256 MAX_MINTS=20; uint256 public mintPrice = 0.002 ether; bool public paused = true; string public baseURI = "ipfs://QmPPrUMefqcPUXAS1dm52GKyu49cWvwYcXPgBUs65zv8RZ/"; constructor() ERC721A("0xOwls", "0O") {} function mint(uint256 quantity) external payable { if (tx.origin!= owner()){ require(quantity <= OnceMintSOperation,"Exceeded the limit of once operation"); require(!paused); if(_numberMinted(tx.origin)<1){ if(quantity>1){ // _safeMint's second argument now takes in a quantity, not a tokenId. require(quantity + _numberMinted(tx.origin) <= MAX_MINTS, "Exceeded the limit"); require(msg.value >= (mintPrice * (quantity-1)), "Not enough ether sent"); } }else{ require(quantity + _numberMinted(tx.origin) <= MAX_MINTS, "Exceeded the limit"); require(msg.value >= (mintPrice * quantity), "Not enough ether sent"); } } require(totalSupply() + quantity <= MAX_SUPPLY, "Not enough tokens left"); _safeMint(tx.origin, quantity); } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _exists(tokenId), "ERC721Metadata: URI query for nonexistent token" ); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension)) : ""; } function withdraw() external payable onlyOwner { payable(owner()).transfer(address(this).balance); } function _baseURI() internal view override returns (string memory) { return baseURI; } // OnlyOwner function setmintPrice(uint256 _mintPrice) public onlyOwner { mintPrice = _mintPrice; } function pause(bool _state) public onlyOwner { paused = _state; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintPrice","type":"uint256"}],"name":"setmintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60806040526040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600990816200004a9190620004d4565b50600a80556103e8600b556014600c5566071afd498d0000600d556001600e60006101000a81548160ff021916908315150217905550604051806060016040528060368152602001620031f360369139600f9081620000aa9190620004d4565b50348015620000b857600080fd5b506040518060400160405280600681526020017f30784f776c7300000000000000000000000000000000000000000000000000008152506040518060400160405280600281526020017f304f0000000000000000000000000000000000000000000000000000000000008152508160029081620001369190620004d4565b508060039081620001489190620004d4565b50620001596200018760201b60201c565b600081905550505062000181620001756200018c60201b60201c565b6200019460201b60201c565b620005bb565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620002dc57607f821691505b602082108103620002f257620002f162000294565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200035c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200031d565b6200036886836200031d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003b5620003af620003a98462000380565b6200038a565b62000380565b9050919050565b6000819050919050565b620003d18362000394565b620003e9620003e082620003bc565b8484546200032a565b825550505050565b600090565b62000400620003f1565b6200040d818484620003c6565b505050565b5b81811015620004355762000429600082620003f6565b60018101905062000413565b5050565b601f82111562000484576200044e81620002f8565b62000459846200030d565b8101602085101562000469578190505b6200048162000478856200030d565b83018262000412565b50505b505050565b600082821c905092915050565b6000620004a96000198460080262000489565b1980831691505092915050565b6000620004c4838362000496565b9150826002028217905092915050565b620004df826200025a565b67ffffffffffffffff811115620004fb57620004fa62000265565b5b620005078254620002c3565b6200051482828562000439565b600060209050601f8311600181146200054c576000841562000537578287015190505b620005438582620004b6565b865550620005b3565b601f1984166200055c86620002f8565b60005b8281101562000586578489015182556001820191506020850194506020810190506200055f565b86831015620005a65784890151620005a2601f89168262000496565b8355505b6001600288020188555050505b505050505050565b612c2880620005cb6000396000f3fe6080604052600436106101665760003560e01c80636c0360eb116100d1578063a22cb4651161008a578063c668286211610064578063c6682862146104b4578063c87b56dd146104df578063e985e9c51461051c578063f2fde38b1461055957610166565b8063a22cb46514610446578063b488cf181461046f578063b88d4fde1461049857610166565b80636c0360eb1461035557806370a0823114610380578063715018a6146103bd5780638da5cb5b146103d457806395d89b41146103ff578063a0712d681461042a57610166565b806323b872dd1161012357806323b872dd146102805780633ccfd60b1461029c57806342842e0e146102a65780635c975abb146102c25780636352211e146102ed5780636817c76c1461032a57610166565b806301ffc9a71461016b57806302329a29146101a857806306fdde03146101d1578063081812fc146101fc578063095ea7b31461023957806318160ddd14610255575b600080fd5b34801561017757600080fd5b50610192600480360381019061018d9190611fc1565b610582565b60405161019f9190612009565b60405180910390f35b3480156101b457600080fd5b506101cf60048036038101906101ca9190612050565b610614565b005b3480156101dd57600080fd5b506101e6610639565b6040516101f3919061210d565b60405180910390f35b34801561020857600080fd5b50610223600480360381019061021e9190612165565b6106cb565b60405161023091906121d3565b60405180910390f35b610253600480360381019061024e919061221a565b61074a565b005b34801561026157600080fd5b5061026a61075a565b6040516102779190612269565b60405180910390f35b61029a60048036038101906102959190612284565b610771565b005b6102a4610a93565b005b6102c060048036038101906102bb9190612284565b610aeb565b005b3480156102ce57600080fd5b506102d7610b0b565b6040516102e49190612009565b60405180910390f35b3480156102f957600080fd5b50610314600480360381019061030f9190612165565b610b1e565b60405161032191906121d3565b60405180910390f35b34801561033657600080fd5b5061033f610b30565b60405161034c9190612269565b60405180910390f35b34801561036157600080fd5b5061036a610b36565b604051610377919061210d565b60405180910390f35b34801561038c57600080fd5b506103a760048036038101906103a291906122d7565b610bc4565b6040516103b49190612269565b60405180910390f35b3480156103c957600080fd5b506103d2610c7c565b005b3480156103e057600080fd5b506103e9610c90565b6040516103f691906121d3565b60405180910390f35b34801561040b57600080fd5b50610414610cba565b604051610421919061210d565b60405180910390f35b610444600480360381019061043f9190612165565b610d4c565b005b34801561045257600080fd5b5061046d60048036038101906104689190612304565b610fc7565b005b34801561047b57600080fd5b5061049660048036038101906104919190612165565b6110d2565b005b6104b260048036038101906104ad9190612479565b6110e4565b005b3480156104c057600080fd5b506104c9611157565b6040516104d6919061210d565b60405180910390f35b3480156104eb57600080fd5b5061050660048036038101906105019190612165565b6111e5565b604051610513919061210d565b60405180910390f35b34801561052857600080fd5b50610543600480360381019061053e91906124fc565b61128f565b6040516105509190612009565b60405180910390f35b34801561056557600080fd5b50610580600480360381019061057b91906122d7565b611323565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105dd57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061060d5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b61061c6113a6565b80600e60006101000a81548160ff02191690831515021790555050565b6060600280546106489061256b565b80601f01602080910402602001604051908101604052809291908181526020018280546106749061256b565b80156106c15780601f10610696576101008083540402835291602001916106c1565b820191906000526020600020905b8154815290600101906020018083116106a457829003601f168201915b5050505050905090565b60006106d682611424565b61070c576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61075682826001611483565b5050565b60006107646115cf565b6001546000540303905090565b600061077c826115d4565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146107e3576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806107ef846116cc565b9150915061080581876108006116f3565b6116fb565b6108515761081a866108156116f3565b61128f565b610850576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036108b7576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c4868686600161173f565b80156108cf57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061099d85610979888887611745565b7c02000000000000000000000000000000000000000000000000000000001761176d565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610a235760006001850190506000600460008381526020019081526020016000205403610a21576000548114610a20578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610a8b8686866001611798565b505050505050565b610a9b6113a6565b610aa3610c90565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610ae8573d6000803e3d6000fd5b50565b610b06838383604051806020016040528060008152506110e4565b505050565b600e60009054906101000a900460ff1681565b6000610b29826115d4565b9050919050565b600d5481565b600f8054610b439061256b565b80601f0160208091040260200160405190810160405280929190818152602001828054610b6f9061256b565b8015610bbc5780601f10610b9157610100808354040283529160200191610bbc565b820191906000526020600020905b815481529060010190602001808311610b9f57829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610c2b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610c846113a6565b610c8e600061179e565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610cc99061256b565b80601f0160208091040260200160405190810160405280929190818152602001828054610cf59061256b565b8015610d425780601f10610d1757610100808354040283529160200191610d42565b820191906000526020600020905b815481529060010190602001808311610d2557829003601f168201915b5050505050905090565b610d54610c90565b73ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610f6357600a54811115610dcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc29061260e565b60405180910390fd5b600e60009054906101000a900460ff1615610de557600080fd5b6001610df032611864565b1015610eb9576001811115610eb457600c54610e0b32611864565b82610e16919061265d565b1115610e57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4e906126dd565b60405180910390fd5b600181610e6491906126fd565b600d54610e719190612731565b341015610eb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eaa906127bf565b60405180910390fd5b5b610f62565b600c54610ec532611864565b82610ed0919061265d565b1115610f11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f08906126dd565b60405180910390fd5b80600d54610f1f9190612731565b341015610f61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f58906127bf565b60405180910390fd5b5b5b600b5481610f6f61075a565b610f79919061265d565b1115610fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb19061282b565b60405180910390fd5b610fc432826118bb565b50565b8060076000610fd46116f3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166110816116f3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110c69190612009565b60405180910390a35050565b6110da6113a6565b80600d8190555050565b6110ef848484610771565b60008373ffffffffffffffffffffffffffffffffffffffff163b146111515761111a848484846118d9565b611150576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600980546111649061256b565b80601f01602080910402602001604051908101604052809291908181526020018280546111909061256b565b80156111dd5780601f106111b2576101008083540402835291602001916111dd565b820191906000526020600020905b8154815290600101906020018083116111c057829003601f168201915b505050505081565b60606111f082611424565b61122f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611226906128bd565b60405180910390fd5b6000611239611a29565b905060008151116112595760405180602001604052806000815250611287565b8061126384611abb565b6009604051602001611277939291906129b1565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61132b6113a6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361139a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139190612a54565b60405180910390fd5b6113a38161179e565b50565b6113ae611b89565b73ffffffffffffffffffffffffffffffffffffffff166113cc610c90565b73ffffffffffffffffffffffffffffffffffffffff1614611422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141990612ac0565b60405180910390fd5b565b60008161142f6115cf565b1115801561143e575060005482105b801561147c575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600061148e83610b1e565b90508115611519578073ffffffffffffffffffffffffffffffffffffffff166114b56116f3565b73ffffffffffffffffffffffffffffffffffffffff1614611518576114e1816114dc6116f3565b61128f565b611517576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b836006600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b600090565b6000816115df6115cf565b11611695576004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611694576000810361168f576000548210611664576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6004600083600190039350838152602001908152602001600020549050600081036116c757611665565b6116c7565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861175c868684611b91565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b6118d5828260405180602001604052806000815250611b9a565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026118ff6116f3565b8786866040518563ffffffff1660e01b81526004016119219493929190612b35565b6020604051808303816000875af192505050801561195d57506040513d601f19601f8201168201806040525081019061195a9190612b96565b60015b6119d6573d806000811461198d576040519150601f19603f3d011682016040523d82523d6000602084013e611992565b606091505b5060008151036119ce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600f8054611a389061256b565b80601f0160208091040260200160405190810160405280929190818152602001828054611a649061256b565b8015611ab15780601f10611a8657610100808354040283529160200191611ab1565b820191906000526020600020905b815481529060010190602001808311611a9457829003601f168201915b5050505050905090565b606060006001611aca84611c37565b01905060008167ffffffffffffffff811115611ae957611ae861234e565b5b6040519080825280601f01601f191660200182016040528015611b1b5781602001600182028036833780820191505090505b509050600082602001820190505b600115611b7e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611b7257611b71612bc3565b5b04945060008503611b29575b819350505050919050565b600033905090565b60009392505050565b611ba48383611d8a565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611c3257600080549050600083820390505b611be460008683806001019450866118d9565b611c1a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611bd1578160005414611c2f57600080fd5b50505b505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611c95577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611c8b57611c8a612bc3565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611cd2576d04ee2d6d415b85acef81000000008381611cc857611cc7612bc3565b5b0492506020810190505b662386f26fc100008310611d0157662386f26fc100008381611cf757611cf6612bc3565b5b0492506010810190505b6305f5e1008310611d2a576305f5e1008381611d2057611d1f612bc3565b5b0492506008810190505b6127108310611d4f576127108381611d4557611d44612bc3565b5b0492506004810190505b60648310611d725760648381611d6857611d67612bc3565b5b0492506002810190505b600a8310611d81576001810190505b80915050919050565b60008054905060008203611dca576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dd7600084838561173f565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611e4e83611e3f6000866000611745565b611e4885611f45565b1761176d565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114611eef57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050611eb4565b5060008203611f2a576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050611f406000848385611798565b505050565b60006001821460e11b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611f9e81611f69565b8114611fa957600080fd5b50565b600081359050611fbb81611f95565b92915050565b600060208284031215611fd757611fd6611f5f565b5b6000611fe584828501611fac565b91505092915050565b60008115159050919050565b61200381611fee565b82525050565b600060208201905061201e6000830184611ffa565b92915050565b61202d81611fee565b811461203857600080fd5b50565b60008135905061204a81612024565b92915050565b60006020828403121561206657612065611f5f565b5b60006120748482850161203b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156120b757808201518184015260208101905061209c565b60008484015250505050565b6000601f19601f8301169050919050565b60006120df8261207d565b6120e98185612088565b93506120f9818560208601612099565b612102816120c3565b840191505092915050565b6000602082019050818103600083015261212781846120d4565b905092915050565b6000819050919050565b6121428161212f565b811461214d57600080fd5b50565b60008135905061215f81612139565b92915050565b60006020828403121561217b5761217a611f5f565b5b600061218984828501612150565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006121bd82612192565b9050919050565b6121cd816121b2565b82525050565b60006020820190506121e860008301846121c4565b92915050565b6121f7816121b2565b811461220257600080fd5b50565b600081359050612214816121ee565b92915050565b6000806040838503121561223157612230611f5f565b5b600061223f85828601612205565b925050602061225085828601612150565b9150509250929050565b6122638161212f565b82525050565b600060208201905061227e600083018461225a565b92915050565b60008060006060848603121561229d5761229c611f5f565b5b60006122ab86828701612205565b93505060206122bc86828701612205565b92505060406122cd86828701612150565b9150509250925092565b6000602082840312156122ed576122ec611f5f565b5b60006122fb84828501612205565b91505092915050565b6000806040838503121561231b5761231a611f5f565b5b600061232985828601612205565b925050602061233a8582860161203b565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612386826120c3565b810181811067ffffffffffffffff821117156123a5576123a461234e565b5b80604052505050565b60006123b8611f55565b90506123c4828261237d565b919050565b600067ffffffffffffffff8211156123e4576123e361234e565b5b6123ed826120c3565b9050602081019050919050565b82818337600083830152505050565b600061241c612417846123c9565b6123ae565b90508281526020810184848401111561243857612437612349565b5b6124438482856123fa565b509392505050565b600082601f8301126124605761245f612344565b5b8135612470848260208601612409565b91505092915050565b6000806000806080858703121561249357612492611f5f565b5b60006124a187828801612205565b94505060206124b287828801612205565b93505060406124c387828801612150565b925050606085013567ffffffffffffffff8111156124e4576124e3611f64565b5b6124f08782880161244b565b91505092959194509250565b6000806040838503121561251357612512611f5f565b5b600061252185828601612205565b925050602061253285828601612205565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061258357607f821691505b6020821081036125965761259561253c565b5b50919050565b7f457863656564656420746865206c696d6974206f66206f6e6365206f7065726160008201527f74696f6e00000000000000000000000000000000000000000000000000000000602082015250565b60006125f8602483612088565b91506126038261259c565b604082019050919050565b60006020820190508181036000830152612627816125eb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006126688261212f565b91506126738361212f565b925082820190508082111561268b5761268a61262e565b5b92915050565b7f457863656564656420746865206c696d69740000000000000000000000000000600082015250565b60006126c7601283612088565b91506126d282612691565b602082019050919050565b600060208201905081810360008301526126f6816126ba565b9050919050565b60006127088261212f565b91506127138361212f565b925082820390508181111561272b5761272a61262e565b5b92915050565b600061273c8261212f565b91506127478361212f565b92508282026127558161212f565b9150828204841483151761276c5761276b61262e565b5b5092915050565b7f4e6f7420656e6f7567682065746865722073656e740000000000000000000000600082015250565b60006127a9601583612088565b91506127b482612773565b602082019050919050565b600060208201905081810360008301526127d88161279c565b9050919050565b7f4e6f7420656e6f75676820746f6b656e73206c65667400000000000000000000600082015250565b6000612815601683612088565b9150612820826127df565b602082019050919050565b6000602082019050818103600083015261284481612808565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006128a7602f83612088565b91506128b28261284b565b604082019050919050565b600060208201905081810360008301526128d68161289a565b9050919050565b600081905092915050565b60006128f38261207d565b6128fd81856128dd565b935061290d818560208601612099565b80840191505092915050565b60008190508160005260206000209050919050565b6000815461293b8161256b565b61294581866128dd565b945060018216600081146129605760018114612975576129a8565b60ff19831686528115158202860193506129a8565b61297e85612919565b60005b838110156129a057815481890152600182019150602081019050612981565b838801955050505b50505092915050565b60006129bd82866128e8565b91506129c982856128e8565b91506129d5828461292e565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612a3e602683612088565b9150612a49826129e2565b604082019050919050565b60006020820190508181036000830152612a6d81612a31565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612aaa602083612088565b9150612ab582612a74565b602082019050919050565b60006020820190508181036000830152612ad981612a9d565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000612b0782612ae0565b612b118185612aeb565b9350612b21818560208601612099565b612b2a816120c3565b840191505092915050565b6000608082019050612b4a60008301876121c4565b612b5760208301866121c4565b612b64604083018561225a565b8181036060830152612b768184612afc565b905095945050505050565b600081519050612b9081611f95565b92915050565b600060208284031215612bac57612bab611f5f565b5b6000612bba84828501612b81565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea264697066735822122050b6c4776d4d3519500ff98f4456d876fd1048940e560bd2eb7eab4f15b97b9a64736f6c63430008120033697066733a2f2f516d505072554d65667163505558415331646d3532474b7975343963577677596358506742557336357a7638525a2f
Deployed Bytecode
0x6080604052600436106101665760003560e01c80636c0360eb116100d1578063a22cb4651161008a578063c668286211610064578063c6682862146104b4578063c87b56dd146104df578063e985e9c51461051c578063f2fde38b1461055957610166565b8063a22cb46514610446578063b488cf181461046f578063b88d4fde1461049857610166565b80636c0360eb1461035557806370a0823114610380578063715018a6146103bd5780638da5cb5b146103d457806395d89b41146103ff578063a0712d681461042a57610166565b806323b872dd1161012357806323b872dd146102805780633ccfd60b1461029c57806342842e0e146102a65780635c975abb146102c25780636352211e146102ed5780636817c76c1461032a57610166565b806301ffc9a71461016b57806302329a29146101a857806306fdde03146101d1578063081812fc146101fc578063095ea7b31461023957806318160ddd14610255575b600080fd5b34801561017757600080fd5b50610192600480360381019061018d9190611fc1565b610582565b60405161019f9190612009565b60405180910390f35b3480156101b457600080fd5b506101cf60048036038101906101ca9190612050565b610614565b005b3480156101dd57600080fd5b506101e6610639565b6040516101f3919061210d565b60405180910390f35b34801561020857600080fd5b50610223600480360381019061021e9190612165565b6106cb565b60405161023091906121d3565b60405180910390f35b610253600480360381019061024e919061221a565b61074a565b005b34801561026157600080fd5b5061026a61075a565b6040516102779190612269565b60405180910390f35b61029a60048036038101906102959190612284565b610771565b005b6102a4610a93565b005b6102c060048036038101906102bb9190612284565b610aeb565b005b3480156102ce57600080fd5b506102d7610b0b565b6040516102e49190612009565b60405180910390f35b3480156102f957600080fd5b50610314600480360381019061030f9190612165565b610b1e565b60405161032191906121d3565b60405180910390f35b34801561033657600080fd5b5061033f610b30565b60405161034c9190612269565b60405180910390f35b34801561036157600080fd5b5061036a610b36565b604051610377919061210d565b60405180910390f35b34801561038c57600080fd5b506103a760048036038101906103a291906122d7565b610bc4565b6040516103b49190612269565b60405180910390f35b3480156103c957600080fd5b506103d2610c7c565b005b3480156103e057600080fd5b506103e9610c90565b6040516103f691906121d3565b60405180910390f35b34801561040b57600080fd5b50610414610cba565b604051610421919061210d565b60405180910390f35b610444600480360381019061043f9190612165565b610d4c565b005b34801561045257600080fd5b5061046d60048036038101906104689190612304565b610fc7565b005b34801561047b57600080fd5b5061049660048036038101906104919190612165565b6110d2565b005b6104b260048036038101906104ad9190612479565b6110e4565b005b3480156104c057600080fd5b506104c9611157565b6040516104d6919061210d565b60405180910390f35b3480156104eb57600080fd5b5061050660048036038101906105019190612165565b6111e5565b604051610513919061210d565b60405180910390f35b34801561052857600080fd5b50610543600480360381019061053e91906124fc565b61128f565b6040516105509190612009565b60405180910390f35b34801561056557600080fd5b50610580600480360381019061057b91906122d7565b611323565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105dd57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061060d5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b61061c6113a6565b80600e60006101000a81548160ff02191690831515021790555050565b6060600280546106489061256b565b80601f01602080910402602001604051908101604052809291908181526020018280546106749061256b565b80156106c15780601f10610696576101008083540402835291602001916106c1565b820191906000526020600020905b8154815290600101906020018083116106a457829003601f168201915b5050505050905090565b60006106d682611424565b61070c576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61075682826001611483565b5050565b60006107646115cf565b6001546000540303905090565b600061077c826115d4565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146107e3576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806107ef846116cc565b9150915061080581876108006116f3565b6116fb565b6108515761081a866108156116f3565b61128f565b610850576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036108b7576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108c4868686600161173f565b80156108cf57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061099d85610979888887611745565b7c02000000000000000000000000000000000000000000000000000000001761176d565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610a235760006001850190506000600460008381526020019081526020016000205403610a21576000548114610a20578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610a8b8686866001611798565b505050505050565b610a9b6113a6565b610aa3610c90565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610ae8573d6000803e3d6000fd5b50565b610b06838383604051806020016040528060008152506110e4565b505050565b600e60009054906101000a900460ff1681565b6000610b29826115d4565b9050919050565b600d5481565b600f8054610b439061256b565b80601f0160208091040260200160405190810160405280929190818152602001828054610b6f9061256b565b8015610bbc5780601f10610b9157610100808354040283529160200191610bbc565b820191906000526020600020905b815481529060010190602001808311610b9f57829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610c2b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610c846113a6565b610c8e600061179e565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054610cc99061256b565b80601f0160208091040260200160405190810160405280929190818152602001828054610cf59061256b565b8015610d425780601f10610d1757610100808354040283529160200191610d42565b820191906000526020600020905b815481529060010190602001808311610d2557829003601f168201915b5050505050905090565b610d54610c90565b73ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610f6357600a54811115610dcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc29061260e565b60405180910390fd5b600e60009054906101000a900460ff1615610de557600080fd5b6001610df032611864565b1015610eb9576001811115610eb457600c54610e0b32611864565b82610e16919061265d565b1115610e57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4e906126dd565b60405180910390fd5b600181610e6491906126fd565b600d54610e719190612731565b341015610eb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eaa906127bf565b60405180910390fd5b5b610f62565b600c54610ec532611864565b82610ed0919061265d565b1115610f11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f08906126dd565b60405180910390fd5b80600d54610f1f9190612731565b341015610f61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f58906127bf565b60405180910390fd5b5b5b600b5481610f6f61075a565b610f79919061265d565b1115610fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb19061282b565b60405180910390fd5b610fc432826118bb565b50565b8060076000610fd46116f3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166110816116f3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110c69190612009565b60405180910390a35050565b6110da6113a6565b80600d8190555050565b6110ef848484610771565b60008373ffffffffffffffffffffffffffffffffffffffff163b146111515761111a848484846118d9565b611150576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600980546111649061256b565b80601f01602080910402602001604051908101604052809291908181526020018280546111909061256b565b80156111dd5780601f106111b2576101008083540402835291602001916111dd565b820191906000526020600020905b8154815290600101906020018083116111c057829003601f168201915b505050505081565b60606111f082611424565b61122f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611226906128bd565b60405180910390fd5b6000611239611a29565b905060008151116112595760405180602001604052806000815250611287565b8061126384611abb565b6009604051602001611277939291906129b1565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61132b6113a6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361139a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139190612a54565b60405180910390fd5b6113a38161179e565b50565b6113ae611b89565b73ffffffffffffffffffffffffffffffffffffffff166113cc610c90565b73ffffffffffffffffffffffffffffffffffffffff1614611422576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141990612ac0565b60405180910390fd5b565b60008161142f6115cf565b1115801561143e575060005482105b801561147c575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600061148e83610b1e565b90508115611519578073ffffffffffffffffffffffffffffffffffffffff166114b56116f3565b73ffffffffffffffffffffffffffffffffffffffff1614611518576114e1816114dc6116f3565b61128f565b611517576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b836006600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b600090565b6000816115df6115cf565b11611695576004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611694576000810361168f576000548210611664576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6004600083600190039350838152602001908152602001600020549050600081036116c757611665565b6116c7565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861175c868684611b91565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b6118d5828260405180602001604052806000815250611b9a565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026118ff6116f3565b8786866040518563ffffffff1660e01b81526004016119219493929190612b35565b6020604051808303816000875af192505050801561195d57506040513d601f19601f8201168201806040525081019061195a9190612b96565b60015b6119d6573d806000811461198d576040519150601f19603f3d011682016040523d82523d6000602084013e611992565b606091505b5060008151036119ce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600f8054611a389061256b565b80601f0160208091040260200160405190810160405280929190818152602001828054611a649061256b565b8015611ab15780601f10611a8657610100808354040283529160200191611ab1565b820191906000526020600020905b815481529060010190602001808311611a9457829003601f168201915b5050505050905090565b606060006001611aca84611c37565b01905060008167ffffffffffffffff811115611ae957611ae861234e565b5b6040519080825280601f01601f191660200182016040528015611b1b5781602001600182028036833780820191505090505b509050600082602001820190505b600115611b7e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611b7257611b71612bc3565b5b04945060008503611b29575b819350505050919050565b600033905090565b60009392505050565b611ba48383611d8a565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611c3257600080549050600083820390505b611be460008683806001019450866118d9565b611c1a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611bd1578160005414611c2f57600080fd5b50505b505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611c95577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611c8b57611c8a612bc3565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611cd2576d04ee2d6d415b85acef81000000008381611cc857611cc7612bc3565b5b0492506020810190505b662386f26fc100008310611d0157662386f26fc100008381611cf757611cf6612bc3565b5b0492506010810190505b6305f5e1008310611d2a576305f5e1008381611d2057611d1f612bc3565b5b0492506008810190505b6127108310611d4f576127108381611d4557611d44612bc3565b5b0492506004810190505b60648310611d725760648381611d6857611d67612bc3565b5b0492506002810190505b600a8310611d81576001810190505b80915050919050565b60008054905060008203611dca576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dd7600084838561173f565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611e4e83611e3f6000866000611745565b611e4885611f45565b1761176d565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114611eef57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050611eb4565b5060008203611f2a576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050611f406000848385611798565b505050565b60006001821460e11b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611f9e81611f69565b8114611fa957600080fd5b50565b600081359050611fbb81611f95565b92915050565b600060208284031215611fd757611fd6611f5f565b5b6000611fe584828501611fac565b91505092915050565b60008115159050919050565b61200381611fee565b82525050565b600060208201905061201e6000830184611ffa565b92915050565b61202d81611fee565b811461203857600080fd5b50565b60008135905061204a81612024565b92915050565b60006020828403121561206657612065611f5f565b5b60006120748482850161203b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156120b757808201518184015260208101905061209c565b60008484015250505050565b6000601f19601f8301169050919050565b60006120df8261207d565b6120e98185612088565b93506120f9818560208601612099565b612102816120c3565b840191505092915050565b6000602082019050818103600083015261212781846120d4565b905092915050565b6000819050919050565b6121428161212f565b811461214d57600080fd5b50565b60008135905061215f81612139565b92915050565b60006020828403121561217b5761217a611f5f565b5b600061218984828501612150565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006121bd82612192565b9050919050565b6121cd816121b2565b82525050565b60006020820190506121e860008301846121c4565b92915050565b6121f7816121b2565b811461220257600080fd5b50565b600081359050612214816121ee565b92915050565b6000806040838503121561223157612230611f5f565b5b600061223f85828601612205565b925050602061225085828601612150565b9150509250929050565b6122638161212f565b82525050565b600060208201905061227e600083018461225a565b92915050565b60008060006060848603121561229d5761229c611f5f565b5b60006122ab86828701612205565b93505060206122bc86828701612205565b92505060406122cd86828701612150565b9150509250925092565b6000602082840312156122ed576122ec611f5f565b5b60006122fb84828501612205565b91505092915050565b6000806040838503121561231b5761231a611f5f565b5b600061232985828601612205565b925050602061233a8582860161203b565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612386826120c3565b810181811067ffffffffffffffff821117156123a5576123a461234e565b5b80604052505050565b60006123b8611f55565b90506123c4828261237d565b919050565b600067ffffffffffffffff8211156123e4576123e361234e565b5b6123ed826120c3565b9050602081019050919050565b82818337600083830152505050565b600061241c612417846123c9565b6123ae565b90508281526020810184848401111561243857612437612349565b5b6124438482856123fa565b509392505050565b600082601f8301126124605761245f612344565b5b8135612470848260208601612409565b91505092915050565b6000806000806080858703121561249357612492611f5f565b5b60006124a187828801612205565b94505060206124b287828801612205565b93505060406124c387828801612150565b925050606085013567ffffffffffffffff8111156124e4576124e3611f64565b5b6124f08782880161244b565b91505092959194509250565b6000806040838503121561251357612512611f5f565b5b600061252185828601612205565b925050602061253285828601612205565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061258357607f821691505b6020821081036125965761259561253c565b5b50919050565b7f457863656564656420746865206c696d6974206f66206f6e6365206f7065726160008201527f74696f6e00000000000000000000000000000000000000000000000000000000602082015250565b60006125f8602483612088565b91506126038261259c565b604082019050919050565b60006020820190508181036000830152612627816125eb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006126688261212f565b91506126738361212f565b925082820190508082111561268b5761268a61262e565b5b92915050565b7f457863656564656420746865206c696d69740000000000000000000000000000600082015250565b60006126c7601283612088565b91506126d282612691565b602082019050919050565b600060208201905081810360008301526126f6816126ba565b9050919050565b60006127088261212f565b91506127138361212f565b925082820390508181111561272b5761272a61262e565b5b92915050565b600061273c8261212f565b91506127478361212f565b92508282026127558161212f565b9150828204841483151761276c5761276b61262e565b5b5092915050565b7f4e6f7420656e6f7567682065746865722073656e740000000000000000000000600082015250565b60006127a9601583612088565b91506127b482612773565b602082019050919050565b600060208201905081810360008301526127d88161279c565b9050919050565b7f4e6f7420656e6f75676820746f6b656e73206c65667400000000000000000000600082015250565b6000612815601683612088565b9150612820826127df565b602082019050919050565b6000602082019050818103600083015261284481612808565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006128a7602f83612088565b91506128b28261284b565b604082019050919050565b600060208201905081810360008301526128d68161289a565b9050919050565b600081905092915050565b60006128f38261207d565b6128fd81856128dd565b935061290d818560208601612099565b80840191505092915050565b60008190508160005260206000209050919050565b6000815461293b8161256b565b61294581866128dd565b945060018216600081146129605760018114612975576129a8565b60ff19831686528115158202860193506129a8565b61297e85612919565b60005b838110156129a057815481890152600182019150602081019050612981565b838801955050505b50505092915050565b60006129bd82866128e8565b91506129c982856128e8565b91506129d5828461292e565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612a3e602683612088565b9150612a49826129e2565b604082019050919050565b60006020820190508181036000830152612a6d81612a31565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612aaa602083612088565b9150612ab582612a74565b602082019050919050565b60006020820190508181036000830152612ad981612a9d565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000612b0782612ae0565b612b118185612aeb565b9350612b21818560208601612099565b612b2a816120c3565b840191505092915050565b6000608082019050612b4a60008301876121c4565b612b5760208301866121c4565b612b64604083018561225a565b8181036060830152612b768184612afc565b905095945050505050565b600081519050612b9081611f95565b92915050565b600060208284031215612bac57612bab611f5f565b5b6000612bba84828501612b81565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea264697066735822122050b6c4776d4d3519500ff98f4456d876fd1048940e560bd2eb7eab4f15b97b9a64736f6c63430008120033
Deployed Bytecode Sourcemap
71622:2307:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37309:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73851:75;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38211:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44611:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44328:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33962:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48250:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73497:114;;;:::i;:::-;;51171:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71883:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39604:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71838:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71917:80;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35146:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18008:103;;;;;;;;;;;;;:::i;:::-;;17360:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38387:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72054:992;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45169:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73743:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51962:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71697:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73054:435;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45560:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18266:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37309:639;37394:4;37733:10;37718:25;;:11;:25;;;;:102;;;;37810:10;37795:25;;:11;:25;;;;37718:102;:179;;;;37887:10;37872:25;;:11;:25;;;;37718:179;37698:199;;37309:639;;;:::o;73851:75::-;17246:13;:11;:13::i;:::-;73912:6:::1;73903;;:15;;;;;;;;;;;;;;;;;;73851:75:::0;:::o;38211:100::-;38265:13;38298:5;38291:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38211:100;:::o;44611:218::-;44687:7;44712:16;44720:7;44712;:16::i;:::-;44707:64;;44737:34;;;;;;;;;;;;;;44707:64;44791:15;:24;44807:7;44791:24;;;;;;;;;;;:30;;;;;;;;;;;;44784:37;;44611:218;;;:::o;44328:124::-;44417:27;44426:2;44430:7;44439:4;44417:8;:27::i;:::-;44328:124;;:::o;33962:323::-;34023:7;34251:15;:13;:15::i;:::-;34236:12;;34220:13;;:28;:46;34213:53;;33962:323;:::o;48250:2825::-;48392:27;48422;48441:7;48422:18;:27::i;:::-;48392:57;;48507:4;48466:45;;48482:19;48466:45;;;48462:86;;48520:28;;;;;;;;;;;;;;48462:86;48562:27;48591:23;48618:35;48645:7;48618:26;:35::i;:::-;48561:92;;;;48753:68;48778:15;48795:4;48801:19;:17;:19::i;:::-;48753:24;:68::i;:::-;48748:180;;48841:43;48858:4;48864:19;:17;:19::i;:::-;48841:16;:43::i;:::-;48836:92;;48893:35;;;;;;;;;;;;;;48836:92;48748:180;48959:1;48945:16;;:2;:16;;;48941:52;;48970:23;;;;;;;;;;;;;;48941:52;49006:43;49028:4;49034:2;49038:7;49047:1;49006:21;:43::i;:::-;49142:15;49139:160;;;49282:1;49261:19;49254:30;49139:160;49679:18;:24;49698:4;49679:24;;;;;;;;;;;;;;;;49677:26;;;;;;;;;;;;49748:18;:22;49767:2;49748:22;;;;;;;;;;;;;;;;49746:24;;;;;;;;;;;50070:146;50107:2;50156:45;50171:4;50177:2;50181:19;50156:14;:45::i;:::-;30361:8;50128:73;50070:18;:146::i;:::-;50041:17;:26;50059:7;50041:26;;;;;;;;;;;:175;;;;50387:1;30361:8;50336:19;:47;:52;50332:627;;50409:19;50441:1;50431:7;:11;50409:33;;50598:1;50564:17;:30;50582:11;50564:30;;;;;;;;;;;;:35;50560:384;;50702:13;;50687:11;:28;50683:242;;50882:19;50849:17;:30;50867:11;50849:30;;;;;;;;;;;:52;;;;50683:242;50560:384;50390:569;50332:627;51006:7;51002:2;50987:27;;50996:4;50987:27;;;;;;;;;;;;51025:42;51046:4;51052:2;51056:7;51065:1;51025:20;:42::i;:::-;48381:2694;;;48250:2825;;;:::o;73497:114::-;17246:13;:11;:13::i;:::-;73563:7:::1;:5;:7::i;:::-;73555:25;;:48;73581:21;73555:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;73497:114::o:0;51171:193::-;51317:39;51334:4;51340:2;51344:7;51317:39;;;;;;;;;;;;:16;:39::i;:::-;51171:193;;;:::o;71883:25::-;;;;;;;;;;;;;:::o;39604:152::-;39676:7;39719:27;39738:7;39719:18;:27::i;:::-;39696:52;;39604:152;;;:::o;71838:38::-;;;;:::o;71917:80::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;35146:233::-;35218:7;35259:1;35242:19;;:5;:19;;;35238:60;;35270:28;;;;;;;;;;;;;;35238:60;29305:13;35316:18;:25;35335:5;35316:25;;;;;;;;;;;;;;;;:55;35309:62;;35146:233;;;:::o;18008:103::-;17246:13;:11;:13::i;:::-;18073:30:::1;18100:1;18073:18;:30::i;:::-;18008:103::o:0;17360:87::-;17406:7;17433:6;;;;;;;;;;;17426:13;;17360:87;:::o;38387:104::-;38443:13;38476:7;38469:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38387:104;:::o;72054:992::-;72130:7;:5;:7::i;:::-;72118:19;;:9;:19;;;72114:794;;72173:18;;72161:8;:30;;72153:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;72255:6;;;;;;;;;;;72254:7;72246:16;;;;;;72305:1;72280:24;72294:9;72280:13;:24::i;:::-;:26;72277:620;;;72338:1;72329:8;:10;72326:346;;;72524:9;;72496:24;72510:9;72496:13;:24::i;:::-;72485:8;:35;;;;:::i;:::-;:48;;72477:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;72623:1;72614:8;:10;;;;:::i;:::-;72601:9;;:24;;;;:::i;:::-;72587:9;:39;;72579:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;72326:346;72277:620;;;72761:9;;72733:24;72747:9;72733:13;:24::i;:::-;72722:8;:35;;;;:::i;:::-;:48;;72714:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;72846:8;72834:9;;:20;;;;:::i;:::-;72820:9;:35;;72812:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;72277:620;72114:794;72956:10;;72944:8;72928:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:38;;72920:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;73008:30;73018:9;73029:8;73008:9;:30::i;:::-;72054:992;:::o;45169:234::-;45316:8;45264:18;:39;45283:19;:17;:19::i;:::-;45264:39;;;;;;;;;;;;;;;:49;45304:8;45264:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;45376:8;45340:55;;45355:19;:17;:19::i;:::-;45340:55;;;45386:8;45340:55;;;;;;:::i;:::-;;;;;;;;45169:234;;:::o;73743:100::-;17246:13;:11;:13::i;:::-;73825:10:::1;73813:9;:22;;;;73743:100:::0;:::o;51962:407::-;52137:31;52150:4;52156:2;52160:7;52137:12;:31::i;:::-;52201:1;52183:2;:14;;;:19;52179:183;;52222:56;52253:4;52259:2;52263:7;52272:5;52222:30;:56::i;:::-;52217:145;;52306:40;;;;;;;;;;;;;;52217:145;52179:183;51962:407;;;;:::o;71697:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;73054:435::-;73152:13;73193:16;73201:7;73193;:16::i;:::-;73177:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;73295:28;73326:10;:8;:10::i;:::-;73295:41;;73381:1;73356:14;73350:28;:32;:133;;;;;;;;;;;;;;;;;73418:14;73434:18;:7;:16;:18::i;:::-;73454:13;73401:67;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73350:133;73343:140;;;73054:435;;;:::o;45560:164::-;45657:4;45681:18;:25;45700:5;45681:25;;;;;;;;;;;;;;;:35;45707:8;45681:35;;;;;;;;;;;;;;;;;;;;;;;;;45674:42;;45560:164;;;;:::o;18266:201::-;17246:13;:11;:13::i;:::-;18375:1:::1;18355:22;;:8;:22;;::::0;18347:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;18431:28;18450:8;18431:18;:28::i;:::-;18266:201:::0;:::o;17525:132::-;17600:12;:10;:12::i;:::-;17589:23;;:7;:5;:7::i;:::-;:23;;;17581:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;17525:132::o;45982:282::-;46047:4;46103:7;46084:15;:13;:15::i;:::-;:26;;:66;;;;;46137:13;;46127:7;:23;46084:66;:153;;;;;46236:1;30081:8;46188:17;:26;46206:7;46188:26;;;;;;;;;;;;:44;:49;46084:153;46064:173;;45982:282;;;:::o;63040:492::-;63169:13;63185:16;63193:7;63185;:16::i;:::-;63169:32;;63218:13;63214:219;;;63273:5;63250:28;;:19;:17;:19::i;:::-;:28;;;63246:187;;63302:44;63319:5;63326:19;:17;:19::i;:::-;63302:16;:44::i;:::-;63297:136;;63378:35;;;;;;;;;;;;;;63297:136;63246:187;63214:219;63478:2;63445:15;:24;63461:7;63445:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;63516:7;63512:2;63496:28;;63505:5;63496:28;;;;;;;;;;;;63158:374;63040:492;;;:::o;33478:92::-;33534:7;33478:92;:::o;40759:1712::-;40826:14;40876:7;40857:15;:13;:15::i;:::-;:26;40853:1562;;40909:17;:26;40927:7;40909:26;;;;;;;;;;;;40900:35;;41013:1;30081:8;40985:6;:24;:29;40981:1423;;41134:1;41124:6;:11;41120:981;;41175:13;;41164:7;:24;41160:68;;41197:31;;;;;;;;;;;;;;41160:68;41825:257;41911:17;:28;41929:9;;;;;;;41911:28;;;;;;;;;;;;41902:37;;42007:1;41997:6;:11;42045:13;41993:25;41825:257;;41120:981;42375:13;;40981:1423;40853:1562;42432:31;;;;;;;;;;;;;;40759:1712;;;;:::o;47145:485::-;47247:27;47276:23;47317:38;47358:15;:24;47374:7;47358:24;;;;;;;;;;;47317:65;;47535:18;47512:41;;47592:19;47586:26;47567:45;;47497:126;47145:485;;;:::o;69588:105::-;69648:7;69675:10;69668:17;;69588:105;:::o;46373:659::-;46522:11;46687:16;46680:5;46676:28;46667:37;;46847:16;46836:9;46832:32;46819:45;;46997:15;46986:9;46983:30;46975:5;46964:9;46961:20;46958:56;46948:66;;46373:659;;;;;:::o;53031:159::-;;;;;:::o;68897:311::-;69032:7;69052:16;30485:3;69078:19;:41;;69052:68;;30485:3;69146:31;69157:4;69163:2;69167:9;69146:10;:31::i;:::-;69138:40;;:62;;69131:69;;;68897:311;;;;;:::o;43019:450::-;43099:14;43267:16;43260:5;43256:28;43247:37;;43444:5;43430:11;43405:23;43401:41;43398:52;43391:5;43388:63;43378:73;;43019:450;;;;:::o;53855:158::-;;;;;:::o;18627:191::-;18701:16;18720:6;;;;;;;;;;;18701:25;;18746:8;18737:6;;:17;;;;;;;;;;;;;;;;;;18801:8;18770:40;;18791:8;18770:40;;;;;;;;;;;;18690:128;18627:191;:::o;35461:178::-;35522:7;29305:13;29443:2;35550:18;:25;35569:5;35550:25;;;;;;;;;;;;;;;;:50;;35549:82;35542:89;;35461:178;;;:::o;62122:112::-;62199:27;62209:2;62213:8;62199:27;;;;;;;;;;;;:9;:27::i;:::-;62122:112;;:::o;54453:716::-;54616:4;54662:2;54637:45;;;54683:19;:17;:19::i;:::-;54704:4;54710:7;54719:5;54637:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;54633:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54937:1;54920:6;:13;:18;54916:235;;54966:40;;;;;;;;;;;;;;54916:235;55109:6;55103:13;55094:6;55090:2;55086:15;55079:38;54633:529;54806:54;;;54796:64;;;:6;:64;;;;54789:71;;;54453:716;;;;;;:::o;73619:100::-;73671:13;73704:7;73697:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73619:100;:::o;13338:716::-;13394:13;13445:14;13482:1;13462:17;13473:5;13462:10;:17::i;:::-;:21;13445:38;;13498:20;13532:6;13521:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13498:41;;13554:11;13683:6;13679:2;13675:15;13667:6;13663:28;13656:35;;13720:288;13727:4;13720:288;;;13752:5;;;;;;;;13894:8;13889:2;13882:5;13878:14;13873:30;13868:3;13860:44;13950:2;13941:11;;;;;;:::i;:::-;;;;;13984:1;13975:5;:10;13720:288;13971:21;13720:288;14029:6;14022:13;;;;;13338:716;;;:::o;15911:98::-;15964:7;15991:10;15984:17;;15911:98;:::o;68598:147::-;68735:6;68598:147;;;;;:::o;61349:689::-;61480:19;61486:2;61490:8;61480:5;:19::i;:::-;61559:1;61541:2;:14;;;:19;61537:483;;61581:11;61595:13;;61581:27;;61627:13;61649:8;61643:3;:14;61627:30;;61676:233;61707:62;61746:1;61750:2;61754:7;;;;;;61763:5;61707:30;:62::i;:::-;61702:167;;61805:40;;;;;;;;;;;;;;61702:167;61904:3;61896:5;:11;61676:233;;61991:3;61974:13;;:20;61970:34;;61996:8;;;61970:34;61562:458;;61537:483;61349:689;;;:::o;10204:922::-;10257:7;10277:14;10294:1;10277:18;;10344:6;10335:5;:15;10331:102;;10380:6;10371:15;;;;;;:::i;:::-;;;;;10415:2;10405:12;;;;10331:102;10460:6;10451:5;:15;10447:102;;10496:6;10487:15;;;;;;:::i;:::-;;;;;10531:2;10521:12;;;;10447:102;10576:6;10567:5;:15;10563:102;;10612:6;10603:15;;;;;;:::i;:::-;;;;;10647:2;10637:12;;;;10563:102;10692:5;10683;:14;10679:99;;10727:5;10718:14;;;;;;:::i;:::-;;;;;10761:1;10751:11;;;;10679:99;10805:5;10796;:14;10792:99;;10840:5;10831:14;;;;;;:::i;:::-;;;;;10874:1;10864:11;;;;10792:99;10918:5;10909;:14;10905:99;;10953:5;10944:14;;;;;;:::i;:::-;;;;;10987:1;10977:11;;;;10905:99;11031:5;11022;:14;11018:66;;11067:1;11057:11;;;;11018:66;11112:6;11105:13;;;10204:922;;;:::o;55631:2966::-;55704:20;55727:13;;55704:36;;55767:1;55755:8;:13;55751:44;;55777:18;;;;;;;;;;;;;;55751:44;55808:61;55838:1;55842:2;55846:12;55860:8;55808:21;:61::i;:::-;56352:1;29443:2;56322:1;:26;;56321:32;56309:8;:45;56283:18;:22;56302:2;56283:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;56631:139;56668:2;56722:33;56745:1;56749:2;56753:1;56722:14;:33::i;:::-;56689:30;56710:8;56689:20;:30::i;:::-;:66;56631:18;:139::i;:::-;56597:17;:31;56615:12;56597:31;;;;;;;;;;;:173;;;;56787:16;56818:11;56847:8;56832:12;:23;56818:37;;57368:16;57364:2;57360:25;57348:37;;57740:12;57700:8;57659:1;57597:25;57538:1;57477;57450:335;58111:1;58097:12;58093:20;58051:346;58152:3;58143:7;58140:16;58051:346;;58370:7;58360:8;58357:1;58330:25;58327:1;58324;58319:59;58205:1;58196:7;58192:15;58181:26;;58051:346;;;58055:77;58442:1;58430:8;:13;58426:45;;58452:19;;;;;;;;;;;;;;58426:45;58504:3;58488:13;:19;;;;56057:2462;;58529:60;58558:1;58562:2;58566:12;58580:8;58529:20;:60::i;:::-;55693:2904;55631:2966;;:::o;43571:324::-;43641:14;43874:1;43864:8;43861:15;43835:24;43831:46;43821:56;;43571:324;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:116::-;1588:21;1603:5;1588:21;:::i;:::-;1581:5;1578:32;1568:60;;1624:1;1621;1614:12;1568:60;1518:116;:::o;1640:133::-;1683:5;1721:6;1708:20;1699:29;;1737:30;1761:5;1737:30;:::i;:::-;1640:133;;;;:::o;1779:323::-;1835:6;1884:2;1872:9;1863:7;1859:23;1855:32;1852:119;;;1890:79;;:::i;:::-;1852:119;2010:1;2035:50;2077:7;2068:6;2057:9;2053:22;2035:50;:::i;:::-;2025:60;;1981:114;1779:323;;;;:::o;2108:99::-;2160:6;2194:5;2188:12;2178:22;;2108:99;;;:::o;2213:169::-;2297:11;2331:6;2326:3;2319:19;2371:4;2366:3;2362:14;2347:29;;2213:169;;;;:::o;2388:246::-;2469:1;2479:113;2493:6;2490:1;2487:13;2479:113;;;2578:1;2573:3;2569:11;2563:18;2559:1;2554:3;2550:11;2543:39;2515:2;2512:1;2508:10;2503:15;;2479:113;;;2626:1;2617:6;2612:3;2608:16;2601:27;2450:184;2388:246;;;:::o;2640:102::-;2681:6;2732:2;2728:7;2723:2;2716:5;2712:14;2708:28;2698:38;;2640:102;;;:::o;2748:377::-;2836:3;2864:39;2897:5;2864:39;:::i;:::-;2919:71;2983:6;2978:3;2919:71;:::i;:::-;2912:78;;2999:65;3057:6;3052:3;3045:4;3038:5;3034:16;2999:65;:::i;:::-;3089:29;3111:6;3089:29;:::i;:::-;3084:3;3080:39;3073:46;;2840:285;2748:377;;;;:::o;3131:313::-;3244:4;3282:2;3271:9;3267:18;3259:26;;3331:9;3325:4;3321:20;3317:1;3306:9;3302:17;3295:47;3359:78;3432:4;3423:6;3359:78;:::i;:::-;3351:86;;3131:313;;;;:::o;3450:77::-;3487:7;3516:5;3505:16;;3450:77;;;:::o;3533:122::-;3606:24;3624:5;3606:24;:::i;:::-;3599:5;3596:35;3586:63;;3645:1;3642;3635:12;3586:63;3533:122;:::o;3661:139::-;3707:5;3745:6;3732:20;3723:29;;3761:33;3788:5;3761:33;:::i;:::-;3661:139;;;;:::o;3806:329::-;3865:6;3914:2;3902:9;3893:7;3889:23;3885:32;3882:119;;;3920:79;;:::i;:::-;3882:119;4040:1;4065:53;4110:7;4101:6;4090:9;4086:22;4065:53;:::i;:::-;4055:63;;4011:117;3806:329;;;;:::o;4141:126::-;4178:7;4218:42;4211:5;4207:54;4196:65;;4141:126;;;:::o;4273:96::-;4310:7;4339:24;4357:5;4339:24;:::i;:::-;4328:35;;4273:96;;;:::o;4375:118::-;4462:24;4480:5;4462:24;:::i;:::-;4457:3;4450:37;4375:118;;:::o;4499:222::-;4592:4;4630:2;4619:9;4615:18;4607:26;;4643:71;4711:1;4700:9;4696:17;4687:6;4643:71;:::i;:::-;4499:222;;;;:::o;4727:122::-;4800:24;4818:5;4800:24;:::i;:::-;4793:5;4790:35;4780:63;;4839:1;4836;4829:12;4780:63;4727:122;:::o;4855:139::-;4901:5;4939:6;4926:20;4917:29;;4955:33;4982:5;4955:33;:::i;:::-;4855:139;;;;:::o;5000:474::-;5068:6;5076;5125:2;5113:9;5104:7;5100:23;5096:32;5093:119;;;5131:79;;:::i;:::-;5093:119;5251:1;5276:53;5321:7;5312:6;5301:9;5297:22;5276:53;:::i;:::-;5266:63;;5222:117;5378:2;5404:53;5449:7;5440:6;5429:9;5425:22;5404:53;:::i;:::-;5394:63;;5349:118;5000:474;;;;;:::o;5480:118::-;5567:24;5585:5;5567:24;:::i;:::-;5562:3;5555:37;5480:118;;:::o;5604:222::-;5697:4;5735:2;5724:9;5720:18;5712:26;;5748:71;5816:1;5805:9;5801:17;5792:6;5748:71;:::i;:::-;5604:222;;;;:::o;5832:619::-;5909:6;5917;5925;5974:2;5962:9;5953:7;5949:23;5945:32;5942:119;;;5980:79;;:::i;:::-;5942:119;6100:1;6125:53;6170:7;6161:6;6150:9;6146:22;6125:53;:::i;:::-;6115:63;;6071:117;6227:2;6253:53;6298:7;6289:6;6278:9;6274:22;6253:53;:::i;:::-;6243:63;;6198:118;6355:2;6381:53;6426:7;6417:6;6406:9;6402:22;6381:53;:::i;:::-;6371:63;;6326:118;5832:619;;;;;:::o;6457:329::-;6516:6;6565:2;6553:9;6544:7;6540:23;6536:32;6533:119;;;6571:79;;:::i;:::-;6533:119;6691:1;6716:53;6761:7;6752:6;6741:9;6737:22;6716:53;:::i;:::-;6706:63;;6662:117;6457:329;;;;:::o;6792:468::-;6857:6;6865;6914:2;6902:9;6893:7;6889:23;6885:32;6882:119;;;6920:79;;:::i;:::-;6882:119;7040:1;7065:53;7110:7;7101:6;7090:9;7086:22;7065:53;:::i;:::-;7055:63;;7011:117;7167:2;7193:50;7235:7;7226:6;7215:9;7211:22;7193:50;:::i;:::-;7183:60;;7138:115;6792:468;;;;;:::o;7266:117::-;7375:1;7372;7365:12;7389:117;7498:1;7495;7488:12;7512:180;7560:77;7557:1;7550:88;7657:4;7654:1;7647:15;7681:4;7678:1;7671:15;7698:281;7781:27;7803:4;7781:27;:::i;:::-;7773:6;7769:40;7911:6;7899:10;7896:22;7875:18;7863:10;7860:34;7857:62;7854:88;;;7922:18;;:::i;:::-;7854:88;7962:10;7958:2;7951:22;7741:238;7698:281;;:::o;7985:129::-;8019:6;8046:20;;:::i;:::-;8036:30;;8075:33;8103:4;8095:6;8075:33;:::i;:::-;7985:129;;;:::o;8120:307::-;8181:4;8271:18;8263:6;8260:30;8257:56;;;8293:18;;:::i;:::-;8257:56;8331:29;8353:6;8331:29;:::i;:::-;8323:37;;8415:4;8409;8405:15;8397:23;;8120:307;;;:::o;8433:146::-;8530:6;8525:3;8520;8507:30;8571:1;8562:6;8557:3;8553:16;8546:27;8433:146;;;:::o;8585:423::-;8662:5;8687:65;8703:48;8744:6;8703:48;:::i;:::-;8687:65;:::i;:::-;8678:74;;8775:6;8768:5;8761:21;8813:4;8806:5;8802:16;8851:3;8842:6;8837:3;8833:16;8830:25;8827:112;;;8858:79;;:::i;:::-;8827:112;8948:54;8995:6;8990:3;8985;8948:54;:::i;:::-;8668:340;8585:423;;;;;:::o;9027:338::-;9082:5;9131:3;9124:4;9116:6;9112:17;9108:27;9098:122;;9139:79;;:::i;:::-;9098:122;9256:6;9243:20;9281:78;9355:3;9347:6;9340:4;9332:6;9328:17;9281:78;:::i;:::-;9272:87;;9088:277;9027:338;;;;:::o;9371:943::-;9466:6;9474;9482;9490;9539:3;9527:9;9518:7;9514:23;9510:33;9507:120;;;9546:79;;:::i;:::-;9507:120;9666:1;9691:53;9736:7;9727:6;9716:9;9712:22;9691:53;:::i;:::-;9681:63;;9637:117;9793:2;9819:53;9864:7;9855:6;9844:9;9840:22;9819:53;:::i;:::-;9809:63;;9764:118;9921:2;9947:53;9992:7;9983:6;9972:9;9968:22;9947:53;:::i;:::-;9937:63;;9892:118;10077:2;10066:9;10062:18;10049:32;10108:18;10100:6;10097:30;10094:117;;;10130:79;;:::i;:::-;10094:117;10235:62;10289:7;10280:6;10269:9;10265:22;10235:62;:::i;:::-;10225:72;;10020:287;9371:943;;;;;;;:::o;10320:474::-;10388:6;10396;10445:2;10433:9;10424:7;10420:23;10416:32;10413:119;;;10451:79;;:::i;:::-;10413:119;10571:1;10596:53;10641:7;10632:6;10621:9;10617:22;10596:53;:::i;:::-;10586:63;;10542:117;10698:2;10724:53;10769:7;10760:6;10749:9;10745:22;10724:53;:::i;:::-;10714:63;;10669:118;10320:474;;;;;:::o;10800:180::-;10848:77;10845:1;10838:88;10945:4;10942:1;10935:15;10969:4;10966:1;10959:15;10986:320;11030:6;11067:1;11061:4;11057:12;11047:22;;11114:1;11108:4;11104:12;11135:18;11125:81;;11191:4;11183:6;11179:17;11169:27;;11125:81;11253:2;11245:6;11242:14;11222:18;11219:38;11216:84;;11272:18;;:::i;:::-;11216:84;11037:269;10986:320;;;:::o;11312:223::-;11452:34;11448:1;11440:6;11436:14;11429:58;11521:6;11516:2;11508:6;11504:15;11497:31;11312:223;:::o;11541:366::-;11683:3;11704:67;11768:2;11763:3;11704:67;:::i;:::-;11697:74;;11780:93;11869:3;11780:93;:::i;:::-;11898:2;11893:3;11889:12;11882:19;;11541:366;;;:::o;11913:419::-;12079:4;12117:2;12106:9;12102:18;12094:26;;12166:9;12160:4;12156:20;12152:1;12141:9;12137:17;12130:47;12194:131;12320:4;12194:131;:::i;:::-;12186:139;;11913:419;;;:::o;12338:180::-;12386:77;12383:1;12376:88;12483:4;12480:1;12473:15;12507:4;12504:1;12497:15;12524:191;12564:3;12583:20;12601:1;12583:20;:::i;:::-;12578:25;;12617:20;12635:1;12617:20;:::i;:::-;12612:25;;12660:1;12657;12653:9;12646:16;;12681:3;12678:1;12675:10;12672:36;;;12688:18;;:::i;:::-;12672:36;12524:191;;;;:::o;12721:168::-;12861:20;12857:1;12849:6;12845:14;12838:44;12721:168;:::o;12895:366::-;13037:3;13058:67;13122:2;13117:3;13058:67;:::i;:::-;13051:74;;13134:93;13223:3;13134:93;:::i;:::-;13252:2;13247:3;13243:12;13236:19;;12895:366;;;:::o;13267:419::-;13433:4;13471:2;13460:9;13456:18;13448:26;;13520:9;13514:4;13510:20;13506:1;13495:9;13491:17;13484:47;13548:131;13674:4;13548:131;:::i;:::-;13540:139;;13267:419;;;:::o;13692:194::-;13732:4;13752:20;13770:1;13752:20;:::i;:::-;13747:25;;13786:20;13804:1;13786:20;:::i;:::-;13781:25;;13830:1;13827;13823:9;13815:17;;13854:1;13848:4;13845:11;13842:37;;;13859:18;;:::i;:::-;13842:37;13692:194;;;;:::o;13892:410::-;13932:7;13955:20;13973:1;13955:20;:::i;:::-;13950:25;;13989:20;14007:1;13989:20;:::i;:::-;13984:25;;14044:1;14041;14037:9;14066:30;14084:11;14066:30;:::i;:::-;14055:41;;14245:1;14236:7;14232:15;14229:1;14226:22;14206:1;14199:9;14179:83;14156:139;;14275:18;;:::i;:::-;14156:139;13940:362;13892:410;;;;:::o;14308:171::-;14448:23;14444:1;14436:6;14432:14;14425:47;14308:171;:::o;14485:366::-;14627:3;14648:67;14712:2;14707:3;14648:67;:::i;:::-;14641:74;;14724:93;14813:3;14724:93;:::i;:::-;14842:2;14837:3;14833:12;14826:19;;14485:366;;;:::o;14857:419::-;15023:4;15061:2;15050:9;15046:18;15038:26;;15110:9;15104:4;15100:20;15096:1;15085:9;15081:17;15074:47;15138:131;15264:4;15138:131;:::i;:::-;15130:139;;14857:419;;;:::o;15282:172::-;15422:24;15418:1;15410:6;15406:14;15399:48;15282:172;:::o;15460:366::-;15602:3;15623:67;15687:2;15682:3;15623:67;:::i;:::-;15616:74;;15699:93;15788:3;15699:93;:::i;:::-;15817:2;15812:3;15808:12;15801:19;;15460:366;;;:::o;15832:419::-;15998:4;16036:2;16025:9;16021:18;16013:26;;16085:9;16079:4;16075:20;16071:1;16060:9;16056:17;16049:47;16113:131;16239:4;16113:131;:::i;:::-;16105:139;;15832:419;;;:::o;16257:234::-;16397:34;16393:1;16385:6;16381:14;16374:58;16466:17;16461:2;16453:6;16449:15;16442:42;16257:234;:::o;16497:366::-;16639:3;16660:67;16724:2;16719:3;16660:67;:::i;:::-;16653:74;;16736:93;16825:3;16736:93;:::i;:::-;16854:2;16849:3;16845:12;16838:19;;16497:366;;;:::o;16869:419::-;17035:4;17073:2;17062:9;17058:18;17050:26;;17122:9;17116:4;17112:20;17108:1;17097:9;17093:17;17086:47;17150:131;17276:4;17150:131;:::i;:::-;17142:139;;16869:419;;;:::o;17294:148::-;17396:11;17433:3;17418:18;;17294:148;;;;:::o;17448:390::-;17554:3;17582:39;17615:5;17582:39;:::i;:::-;17637:89;17719:6;17714:3;17637:89;:::i;:::-;17630:96;;17735:65;17793:6;17788:3;17781:4;17774:5;17770:16;17735:65;:::i;:::-;17825:6;17820:3;17816:16;17809:23;;17558:280;17448:390;;;;:::o;17844:141::-;17893:4;17916:3;17908:11;;17939:3;17936:1;17929:14;17973:4;17970:1;17960:18;17952:26;;17844:141;;;:::o;18015:874::-;18118:3;18155:5;18149:12;18184:36;18210:9;18184:36;:::i;:::-;18236:89;18318:6;18313:3;18236:89;:::i;:::-;18229:96;;18356:1;18345:9;18341:17;18372:1;18367:166;;;;18547:1;18542:341;;;;18334:549;;18367:166;18451:4;18447:9;18436;18432:25;18427:3;18420:38;18513:6;18506:14;18499:22;18491:6;18487:35;18482:3;18478:45;18471:52;;18367:166;;18542:341;18609:38;18641:5;18609:38;:::i;:::-;18669:1;18683:154;18697:6;18694:1;18691:13;18683:154;;;18771:7;18765:14;18761:1;18756:3;18752:11;18745:35;18821:1;18812:7;18808:15;18797:26;;18719:4;18716:1;18712:12;18707:17;;18683:154;;;18866:6;18861:3;18857:16;18850:23;;18549:334;;18334:549;;18122:767;;18015:874;;;;:::o;18895:589::-;19120:3;19142:95;19233:3;19224:6;19142:95;:::i;:::-;19135:102;;19254:95;19345:3;19336:6;19254:95;:::i;:::-;19247:102;;19366:92;19454:3;19445:6;19366:92;:::i;:::-;19359:99;;19475:3;19468:10;;18895:589;;;;;;:::o;19490:225::-;19630:34;19626:1;19618:6;19614:14;19607:58;19699:8;19694:2;19686:6;19682:15;19675:33;19490:225;:::o;19721:366::-;19863:3;19884:67;19948:2;19943:3;19884:67;:::i;:::-;19877:74;;19960:93;20049:3;19960:93;:::i;:::-;20078:2;20073:3;20069:12;20062:19;;19721:366;;;:::o;20093:419::-;20259:4;20297:2;20286:9;20282:18;20274:26;;20346:9;20340:4;20336:20;20332:1;20321:9;20317:17;20310:47;20374:131;20500:4;20374:131;:::i;:::-;20366:139;;20093:419;;;:::o;20518:182::-;20658:34;20654:1;20646:6;20642:14;20635:58;20518:182;:::o;20706:366::-;20848:3;20869:67;20933:2;20928:3;20869:67;:::i;:::-;20862:74;;20945:93;21034:3;20945:93;:::i;:::-;21063:2;21058:3;21054:12;21047:19;;20706:366;;;:::o;21078:419::-;21244:4;21282:2;21271:9;21267:18;21259:26;;21331:9;21325:4;21321:20;21317:1;21306:9;21302:17;21295:47;21359:131;21485:4;21359:131;:::i;:::-;21351:139;;21078:419;;;:::o;21503:98::-;21554:6;21588:5;21582:12;21572:22;;21503:98;;;:::o;21607:168::-;21690:11;21724:6;21719:3;21712:19;21764:4;21759:3;21755:14;21740:29;;21607:168;;;;:::o;21781:373::-;21867:3;21895:38;21927:5;21895:38;:::i;:::-;21949:70;22012:6;22007:3;21949:70;:::i;:::-;21942:77;;22028:65;22086:6;22081:3;22074:4;22067:5;22063:16;22028:65;:::i;:::-;22118:29;22140:6;22118:29;:::i;:::-;22113:3;22109:39;22102:46;;21871:283;21781:373;;;;:::o;22160:640::-;22355:4;22393:3;22382:9;22378:19;22370:27;;22407:71;22475:1;22464:9;22460:17;22451:6;22407:71;:::i;:::-;22488:72;22556:2;22545:9;22541:18;22532:6;22488:72;:::i;:::-;22570;22638:2;22627:9;22623:18;22614:6;22570:72;:::i;:::-;22689:9;22683:4;22679:20;22674:2;22663:9;22659:18;22652:48;22717:76;22788:4;22779:6;22717:76;:::i;:::-;22709:84;;22160:640;;;;;;;:::o;22806:141::-;22862:5;22893:6;22887:13;22878:22;;22909:32;22935:5;22909:32;:::i;:::-;22806:141;;;;:::o;22953:349::-;23022:6;23071:2;23059:9;23050:7;23046:23;23042:32;23039:119;;;23077:79;;:::i;:::-;23039:119;23197:1;23222:63;23277:7;23268:6;23257:9;23253:22;23222:63;:::i;:::-;23212:73;;23168:127;22953:349;;;;:::o;23308:180::-;23356:77;23353:1;23346:88;23453:4;23450:1;23443:15;23477:4;23474:1;23467:15
Swarm Source
ipfs://50b6c4776d4d3519500ff98f4456d876fd1048940e560bd2eb7eab4f15b97b9a
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.