Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Loading...
Loading
Contract Name:
MatrixCode
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Nova.Arbiscan.io on 2023-02-10 */ // File: @openzeppelin/contracts/utils/Counters.sol // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // 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: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256, /* firstTokenId */ uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol) pragma solidity ^0.8.0; /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is ERC721 { using Strings for uint256; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = _baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } return super.tokenURI(tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev See {ERC721-_burn}. This override additionally checks to see if a * token-specific URI was set for the token, and if so, it deletes the token URI from * the storage mapping. */ function _burn(uint256 tokenId) internal virtual override { super._burn(tokenId); if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File: matrixcode.sol pragma solidity ^0.8.9; contract MatrixCode is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIdCounter; constructor() ERC721("Matrix Code", "mcode") {} function safeMint(address to, uint256 num, string memory uri) public onlyOwner { uint256 supply = totalSupply(); uint256 tokenId = _tokenIdCounter.current(); for (uint256 i; i < num; i++) { _safeMint(to, supply + i); _setTokenURI(supply + i, uri); } } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"num","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040518060400160405280600b81526020017f4d617472697820436f64650000000000000000000000000000000000000000008152506040518060400160405280600581526020017f6d636f6465000000000000000000000000000000000000000000000000000000815250816000908051906020019062000096929190620001a6565b508060019080519060200190620000af929190620001a6565b505050620000d2620000c6620000d860201b60201c565b620000e060201b60201c565b620002bb565b600033905090565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620001b49062000285565b90600052602060002090601f016020900481019282620001d8576000855562000224565b82601f10620001f357805160ff191683800117855562000224565b8280016001018555821562000224579182015b828111156200022357825182559160200191906001019062000206565b5b50905062000233919062000237565b5090565b5b808211156200025257600081600090555060010162000238565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200029e57607f821691505b60208210811415620002b557620002b462000256565b5b50919050565b6137b280620002cb6000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c806370a08231116100ad578063b88d4fde11610071578063b88d4fde14610343578063c87b56dd1461035f578063cd279c7c1461038f578063e985e9c5146103ab578063f2fde38b146103db5761012c565b806370a08231146102b1578063715018a6146102e15780638da5cb5b146102eb57806395d89b4114610309578063a22cb465146103275761012c565b806323b872dd116100f457806323b872dd146101e95780632f745c591461020557806342842e0e146102355780634f6ccce7146102515780636352211e146102815761012c565b806301ffc9a71461013157806306fdde0314610161578063081812fc1461017f578063095ea7b3146101af57806318160ddd146101cb575b600080fd5b61014b600480360381019061014691906124ee565b6103f7565b6040516101589190612536565b60405180910390f35b610169610409565b60405161017691906125ea565b60405180910390f35b61019960048036038101906101949190612642565b61049b565b6040516101a691906126b0565b60405180910390f35b6101c960048036038101906101c491906126f7565b6104e1565b005b6101d36105f9565b6040516101e09190612746565b60405180910390f35b61020360048036038101906101fe9190612761565b610606565b005b61021f600480360381019061021a91906126f7565b610666565b60405161022c9190612746565b60405180910390f35b61024f600480360381019061024a9190612761565b61070b565b005b61026b60048036038101906102669190612642565b61072b565b6040516102789190612746565b60405180910390f35b61029b60048036038101906102969190612642565b61079c565b6040516102a891906126b0565b60405180910390f35b6102cb60048036038101906102c691906127b4565b610823565b6040516102d89190612746565b60405180910390f35b6102e96108db565b005b6102f36108ef565b60405161030091906126b0565b60405180910390f35b610311610919565b60405161031e91906125ea565b60405180910390f35b610341600480360381019061033c919061280d565b6109ab565b005b61035d60048036038101906103589190612982565b6109c1565b005b61037960048036038101906103749190612642565b610a23565b60405161038691906125ea565b60405180910390f35b6103a960048036038101906103a49190612aa6565b610a35565b005b6103c560048036038101906103c09190612b15565b610aa7565b6040516103d29190612536565b60405180910390f35b6103f560048036038101906103f091906127b4565b610b3b565b005b600061040282610bbf565b9050919050565b60606000805461041890612b84565b80601f016020809104026020016040519081016040528092919081815260200182805461044490612b84565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b5050505050905090565b60006104a682610c39565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006104ec8261079c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561055d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161055490612c28565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661057c610c84565b73ffffffffffffffffffffffffffffffffffffffff1614806105ab57506105aa816105a5610c84565b610aa7565b5b6105ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e190612cba565b60405180910390fd5b6105f48383610c8c565b505050565b6000600880549050905090565b610617610611610c84565b82610d45565b610656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064d90612d4c565b60405180910390fd5b610661838383610dda565b505050565b600061067183610823565b82106106b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a990612dde565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610726838383604051806020016040528060008152506109c1565b505050565b60006107356105f9565b8210610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076d90612e70565b60405180910390fd5b6008828154811061078a57610789612e90565b5b90600052602060002001549050919050565b6000806107a8836110d4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561081a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081190612f0b565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610894576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088b90612f9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6108e3611111565b6108ed600061118f565b565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461092890612b84565b80601f016020809104026020016040519081016040528092919081815260200182805461095490612b84565b80156109a15780601f10610976576101008083540402835291602001916109a1565b820191906000526020600020905b81548152906001019060200180831161098457829003601f168201915b5050505050905090565b6109bd6109b6610c84565b8383611255565b5050565b6109d26109cc610c84565b83610d45565b610a11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0890612d4c565b60405180910390fd5b610a1d848484846113c2565b50505050565b6060610a2e8261141e565b9050919050565b610a3d611111565b6000610a476105f9565b90506000610a55600c611531565b905060005b84811015610a9f57610a77868285610a729190612fec565b61153f565b610a8c8184610a869190612fec565b8561155d565b8080610a9790613042565b915050610a5a565b505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610b43611111565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610baa906130fd565b60405180910390fd5b610bbc8161118f565b50565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c325750610c31826115d1565b5b9050919050565b610c42816116b3565b610c81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7890612f0b565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610cff8361079c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610d518361079c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610d935750610d928185610aa7565b5b80610dd157508373ffffffffffffffffffffffffffffffffffffffff16610db98461049b565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610dfa8261079c565b73ffffffffffffffffffffffffffffffffffffffff1614610e50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e479061318f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb790613221565b60405180910390fd5b610ecd83838360016116f4565b8273ffffffffffffffffffffffffffffffffffffffff16610eed8261079c565b73ffffffffffffffffffffffffffffffffffffffff1614610f43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3a9061318f565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46110cf8383836001611706565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b611119610c84565b73ffffffffffffffffffffffffffffffffffffffff166111376108ef565b73ffffffffffffffffffffffffffffffffffffffff161461118d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111849061328d565b60405180910390fd5b565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156112c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112bb906132f9565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516113b59190612536565b60405180910390a3505050565b6113cd848484610dda565b6113d98484848461170c565b611418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140f9061338b565b60405180910390fd5b50505050565b606061142982610c39565b6000600a6000848152602001908152602001600020805461144990612b84565b80601f016020809104026020016040519081016040528092919081815260200182805461147590612b84565b80156114c25780601f10611497576101008083540402835291602001916114c2565b820191906000526020600020905b8154815290600101906020018083116114a557829003601f168201915b5050505050905060006114d36118a3565b90506000815114156114e957819250505061152c565b60008251111561151e5780826040516020016115069291906133e7565b6040516020818303038152906040529250505061152c565b611527846118ba565b925050505b919050565b600081600001549050919050565b611559828260405180602001604052806000815250611922565b5050565b611566826116b3565b6115a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159c9061347d565b60405180910390fd5b80600a600084815260200190815260200160002090805190602001906115cc9291906123df565b505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061169c57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806116ac57506116ab8261197d565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166116d5836110d4565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b611700848484846119e7565b50505050565b50505050565b600061172d8473ffffffffffffffffffffffffffffffffffffffff16611b47565b15611896578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611756610c84565b8786866040518563ffffffff1660e01b815260040161177894939291906134f2565b602060405180830381600087803b15801561179257600080fd5b505af19250505080156117c357506040513d601f19601f820116820180604052508101906117c09190613553565b60015b611846573d80600081146117f3576040519150601f19603f3d011682016040523d82523d6000602084013e6117f8565b606091505b5060008151141561183e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118359061338b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061189b565b600190505b949350505050565b606060405180602001604052806000815250905090565b60606118c582610c39565b60006118cf6118a3565b905060008151116118ef576040518060200160405280600081525061191a565b806118f984611b6a565b60405160200161190a9291906133e7565b6040516020818303038152906040525b915050919050565b61192c8383611c42565b611939600084848461170c565b611978576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196f9061338b565b60405180910390fd5b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6119f384848484611e60565b6001811115611a37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2e906135f2565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415611a7f57611a7a81611f86565b611abe565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611abd57611abc8582611fcf565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611b0157611afc8161213c565b611b40565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611b3f57611b3e848261220d565b5b5b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606060006001611b798461228c565b01905060008167ffffffffffffffff811115611b9857611b97612857565b5b6040519080825280601f01601f191660200182016040528015611bca5781602001600182028036833780820191505090505b509050600082602001820190505b600115611c37578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611c2157611c20613612565b5b0494506000851415611c3257611c37565b611bd8565b819350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca99061368d565b60405180910390fd5b611cbb816116b3565b15611cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf2906136f9565b60405180910390fd5b611d096000838360016116f4565b611d12816116b3565b15611d52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d49906136f9565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611e5c600083836001611706565b5050565b6001811115611f8057600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611ef45780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611eec9190613719565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611f7f5780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f779190612fec565b925050819055505b5b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001611fdc84610823565b611fe69190613719565b90506000600760008481526020019081526020016000205490508181146120cb576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016008805490506121509190613719565b90506000600960008481526020019081526020016000205490506000600883815481106121805761217f612e90565b5b9060005260206000200154905080600883815481106121a2576121a1612e90565b5b9060005260206000200181905550816009600083815260200190815260200160002081905550600960008581526020019081526020016000206000905560088054806121f1576121f061374d565b5b6001900381819060005260206000200160009055905550505050565b600061221883610823565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106122ea577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816122e0576122df613612565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612327576d04ee2d6d415b85acef8100000000838161231d5761231c613612565b5b0492506020810190505b662386f26fc10000831061235657662386f26fc10000838161234c5761234b613612565b5b0492506010810190505b6305f5e100831061237f576305f5e100838161237557612374613612565b5b0492506008810190505b61271083106123a457612710838161239a57612399613612565b5b0492506004810190505b606483106123c757606483816123bd576123bc613612565b5b0492506002810190505b600a83106123d6576001810190505b80915050919050565b8280546123eb90612b84565b90600052602060002090601f01602090048101928261240d5760008555612454565b82601f1061242657805160ff1916838001178555612454565b82800160010185558215612454579182015b82811115612453578251825591602001919060010190612438565b5b5090506124619190612465565b5090565b5b8082111561247e576000816000905550600101612466565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6124cb81612496565b81146124d657600080fd5b50565b6000813590506124e8816124c2565b92915050565b6000602082840312156125045761250361248c565b5b6000612512848285016124d9565b91505092915050565b60008115159050919050565b6125308161251b565b82525050565b600060208201905061254b6000830184612527565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561258b578082015181840152602081019050612570565b8381111561259a576000848401525b50505050565b6000601f19601f8301169050919050565b60006125bc82612551565b6125c6818561255c565b93506125d681856020860161256d565b6125df816125a0565b840191505092915050565b6000602082019050818103600083015261260481846125b1565b905092915050565b6000819050919050565b61261f8161260c565b811461262a57600080fd5b50565b60008135905061263c81612616565b92915050565b6000602082840312156126585761265761248c565b5b60006126668482850161262d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061269a8261266f565b9050919050565b6126aa8161268f565b82525050565b60006020820190506126c560008301846126a1565b92915050565b6126d48161268f565b81146126df57600080fd5b50565b6000813590506126f1816126cb565b92915050565b6000806040838503121561270e5761270d61248c565b5b600061271c858286016126e2565b925050602061272d8582860161262d565b9150509250929050565b6127408161260c565b82525050565b600060208201905061275b6000830184612737565b92915050565b60008060006060848603121561277a5761277961248c565b5b6000612788868287016126e2565b9350506020612799868287016126e2565b92505060406127aa8682870161262d565b9150509250925092565b6000602082840312156127ca576127c961248c565b5b60006127d8848285016126e2565b91505092915050565b6127ea8161251b565b81146127f557600080fd5b50565b600081359050612807816127e1565b92915050565b600080604083850312156128245761282361248c565b5b6000612832858286016126e2565b9250506020612843858286016127f8565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61288f826125a0565b810181811067ffffffffffffffff821117156128ae576128ad612857565b5b80604052505050565b60006128c1612482565b90506128cd8282612886565b919050565b600067ffffffffffffffff8211156128ed576128ec612857565b5b6128f6826125a0565b9050602081019050919050565b82818337600083830152505050565b6000612925612920846128d2565b6128b7565b90508281526020810184848401111561294157612940612852565b5b61294c848285612903565b509392505050565b600082601f8301126129695761296861284d565b5b8135612979848260208601612912565b91505092915050565b6000806000806080858703121561299c5761299b61248c565b5b60006129aa878288016126e2565b94505060206129bb878288016126e2565b93505060406129cc8782880161262d565b925050606085013567ffffffffffffffff8111156129ed576129ec612491565b5b6129f987828801612954565b91505092959194509250565b600067ffffffffffffffff821115612a2057612a1f612857565b5b612a29826125a0565b9050602081019050919050565b6000612a49612a4484612a05565b6128b7565b905082815260208101848484011115612a6557612a64612852565b5b612a70848285612903565b509392505050565b600082601f830112612a8d57612a8c61284d565b5b8135612a9d848260208601612a36565b91505092915050565b600080600060608486031215612abf57612abe61248c565b5b6000612acd868287016126e2565b9350506020612ade8682870161262d565b925050604084013567ffffffffffffffff811115612aff57612afe612491565b5b612b0b86828701612a78565b9150509250925092565b60008060408385031215612b2c57612b2b61248c565b5b6000612b3a858286016126e2565b9250506020612b4b858286016126e2565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612b9c57607f821691505b60208210811415612bb057612baf612b55565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000612c1260218361255c565b9150612c1d82612bb6565b604082019050919050565b60006020820190508181036000830152612c4181612c05565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612ca4603d8361255c565b9150612caf82612c48565b604082019050919050565b60006020820190508181036000830152612cd381612c97565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000612d36602d8361255c565b9150612d4182612cda565b604082019050919050565b60006020820190508181036000830152612d6581612d29565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000612dc8602b8361255c565b9150612dd382612d6c565b604082019050919050565b60006020820190508181036000830152612df781612dbb565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000612e5a602c8361255c565b9150612e6582612dfe565b604082019050919050565b60006020820190508181036000830152612e8981612e4d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000612ef560188361255c565b9150612f0082612ebf565b602082019050919050565b60006020820190508181036000830152612f2481612ee8565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612f8760298361255c565b9150612f9282612f2b565b604082019050919050565b60006020820190508181036000830152612fb681612f7a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ff78261260c565b91506130028361260c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561303757613036612fbd565b5b828201905092915050565b600061304d8261260c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156130805761307f612fbd565b5b600182019050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006130e760268361255c565b91506130f28261308b565b604082019050919050565b60006020820190508181036000830152613116816130da565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061317960258361255c565b91506131848261311d565b604082019050919050565b600060208201905081810360008301526131a88161316c565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061320b60248361255c565b9150613216826131af565b604082019050919050565b6000602082019050818103600083015261323a816131fe565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061327760208361255c565b915061328282613241565b602082019050919050565b600060208201905081810360008301526132a68161326a565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b60006132e360198361255c565b91506132ee826132ad565b602082019050919050565b60006020820190508181036000830152613312816132d6565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b600061337560328361255c565b915061338082613319565b604082019050919050565b600060208201905081810360008301526133a481613368565b9050919050565b600081905092915050565b60006133c182612551565b6133cb81856133ab565b93506133db81856020860161256d565b80840191505092915050565b60006133f382856133b6565b91506133ff82846133b6565b91508190509392505050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000613467602e8361255c565b91506134728261340b565b604082019050919050565b600060208201905081810360008301526134968161345a565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006134c48261349d565b6134ce81856134a8565b93506134de81856020860161256d565b6134e7816125a0565b840191505092915050565b600060808201905061350760008301876126a1565b61351460208301866126a1565b6135216040830185612737565b818103606083015261353381846134b9565b905095945050505050565b60008151905061354d816124c2565b92915050565b6000602082840312156135695761356861248c565b5b60006135778482850161353e565b91505092915050565b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b60006135dc60358361255c565b91506135e782613580565b604082019050919050565b6000602082019050818103600083015261360b816135cf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b600061367760208361255c565b915061368282613641565b602082019050919050565b600060208201905081810360008301526136a68161366a565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006136e3601c8361255c565b91506136ee826136ad565b602082019050919050565b60006020820190508181036000830152613712816136d6565b9050919050565b60006137248261260c565b915061372f8361260c565b92508282101561374257613741612fbd565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212207c462ff4d72db6c87bac0b54ceb71f8bc32f5b7fb1c8b1ab93661ef8c698a27164736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061012c5760003560e01c806370a08231116100ad578063b88d4fde11610071578063b88d4fde14610343578063c87b56dd1461035f578063cd279c7c1461038f578063e985e9c5146103ab578063f2fde38b146103db5761012c565b806370a08231146102b1578063715018a6146102e15780638da5cb5b146102eb57806395d89b4114610309578063a22cb465146103275761012c565b806323b872dd116100f457806323b872dd146101e95780632f745c591461020557806342842e0e146102355780634f6ccce7146102515780636352211e146102815761012c565b806301ffc9a71461013157806306fdde0314610161578063081812fc1461017f578063095ea7b3146101af57806318160ddd146101cb575b600080fd5b61014b600480360381019061014691906124ee565b6103f7565b6040516101589190612536565b60405180910390f35b610169610409565b60405161017691906125ea565b60405180910390f35b61019960048036038101906101949190612642565b61049b565b6040516101a691906126b0565b60405180910390f35b6101c960048036038101906101c491906126f7565b6104e1565b005b6101d36105f9565b6040516101e09190612746565b60405180910390f35b61020360048036038101906101fe9190612761565b610606565b005b61021f600480360381019061021a91906126f7565b610666565b60405161022c9190612746565b60405180910390f35b61024f600480360381019061024a9190612761565b61070b565b005b61026b60048036038101906102669190612642565b61072b565b6040516102789190612746565b60405180910390f35b61029b60048036038101906102969190612642565b61079c565b6040516102a891906126b0565b60405180910390f35b6102cb60048036038101906102c691906127b4565b610823565b6040516102d89190612746565b60405180910390f35b6102e96108db565b005b6102f36108ef565b60405161030091906126b0565b60405180910390f35b610311610919565b60405161031e91906125ea565b60405180910390f35b610341600480360381019061033c919061280d565b6109ab565b005b61035d60048036038101906103589190612982565b6109c1565b005b61037960048036038101906103749190612642565b610a23565b60405161038691906125ea565b60405180910390f35b6103a960048036038101906103a49190612aa6565b610a35565b005b6103c560048036038101906103c09190612b15565b610aa7565b6040516103d29190612536565b60405180910390f35b6103f560048036038101906103f091906127b4565b610b3b565b005b600061040282610bbf565b9050919050565b60606000805461041890612b84565b80601f016020809104026020016040519081016040528092919081815260200182805461044490612b84565b80156104915780601f1061046657610100808354040283529160200191610491565b820191906000526020600020905b81548152906001019060200180831161047457829003601f168201915b5050505050905090565b60006104a682610c39565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006104ec8261079c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561055d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161055490612c28565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661057c610c84565b73ffffffffffffffffffffffffffffffffffffffff1614806105ab57506105aa816105a5610c84565b610aa7565b5b6105ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e190612cba565b60405180910390fd5b6105f48383610c8c565b505050565b6000600880549050905090565b610617610611610c84565b82610d45565b610656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064d90612d4c565b60405180910390fd5b610661838383610dda565b505050565b600061067183610823565b82106106b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a990612dde565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610726838383604051806020016040528060008152506109c1565b505050565b60006107356105f9565b8210610776576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076d90612e70565b60405180910390fd5b6008828154811061078a57610789612e90565b5b90600052602060002001549050919050565b6000806107a8836110d4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561081a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081190612f0b565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610894576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088b90612f9d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6108e3611111565b6108ed600061118f565b565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461092890612b84565b80601f016020809104026020016040519081016040528092919081815260200182805461095490612b84565b80156109a15780601f10610976576101008083540402835291602001916109a1565b820191906000526020600020905b81548152906001019060200180831161098457829003601f168201915b5050505050905090565b6109bd6109b6610c84565b8383611255565b5050565b6109d26109cc610c84565b83610d45565b610a11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0890612d4c565b60405180910390fd5b610a1d848484846113c2565b50505050565b6060610a2e8261141e565b9050919050565b610a3d611111565b6000610a476105f9565b90506000610a55600c611531565b905060005b84811015610a9f57610a77868285610a729190612fec565b61153f565b610a8c8184610a869190612fec565b8561155d565b8080610a9790613042565b915050610a5a565b505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610b43611111565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bb3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610baa906130fd565b60405180910390fd5b610bbc8161118f565b50565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c325750610c31826115d1565b5b9050919050565b610c42816116b3565b610c81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7890612f0b565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610cff8361079c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610d518361079c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610d935750610d928185610aa7565b5b80610dd157508373ffffffffffffffffffffffffffffffffffffffff16610db98461049b565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610dfa8261079c565b73ffffffffffffffffffffffffffffffffffffffff1614610e50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e479061318f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb790613221565b60405180910390fd5b610ecd83838360016116f4565b8273ffffffffffffffffffffffffffffffffffffffff16610eed8261079c565b73ffffffffffffffffffffffffffffffffffffffff1614610f43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3a9061318f565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46110cf8383836001611706565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b611119610c84565b73ffffffffffffffffffffffffffffffffffffffff166111376108ef565b73ffffffffffffffffffffffffffffffffffffffff161461118d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111849061328d565b60405180910390fd5b565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156112c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112bb906132f9565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516113b59190612536565b60405180910390a3505050565b6113cd848484610dda565b6113d98484848461170c565b611418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140f9061338b565b60405180910390fd5b50505050565b606061142982610c39565b6000600a6000848152602001908152602001600020805461144990612b84565b80601f016020809104026020016040519081016040528092919081815260200182805461147590612b84565b80156114c25780601f10611497576101008083540402835291602001916114c2565b820191906000526020600020905b8154815290600101906020018083116114a557829003601f168201915b5050505050905060006114d36118a3565b90506000815114156114e957819250505061152c565b60008251111561151e5780826040516020016115069291906133e7565b6040516020818303038152906040529250505061152c565b611527846118ba565b925050505b919050565b600081600001549050919050565b611559828260405180602001604052806000815250611922565b5050565b611566826116b3565b6115a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159c9061347d565b60405180910390fd5b80600a600084815260200190815260200160002090805190602001906115cc9291906123df565b505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061169c57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806116ac57506116ab8261197d565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166116d5836110d4565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b611700848484846119e7565b50505050565b50505050565b600061172d8473ffffffffffffffffffffffffffffffffffffffff16611b47565b15611896578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611756610c84565b8786866040518563ffffffff1660e01b815260040161177894939291906134f2565b602060405180830381600087803b15801561179257600080fd5b505af19250505080156117c357506040513d601f19601f820116820180604052508101906117c09190613553565b60015b611846573d80600081146117f3576040519150601f19603f3d011682016040523d82523d6000602084013e6117f8565b606091505b5060008151141561183e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118359061338b565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061189b565b600190505b949350505050565b606060405180602001604052806000815250905090565b60606118c582610c39565b60006118cf6118a3565b905060008151116118ef576040518060200160405280600081525061191a565b806118f984611b6a565b60405160200161190a9291906133e7565b6040516020818303038152906040525b915050919050565b61192c8383611c42565b611939600084848461170c565b611978576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196f9061338b565b60405180910390fd5b505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6119f384848484611e60565b6001811115611a37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2e906135f2565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415611a7f57611a7a81611f86565b611abe565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611abd57611abc8582611fcf565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611b0157611afc8161213c565b611b40565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611b3f57611b3e848261220d565b5b5b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606060006001611b798461228c565b01905060008167ffffffffffffffff811115611b9857611b97612857565b5b6040519080825280601f01601f191660200182016040528015611bca5781602001600182028036833780820191505090505b509050600082602001820190505b600115611c37578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611c2157611c20613612565b5b0494506000851415611c3257611c37565b611bd8565b819350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca99061368d565b60405180910390fd5b611cbb816116b3565b15611cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf2906136f9565b60405180910390fd5b611d096000838360016116f4565b611d12816116b3565b15611d52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d49906136f9565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611e5c600083836001611706565b5050565b6001811115611f8057600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611ef45780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611eec9190613719565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611f7f5780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f779190612fec565b925050819055505b5b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001611fdc84610823565b611fe69190613719565b90506000600760008481526020019081526020016000205490508181146120cb576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b600060016008805490506121509190613719565b90506000600960008481526020019081526020016000205490506000600883815481106121805761217f612e90565b5b9060005260206000200154905080600883815481106121a2576121a1612e90565b5b9060005260206000200181905550816009600083815260200190815260200160002081905550600960008581526020019081526020016000206000905560088054806121f1576121f061374d565b5b6001900381819060005260206000200160009055905550505050565b600061221883610823565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106122ea577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816122e0576122df613612565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612327576d04ee2d6d415b85acef8100000000838161231d5761231c613612565b5b0492506020810190505b662386f26fc10000831061235657662386f26fc10000838161234c5761234b613612565b5b0492506010810190505b6305f5e100831061237f576305f5e100838161237557612374613612565b5b0492506008810190505b61271083106123a457612710838161239a57612399613612565b5b0492506004810190505b606483106123c757606483816123bd576123bc613612565b5b0492506002810190505b600a83106123d6576001810190505b80915050919050565b8280546123eb90612b84565b90600052602060002090601f01602090048101928261240d5760008555612454565b82601f1061242657805160ff1916838001178555612454565b82800160010185558215612454579182015b82811115612453578251825591602001919060010190612438565b5b5090506124619190612465565b5090565b5b8082111561247e576000816000905550600101612466565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6124cb81612496565b81146124d657600080fd5b50565b6000813590506124e8816124c2565b92915050565b6000602082840312156125045761250361248c565b5b6000612512848285016124d9565b91505092915050565b60008115159050919050565b6125308161251b565b82525050565b600060208201905061254b6000830184612527565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561258b578082015181840152602081019050612570565b8381111561259a576000848401525b50505050565b6000601f19601f8301169050919050565b60006125bc82612551565b6125c6818561255c565b93506125d681856020860161256d565b6125df816125a0565b840191505092915050565b6000602082019050818103600083015261260481846125b1565b905092915050565b6000819050919050565b61261f8161260c565b811461262a57600080fd5b50565b60008135905061263c81612616565b92915050565b6000602082840312156126585761265761248c565b5b60006126668482850161262d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061269a8261266f565b9050919050565b6126aa8161268f565b82525050565b60006020820190506126c560008301846126a1565b92915050565b6126d48161268f565b81146126df57600080fd5b50565b6000813590506126f1816126cb565b92915050565b6000806040838503121561270e5761270d61248c565b5b600061271c858286016126e2565b925050602061272d8582860161262d565b9150509250929050565b6127408161260c565b82525050565b600060208201905061275b6000830184612737565b92915050565b60008060006060848603121561277a5761277961248c565b5b6000612788868287016126e2565b9350506020612799868287016126e2565b92505060406127aa8682870161262d565b9150509250925092565b6000602082840312156127ca576127c961248c565b5b60006127d8848285016126e2565b91505092915050565b6127ea8161251b565b81146127f557600080fd5b50565b600081359050612807816127e1565b92915050565b600080604083850312156128245761282361248c565b5b6000612832858286016126e2565b9250506020612843858286016127f8565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61288f826125a0565b810181811067ffffffffffffffff821117156128ae576128ad612857565b5b80604052505050565b60006128c1612482565b90506128cd8282612886565b919050565b600067ffffffffffffffff8211156128ed576128ec612857565b5b6128f6826125a0565b9050602081019050919050565b82818337600083830152505050565b6000612925612920846128d2565b6128b7565b90508281526020810184848401111561294157612940612852565b5b61294c848285612903565b509392505050565b600082601f8301126129695761296861284d565b5b8135612979848260208601612912565b91505092915050565b6000806000806080858703121561299c5761299b61248c565b5b60006129aa878288016126e2565b94505060206129bb878288016126e2565b93505060406129cc8782880161262d565b925050606085013567ffffffffffffffff8111156129ed576129ec612491565b5b6129f987828801612954565b91505092959194509250565b600067ffffffffffffffff821115612a2057612a1f612857565b5b612a29826125a0565b9050602081019050919050565b6000612a49612a4484612a05565b6128b7565b905082815260208101848484011115612a6557612a64612852565b5b612a70848285612903565b509392505050565b600082601f830112612a8d57612a8c61284d565b5b8135612a9d848260208601612a36565b91505092915050565b600080600060608486031215612abf57612abe61248c565b5b6000612acd868287016126e2565b9350506020612ade8682870161262d565b925050604084013567ffffffffffffffff811115612aff57612afe612491565b5b612b0b86828701612a78565b9150509250925092565b60008060408385031215612b2c57612b2b61248c565b5b6000612b3a858286016126e2565b9250506020612b4b858286016126e2565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612b9c57607f821691505b60208210811415612bb057612baf612b55565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000612c1260218361255c565b9150612c1d82612bb6565b604082019050919050565b60006020820190508181036000830152612c4181612c05565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612ca4603d8361255c565b9150612caf82612c48565b604082019050919050565b60006020820190508181036000830152612cd381612c97565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000612d36602d8361255c565b9150612d4182612cda565b604082019050919050565b60006020820190508181036000830152612d6581612d29565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000612dc8602b8361255c565b9150612dd382612d6c565b604082019050919050565b60006020820190508181036000830152612df781612dbb565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000612e5a602c8361255c565b9150612e6582612dfe565b604082019050919050565b60006020820190508181036000830152612e8981612e4d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000612ef560188361255c565b9150612f0082612ebf565b602082019050919050565b60006020820190508181036000830152612f2481612ee8565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612f8760298361255c565b9150612f9282612f2b565b604082019050919050565b60006020820190508181036000830152612fb681612f7a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ff78261260c565b91506130028361260c565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561303757613036612fbd565b5b828201905092915050565b600061304d8261260c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156130805761307f612fbd565b5b600182019050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006130e760268361255c565b91506130f28261308b565b604082019050919050565b60006020820190508181036000830152613116816130da565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061317960258361255c565b91506131848261311d565b604082019050919050565b600060208201905081810360008301526131a88161316c565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061320b60248361255c565b9150613216826131af565b604082019050919050565b6000602082019050818103600083015261323a816131fe565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061327760208361255c565b915061328282613241565b602082019050919050565b600060208201905081810360008301526132a68161326a565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b60006132e360198361255c565b91506132ee826132ad565b602082019050919050565b60006020820190508181036000830152613312816132d6565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b600061337560328361255c565b915061338082613319565b604082019050919050565b600060208201905081810360008301526133a481613368565b9050919050565b600081905092915050565b60006133c182612551565b6133cb81856133ab565b93506133db81856020860161256d565b80840191505092915050565b60006133f382856133b6565b91506133ff82846133b6565b91508190509392505050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000613467602e8361255c565b91506134728261340b565b604082019050919050565b600060208201905081810360008301526134968161345a565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006134c48261349d565b6134ce81856134a8565b93506134de81856020860161256d565b6134e7816125a0565b840191505092915050565b600060808201905061350760008301876126a1565b61351460208301866126a1565b6135216040830185612737565b818103606083015261353381846134b9565b905095945050505050565b60008151905061354d816124c2565b92915050565b6000602082840312156135695761356861248c565b5b60006135778482850161353e565b91505092915050565b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b60006135dc60358361255c565b91506135e782613580565b604082019050919050565b6000602082019050818103600083015261360b816135cf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b600061367760208361255c565b915061368282613641565b602082019050919050565b600060208201905081810360008301526136a68161366a565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006136e3601c8361255c565b91506136ee826136ad565b602082019050919050565b60006020820190508181036000830152613712816136d6565b9050919050565b60006137248261260c565b915061372f8361260c565b92508282101561374257613741612fbd565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212207c462ff4d72db6c87bac0b54ceb71f8bc32f5b7fb1c8b1ab93661ef8c698a27164736f6c63430008090033
Deployed Bytecode Sourcemap
65917:1398:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67100:212;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42017:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43529:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43047:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60556:113;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44229:335;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60224:256;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44635:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60746:233;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41727:223;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41458:207;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19440:103;;;:::i;:::-;;18792:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42186:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43772:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44891:322;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66896:196;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66143:310;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43998:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19698:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67100:212;67239:4;67268:36;67292:11;67268:23;:36::i;:::-;67261:43;;67100:212;;;:::o;42017:100::-;42071:13;42104:5;42097:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42017:100;:::o;43529:171::-;43605:7;43625:23;43640:7;43625:14;:23::i;:::-;43668:15;:24;43684:7;43668:24;;;;;;;;;;;;;;;;;;;;;43661:31;;43529:171;;;:::o;43047:416::-;43128:13;43144:23;43159:7;43144:14;:23::i;:::-;43128:39;;43192:5;43186:11;;:2;:11;;;;43178:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;43286:5;43270:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;43295:37;43312:5;43319:12;:10;:12::i;:::-;43295:16;:37::i;:::-;43270:62;43248:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;43434:21;43443:2;43447:7;43434:8;:21::i;:::-;43117:346;43047:416;;:::o;60556:113::-;60617:7;60644:10;:17;;;;60637:24;;60556:113;:::o;44229:335::-;44424:41;44443:12;:10;:12::i;:::-;44457:7;44424:18;:41::i;:::-;44416:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;44528:28;44538:4;44544:2;44548:7;44528:9;:28::i;:::-;44229:335;;;:::o;60224:256::-;60321:7;60357:23;60374:5;60357:16;:23::i;:::-;60349:5;:31;60341:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;60446:12;:19;60459:5;60446:19;;;;;;;;;;;;;;;:26;60466:5;60446:26;;;;;;;;;;;;60439:33;;60224:256;;;;:::o;44635:185::-;44773:39;44790:4;44796:2;44800:7;44773:39;;;;;;;;;;;;:16;:39::i;:::-;44635:185;;;:::o;60746:233::-;60821:7;60857:30;:28;:30::i;:::-;60849:5;:38;60841:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;60954:10;60965:5;60954:17;;;;;;;;:::i;:::-;;;;;;;;;;60947:24;;60746:233;;;:::o;41727:223::-;41799:7;41819:13;41835:17;41844:7;41835:8;:17::i;:::-;41819:33;;41888:1;41871:19;;:5;:19;;;;41863:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;41937:5;41930:12;;;41727:223;;;:::o;41458:207::-;41530:7;41575:1;41558:19;;:5;:19;;;;41550:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;41641:9;:16;41651:5;41641:16;;;;;;;;;;;;;;;;41634:23;;41458:207;;;:::o;19440:103::-;18678:13;:11;:13::i;:::-;19505:30:::1;19532:1;19505:18;:30::i;:::-;19440:103::o:0;18792:87::-;18838:7;18865:6;;;;;;;;;;;18858:13;;18792:87;:::o;42186:104::-;42242:13;42275:7;42268:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42186:104;:::o;43772:155::-;43867:52;43886:12;:10;:12::i;:::-;43900:8;43910;43867:18;:52::i;:::-;43772:155;;:::o;44891:322::-;45065:41;45084:12;:10;:12::i;:::-;45098:7;45065:18;:41::i;:::-;45057:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;45167:38;45181:4;45187:2;45191:7;45200:4;45167:13;:38::i;:::-;44891:322;;;;:::o;66896:196::-;67023:13;67061:23;67076:7;67061:14;:23::i;:::-;67054:30;;66896:196;;;:::o;66143:310::-;18678:13;:11;:13::i;:::-;66233:14:::1;66250:13;:11;:13::i;:::-;66233:30;;66274:15;66292:25;:15;:23;:25::i;:::-;66274:43;;66333:9;66328:118;66348:3;66344:1;:7;66328:118;;;66369:25;66379:2;66392:1;66383:6;:10;;;;:::i;:::-;66369:9;:25::i;:::-;66405:29;66427:1;66418:6;:10;;;;:::i;:::-;66430:3;66405:12;:29::i;:::-;66353:3;;;;;:::i;:::-;;;;66328:118;;;;66222:231;;66143:310:::0;;;:::o;43998:164::-;44095:4;44119:18;:25;44138:5;44119:25;;;;;;;;;;;;;;;:35;44145:8;44119:35;;;;;;;;;;;;;;;;;;;;;;;;;44112:42;;43998:164;;;;:::o;19698:201::-;18678:13;:11;:13::i;:::-;19807:1:::1;19787:22;;:8;:22;;;;19779:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;19863:28;19882:8;19863:18;:28::i;:::-;19698:201:::0;:::o;59916:224::-;60018:4;60057:35;60042:50;;;:11;:50;;;;:90;;;;60096:36;60120:11;60096:23;:36::i;:::-;60042:90;60035:97;;59916:224;;;:::o;53348:135::-;53430:16;53438:7;53430;:16::i;:::-;53422:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;53348:135;:::o;17343:98::-;17396:7;17423:10;17416:17;;17343:98;:::o;52627:174::-;52729:2;52702:15;:24;52718:7;52702:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;52785:7;52781:2;52747:46;;52756:23;52771:7;52756:14;:23::i;:::-;52747:46;;;;;;;;;;;;52627:174;;:::o;47246:264::-;47339:4;47356:13;47372:23;47387:7;47372:14;:23::i;:::-;47356:39;;47425:5;47414:16;;:7;:16;;;:52;;;;47434:32;47451:5;47458:7;47434:16;:32::i;:::-;47414:52;:87;;;;47494:7;47470:31;;:20;47482:7;47470:11;:20::i;:::-;:31;;;47414:87;47406:96;;;47246:264;;;;:::o;51245:1263::-;51404:4;51377:31;;:23;51392:7;51377:14;:23::i;:::-;:31;;;51369:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;51483:1;51469:16;;:2;:16;;;;51461:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;51539:42;51560:4;51566:2;51570:7;51579:1;51539:20;:42::i;:::-;51711:4;51684:31;;:23;51699:7;51684:14;:23::i;:::-;:31;;;51676:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;51829:15;:24;51845:7;51829:24;;;;;;;;;;;;51822:31;;;;;;;;;;;52324:1;52305:9;:15;52315:4;52305:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;52357:1;52340:9;:13;52350:2;52340:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;52399:2;52380:7;:16;52388:7;52380:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;52438:7;52434:2;52419:27;;52428:4;52419:27;;;;;;;;;;;;52459:41;52479:4;52485:2;52489:7;52498:1;52459:19;:41::i;:::-;51245:1263;;;:::o;46521:117::-;46587:7;46614;:16;46622:7;46614:16;;;;;;;;;;;;;;;;;;;;;46607:23;;46521:117;;;:::o;18957:132::-;19032:12;:10;:12::i;:::-;19021:23;;:7;:5;:7::i;:::-;:23;;;19013:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;18957:132::o;20059:191::-;20133:16;20152:6;;;;;;;;;;;20133:25;;20178:8;20169:6;;:17;;;;;;;;;;;;;;;;;;20233:8;20202:40;;20223:8;20202:40;;;;;;;;;;;;20122:128;20059:191;:::o;52944:315::-;53099:8;53090:17;;:5;:17;;;;53082:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;53186:8;53148:18;:25;53167:5;53148:25;;;;;;;;;;;;;;;:35;53174:8;53148:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;53232:8;53210:41;;53225:5;53210:41;;;53242:8;53210:41;;;;;;:::i;:::-;;;;;;;;52944:315;;;:::o;46094:313::-;46250:28;46260:4;46266:2;46270:7;46250:9;:28::i;:::-;46297:47;46320:4;46326:2;46330:7;46339:4;46297:22;:47::i;:::-;46289:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;46094:313;;;;:::o;57455:624::-;57528:13;57554:23;57569:7;57554:14;:23::i;:::-;57590;57616:10;:19;57627:7;57616:19;;;;;;;;;;;57590:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57646:18;57667:10;:8;:10::i;:::-;57646:31;;57775:1;57759:4;57753:18;:23;57749:72;;;57800:9;57793:16;;;;;;57749:72;57951:1;57931:9;57925:23;:27;57921:108;;;58000:4;58006:9;57983:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57969:48;;;;;;57921:108;58048:23;58063:7;58048:14;:23::i;:::-;58041:30;;;;57455:624;;;;:::o;872:114::-;937:7;964;:14;;;957:21;;872:114;;;:::o;47852:110::-;47928:26;47938:2;47942:7;47928:26;;;;;;;;;;;;:9;:26::i;:::-;47852:110;;:::o;58235:217::-;58335:16;58343:7;58335;:16::i;:::-;58327:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;58435:9;58413:10;:19;58424:7;58413:19;;;;;;;;;;;:31;;;;;;;;;;;;:::i;:::-;;58235:217;;:::o;41089:305::-;41191:4;41243:25;41228:40;;;:11;:40;;;;:105;;;;41300:33;41285:48;;;:11;:48;;;;41228:105;:158;;;;41350:36;41374:11;41350:23;:36::i;:::-;41228:158;41208:178;;41089:305;;;:::o;46951:128::-;47016:4;47069:1;47040:31;;:17;47049:7;47040:8;:17::i;:::-;:31;;;;47033:38;;46951:128;;;:::o;66531:234::-;66701:56;66728:4;66734:2;66738:7;66747:9;66701:26;:56::i;:::-;66531:234;;;;:::o;56764:158::-;;;;;:::o;54047:853::-;54201:4;54222:15;:2;:13;;;:15::i;:::-;54218:675;;;54274:2;54258:36;;;54295:12;:10;:12::i;:::-;54309:4;54315:7;54324:4;54258:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;54254:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54516:1;54499:6;:13;:18;54495:328;;;54542:60;;;;;;;;;;:::i;:::-;;;;;;;;54495:328;54773:6;54767:13;54758:6;54754:2;54750:15;54743:38;54254:584;54390:41;;;54380:51;;;:6;:51;;;;54373:58;;;;;54218:675;54877:4;54870:11;;54047:853;;;;;;;:::o;42891:94::-;42942:13;42968:9;;;;;;;;;;;;;;42891:94;:::o;42361:281::-;42434:13;42460:23;42475:7;42460:14;:23::i;:::-;42496:21;42520:10;:8;:10::i;:::-;42496:34;;42572:1;42554:7;42548:21;:25;:86;;;;;;;;;;;;;;;;;42600:7;42609:18;:7;:16;:18::i;:::-;42583:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;42548:86;42541:93;;;42361:281;;;:::o;48189:319::-;48318:18;48324:2;48328:7;48318:5;:18::i;:::-;48369:53;48400:1;48404:2;48408:7;48417:4;48369:22;:53::i;:::-;48347:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;48189:319;;;:::o;32521:157::-;32606:4;32645:25;32630:40;;;:11;:40;;;;32623:47;;32521:157;;;:::o;61053:915::-;61230:61;61257:4;61263:2;61267:12;61281:9;61230:26;:61::i;:::-;61320:1;61308:9;:13;61304:222;;;61451:63;;;;;;;;;;:::i;:::-;;;;;;;;61304:222;61538:15;61556:12;61538:30;;61601:1;61585:18;;:4;:18;;;61581:187;;;61620:40;61652:7;61620:31;:40::i;:::-;61581:187;;;61690:2;61682:10;;:4;:10;;;61678:90;;61709:47;61742:4;61748:7;61709:32;:47::i;:::-;61678:90;61581:187;61796:1;61782:16;;:2;:16;;;61778:183;;;61815:45;61852:7;61815:36;:45::i;:::-;61778:183;;;61888:4;61882:10;;:2;:10;;;61878:83;;61909:40;61937:2;61941:7;61909:27;:40::i;:::-;61878:83;61778:183;61219:749;61053:915;;;;:::o;21490:326::-;21550:4;21807:1;21785:7;:19;;;:23;21778:30;;21490:326;;;:::o;14770:716::-;14826:13;14877:14;14914:1;14894:17;14905:5;14894:10;:17::i;:::-;:21;14877:38;;14930:20;14964:6;14953:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14930:41;;14986:11;15115:6;15111:2;15107:15;15099:6;15095:28;15088:35;;15152:288;15159:4;15152:288;;;15184:5;;;;;;;;15326:8;15321:2;15314:5;15310:14;15305:30;15300:3;15292:44;15382:2;15373:11;;;;;;:::i;:::-;;;;;15416:1;15407:5;:10;15403:21;;;15419:5;;15403:21;15152:288;;;15461:6;15454:13;;;;;14770:716;;;:::o;48844:942::-;48938:1;48924:16;;:2;:16;;;;48916:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;48997:16;49005:7;48997;:16::i;:::-;48996:17;48988:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;49059:48;49088:1;49092:2;49096:7;49105:1;49059:20;:48::i;:::-;49206:16;49214:7;49206;:16::i;:::-;49205:17;49197:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;49621:1;49604:9;:13;49614:2;49604:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;49665:2;49646:7;:16;49654:7;49646:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;49710:7;49706:2;49685:33;;49702:1;49685:33;;;;;;;;;;;;49731:47;49759:1;49763:2;49767:7;49776:1;49731:19;:47::i;:::-;48844:942;;:::o;55632:410::-;55822:1;55810:9;:13;55806:229;;;55860:1;55844:18;;:4;:18;;;55840:87;;55902:9;55883;:15;55893:4;55883:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;55840:87;55959:1;55945:16;;:2;:16;;;55941:83;;55999:9;55982;:13;55992:2;55982:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;55941:83;55806:229;55632:410;;;;:::o;62691:164::-;62795:10;:17;;;;62768:15;:24;62784:7;62768:24;;;;;;;;;;;:44;;;;62823:10;62839:7;62823:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62691:164;:::o;63482:988::-;63748:22;63798:1;63773:22;63790:4;63773:16;:22::i;:::-;:26;;;;:::i;:::-;63748:51;;63810:18;63831:17;:26;63849:7;63831:26;;;;;;;;;;;;63810:47;;63978:14;63964:10;:28;63960:328;;64009:19;64031:12;:18;64044:4;64031:18;;;;;;;;;;;;;;;:34;64050:14;64031:34;;;;;;;;;;;;64009:56;;64115:11;64082:12;:18;64095:4;64082:18;;;;;;;;;;;;;;;:30;64101:10;64082:30;;;;;;;;;;;:44;;;;64232:10;64199:17;:30;64217:11;64199:30;;;;;;;;;;;:43;;;;63994:294;63960:328;64384:17;:26;64402:7;64384:26;;;;;;;;;;;64377:33;;;64428:12;:18;64441:4;64428:18;;;;;;;;;;;;;;;:34;64447:14;64428:34;;;;;;;;;;;64421:41;;;63563:907;;63482:988;;:::o;64765:1079::-;65018:22;65063:1;65043:10;:17;;;;:21;;;;:::i;:::-;65018:46;;65075:18;65096:15;:24;65112:7;65096:24;;;;;;;;;;;;65075:45;;65447:19;65469:10;65480:14;65469:26;;;;;;;;:::i;:::-;;;;;;;;;;65447:48;;65533:11;65508:10;65519;65508:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;65644:10;65613:15;:28;65629:11;65613:28;;;;;;;;;;;:41;;;;65785:15;:24;65801:7;65785:24;;;;;;;;;;;65778:31;;;65820:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;64836:1008;;;64765:1079;:::o;62269:221::-;62354:14;62371:20;62388:2;62371:16;:20::i;:::-;62354:37;;62429:7;62402:12;:16;62415:2;62402:16;;;;;;;;;;;;;;;:24;62419:6;62402:24;;;;;;;;;;;:34;;;;62476:6;62447:17;:26;62465:7;62447:26;;;;;;;;;;;:35;;;;62343:147;62269:221;;:::o;11636:922::-;11689:7;11709:14;11726:1;11709:18;;11776:6;11767:5;:15;11763:102;;11812:6;11803:15;;;;;;:::i;:::-;;;;;11847:2;11837:12;;;;11763:102;11892:6;11883:5;:15;11879:102;;11928:6;11919:15;;;;;;:::i;:::-;;;;;11963:2;11953:12;;;;11879:102;12008:6;11999:5;:15;11995:102;;12044:6;12035:15;;;;;;:::i;:::-;;;;;12079:2;12069:12;;;;11995:102;12124:5;12115;:14;12111:99;;12159:5;12150:14;;;;;;:::i;:::-;;;;;12193:1;12183:11;;;;12111:99;12237:5;12228;:14;12224:99;;12272:5;12263:14;;;;;;:::i;:::-;;;;;12306:1;12296:11;;;;12224:99;12350:5;12341;:14;12337:99;;12385:5;12376:14;;;;;;:::i;:::-;;;;;12419:1;12409:11;;;;12337:99;12463:5;12454;:14;12450:66;;12499:1;12489:11;;;;12450:66;12544:6;12537:13;;;11636:922;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:118::-;5025:24;5043:5;5025:24;:::i;:::-;5020:3;5013:37;4938:118;;:::o;5062:222::-;5155:4;5193:2;5182:9;5178:18;5170:26;;5206:71;5274:1;5263:9;5259:17;5250:6;5206:71;:::i;:::-;5062:222;;;;:::o;5290:619::-;5367:6;5375;5383;5432:2;5420:9;5411:7;5407:23;5403:32;5400:119;;;5438:79;;:::i;:::-;5400:119;5558:1;5583:53;5628:7;5619:6;5608:9;5604:22;5583:53;:::i;:::-;5573:63;;5529:117;5685:2;5711:53;5756:7;5747:6;5736:9;5732:22;5711:53;:::i;:::-;5701:63;;5656:118;5813:2;5839:53;5884:7;5875:6;5864:9;5860:22;5839:53;:::i;:::-;5829:63;;5784:118;5290:619;;;;;:::o;5915:329::-;5974:6;6023:2;6011:9;6002:7;5998:23;5994:32;5991:119;;;6029:79;;:::i;:::-;5991:119;6149:1;6174:53;6219:7;6210:6;6199:9;6195:22;6174:53;:::i;:::-;6164:63;;6120:117;5915:329;;;;:::o;6250:116::-;6320:21;6335:5;6320:21;:::i;:::-;6313:5;6310:32;6300:60;;6356:1;6353;6346:12;6300:60;6250:116;:::o;6372:133::-;6415:5;6453:6;6440:20;6431:29;;6469:30;6493:5;6469:30;:::i;:::-;6372:133;;;;:::o;6511:468::-;6576:6;6584;6633:2;6621:9;6612:7;6608:23;6604:32;6601:119;;;6639:79;;:::i;:::-;6601:119;6759:1;6784:53;6829:7;6820:6;6809:9;6805:22;6784:53;:::i;:::-;6774:63;;6730:117;6886:2;6912:50;6954:7;6945:6;6934:9;6930:22;6912:50;:::i;:::-;6902:60;;6857:115;6511:468;;;;;:::o;6985:117::-;7094:1;7091;7084:12;7108:117;7217:1;7214;7207:12;7231:180;7279:77;7276:1;7269:88;7376:4;7373:1;7366:15;7400:4;7397:1;7390:15;7417:281;7500:27;7522:4;7500:27;:::i;:::-;7492:6;7488:40;7630:6;7618:10;7615:22;7594:18;7582:10;7579:34;7576:62;7573:88;;;7641:18;;:::i;:::-;7573:88;7681:10;7677:2;7670:22;7460:238;7417:281;;:::o;7704:129::-;7738:6;7765:20;;:::i;:::-;7755:30;;7794:33;7822:4;7814:6;7794:33;:::i;:::-;7704:129;;;:::o;7839:307::-;7900:4;7990:18;7982:6;7979:30;7976:56;;;8012:18;;:::i;:::-;7976:56;8050:29;8072:6;8050:29;:::i;:::-;8042:37;;8134:4;8128;8124:15;8116:23;;7839:307;;;:::o;8152:154::-;8236:6;8231:3;8226;8213:30;8298:1;8289:6;8284:3;8280:16;8273:27;8152:154;;;:::o;8312:410::-;8389:5;8414:65;8430:48;8471:6;8430:48;:::i;:::-;8414:65;:::i;:::-;8405:74;;8502:6;8495:5;8488:21;8540:4;8533:5;8529:16;8578:3;8569:6;8564:3;8560:16;8557:25;8554:112;;;8585:79;;:::i;:::-;8554:112;8675:41;8709:6;8704:3;8699;8675:41;:::i;:::-;8395:327;8312:410;;;;;:::o;8741:338::-;8796:5;8845:3;8838:4;8830:6;8826:17;8822:27;8812:122;;8853:79;;:::i;:::-;8812:122;8970:6;8957:20;8995:78;9069:3;9061:6;9054:4;9046:6;9042:17;8995:78;:::i;:::-;8986:87;;8802:277;8741:338;;;;:::o;9085:943::-;9180:6;9188;9196;9204;9253:3;9241:9;9232:7;9228:23;9224:33;9221:120;;;9260:79;;:::i;:::-;9221:120;9380:1;9405:53;9450:7;9441:6;9430:9;9426:22;9405:53;:::i;:::-;9395:63;;9351:117;9507:2;9533:53;9578:7;9569:6;9558:9;9554:22;9533:53;:::i;:::-;9523:63;;9478:118;9635:2;9661:53;9706:7;9697:6;9686:9;9682:22;9661:53;:::i;:::-;9651:63;;9606:118;9791:2;9780:9;9776:18;9763:32;9822:18;9814:6;9811:30;9808:117;;;9844:79;;:::i;:::-;9808:117;9949:62;10003:7;9994:6;9983:9;9979:22;9949:62;:::i;:::-;9939:72;;9734:287;9085:943;;;;;;;:::o;10034:308::-;10096:4;10186:18;10178:6;10175:30;10172:56;;;10208:18;;:::i;:::-;10172:56;10246:29;10268:6;10246:29;:::i;:::-;10238:37;;10330:4;10324;10320:15;10312:23;;10034:308;;;:::o;10348:412::-;10426:5;10451:66;10467:49;10509:6;10467:49;:::i;:::-;10451:66;:::i;:::-;10442:75;;10540:6;10533:5;10526:21;10578:4;10571:5;10567:16;10616:3;10607:6;10602:3;10598:16;10595:25;10592:112;;;10623:79;;:::i;:::-;10592:112;10713:41;10747:6;10742:3;10737;10713:41;:::i;:::-;10432:328;10348:412;;;;;:::o;10780:340::-;10836:5;10885:3;10878:4;10870:6;10866:17;10862:27;10852:122;;10893:79;;:::i;:::-;10852:122;11010:6;10997:20;11035:79;11110:3;11102:6;11095:4;11087:6;11083:17;11035:79;:::i;:::-;11026:88;;10842:278;10780:340;;;;:::o;11126:799::-;11213:6;11221;11229;11278:2;11266:9;11257:7;11253:23;11249:32;11246:119;;;11284:79;;:::i;:::-;11246:119;11404:1;11429:53;11474:7;11465:6;11454:9;11450:22;11429:53;:::i;:::-;11419:63;;11375:117;11531:2;11557:53;11602:7;11593:6;11582:9;11578:22;11557:53;:::i;:::-;11547:63;;11502:118;11687:2;11676:9;11672:18;11659:32;11718:18;11710:6;11707:30;11704:117;;;11740:79;;:::i;:::-;11704:117;11845:63;11900:7;11891:6;11880:9;11876:22;11845:63;:::i;:::-;11835:73;;11630:288;11126:799;;;;;:::o;11931:474::-;11999:6;12007;12056:2;12044:9;12035:7;12031:23;12027:32;12024:119;;;12062:79;;:::i;:::-;12024:119;12182:1;12207:53;12252:7;12243:6;12232:9;12228:22;12207:53;:::i;:::-;12197:63;;12153:117;12309:2;12335:53;12380:7;12371:6;12360:9;12356:22;12335:53;:::i;:::-;12325:63;;12280:118;11931:474;;;;;:::o;12411:180::-;12459:77;12456:1;12449:88;12556:4;12553:1;12546:15;12580:4;12577:1;12570:15;12597:320;12641:6;12678:1;12672:4;12668:12;12658:22;;12725:1;12719:4;12715:12;12746:18;12736:81;;12802:4;12794:6;12790:17;12780:27;;12736:81;12864:2;12856:6;12853:14;12833:18;12830:38;12827:84;;;12883:18;;:::i;:::-;12827:84;12648:269;12597:320;;;:::o;12923:220::-;13063:34;13059:1;13051:6;13047:14;13040:58;13132:3;13127:2;13119:6;13115:15;13108:28;12923:220;:::o;13149:366::-;13291:3;13312:67;13376:2;13371:3;13312:67;:::i;:::-;13305:74;;13388:93;13477:3;13388:93;:::i;:::-;13506:2;13501:3;13497:12;13490:19;;13149:366;;;:::o;13521:419::-;13687:4;13725:2;13714:9;13710:18;13702:26;;13774:9;13768:4;13764:20;13760:1;13749:9;13745:17;13738:47;13802:131;13928:4;13802:131;:::i;:::-;13794:139;;13521:419;;;:::o;13946:248::-;14086:34;14082:1;14074:6;14070:14;14063:58;14155:31;14150:2;14142:6;14138:15;14131:56;13946:248;:::o;14200:366::-;14342:3;14363:67;14427:2;14422:3;14363:67;:::i;:::-;14356:74;;14439:93;14528:3;14439:93;:::i;:::-;14557:2;14552:3;14548:12;14541:19;;14200:366;;;:::o;14572:419::-;14738:4;14776:2;14765:9;14761:18;14753:26;;14825:9;14819:4;14815:20;14811:1;14800:9;14796:17;14789:47;14853:131;14979:4;14853:131;:::i;:::-;14845:139;;14572:419;;;:::o;14997:232::-;15137:34;15133:1;15125:6;15121:14;15114:58;15206:15;15201:2;15193:6;15189:15;15182:40;14997:232;:::o;15235:366::-;15377:3;15398:67;15462:2;15457:3;15398:67;:::i;:::-;15391:74;;15474:93;15563:3;15474:93;:::i;:::-;15592:2;15587:3;15583:12;15576:19;;15235:366;;;:::o;15607:419::-;15773:4;15811:2;15800:9;15796:18;15788:26;;15860:9;15854:4;15850:20;15846:1;15835:9;15831:17;15824:47;15888:131;16014:4;15888:131;:::i;:::-;15880:139;;15607:419;;;:::o;16032:230::-;16172:34;16168:1;16160:6;16156:14;16149:58;16241:13;16236:2;16228:6;16224:15;16217:38;16032:230;:::o;16268:366::-;16410:3;16431:67;16495:2;16490:3;16431:67;:::i;:::-;16424:74;;16507:93;16596:3;16507:93;:::i;:::-;16625:2;16620:3;16616:12;16609:19;;16268:366;;;:::o;16640:419::-;16806:4;16844:2;16833:9;16829:18;16821:26;;16893:9;16887:4;16883:20;16879:1;16868:9;16864:17;16857:47;16921:131;17047:4;16921:131;:::i;:::-;16913:139;;16640:419;;;:::o;17065:231::-;17205:34;17201:1;17193:6;17189:14;17182:58;17274:14;17269:2;17261:6;17257:15;17250:39;17065:231;:::o;17302:366::-;17444:3;17465:67;17529:2;17524:3;17465:67;:::i;:::-;17458:74;;17541:93;17630:3;17541:93;:::i;:::-;17659:2;17654:3;17650:12;17643:19;;17302:366;;;:::o;17674:419::-;17840:4;17878:2;17867:9;17863:18;17855:26;;17927:9;17921:4;17917:20;17913:1;17902:9;17898:17;17891:47;17955:131;18081:4;17955:131;:::i;:::-;17947:139;;17674:419;;;:::o;18099:180::-;18147:77;18144:1;18137:88;18244:4;18241:1;18234:15;18268:4;18265:1;18258:15;18285:174;18425:26;18421:1;18413:6;18409:14;18402:50;18285:174;:::o;18465:366::-;18607:3;18628:67;18692:2;18687:3;18628:67;:::i;:::-;18621:74;;18704:93;18793:3;18704:93;:::i;:::-;18822:2;18817:3;18813:12;18806:19;;18465:366;;;:::o;18837:419::-;19003:4;19041:2;19030:9;19026:18;19018:26;;19090:9;19084:4;19080:20;19076:1;19065:9;19061:17;19054:47;19118:131;19244:4;19118:131;:::i;:::-;19110:139;;18837:419;;;:::o;19262:228::-;19402:34;19398:1;19390:6;19386:14;19379:58;19471:11;19466:2;19458:6;19454:15;19447:36;19262:228;:::o;19496:366::-;19638:3;19659:67;19723:2;19718:3;19659:67;:::i;:::-;19652:74;;19735:93;19824:3;19735:93;:::i;:::-;19853:2;19848:3;19844:12;19837:19;;19496:366;;;:::o;19868:419::-;20034:4;20072:2;20061:9;20057:18;20049:26;;20121:9;20115:4;20111:20;20107:1;20096:9;20092:17;20085:47;20149:131;20275:4;20149:131;:::i;:::-;20141:139;;19868:419;;;:::o;20293:180::-;20341:77;20338:1;20331:88;20438:4;20435:1;20428:15;20462:4;20459:1;20452:15;20479:305;20519:3;20538:20;20556:1;20538:20;:::i;:::-;20533:25;;20572:20;20590:1;20572:20;:::i;:::-;20567:25;;20726:1;20658:66;20654:74;20651:1;20648:81;20645:107;;;20732:18;;:::i;:::-;20645:107;20776:1;20773;20769:9;20762:16;;20479:305;;;;:::o;20790:233::-;20829:3;20852:24;20870:5;20852:24;:::i;:::-;20843:33;;20898:66;20891:5;20888:77;20885:103;;;20968:18;;:::i;:::-;20885:103;21015:1;21008:5;21004:13;20997:20;;20790:233;;;:::o;21029:225::-;21169:34;21165:1;21157:6;21153:14;21146:58;21238:8;21233:2;21225:6;21221:15;21214:33;21029:225;:::o;21260:366::-;21402:3;21423:67;21487:2;21482:3;21423:67;:::i;:::-;21416:74;;21499:93;21588:3;21499:93;:::i;:::-;21617:2;21612:3;21608:12;21601:19;;21260:366;;;:::o;21632:419::-;21798:4;21836:2;21825:9;21821:18;21813:26;;21885:9;21879:4;21875:20;21871:1;21860:9;21856:17;21849:47;21913:131;22039:4;21913:131;:::i;:::-;21905:139;;21632:419;;;:::o;22057:224::-;22197:34;22193:1;22185:6;22181:14;22174:58;22266:7;22261:2;22253:6;22249:15;22242:32;22057:224;:::o;22287:366::-;22429:3;22450:67;22514:2;22509:3;22450:67;:::i;:::-;22443:74;;22526:93;22615:3;22526:93;:::i;:::-;22644:2;22639:3;22635:12;22628:19;;22287:366;;;:::o;22659:419::-;22825:4;22863:2;22852:9;22848:18;22840:26;;22912:9;22906:4;22902:20;22898:1;22887:9;22883:17;22876:47;22940:131;23066:4;22940:131;:::i;:::-;22932:139;;22659:419;;;:::o;23084:223::-;23224:34;23220:1;23212:6;23208:14;23201:58;23293:6;23288:2;23280:6;23276:15;23269:31;23084:223;:::o;23313:366::-;23455:3;23476:67;23540:2;23535:3;23476:67;:::i;:::-;23469:74;;23552:93;23641:3;23552:93;:::i;:::-;23670:2;23665:3;23661:12;23654:19;;23313:366;;;:::o;23685:419::-;23851:4;23889:2;23878:9;23874:18;23866:26;;23938:9;23932:4;23928:20;23924:1;23913:9;23909:17;23902:47;23966:131;24092:4;23966:131;:::i;:::-;23958:139;;23685:419;;;:::o;24110:182::-;24250:34;24246:1;24238:6;24234:14;24227:58;24110:182;:::o;24298:366::-;24440:3;24461:67;24525:2;24520:3;24461:67;:::i;:::-;24454:74;;24537:93;24626:3;24537:93;:::i;:::-;24655:2;24650:3;24646:12;24639:19;;24298:366;;;:::o;24670:419::-;24836:4;24874:2;24863:9;24859:18;24851:26;;24923:9;24917:4;24913:20;24909:1;24898:9;24894:17;24887:47;24951:131;25077:4;24951:131;:::i;:::-;24943:139;;24670:419;;;:::o;25095:175::-;25235:27;25231:1;25223:6;25219:14;25212:51;25095:175;:::o;25276:366::-;25418:3;25439:67;25503:2;25498:3;25439:67;:::i;:::-;25432:74;;25515:93;25604:3;25515:93;:::i;:::-;25633:2;25628:3;25624:12;25617:19;;25276:366;;;:::o;25648:419::-;25814:4;25852:2;25841:9;25837:18;25829:26;;25901:9;25895:4;25891:20;25887:1;25876:9;25872:17;25865:47;25929:131;26055:4;25929:131;:::i;:::-;25921:139;;25648:419;;;:::o;26073:237::-;26213:34;26209:1;26201:6;26197:14;26190:58;26282:20;26277:2;26269:6;26265:15;26258:45;26073:237;:::o;26316:366::-;26458:3;26479:67;26543:2;26538:3;26479:67;:::i;:::-;26472:74;;26555:93;26644:3;26555:93;:::i;:::-;26673:2;26668:3;26664:12;26657:19;;26316:366;;;:::o;26688:419::-;26854:4;26892:2;26881:9;26877:18;26869:26;;26941:9;26935:4;26931:20;26927:1;26916:9;26912:17;26905:47;26969:131;27095:4;26969:131;:::i;:::-;26961:139;;26688:419;;;:::o;27113:148::-;27215:11;27252:3;27237:18;;27113:148;;;;:::o;27267:377::-;27373:3;27401:39;27434:5;27401:39;:::i;:::-;27456:89;27538:6;27533:3;27456:89;:::i;:::-;27449:96;;27554:52;27599:6;27594:3;27587:4;27580:5;27576:16;27554:52;:::i;:::-;27631:6;27626:3;27622:16;27615:23;;27377:267;27267:377;;;;:::o;27650:435::-;27830:3;27852:95;27943:3;27934:6;27852:95;:::i;:::-;27845:102;;27964:95;28055:3;28046:6;27964:95;:::i;:::-;27957:102;;28076:3;28069:10;;27650:435;;;;;:::o;28091:233::-;28231:34;28227:1;28219:6;28215:14;28208:58;28300:16;28295:2;28287:6;28283:15;28276:41;28091:233;:::o;28330:366::-;28472:3;28493:67;28557:2;28552:3;28493:67;:::i;:::-;28486:74;;28569:93;28658:3;28569:93;:::i;:::-;28687:2;28682:3;28678:12;28671:19;;28330:366;;;:::o;28702:419::-;28868:4;28906:2;28895:9;28891:18;28883:26;;28955:9;28949:4;28945:20;28941:1;28930:9;28926:17;28919:47;28983:131;29109:4;28983:131;:::i;:::-;28975:139;;28702:419;;;:::o;29127:98::-;29178:6;29212:5;29206:12;29196:22;;29127:98;;;:::o;29231:168::-;29314:11;29348:6;29343:3;29336:19;29388:4;29383:3;29379:14;29364:29;;29231:168;;;;:::o;29405:360::-;29491:3;29519:38;29551:5;29519:38;:::i;:::-;29573:70;29636:6;29631:3;29573:70;:::i;:::-;29566:77;;29652:52;29697:6;29692:3;29685:4;29678:5;29674:16;29652:52;:::i;:::-;29729:29;29751:6;29729:29;:::i;:::-;29724:3;29720:39;29713:46;;29495:270;29405:360;;;;:::o;29771:640::-;29966:4;30004:3;29993:9;29989:19;29981:27;;30018:71;30086:1;30075:9;30071:17;30062:6;30018:71;:::i;:::-;30099:72;30167:2;30156:9;30152:18;30143:6;30099:72;:::i;:::-;30181;30249:2;30238:9;30234:18;30225:6;30181:72;:::i;:::-;30300:9;30294:4;30290:20;30285:2;30274:9;30270:18;30263:48;30328:76;30399:4;30390:6;30328:76;:::i;:::-;30320:84;;29771:640;;;;;;;:::o;30417:141::-;30473:5;30504:6;30498:13;30489:22;;30520:32;30546:5;30520:32;:::i;:::-;30417:141;;;;:::o;30564:349::-;30633:6;30682:2;30670:9;30661:7;30657:23;30653:32;30650:119;;;30688:79;;:::i;:::-;30650:119;30808:1;30833:63;30888:7;30879:6;30868:9;30864:22;30833:63;:::i;:::-;30823:73;;30779:127;30564:349;;;;:::o;30919:240::-;31059:34;31055:1;31047:6;31043:14;31036:58;31128:23;31123:2;31115:6;31111:15;31104:48;30919:240;:::o;31165:366::-;31307:3;31328:67;31392:2;31387:3;31328:67;:::i;:::-;31321:74;;31404:93;31493:3;31404:93;:::i;:::-;31522:2;31517:3;31513:12;31506:19;;31165:366;;;:::o;31537:419::-;31703:4;31741:2;31730:9;31726:18;31718:26;;31790:9;31784:4;31780:20;31776:1;31765:9;31761:17;31754:47;31818:131;31944:4;31818:131;:::i;:::-;31810:139;;31537:419;;;:::o;31962:180::-;32010:77;32007:1;32000:88;32107:4;32104:1;32097:15;32131:4;32128:1;32121:15;32148:182;32288:34;32284:1;32276:6;32272:14;32265:58;32148:182;:::o;32336:366::-;32478:3;32499:67;32563:2;32558:3;32499:67;:::i;:::-;32492:74;;32575:93;32664:3;32575:93;:::i;:::-;32693:2;32688:3;32684:12;32677:19;;32336:366;;;:::o;32708:419::-;32874:4;32912:2;32901:9;32897:18;32889:26;;32961:9;32955:4;32951:20;32947:1;32936:9;32932:17;32925:47;32989:131;33115:4;32989:131;:::i;:::-;32981:139;;32708:419;;;:::o;33133:178::-;33273:30;33269:1;33261:6;33257:14;33250:54;33133:178;:::o;33317:366::-;33459:3;33480:67;33544:2;33539:3;33480:67;:::i;:::-;33473:74;;33556:93;33645:3;33556:93;:::i;:::-;33674:2;33669:3;33665:12;33658:19;;33317:366;;;:::o;33689:419::-;33855:4;33893:2;33882:9;33878:18;33870:26;;33942:9;33936:4;33932:20;33928:1;33917:9;33913:17;33906:47;33970:131;34096:4;33970:131;:::i;:::-;33962:139;;33689:419;;;:::o;34114:191::-;34154:4;34174:20;34192:1;34174:20;:::i;:::-;34169:25;;34208:20;34226:1;34208:20;:::i;:::-;34203:25;;34247:1;34244;34241:8;34238:34;;;34252:18;;:::i;:::-;34238:34;34297:1;34294;34290:9;34282:17;;34114:191;;;;:::o;34311:180::-;34359:77;34356:1;34349:88;34456:4;34453:1;34446:15;34480:4;34477:1;34470:15
Swarm Source
ipfs://7c462ff4d72db6c87bac0b54ceb71f8bc32f5b7fb1c8b1ab93661ef8c698a271
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.