Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 23026372 | 228 days ago | 0.00313465 ETH | ||||
| Transfer | 23026367 | 228 days ago | 0.00313465 ETH | ||||
| Transfer | 23026354 | 228 days ago | 0.00370459 ETH | ||||
| Transfer | 23026348 | 228 days ago | 0.00370459 ETH | ||||
| Transfer | 23026337 | 228 days ago | 0.00452783 ETH | ||||
| Transfer | 23025109 | 229 days ago | 0.00452783 ETH | ||||
| Transfer | 23025093 | 229 days ago | 0.00452783 ETH | ||||
| Transfer | 23025080 | 229 days ago | 0.0058215 ETH | ||||
| Transfer | 23025071 | 229 days ago | 0.0058215 ETH | ||||
| Transfer | 23025062 | 229 days ago | 0.0058215 ETH | ||||
| Transfer | 23024872 | 229 days ago | 0.0081501 ETH | ||||
| Transfer | 23024864 | 229 days ago | 0.0081501 ETH | ||||
| Transfer | 23024857 | 229 days ago | 0.0081501 ETH | ||||
| Transfer | 23024851 | 229 days ago | 0.0081501 ETH | ||||
| Transfer | 23024842 | 229 days ago | 0.0081501 ETH | ||||
| Transfer | 23024832 | 229 days ago | 0.0081501 ETH | ||||
| Transfer | 23024717 | 229 days ago | 0.0135835 ETH | ||||
| Transfer | 23024712 | 229 days ago | 0.0135835 ETH | ||||
| Transfer | 23024707 | 229 days ago | 0.0135835 ETH | ||||
| Transfer | 23024701 | 229 days ago | 0.0135835 ETH | ||||
| Transfer | 23024689 | 229 days ago | 0.0135835 ETH | ||||
| Transfer | 23024680 | 229 days ago | 0.0135835 ETH | ||||
| Transfer | 19809201 | 678 days ago | 0.00063957 ETH | ||||
| Transfer | 18944167 | 799 days ago | 0.00266107 ETH | ||||
| Transfer | 18865235 | 810 days ago | 0.0009198 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TamagotchiERC721
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2023-12-18
*/
// TamaBlockChi.com Game v 1.00
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
// File: tamanft_flattened.sol
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
// 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/interfaces/draft-IERC6093.sol
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
// File: @openzeppelin/contracts/utils/math/SignedMath.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}
// File: @openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Muldiv operation overflow.
*/
error MathOverflowedMulDiv();
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
return a / b;
}
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
* Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0 = x * y; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator.
// Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
uint256 twos = denominator & (0 - denominator);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
// works in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
// File: @openzeppelin/contracts/utils/Strings.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)
pragma solidity ^0.8.20;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
/**
* @dev The `value` string doesn't fit in the specified `length`.
*/
error StringsInsufficientHexLength(uint256 value, uint256 length);
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
uint256 localValue = value;
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
* representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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/token/ERC721/IERC721Receiver.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.20;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be
* reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @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 (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// File: @openzeppelin/contracts/token/ERC721/IERC721.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.20;
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
* {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.20;
/**
* @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 (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.20;
/**
* @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 v5.0.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.20;
/**
* @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}.
*/
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
mapping(uint256 tokenId => address) private _owners;
mapping(address owner => uint256) private _balances;
mapping(uint256 tokenId => address) private _tokenApprovals;
mapping(address owner => mapping(address operator => 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 returns (uint256) {
if (owner == address(0)) {
revert ERC721InvalidOwner(address(0));
}
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual returns (address) {
return _requireOwned(tokenId);
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
_requireOwned(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string.concat(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 {
_approve(to, tokenId, _msgSender());
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual returns (address) {
_requireOwned(tokenId);
return _getApproved(tokenId);
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(address from, address to, uint256 tokenId) public virtual {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
// Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists
// (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.
address previousOwner = _update(to, tokenId, _msgSender());
if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
transferFrom(from, to, tokenId);
_checkOnERC721Received(from, to, tokenId, data);
}
/**
* @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
*
* IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
* core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances
* consistent with ownership. The invariant to preserve is that for any address `a` the value returned by
* `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.
*/
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
/**
* @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.
*/
function _getApproved(uint256 tokenId) internal view virtual returns (address) {
return _tokenApprovals[tokenId];
}
/**
* @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in
* particular (ignoring whether it is owned by `owner`).
*
* WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
* assumption.
*/
function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
return
spender != address(0) &&
(owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
}
/**
* @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.
* Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets
* the `spender` for the specific `tokenId`.
*
* WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
* assumption.
*/
function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
if (!_isAuthorized(owner, spender, tokenId)) {
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else {
revert ERC721InsufficientApproval(spender, tokenId);
}
}
}
/**
* @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
*
* NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that
* a uint256 would ever overflow from increments when these increments are bounded to uint128 values.
*
* WARNING: Increasing an account's balance using this function tends to be paired with an override of the
* {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership
* remain consistent with one another.
*/
function _increaseBalance(address account, uint128 value) internal virtual {
unchecked {
_balances[account] += value;
}
}
/**
* @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner
* (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.
*
* The `auth` argument is optional. If the value passed is non 0, then this function will check that
* `auth` is either the owner of the token, or approved to operate on the token (by the owner).
*
* Emits a {Transfer} event.
*
* NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.
*/
function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
address from = _ownerOf(tokenId);
// Perform (optional) operator check
if (auth != address(0)) {
_checkAuthorized(from, auth, tokenId);
}
// Execute the update
if (from != address(0)) {
// Clear approval. No need to re-authorize or emit the Approval event
_approve(address(0), tokenId, address(0), false);
unchecked {
_balances[from] -= 1;
}
}
if (to != address(0)) {
unchecked {
_balances[to] += 1;
}
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
return from;
}
/**
* @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 {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner != address(0)) {
revert ERC721InvalidSender(address(0));
}
}
/**
* @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.
*
* 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 {
_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);
_checkOnERC721Received(address(0), to, tokenId, data);
}
/**
* @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 {
address previousOwner = _update(address(0), tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
}
/**
* @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 {
if (to == address(0)) {
revert ERC721InvalidReceiver(address(0));
}
address previousOwner = _update(to, tokenId, address(0));
if (previousOwner == address(0)) {
revert ERC721NonexistentToken(tokenId);
} else if (previousOwner != from) {
revert ERC721IncorrectOwner(from, tokenId, previousOwner);
}
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients
* are aware of the ERC721 standard 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 like {safeTransferFrom} in the sense that it invokes
* {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `tokenId` token must exist and be owned by `from`.
* - `to` cannot be the zero address.
* - `from` cannot be the zero address.
* - 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) internal {
_safeTransfer(from, to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
_transfer(from, to, tokenId);
_checkOnERC721Received(from, to, tokenId, data);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is
* either the owner of the token, or approved to operate on all tokens held by this owner.
*
* Emits an {Approval} event.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address to, uint256 tokenId, address auth) internal {
_approve(to, tokenId, auth, true);
}
/**
* @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not
* emitted in the context of transfers.
*/
function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {
// Avoid reading the owner unless necessary
if (emitEvent || auth != address(0)) {
address owner = _requireOwned(tokenId);
// We do not use _isAuthorized because single-token approvals should not be able to call approve
if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
revert ERC721InvalidApprover(auth);
}
if (emitEvent) {
emit Approval(owner, to, tokenId);
}
}
_tokenApprovals[tokenId] = to;
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Requirements:
* - operator can't be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
if (operator == address(0)) {
revert ERC721InvalidOperator(operator);
}
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).
* Returns the owner.
*
* Overrides to ownership logic should be done to {_ownerOf}.
*/
function _requireOwned(uint256 tokenId) internal view returns (address) {
address owner = _ownerOf(tokenId);
if (owner == address(0)) {
revert ERC721NonexistentToken(tokenId);
}
return owner;
}
/**
* @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the
* recipient doesn't accept the token transfer. 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
*/
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
if (to.code.length > 0) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
if (retval != IERC721Receiver.onERC721Received.selector) {
revert ERC721InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
revert ERC721InvalidReceiver(to);
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
}
// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Enumerable.sol)
pragma solidity ^0.8.20;
/**
* @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.
*
* CAUTION: `ERC721` extensions that implement custom `balanceOf` logic, such as `ERC721Consecutive`,
* interfere with enumerability and should not be used together with `ERC721Enumerable`.
*/
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
mapping(address owner => mapping(uint256 index => uint256)) private _ownedTokens;
mapping(uint256 tokenId => uint256) private _ownedTokensIndex;
uint256[] private _allTokens;
mapping(uint256 tokenId => uint256) private _allTokensIndex;
/**
* @dev An `owner`'s token query was out of bounds for `index`.
*
* NOTE: The owner being `address(0)` indicates a global out of bounds index.
*/
error ERC721OutOfBoundsIndex(address owner, uint256 index);
/**
* @dev Batch mint is not allowed.
*/
error ERC721EnumerableForbiddenBatchMint();
/**
* @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 returns (uint256) {
if (index >= balanceOf(owner)) {
revert ERC721OutOfBoundsIndex(owner, index);
}
return _ownedTokens[owner][index];
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _allTokens.length;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual returns (uint256) {
if (index >= totalSupply()) {
revert ERC721OutOfBoundsIndex(address(0), index);
}
return _allTokens[index];
}
/**
* @dev See {ERC721-_update}.
*/
function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {
address previousOwner = super._update(to, tokenId, auth);
if (previousOwner == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (previousOwner != to) {
_removeTokenFromOwnerEnumeration(previousOwner, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (previousOwner != to) {
_addTokenToOwnerEnumeration(to, tokenId);
}
return previousOwner;
}
/**
* @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 = balanceOf(to) - 1;
_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 = balanceOf(from);
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();
}
/**
* See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch
*/
function _increaseBalance(address account, uint128 amount) internal virtual override {
if (amount > 0) {
revert ERC721EnumerableForbiddenBatchMint();
}
super._increaseBalance(account, amount);
}
}
// File: tamanft.sol
pragma solidity ^0.8.20;
contract TamagotchiERC721 is ERC721Enumerable, ReentrancyGuard {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
uint256 public totalGoldStored;
uint256 public totalETHAvailable;
mapping(address => bool) public hasMinted;
IERC20 public paymentToken;
uint256 public mintPrice;
struct Tamagotchi {
uint8 level;
uint8 experience;
uint8 experienceRequired;
uint256 storedGold;
uint256 lastCheckedBlock;
uint8 action;
uint8 imageId;
}
constructor(address _paymentTokenAddress, uint256 _mintPrice) ERC721("TamagotchiToken", "TAMA") {
paymentToken = IERC20(_paymentTokenAddress);
mintPrice = _mintPrice;
}
Tamagotchi[] public tamagotchis;
mapping(address => uint256) private _ownerToPets;
function mintTamagotchi(address to) public {
require(!hasMinted[to], "Each wallet can only mint one token.");
require(paymentToken.balanceOf(msg.sender) >= mintPrice, "Insufficient token balance.");
require(paymentToken.allowance(msg.sender, address(this)) >= mintPrice, "Insufficient token allowance.");
paymentToken.transferFrom(msg.sender, address(this), mintPrice);
_tokenIds.increment();
uint256 tamagotchiId = _tokenIds.current();
_mint(to, tamagotchiId);
// Set initial values for the new Tamagotchi
Tamagotchi memory newTamagotchi = Tamagotchi({
level: 1, // Setting the level to 1 as default
experience: 0,
experienceRequired: 13,
storedGold: 0,
lastCheckedBlock: block.number,
action: 0,
imageId: 0
});
tamagotchis.push(newTamagotchi);
_ownerToPets[to] = tamagotchiId;
hasMinted[to] = true;
}
uint256 private constant BLOCKS_TO_WAIT = 140;
uint256 private constant SPECIAL_COOKIE_PRICE = 100;
uint256 private constant SPECIAL_COOKIE_EXP = 3;
event ActionDecided(uint256 indexed tamagotchiId, uint8 action);
function randomUsingTxDetails() public view returns (uint256) {
return uint256(keccak256(abi.encodePacked(block.prevrandao, block.timestamp, msg.sender)));
}
receive() external payable {
totalETHAvailable += msg.value;
}
function pet(uint256 _tamagotchiId) external {
require(_tamagotchiId > 0 && _tamagotchiId <= tamagotchis.length, "Tamagotchi does not exist.");
Tamagotchi storage tamagotchi = tamagotchis[_tamagotchiId - 1];
require(block.number >= tamagotchi.lastCheckedBlock + BLOCKS_TO_WAIT, "You must wait more blocks before petting again.");
// Randomly determine the action to be taken
uint256 randomValue = randomUsingTxDetails();
tamagotchi.action = uint8(randomValue % 6 + 1); // Ensures the action is between 1 and 6
emit ActionDecided(_tamagotchiId, tamagotchi.action);
}
function petAction(uint256 _tamagotchiId) external {
Tamagotchi storage tamagotchi = tamagotchis[_tamagotchiId - 1];
require(tamagotchi.action < 8);
require(block.number >= tamagotchi.lastCheckedBlock + BLOCKS_TO_WAIT, "You must wait more blocks before performing an action.");
// Perform action based on the decided action.
if (tamagotchi.action >= 1 && tamagotchi.action <= 4) { // Feed, Water, Cheer, Train
tamagotchi.experience += 1;
} else if (tamagotchi.action == 5) { // Special Cookie
tamagotchi.experience += uint8(SPECIAL_COOKIE_EXP);
} else if (tamagotchi.action == 6) { // Poop Gold
tamagotchi.storedGold += tamagotchi.level;
totalGoldStored += tamagotchi.level;
}
// Level up if experience is over the required amount.
if (tamagotchi.experience >= tamagotchi.experienceRequired) {
tamagotchi.level += 1;
tamagotchi.experienceRequired = tamagotchi.level * 13;
tamagotchi.experience = 0;
}
tamagotchi.action = 9;
tamagotchi.lastCheckedBlock = block.number;
}
function viewPetAndStats(address owner) external view returns (uint256 petId, uint8 level, uint8 experience, uint8 experienceRequired, uint256 storedGold, uint8 action, uint256 lastCheckedBlock, uint256 currentblock) {
petId = _ownerToPets[owner];
if (petId != 0) {
Tamagotchi storage tamagotchi = tamagotchis[petId - 1];
currentblock = block.number;
return (petId, tamagotchi.level, tamagotchi.experience, tamagotchi.experienceRequired, tamagotchi.storedGold, tamagotchi.action, tamagotchi.lastCheckedBlock, currentblock);
} else {
// Handle the case where the owner does not have any pets
revert("Owner does not have a pet.");
}
}
function convertGoldToETHAndWithdraw(uint256 _tamagotchiId) external nonReentrant {
// Checks
require(_tamagotchiId > 0 && _tamagotchiId <= tamagotchis.length, "Tamagotchi does not exist.");
require(ownerOf(_tamagotchiId) == msg.sender, "Caller is not the owner of the NFT.");
Tamagotchi storage tamagotchiToUpdate = tamagotchis[_tamagotchiId - 1];
require(tamagotchiToUpdate.level >= 2, "Pet level must be at least 2.");
uint256 goldAmount = tamagotchiToUpdate.storedGold;
require(goldAmount > 0, "No gold to convert.");
require(totalGoldStored > 0, "Total gold is zero, cannot calculate conversion rate.");
// Effects
uint256 conversionRate = (totalETHAvailable / 10) / totalGoldStored;
uint256 ethAmount = goldAmount * conversionRate;
require((address(this).balance / 10) >= ethAmount, "Insufficient ETH in contract for withdrawal.");
tamagotchiToUpdate.storedGold = 0;
totalGoldStored -= goldAmount;
payable(msg.sender).transfer(ethAmount);
}
function totalStoredGold() external view returns (uint256) {
uint256 totalGold = 0;
for (uint256 i = 0; i < tamagotchis.length; i++) {
Tamagotchi storage tamagotchi = tamagotchis[i];
if (tamagotchi.level > 2) {
totalGold += tamagotchi.storedGold;
}
}
return totalGold;
}
function calculateTotalETHClaim(address _owner) public view returns (uint256) {
uint256 ownerBalance = balanceOf(_owner);
uint256 totalClaimableETH = 0;
for (uint256 i = 0; i < ownerBalance; i++) {
uint256 tamagotchiId = tokenOfOwnerByIndex(_owner, i);
Tamagotchi memory tamagotchi = tamagotchis[tamagotchiId - 1];
if (tamagotchi.level >= 2) {
uint256 goldAmount = tamagotchi.storedGold;
uint256 conversionRate = (totalETHAvailable / 10) / totalGoldStored;
uint256 ethAmount = goldAmount * conversionRate;
totalClaimableETH += ethAmount;
}
}
return totalClaimableETH;
}
function getTamagotchiStats(uint256 _tamagotchiId) external view returns (uint8 level, uint8 experience, uint8 experienceRequired, uint256 storedGold, uint8 action, uint256 lastCheckedBlock) {
require(_tamagotchiId > 0 && _tamagotchiId <= tamagotchis.length, "Tamagotchi does not exist.");
Tamagotchi storage tamagotchi = tamagotchis[_tamagotchiId - 1];
return (tamagotchi.level, tamagotchi.experience, tamagotchi.experienceRequired, tamagotchi.storedGold, tamagotchi.action, tamagotchi.lastCheckedBlock);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_paymentTokenAddress","type":"address"},{"internalType":"uint256","name":"_mintPrice","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC721EnumerableForbiddenBatchMint","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ERC721OutOfBoundsIndex","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tamagotchiId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"action","type":"uint8"}],"name":"ActionDecided","type":"event"},{"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":"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":"address","name":"_owner","type":"address"}],"name":"calculateTotalETHClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tamagotchiId","type":"uint256"}],"name":"convertGoldToETHAndWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tamagotchiId","type":"uint256"}],"name":"getTamagotchiStats","outputs":[{"internalType":"uint8","name":"level","type":"uint8"},{"internalType":"uint8","name":"experience","type":"uint8"},{"internalType":"uint8","name":"experienceRequired","type":"uint8"},{"internalType":"uint256","name":"storedGold","type":"uint256"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint256","name":"lastCheckedBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mintTamagotchi","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"paymentToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tamagotchiId","type":"uint256"}],"name":"pet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tamagotchiId","type":"uint256"}],"name":"petAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"randomUsingTxDetails","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":"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":"","type":"uint256"}],"name":"tamagotchis","outputs":[{"internalType":"uint8","name":"level","type":"uint8"},{"internalType":"uint8","name":"experience","type":"uint8"},{"internalType":"uint8","name":"experienceRequired","type":"uint8"},{"internalType":"uint256","name":"storedGold","type":"uint256"},{"internalType":"uint256","name":"lastCheckedBlock","type":"uint256"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint8","name":"imageId","type":"uint8"}],"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":"totalETHAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGoldStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStoredGold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"viewPetAndStats","outputs":[{"internalType":"uint256","name":"petId","type":"uint256"},{"internalType":"uint8","name":"level","type":"uint8"},{"internalType":"uint8","name":"experience","type":"uint8"},{"internalType":"uint8","name":"experienceRequired","type":"uint8"},{"internalType":"uint256","name":"storedGold","type":"uint256"},{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"uint256","name":"lastCheckedBlock","type":"uint256"},{"internalType":"uint256","name":"currentblock","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608060405234801562000010575f80fd5b50604051620049ce380380620049ce8339818101604052810190620000369190620001bb565b6040518060400160405280600f81526020017f54616d61676f74636869546f6b656e00000000000000000000000000000000008152506040518060400160405280600481526020017f54414d4100000000000000000000000000000000000000000000000000000000815250815f9081620000b291906200045b565b508060019081620000c491906200045b565b5050506001600a8190555081600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060108190555050506200053f565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200014d8262000122565b9050919050565b6200015f8162000141565b81146200016a575f80fd5b50565b5f815190506200017d8162000154565b92915050565b5f819050919050565b620001978162000183565b8114620001a2575f80fd5b50565b5f81519050620001b5816200018c565b92915050565b5f8060408385031215620001d457620001d36200011e565b5b5f620001e3858286016200016d565b9250506020620001f685828601620001a5565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200027c57607f821691505b60208210810362000292576200029162000237565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620002f67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002b9565b620003028683620002b9565b95508019841693508086168417925050509392505050565b5f819050919050565b5f620003436200033d620003378462000183565b6200031a565b62000183565b9050919050565b5f819050919050565b6200035e8362000323565b620003766200036d826200034a565b848454620002c5565b825550505050565b5f90565b6200038c6200037e565b6200039981848462000353565b505050565b5b81811015620003c057620003b45f8262000382565b6001810190506200039f565b5050565b601f8211156200040f57620003d98162000298565b620003e484620002aa565b81016020851015620003f4578190505b6200040c6200040385620002aa565b8301826200039e565b50505b505050565b5f82821c905092915050565b5f620004315f198460080262000414565b1980831691505092915050565b5f6200044b838362000420565b9150826002028217905092915050565b620004668262000200565b67ffffffffffffffff8111156200048257620004816200020a565b5b6200048e825462000264565b6200049b828285620003c4565b5f60209050601f831160018114620004d1575f8415620004bc578287015190505b620004c885826200043e565b86555062000537565b601f198416620004e18662000298565b5f5b828110156200050a57848901518255600182019150602085019450602081019050620004e3565b868310156200052a578489015162000526601f89168262000420565b8355505b6001600288020188555050505b505050505050565b614481806200054d5f395ff3fe6080604052600436106101db575f3560e01c80634f6ccce711610101578063a22cb46511610094578063d82de1e711610063578063d82de1e714610745578063e0c8a2451461076f578063e985e9c514610799578063f3dea105146107d5576101f9565b8063a22cb46514610691578063aac9c209146106b9578063b88d4fde146106e1578063c87b56dd14610709576101f9565b806390adc063116100d057806390adc063146105d457806395d89b41146105fe578063a07d797214610628578063a1448f0314610650576101f9565b80634f6ccce7146104f65780636352211e146105325780636817c76c1461056e57806370a0823114610598576101f9565b80631ac53b241161017957806338e21cce1161014857806338e21cce1461041357806342842e0e1461044f57806344008dc9146104775780634b7d34eb146104b3576101f9565b80631ac53b241461034357806323b872dd146103855780632f745c59146103ad5780633013ce29146103e9576101f9565b8063095ea7b3116101b5578063095ea7b31461029f5780630c5a513c146102c7578063117c5f20146102ef57806318160ddd14610319576101f9565b806301ffc9a7146101fd57806306fdde0314610239578063081812fc14610263576101f9565b366101f95734600d5f8282546101f1919061314d565b925050819055005b5f80fd5b348015610208575f80fd5b50610223600480360381019061021e91906131e6565b6107fd565b604051610230919061322b565b60405180910390f35b348015610244575f80fd5b5061024d610876565b60405161025a91906132ce565b60405180910390f35b34801561026e575f80fd5b5061028960048036038101906102849190613318565b610905565b6040516102969190613382565b60405180910390f35b3480156102aa575f80fd5b506102c560048036038101906102c091906133c5565b610920565b005b3480156102d2575f80fd5b506102ed60048036038101906102e89190613318565b610936565b005b3480156102fa575f80fd5b50610303610c0b565b6040516103109190613412565b60405180910390f35b348015610324575f80fd5b5061032d610c11565b60405161033a9190613412565b60405180910390f35b34801561034e575f80fd5b5061036960048036038101906103649190613318565b610c1d565b60405161037c9796959493929190613446565b60405180910390f35b348015610390575f80fd5b506103ab60048036038101906103a691906134b3565b610ca7565b005b3480156103b8575f80fd5b506103d360048036038101906103ce91906133c5565b610da6565b6040516103e09190613412565b60405180910390f35b3480156103f4575f80fd5b506103fd610e4a565b60405161040a919061355e565b60405180910390f35b34801561041e575f80fd5b5061043960048036038101906104349190613577565b610e6f565b604051610446919061322b565b60405180910390f35b34801561045a575f80fd5b50610475600480360381019061047091906134b3565b610e8c565b005b348015610482575f80fd5b5061049d60048036038101906104989190613577565b610eab565b6040516104aa9190613412565b60405180910390f35b3480156104be575f80fd5b506104d960048036038101906104d49190613577565b61101a565b6040516104ed9897969594939291906135a2565b60405180910390f35b348015610501575f80fd5b5061051c60048036038101906105179190613318565b611143565b6040516105299190613412565b60405180910390f35b34801561053d575f80fd5b5061055860048036038101906105539190613318565b6111b5565b6040516105659190613382565b60405180910390f35b348015610579575f80fd5b506105826111c6565b60405161058f9190613412565b60405180910390f35b3480156105a3575f80fd5b506105be60048036038101906105b99190613577565b6111cc565b6040516105cb9190613412565b60405180910390f35b3480156105df575f80fd5b506105e8611282565b6040516105f59190613412565b60405180910390f35b348015610609575f80fd5b506106126112fd565b60405161061f91906132ce565b60405180910390f35b348015610633575f80fd5b5061064e60048036038101906106499190613318565b61138d565b005b34801561065b575f80fd5b5061067660048036038101906106719190613318565b6114ee565b6040516106889695949392919061361e565b60405180910390f35b34801561069c575f80fd5b506106b760048036038101906106b291906136a7565b6115d9565b005b3480156106c4575f80fd5b506106df60048036038101906106da9190613318565b6115ef565b005b3480156106ec575f80fd5b5061070760048036038101906107029190613811565b6118b8565b005b348015610714575f80fd5b5061072f600480360381019061072a9190613318565b6118d5565b60405161073c91906132ce565b60405180910390f35b348015610750575f80fd5b5061075961193b565b6040516107669190613412565b60405180910390f35b34801561077a575f80fd5b50610783611941565b6040516107909190613412565b60405180910390f35b3480156107a4575f80fd5b506107bf60048036038101906107ba9190613891565b611974565b6040516107cc919061322b565b60405180910390f35b3480156107e0575f80fd5b506107fb60048036038101906107f69190613577565b611a02565b005b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061086f575061086e82611ecb565b5b9050919050565b60605f8054610884906138fc565b80601f01602080910402602001604051908101604052809291908181526020018280546108b0906138fc565b80156108fb5780601f106108d2576101008083540402835291602001916108fb565b820191905f5260205f20905b8154815290600101906020018083116108de57829003601f168201915b5050505050905090565b5f61090f82611fac565b5061091982612032565b9050919050565b610932828261092d61206b565b612072565b5050565b61093e612084565b5f8111801561095257506011805490508111155b610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890613976565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166109b1826111b5565b73ffffffffffffffffffffffffffffffffffffffff1614610a07576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fe90613a04565b60405180910390fd5b5f6011600183610a179190613a22565b81548110610a2857610a27613a55565b5b905f5260205f20906004020190506002815f015f9054906101000a900460ff1660ff161015610a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8390613acc565b60405180910390fd5b5f816001015490505f8111610ad6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acd90613b34565b60405180910390fd5b5f600c5411610b1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1190613bc2565b60405180910390fd5b5f600c54600a600d54610b2d9190613c0d565b610b379190613c0d565b90505f8183610b469190613c3d565b905080600a47610b569190613c0d565b1015610b97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8e90613cee565b60405180910390fd5b5f846001018190555082600c5f828254610bb19190613a22565b925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610bfb573d5f803e3d5ffd5b5050505050610c086120d3565b50565b600d5481565b5f600880549050905090565b60118181548110610c2c575f80fd5b905f5260205f2090600402015f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff1690805f0160029054906101000a900460ff1690806001015490806002015490806003015f9054906101000a900460ff16908060030160019054906101000a900460ff16905087565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d17575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610d0e9190613382565b60405180910390fd5b5f610d2a8383610d2561206b565b6120dd565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610da0578382826040517f64283d7b000000000000000000000000000000000000000000000000000000008152600401610d9793929190613d0c565b60405180910390fd5b50505050565b5f610db0836111cc565b8210610df55782826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610dec929190613d41565b60405180910390fd5b60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e602052805f5260405f205f915054906101000a900460ff1681565b610ea683838360405180602001604052805f8152506118b8565b505050565b5f80610eb6836111cc565b90505f805b8281101561100f575f610ece8683610da6565b90505f6011600183610ee09190613a22565b81548110610ef157610ef0613a55565b5b905f5260205f2090600402016040518060e00160405290815f82015f9054906101000a900460ff1660ff1660ff1681526020015f820160019054906101000a900460ff1660ff1660ff1681526020015f820160029054906101000a900460ff1660ff1660ff1681526020016001820154815260200160028201548152602001600382015f9054906101000a900460ff1660ff1660ff1681526020016003820160019054906101000a900460ff1660ff1660ff168152505090506002815f015160ff1610611000575f816060015190505f600c54600a600d54610fd39190613c0d565b610fdd9190613c0d565b90505f8183610fec9190613c3d565b90508087610ffa919061314d565b96505050505b50508080600101915050610ebb565b508092505050919050565b5f805f805f805f8060125f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205497505f88146110fd575f601160018a6110799190613a22565b8154811061108a57611089613a55565b5b905f5260205f209060040201905043915088815f015f9054906101000a900460ff16825f0160019054906101000a900460ff16835f0160029054906101000a900460ff168460010154856003015f9054906101000a900460ff168660020154985098509850985098509850985050611138565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112f90613db2565b60405180910390fd5b919395975091939597565b5f61114c610c11565b8210611191575f826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401611188929190613d41565b60405180910390fd5b600882815481106111a5576111a4613a55565b5b905f5260205f2001549050919050565b5f6111bf82611fac565b9050919050565b60105481565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361123d575f6040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016112349190613382565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b5f805f90505f5b6011805490508110156112f5575f601182815481106112ab576112aa613a55565b5b905f5260205f20906004020190506002815f015f9054906101000a900460ff1660ff1611156112e7578060010154836112e4919061314d565b92505b508080600101915050611289565b508091505090565b60606001805461130c906138fc565b80601f0160208091040260200160405190810160405280929190818152602001828054611338906138fc565b80156113835780601f1061135a57610100808354040283529160200191611383565b820191905f5260205f20905b81548152906001019060200180831161136657829003601f168201915b5050505050905090565b5f811180156113a157506011805490508111155b6113e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d790613976565b60405180910390fd5b5f60116001836113f09190613a22565b8154811061140157611400613a55565b5b905f5260205f2090600402019050608c8160020154611420919061314d565b431015611462576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145990613e40565b60405180910390fd5b5f61146b611941565b9050600160068261147c9190613e5e565b611486919061314d565b826003015f6101000a81548160ff021916908360ff160217905550827fd1c8f124670798f64d9fd0e5548b38c40a34df482890d88baaf3bf970b600d6e836003015f9054906101000a900460ff166040516114e19190613e8e565b60405180910390a2505050565b5f805f805f805f8711801561150857506011805490508711155b611547576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153e90613976565b60405180910390fd5b5f60116001896115579190613a22565b8154811061156857611567613a55565b5b905f5260205f2090600402019050805f015f9054906101000a900460ff16815f0160019054906101000a900460ff16825f0160029054906101000a900460ff168360010154846003015f9054906101000a900460ff1685600201549650965096509650965096505091939550919395565b6115eb6115e461206b565b83836121f7565b5050565b5f60116001836115ff9190613a22565b815481106116105761160f613a55565b5b905f5260205f20906004020190506008816003015f9054906101000a900460ff1660ff161061163d575f80fd5b608c816002015461164e919061314d565b431015611690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168790613f17565b60405180910390fd5b6001816003015f9054906101000a900460ff1660ff16101580156116c857506004816003015f9054906101000a900460ff1660ff1611155b1561170a576001815f0160018282829054906101000a900460ff166116ed9190613f35565b92506101000a81548160ff021916908360ff1602179055506117d6565b6005816003015f9054906101000a900460ff1660ff1603611762576003815f0160018282829054906101000a900460ff166117459190613f35565b92506101000a81548160ff021916908360ff1602179055506117d5565b6006816003015f9054906101000a900460ff1660ff16036117d457805f015f9054906101000a900460ff1660ff16816001015f8282546117a2919061314d565b92505081905550805f015f9054906101000a900460ff1660ff16600c5f8282546117cc919061314d565b925050819055505b5b5b805f0160029054906101000a900460ff1660ff16815f0160019054906101000a900460ff1660ff161061188e576001815f015f8282829054906101000a900460ff166118229190613f35565b92506101000a81548160ff021916908360ff160217905550600d815f015f9054906101000a900460ff166118569190613f69565b815f0160026101000a81548160ff021916908360ff1602179055505f815f0160016101000a81548160ff021916908360ff1602179055505b6009816003015f6101000a81548160ff021916908360ff1602179055504381600201819055505050565b6118c3848484610ca7565b6118cf84848484612360565b50505050565b60606118e082611fac565b505f6118ea612512565b90505f8151116119085760405180602001604052805f815250611933565b8061191284612528565b604051602001611923929190613fdf565b6040516020818303038152906040525b915050919050565b600c5481565b5f44423360405160200161195793929190614067565b604051602081830303815290604052805190602001205f1c905090565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b600e5f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615611a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8390614113565b60405180910390fd5b601054600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401611ae99190613382565b602060405180830381865afa158015611b04573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b289190614145565b1015611b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b60906141ba565b60405180910390fd5b601054600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401611bc89291906141d8565b602060405180830381865afa158015611be3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c079190614145565b1015611c48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3f90614249565b60405180910390fd5b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd33306010546040518463ffffffff1660e01b8152600401611ca893929190614267565b6020604051808303815f875af1158015611cc4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ce891906142b0565b50611cf3600b6125f2565b5f611cfe600b612606565b9050611d0a8282612612565b5f6040518060e00160405280600160ff1681526020015f60ff168152602001600d60ff1681526020015f81526020014381526020015f60ff1681526020015f60ff168152509050601181908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f820151815f015f6101000a81548160ff021916908360ff1602179055506020820151815f0160016101000a81548160ff021916908360ff1602179055506040820151815f0160026101000a81548160ff021916908360ff160217905550606082015181600101556080820151816002015560a0820151816003015f6101000a81548160ff021916908360ff16021790555060c08201518160030160016101000a81548160ff021916908360ff16021790555050508160125f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055506001600e5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550505050565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611f9557507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611fa55750611fa482612705565b5b9050919050565b5f80611fb78361276e565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361202957826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016120209190613412565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61207f83838360016127a7565b505050565b6002600a54036120c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c090614325565b60405180910390fd5b6002600a81905550565b6001600a81905550565b5f806120ea858585612966565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361212d5761212884612b71565b61216c565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461216b5761216a8185612bb5565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036121ad576121a884612cff565b6121ec565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146121eb576121ea8585612dbf565b5b5b809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361226757816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161225e9190613382565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612353919061322b565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b111561250c578273ffffffffffffffffffffffffffffffffffffffff1663150b7a026123a361206b565b8685856040518563ffffffff1660e01b81526004016123c59493929190614395565b6020604051808303815f875af192505050801561240057506040513d601f19601f820116820180604052508101906123fd91906143f3565b60015b612481573d805f811461242e576040519150601f19603f3d011682016040523d82523d5f602084013e612433565b606091505b505f81510361247957836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016124709190613382565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461250a57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016125019190613382565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f600161253684612e43565b0190505f8167ffffffffffffffff811115612554576125536136ed565b5b6040519080825280601f01601f1916602001820160405280156125865781602001600182028036833780820191505090505b5090505f82602001820190505b6001156125e7578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816125dc576125db613be0565b5b0494505f8503612593575b819350505050919050565b6001815f015f828254019250508190555050565b5f815f01549050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612682575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016126799190613382565b60405180910390fd5b5f61268e83835f6120dd565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612700575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016126f79190613382565b60405180910390fd5b505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806127df57505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15612911575f6127ee84611fac565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561285857508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561286b57506128698184611974565b155b156128ad57826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016128a49190613382565b60405180910390fd5b811561290f57838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f806129718461276e565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129b2576129b1818486612f94565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612a3d576129f15f855f806127a7565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612abc57600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b60088054905060095f8381526020019081526020015f2081905550600881908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f612bbf836111cc565b90505f60075f8481526020019081526020015f20549050818114612c96575f60065f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205490508060065f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f20819055508160075f8381526020019081526020015f2081905550505b60075f8481526020019081526020015f205f905560065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f905550505050565b5f6001600880549050612d129190613a22565b90505f60095f8481526020019081526020015f205490505f60088381548110612d3e57612d3d613a55565b5b905f5260205f20015490508060088381548110612d5e57612d5d613a55565b5b905f5260205f2001819055508160095f8381526020019081526020015f208190555060095f8581526020019081526020015f205f90556008805480612da657612da561441e565b5b600190038181905f5260205f20015f9055905550505050565b5f6001612dcb846111cc565b612dd59190613a22565b90508160065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060075f8481526020019081526020015f2081905550505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612e9f577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612e9557612e94613be0565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612edc576d04ee2d6d415b85acef81000000008381612ed257612ed1613be0565b5b0492506020810190505b662386f26fc100008310612f0b57662386f26fc100008381612f0157612f00613be0565b5b0492506010810190505b6305f5e1008310612f34576305f5e1008381612f2a57612f29613be0565b5b0492506008810190505b6127108310612f59576127108381612f4f57612f4e613be0565b5b0492506004810190505b60648310612f7c5760648381612f7257612f71613be0565b5b0492506002810190505b600a8310612f8b576001810190505b80915050919050565b612f9f838383613057565b613052575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361301357806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040161300a9190613412565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401613049929190613d41565b60405180910390fd5b505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561310e57508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806130cf57506130ce8484611974565b5b8061310d57508273ffffffffffffffffffffffffffffffffffffffff166130f583612032565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61315782613117565b915061316283613117565b925082820190508082111561317a57613179613120565b5b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6131c581613191565b81146131cf575f80fd5b50565b5f813590506131e0816131bc565b92915050565b5f602082840312156131fb576131fa613189565b5b5f613208848285016131d2565b91505092915050565b5f8115159050919050565b61322581613211565b82525050565b5f60208201905061323e5f83018461321c565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561327b578082015181840152602081019050613260565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6132a082613244565b6132aa818561324e565b93506132ba81856020860161325e565b6132c381613286565b840191505092915050565b5f6020820190508181035f8301526132e68184613296565b905092915050565b6132f781613117565b8114613301575f80fd5b50565b5f81359050613312816132ee565b92915050565b5f6020828403121561332d5761332c613189565b5b5f61333a84828501613304565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61336c82613343565b9050919050565b61337c81613362565b82525050565b5f6020820190506133955f830184613373565b92915050565b6133a481613362565b81146133ae575f80fd5b50565b5f813590506133bf8161339b565b92915050565b5f80604083850312156133db576133da613189565b5b5f6133e8858286016133b1565b92505060206133f985828601613304565b9150509250929050565b61340c81613117565b82525050565b5f6020820190506134255f830184613403565b92915050565b5f60ff82169050919050565b6134408161342b565b82525050565b5f60e0820190506134595f83018a613437565b6134666020830189613437565b6134736040830188613437565b6134806060830187613403565b61348d6080830186613403565b61349a60a0830185613437565b6134a760c0830184613437565b98975050505050505050565b5f805f606084860312156134ca576134c9613189565b5b5f6134d7868287016133b1565b93505060206134e8868287016133b1565b92505060406134f986828701613304565b9150509250925092565b5f819050919050565b5f61352661352161351c84613343565b613503565b613343565b9050919050565b5f6135378261350c565b9050919050565b5f6135488261352d565b9050919050565b6135588161353e565b82525050565b5f6020820190506135715f83018461354f565b92915050565b5f6020828403121561358c5761358b613189565b5b5f613599848285016133b1565b91505092915050565b5f610100820190506135b65f83018b613403565b6135c3602083018a613437565b6135d06040830189613437565b6135dd6060830188613437565b6135ea6080830187613403565b6135f760a0830186613437565b61360460c0830185613403565b61361160e0830184613403565b9998505050505050505050565b5f60c0820190506136315f830189613437565b61363e6020830188613437565b61364b6040830187613437565b6136586060830186613403565b6136656080830185613437565b61367260a0830184613403565b979650505050505050565b61368681613211565b8114613690575f80fd5b50565b5f813590506136a18161367d565b92915050565b5f80604083850312156136bd576136bc613189565b5b5f6136ca858286016133b1565b92505060206136db85828601613693565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61372382613286565b810181811067ffffffffffffffff82111715613742576137416136ed565b5b80604052505050565b5f613754613180565b9050613760828261371a565b919050565b5f67ffffffffffffffff82111561377f5761377e6136ed565b5b61378882613286565b9050602081019050919050565b828183375f83830152505050565b5f6137b56137b084613765565b61374b565b9050828152602081018484840111156137d1576137d06136e9565b5b6137dc848285613795565b509392505050565b5f82601f8301126137f8576137f76136e5565b5b81356138088482602086016137a3565b91505092915050565b5f805f806080858703121561382957613828613189565b5b5f613836878288016133b1565b9450506020613847878288016133b1565b935050604061385887828801613304565b925050606085013567ffffffffffffffff8111156138795761387861318d565b5b613885878288016137e4565b91505092959194509250565b5f80604083850312156138a7576138a6613189565b5b5f6138b4858286016133b1565b92505060206138c5858286016133b1565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061391357607f821691505b602082108103613926576139256138cf565b5b50919050565b7f54616d61676f7463686920646f6573206e6f742065786973742e0000000000005f82015250565b5f613960601a8361324e565b915061396b8261392c565b602082019050919050565b5f6020820190508181035f83015261398d81613954565b9050919050565b7f43616c6c6572206973206e6f7420746865206f776e6572206f6620746865204e5f8201527f46542e0000000000000000000000000000000000000000000000000000000000602082015250565b5f6139ee60238361324e565b91506139f982613994565b604082019050919050565b5f6020820190508181035f830152613a1b816139e2565b9050919050565b5f613a2c82613117565b9150613a3783613117565b9250828203905081811115613a4f57613a4e613120565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f506574206c6576656c206d757374206265206174206c6561737420322e0000005f82015250565b5f613ab6601d8361324e565b9150613ac182613a82565b602082019050919050565b5f6020820190508181035f830152613ae381613aaa565b9050919050565b7f4e6f20676f6c6420746f20636f6e766572742e000000000000000000000000005f82015250565b5f613b1e60138361324e565b9150613b2982613aea565b602082019050919050565b5f6020820190508181035f830152613b4b81613b12565b9050919050565b7f546f74616c20676f6c64206973207a65726f2c2063616e6e6f742063616c63755f8201527f6c61746520636f6e76657273696f6e20726174652e0000000000000000000000602082015250565b5f613bac60358361324e565b9150613bb782613b52565b604082019050919050565b5f6020820190508181035f830152613bd981613ba0565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f613c1782613117565b9150613c2283613117565b925082613c3257613c31613be0565b5b828204905092915050565b5f613c4782613117565b9150613c5283613117565b9250828202613c6081613117565b91508282048414831517613c7757613c76613120565b5b5092915050565b7f496e73756666696369656e742045544820696e20636f6e747261637420666f725f8201527f207769746864726177616c2e0000000000000000000000000000000000000000602082015250565b5f613cd8602c8361324e565b9150613ce382613c7e565b604082019050919050565b5f6020820190508181035f830152613d0581613ccc565b9050919050565b5f606082019050613d1f5f830186613373565b613d2c6020830185613403565b613d396040830184613373565b949350505050565b5f604082019050613d545f830185613373565b613d616020830184613403565b9392505050565b7f4f776e657220646f6573206e6f7420686176652061207065742e0000000000005f82015250565b5f613d9c601a8361324e565b9150613da782613d68565b602082019050919050565b5f6020820190508181035f830152613dc981613d90565b9050919050565b7f596f75206d7573742077616974206d6f726520626c6f636b73206265666f72655f8201527f2070657474696e6720616761696e2e0000000000000000000000000000000000602082015250565b5f613e2a602f8361324e565b9150613e3582613dd0565b604082019050919050565b5f6020820190508181035f830152613e5781613e1e565b9050919050565b5f613e6882613117565b9150613e7383613117565b925082613e8357613e82613be0565b5b828206905092915050565b5f602082019050613ea15f830184613437565b92915050565b7f596f75206d7573742077616974206d6f726520626c6f636b73206265666f72655f8201527f20706572666f726d696e6720616e20616374696f6e2e00000000000000000000602082015250565b5f613f0160368361324e565b9150613f0c82613ea7565b604082019050919050565b5f6020820190508181035f830152613f2e81613ef5565b9050919050565b5f613f3f8261342b565b9150613f4a8361342b565b9250828201905060ff811115613f6357613f62613120565b5b92915050565b5f613f738261342b565b9150613f7e8361342b565b9250828202613f8c8161342b565b9150808214613f9e57613f9d613120565b5b5092915050565b5f81905092915050565b5f613fb982613244565b613fc38185613fa5565b9350613fd381856020860161325e565b80840191505092915050565b5f613fea8285613faf565b9150613ff68284613faf565b91508190509392505050565b5f819050919050565b61401c61401782613117565b614002565b82525050565b5f8160601b9050919050565b5f61403882614022565b9050919050565b5f6140498261402e565b9050919050565b61406161405c82613362565b61403f565b82525050565b5f614072828661400b565b602082019150614082828561400b565b6020820191506140928284614050565b601482019150819050949350505050565b7f456163682077616c6c65742063616e206f6e6c79206d696e74206f6e6520746f5f8201527f6b656e2e00000000000000000000000000000000000000000000000000000000602082015250565b5f6140fd60248361324e565b9150614108826140a3565b604082019050919050565b5f6020820190508181035f83015261412a816140f1565b9050919050565b5f8151905061413f816132ee565b92915050565b5f6020828403121561415a57614159613189565b5b5f61416784828501614131565b91505092915050565b7f496e73756666696369656e7420746f6b656e2062616c616e63652e00000000005f82015250565b5f6141a4601b8361324e565b91506141af82614170565b602082019050919050565b5f6020820190508181035f8301526141d181614198565b9050919050565b5f6040820190506141eb5f830185613373565b6141f86020830184613373565b9392505050565b7f496e73756666696369656e7420746f6b656e20616c6c6f77616e63652e0000005f82015250565b5f614233601d8361324e565b915061423e826141ff565b602082019050919050565b5f6020820190508181035f83015261426081614227565b9050919050565b5f60608201905061427a5f830186613373565b6142876020830185613373565b6142946040830184613403565b949350505050565b5f815190506142aa8161367d565b92915050565b5f602082840312156142c5576142c4613189565b5b5f6142d28482850161429c565b91505092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f61430f601f8361324e565b915061431a826142db565b602082019050919050565b5f6020820190508181035f83015261433c81614303565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f61436782614343565b614371818561434d565b935061438181856020860161325e565b61438a81613286565b840191505092915050565b5f6080820190506143a85f830187613373565b6143b56020830186613373565b6143c26040830185613403565b81810360608301526143d4818461435d565b905095945050505050565b5f815190506143ed816131bc565b92915050565b5f6020828403121561440857614407613189565b5b5f614415848285016143df565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220910124ce1472feea374ec91d7c2d7065334b1858a65553dd7f0cec3249ada7a564736f6c634300081600330000000000000000000000007857becfad52aa32996dcb4425d74181c3bbcfa800000000000000000000000000000000000000000000021e19e0c9bab2400000
Deployed Bytecode
0x6080604052600436106101db575f3560e01c80634f6ccce711610101578063a22cb46511610094578063d82de1e711610063578063d82de1e714610745578063e0c8a2451461076f578063e985e9c514610799578063f3dea105146107d5576101f9565b8063a22cb46514610691578063aac9c209146106b9578063b88d4fde146106e1578063c87b56dd14610709576101f9565b806390adc063116100d057806390adc063146105d457806395d89b41146105fe578063a07d797214610628578063a1448f0314610650576101f9565b80634f6ccce7146104f65780636352211e146105325780636817c76c1461056e57806370a0823114610598576101f9565b80631ac53b241161017957806338e21cce1161014857806338e21cce1461041357806342842e0e1461044f57806344008dc9146104775780634b7d34eb146104b3576101f9565b80631ac53b241461034357806323b872dd146103855780632f745c59146103ad5780633013ce29146103e9576101f9565b8063095ea7b3116101b5578063095ea7b31461029f5780630c5a513c146102c7578063117c5f20146102ef57806318160ddd14610319576101f9565b806301ffc9a7146101fd57806306fdde0314610239578063081812fc14610263576101f9565b366101f95734600d5f8282546101f1919061314d565b925050819055005b5f80fd5b348015610208575f80fd5b50610223600480360381019061021e91906131e6565b6107fd565b604051610230919061322b565b60405180910390f35b348015610244575f80fd5b5061024d610876565b60405161025a91906132ce565b60405180910390f35b34801561026e575f80fd5b5061028960048036038101906102849190613318565b610905565b6040516102969190613382565b60405180910390f35b3480156102aa575f80fd5b506102c560048036038101906102c091906133c5565b610920565b005b3480156102d2575f80fd5b506102ed60048036038101906102e89190613318565b610936565b005b3480156102fa575f80fd5b50610303610c0b565b6040516103109190613412565b60405180910390f35b348015610324575f80fd5b5061032d610c11565b60405161033a9190613412565b60405180910390f35b34801561034e575f80fd5b5061036960048036038101906103649190613318565b610c1d565b60405161037c9796959493929190613446565b60405180910390f35b348015610390575f80fd5b506103ab60048036038101906103a691906134b3565b610ca7565b005b3480156103b8575f80fd5b506103d360048036038101906103ce91906133c5565b610da6565b6040516103e09190613412565b60405180910390f35b3480156103f4575f80fd5b506103fd610e4a565b60405161040a919061355e565b60405180910390f35b34801561041e575f80fd5b5061043960048036038101906104349190613577565b610e6f565b604051610446919061322b565b60405180910390f35b34801561045a575f80fd5b50610475600480360381019061047091906134b3565b610e8c565b005b348015610482575f80fd5b5061049d60048036038101906104989190613577565b610eab565b6040516104aa9190613412565b60405180910390f35b3480156104be575f80fd5b506104d960048036038101906104d49190613577565b61101a565b6040516104ed9897969594939291906135a2565b60405180910390f35b348015610501575f80fd5b5061051c60048036038101906105179190613318565b611143565b6040516105299190613412565b60405180910390f35b34801561053d575f80fd5b5061055860048036038101906105539190613318565b6111b5565b6040516105659190613382565b60405180910390f35b348015610579575f80fd5b506105826111c6565b60405161058f9190613412565b60405180910390f35b3480156105a3575f80fd5b506105be60048036038101906105b99190613577565b6111cc565b6040516105cb9190613412565b60405180910390f35b3480156105df575f80fd5b506105e8611282565b6040516105f59190613412565b60405180910390f35b348015610609575f80fd5b506106126112fd565b60405161061f91906132ce565b60405180910390f35b348015610633575f80fd5b5061064e60048036038101906106499190613318565b61138d565b005b34801561065b575f80fd5b5061067660048036038101906106719190613318565b6114ee565b6040516106889695949392919061361e565b60405180910390f35b34801561069c575f80fd5b506106b760048036038101906106b291906136a7565b6115d9565b005b3480156106c4575f80fd5b506106df60048036038101906106da9190613318565b6115ef565b005b3480156106ec575f80fd5b5061070760048036038101906107029190613811565b6118b8565b005b348015610714575f80fd5b5061072f600480360381019061072a9190613318565b6118d5565b60405161073c91906132ce565b60405180910390f35b348015610750575f80fd5b5061075961193b565b6040516107669190613412565b60405180910390f35b34801561077a575f80fd5b50610783611941565b6040516107909190613412565b60405180910390f35b3480156107a4575f80fd5b506107bf60048036038101906107ba9190613891565b611974565b6040516107cc919061322b565b60405180910390f35b3480156107e0575f80fd5b506107fb60048036038101906107f69190613577565b611a02565b005b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061086f575061086e82611ecb565b5b9050919050565b60605f8054610884906138fc565b80601f01602080910402602001604051908101604052809291908181526020018280546108b0906138fc565b80156108fb5780601f106108d2576101008083540402835291602001916108fb565b820191905f5260205f20905b8154815290600101906020018083116108de57829003601f168201915b5050505050905090565b5f61090f82611fac565b5061091982612032565b9050919050565b610932828261092d61206b565b612072565b5050565b61093e612084565b5f8111801561095257506011805490508111155b610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890613976565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166109b1826111b5565b73ffffffffffffffffffffffffffffffffffffffff1614610a07576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fe90613a04565b60405180910390fd5b5f6011600183610a179190613a22565b81548110610a2857610a27613a55565b5b905f5260205f20906004020190506002815f015f9054906101000a900460ff1660ff161015610a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8390613acc565b60405180910390fd5b5f816001015490505f8111610ad6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acd90613b34565b60405180910390fd5b5f600c5411610b1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1190613bc2565b60405180910390fd5b5f600c54600a600d54610b2d9190613c0d565b610b379190613c0d565b90505f8183610b469190613c3d565b905080600a47610b569190613c0d565b1015610b97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8e90613cee565b60405180910390fd5b5f846001018190555082600c5f828254610bb19190613a22565b925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610bfb573d5f803e3d5ffd5b5050505050610c086120d3565b50565b600d5481565b5f600880549050905090565b60118181548110610c2c575f80fd5b905f5260205f2090600402015f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff1690805f0160029054906101000a900460ff1690806001015490806002015490806003015f9054906101000a900460ff16908060030160019054906101000a900460ff16905087565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d17575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401610d0e9190613382565b60405180910390fd5b5f610d2a8383610d2561206b565b6120dd565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610da0578382826040517f64283d7b000000000000000000000000000000000000000000000000000000008152600401610d9793929190613d0c565b60405180910390fd5b50505050565b5f610db0836111cc565b8210610df55782826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610dec929190613d41565b60405180910390fd5b60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e602052805f5260405f205f915054906101000a900460ff1681565b610ea683838360405180602001604052805f8152506118b8565b505050565b5f80610eb6836111cc565b90505f805b8281101561100f575f610ece8683610da6565b90505f6011600183610ee09190613a22565b81548110610ef157610ef0613a55565b5b905f5260205f2090600402016040518060e00160405290815f82015f9054906101000a900460ff1660ff1660ff1681526020015f820160019054906101000a900460ff1660ff1660ff1681526020015f820160029054906101000a900460ff1660ff1660ff1681526020016001820154815260200160028201548152602001600382015f9054906101000a900460ff1660ff1660ff1681526020016003820160019054906101000a900460ff1660ff1660ff168152505090506002815f015160ff1610611000575f816060015190505f600c54600a600d54610fd39190613c0d565b610fdd9190613c0d565b90505f8183610fec9190613c3d565b90508087610ffa919061314d565b96505050505b50508080600101915050610ebb565b508092505050919050565b5f805f805f805f8060125f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205497505f88146110fd575f601160018a6110799190613a22565b8154811061108a57611089613a55565b5b905f5260205f209060040201905043915088815f015f9054906101000a900460ff16825f0160019054906101000a900460ff16835f0160029054906101000a900460ff168460010154856003015f9054906101000a900460ff168660020154985098509850985098509850985050611138565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112f90613db2565b60405180910390fd5b919395975091939597565b5f61114c610c11565b8210611191575f826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401611188929190613d41565b60405180910390fd5b600882815481106111a5576111a4613a55565b5b905f5260205f2001549050919050565b5f6111bf82611fac565b9050919050565b60105481565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361123d575f6040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016112349190613382565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b5f805f90505f5b6011805490508110156112f5575f601182815481106112ab576112aa613a55565b5b905f5260205f20906004020190506002815f015f9054906101000a900460ff1660ff1611156112e7578060010154836112e4919061314d565b92505b508080600101915050611289565b508091505090565b60606001805461130c906138fc565b80601f0160208091040260200160405190810160405280929190818152602001828054611338906138fc565b80156113835780601f1061135a57610100808354040283529160200191611383565b820191905f5260205f20905b81548152906001019060200180831161136657829003601f168201915b5050505050905090565b5f811180156113a157506011805490508111155b6113e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d790613976565b60405180910390fd5b5f60116001836113f09190613a22565b8154811061140157611400613a55565b5b905f5260205f2090600402019050608c8160020154611420919061314d565b431015611462576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145990613e40565b60405180910390fd5b5f61146b611941565b9050600160068261147c9190613e5e565b611486919061314d565b826003015f6101000a81548160ff021916908360ff160217905550827fd1c8f124670798f64d9fd0e5548b38c40a34df482890d88baaf3bf970b600d6e836003015f9054906101000a900460ff166040516114e19190613e8e565b60405180910390a2505050565b5f805f805f805f8711801561150857506011805490508711155b611547576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153e90613976565b60405180910390fd5b5f60116001896115579190613a22565b8154811061156857611567613a55565b5b905f5260205f2090600402019050805f015f9054906101000a900460ff16815f0160019054906101000a900460ff16825f0160029054906101000a900460ff168360010154846003015f9054906101000a900460ff1685600201549650965096509650965096505091939550919395565b6115eb6115e461206b565b83836121f7565b5050565b5f60116001836115ff9190613a22565b815481106116105761160f613a55565b5b905f5260205f20906004020190506008816003015f9054906101000a900460ff1660ff161061163d575f80fd5b608c816002015461164e919061314d565b431015611690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168790613f17565b60405180910390fd5b6001816003015f9054906101000a900460ff1660ff16101580156116c857506004816003015f9054906101000a900460ff1660ff1611155b1561170a576001815f0160018282829054906101000a900460ff166116ed9190613f35565b92506101000a81548160ff021916908360ff1602179055506117d6565b6005816003015f9054906101000a900460ff1660ff1603611762576003815f0160018282829054906101000a900460ff166117459190613f35565b92506101000a81548160ff021916908360ff1602179055506117d5565b6006816003015f9054906101000a900460ff1660ff16036117d457805f015f9054906101000a900460ff1660ff16816001015f8282546117a2919061314d565b92505081905550805f015f9054906101000a900460ff1660ff16600c5f8282546117cc919061314d565b925050819055505b5b5b805f0160029054906101000a900460ff1660ff16815f0160019054906101000a900460ff1660ff161061188e576001815f015f8282829054906101000a900460ff166118229190613f35565b92506101000a81548160ff021916908360ff160217905550600d815f015f9054906101000a900460ff166118569190613f69565b815f0160026101000a81548160ff021916908360ff1602179055505f815f0160016101000a81548160ff021916908360ff1602179055505b6009816003015f6101000a81548160ff021916908360ff1602179055504381600201819055505050565b6118c3848484610ca7565b6118cf84848484612360565b50505050565b60606118e082611fac565b505f6118ea612512565b90505f8151116119085760405180602001604052805f815250611933565b8061191284612528565b604051602001611923929190613fdf565b6040516020818303038152906040525b915050919050565b600c5481565b5f44423360405160200161195793929190614067565b604051602081830303815290604052805190602001205f1c905090565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b600e5f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1615611a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8390614113565b60405180910390fd5b601054600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401611ae99190613382565b602060405180830381865afa158015611b04573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b289190614145565b1015611b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b60906141ba565b60405180910390fd5b601054600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401611bc89291906141d8565b602060405180830381865afa158015611be3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c079190614145565b1015611c48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3f90614249565b60405180910390fd5b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd33306010546040518463ffffffff1660e01b8152600401611ca893929190614267565b6020604051808303815f875af1158015611cc4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ce891906142b0565b50611cf3600b6125f2565b5f611cfe600b612606565b9050611d0a8282612612565b5f6040518060e00160405280600160ff1681526020015f60ff168152602001600d60ff1681526020015f81526020014381526020015f60ff1681526020015f60ff168152509050601181908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f820151815f015f6101000a81548160ff021916908360ff1602179055506020820151815f0160016101000a81548160ff021916908360ff1602179055506040820151815f0160026101000a81548160ff021916908360ff160217905550606082015181600101556080820151816002015560a0820151816003015f6101000a81548160ff021916908360ff16021790555060c08201518160030160016101000a81548160ff021916908360ff16021790555050508160125f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055506001600e5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550505050565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611f9557507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611fa55750611fa482612705565b5b9050919050565b5f80611fb78361276e565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361202957826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016120209190613412565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b61207f83838360016127a7565b505050565b6002600a54036120c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c090614325565b60405180910390fd5b6002600a81905550565b6001600a81905550565b5f806120ea858585612966565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361212d5761212884612b71565b61216c565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461216b5761216a8185612bb5565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036121ad576121a884612cff565b6121ec565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146121eb576121ea8585612dbf565b5b5b809150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361226757816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161225e9190613382565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612353919061322b565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b111561250c578273ffffffffffffffffffffffffffffffffffffffff1663150b7a026123a361206b565b8685856040518563ffffffff1660e01b81526004016123c59493929190614395565b6020604051808303815f875af192505050801561240057506040513d601f19601f820116820180604052508101906123fd91906143f3565b60015b612481573d805f811461242e576040519150601f19603f3d011682016040523d82523d5f602084013e612433565b606091505b505f81510361247957836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016124709190613382565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461250a57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016125019190613382565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b60605f600161253684612e43565b0190505f8167ffffffffffffffff811115612554576125536136ed565b5b6040519080825280601f01601f1916602001820160405280156125865781602001600182028036833780820191505090505b5090505f82602001820190505b6001156125e7578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816125dc576125db613be0565b5b0494505f8503612593575b819350505050919050565b6001815f015f828254019250508190555050565b5f815f01549050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612682575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016126799190613382565b60405180910390fd5b5f61268e83835f6120dd565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612700575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016126f79190613382565b60405180910390fd5b505050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806127df57505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15612911575f6127ee84611fac565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561285857508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561286b57506128698184611974565b155b156128ad57826040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526004016128a49190613382565b60405180910390fd5b811561290f57838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f806129718461276e565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146129b2576129b1818486612f94565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612a3d576129f15f855f806127a7565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612abc57600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b60088054905060095f8381526020019081526020015f2081905550600881908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f612bbf836111cc565b90505f60075f8481526020019081526020015f20549050818114612c96575f60065f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205490508060065f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f20819055508160075f8381526020019081526020015f2081905550505b60075f8481526020019081526020015f205f905560065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f905550505050565b5f6001600880549050612d129190613a22565b90505f60095f8481526020019081526020015f205490505f60088381548110612d3e57612d3d613a55565b5b905f5260205f20015490508060088381548110612d5e57612d5d613a55565b5b905f5260205f2001819055508160095f8381526020019081526020015f208190555060095f8581526020019081526020015f205f90556008805480612da657612da561441e565b5b600190038181905f5260205f20015f9055905550505050565b5f6001612dcb846111cc565b612dd59190613a22565b90508160065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060075f8481526020019081526020015f2081905550505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612e9f577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612e9557612e94613be0565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612edc576d04ee2d6d415b85acef81000000008381612ed257612ed1613be0565b5b0492506020810190505b662386f26fc100008310612f0b57662386f26fc100008381612f0157612f00613be0565b5b0492506010810190505b6305f5e1008310612f34576305f5e1008381612f2a57612f29613be0565b5b0492506008810190505b6127108310612f59576127108381612f4f57612f4e613be0565b5b0492506004810190505b60648310612f7c5760648381612f7257612f71613be0565b5b0492506002810190505b600a8310612f8b576001810190505b80915050919050565b612f9f838383613057565b613052575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361301357806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040161300a9190613412565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401613049929190613d41565b60405180910390fd5b505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561310e57508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806130cf57506130ce8484611974565b5b8061310d57508273ffffffffffffffffffffffffffffffffffffffff166130f583612032565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61315782613117565b915061316283613117565b925082820190508082111561317a57613179613120565b5b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6131c581613191565b81146131cf575f80fd5b50565b5f813590506131e0816131bc565b92915050565b5f602082840312156131fb576131fa613189565b5b5f613208848285016131d2565b91505092915050565b5f8115159050919050565b61322581613211565b82525050565b5f60208201905061323e5f83018461321c565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561327b578082015181840152602081019050613260565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6132a082613244565b6132aa818561324e565b93506132ba81856020860161325e565b6132c381613286565b840191505092915050565b5f6020820190508181035f8301526132e68184613296565b905092915050565b6132f781613117565b8114613301575f80fd5b50565b5f81359050613312816132ee565b92915050565b5f6020828403121561332d5761332c613189565b5b5f61333a84828501613304565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61336c82613343565b9050919050565b61337c81613362565b82525050565b5f6020820190506133955f830184613373565b92915050565b6133a481613362565b81146133ae575f80fd5b50565b5f813590506133bf8161339b565b92915050565b5f80604083850312156133db576133da613189565b5b5f6133e8858286016133b1565b92505060206133f985828601613304565b9150509250929050565b61340c81613117565b82525050565b5f6020820190506134255f830184613403565b92915050565b5f60ff82169050919050565b6134408161342b565b82525050565b5f60e0820190506134595f83018a613437565b6134666020830189613437565b6134736040830188613437565b6134806060830187613403565b61348d6080830186613403565b61349a60a0830185613437565b6134a760c0830184613437565b98975050505050505050565b5f805f606084860312156134ca576134c9613189565b5b5f6134d7868287016133b1565b93505060206134e8868287016133b1565b92505060406134f986828701613304565b9150509250925092565b5f819050919050565b5f61352661352161351c84613343565b613503565b613343565b9050919050565b5f6135378261350c565b9050919050565b5f6135488261352d565b9050919050565b6135588161353e565b82525050565b5f6020820190506135715f83018461354f565b92915050565b5f6020828403121561358c5761358b613189565b5b5f613599848285016133b1565b91505092915050565b5f610100820190506135b65f83018b613403565b6135c3602083018a613437565b6135d06040830189613437565b6135dd6060830188613437565b6135ea6080830187613403565b6135f760a0830186613437565b61360460c0830185613403565b61361160e0830184613403565b9998505050505050505050565b5f60c0820190506136315f830189613437565b61363e6020830188613437565b61364b6040830187613437565b6136586060830186613403565b6136656080830185613437565b61367260a0830184613403565b979650505050505050565b61368681613211565b8114613690575f80fd5b50565b5f813590506136a18161367d565b92915050565b5f80604083850312156136bd576136bc613189565b5b5f6136ca858286016133b1565b92505060206136db85828601613693565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61372382613286565b810181811067ffffffffffffffff82111715613742576137416136ed565b5b80604052505050565b5f613754613180565b9050613760828261371a565b919050565b5f67ffffffffffffffff82111561377f5761377e6136ed565b5b61378882613286565b9050602081019050919050565b828183375f83830152505050565b5f6137b56137b084613765565b61374b565b9050828152602081018484840111156137d1576137d06136e9565b5b6137dc848285613795565b509392505050565b5f82601f8301126137f8576137f76136e5565b5b81356138088482602086016137a3565b91505092915050565b5f805f806080858703121561382957613828613189565b5b5f613836878288016133b1565b9450506020613847878288016133b1565b935050604061385887828801613304565b925050606085013567ffffffffffffffff8111156138795761387861318d565b5b613885878288016137e4565b91505092959194509250565b5f80604083850312156138a7576138a6613189565b5b5f6138b4858286016133b1565b92505060206138c5858286016133b1565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061391357607f821691505b602082108103613926576139256138cf565b5b50919050565b7f54616d61676f7463686920646f6573206e6f742065786973742e0000000000005f82015250565b5f613960601a8361324e565b915061396b8261392c565b602082019050919050565b5f6020820190508181035f83015261398d81613954565b9050919050565b7f43616c6c6572206973206e6f7420746865206f776e6572206f6620746865204e5f8201527f46542e0000000000000000000000000000000000000000000000000000000000602082015250565b5f6139ee60238361324e565b91506139f982613994565b604082019050919050565b5f6020820190508181035f830152613a1b816139e2565b9050919050565b5f613a2c82613117565b9150613a3783613117565b9250828203905081811115613a4f57613a4e613120565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f506574206c6576656c206d757374206265206174206c6561737420322e0000005f82015250565b5f613ab6601d8361324e565b9150613ac182613a82565b602082019050919050565b5f6020820190508181035f830152613ae381613aaa565b9050919050565b7f4e6f20676f6c6420746f20636f6e766572742e000000000000000000000000005f82015250565b5f613b1e60138361324e565b9150613b2982613aea565b602082019050919050565b5f6020820190508181035f830152613b4b81613b12565b9050919050565b7f546f74616c20676f6c64206973207a65726f2c2063616e6e6f742063616c63755f8201527f6c61746520636f6e76657273696f6e20726174652e0000000000000000000000602082015250565b5f613bac60358361324e565b9150613bb782613b52565b604082019050919050565b5f6020820190508181035f830152613bd981613ba0565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f613c1782613117565b9150613c2283613117565b925082613c3257613c31613be0565b5b828204905092915050565b5f613c4782613117565b9150613c5283613117565b9250828202613c6081613117565b91508282048414831517613c7757613c76613120565b5b5092915050565b7f496e73756666696369656e742045544820696e20636f6e747261637420666f725f8201527f207769746864726177616c2e0000000000000000000000000000000000000000602082015250565b5f613cd8602c8361324e565b9150613ce382613c7e565b604082019050919050565b5f6020820190508181035f830152613d0581613ccc565b9050919050565b5f606082019050613d1f5f830186613373565b613d2c6020830185613403565b613d396040830184613373565b949350505050565b5f604082019050613d545f830185613373565b613d616020830184613403565b9392505050565b7f4f776e657220646f6573206e6f7420686176652061207065742e0000000000005f82015250565b5f613d9c601a8361324e565b9150613da782613d68565b602082019050919050565b5f6020820190508181035f830152613dc981613d90565b9050919050565b7f596f75206d7573742077616974206d6f726520626c6f636b73206265666f72655f8201527f2070657474696e6720616761696e2e0000000000000000000000000000000000602082015250565b5f613e2a602f8361324e565b9150613e3582613dd0565b604082019050919050565b5f6020820190508181035f830152613e5781613e1e565b9050919050565b5f613e6882613117565b9150613e7383613117565b925082613e8357613e82613be0565b5b828206905092915050565b5f602082019050613ea15f830184613437565b92915050565b7f596f75206d7573742077616974206d6f726520626c6f636b73206265666f72655f8201527f20706572666f726d696e6720616e20616374696f6e2e00000000000000000000602082015250565b5f613f0160368361324e565b9150613f0c82613ea7565b604082019050919050565b5f6020820190508181035f830152613f2e81613ef5565b9050919050565b5f613f3f8261342b565b9150613f4a8361342b565b9250828201905060ff811115613f6357613f62613120565b5b92915050565b5f613f738261342b565b9150613f7e8361342b565b9250828202613f8c8161342b565b9150808214613f9e57613f9d613120565b5b5092915050565b5f81905092915050565b5f613fb982613244565b613fc38185613fa5565b9350613fd381856020860161325e565b80840191505092915050565b5f613fea8285613faf565b9150613ff68284613faf565b91508190509392505050565b5f819050919050565b61401c61401782613117565b614002565b82525050565b5f8160601b9050919050565b5f61403882614022565b9050919050565b5f6140498261402e565b9050919050565b61406161405c82613362565b61403f565b82525050565b5f614072828661400b565b602082019150614082828561400b565b6020820191506140928284614050565b601482019150819050949350505050565b7f456163682077616c6c65742063616e206f6e6c79206d696e74206f6e6520746f5f8201527f6b656e2e00000000000000000000000000000000000000000000000000000000602082015250565b5f6140fd60248361324e565b9150614108826140a3565b604082019050919050565b5f6020820190508181035f83015261412a816140f1565b9050919050565b5f8151905061413f816132ee565b92915050565b5f6020828403121561415a57614159613189565b5b5f61416784828501614131565b91505092915050565b7f496e73756666696369656e7420746f6b656e2062616c616e63652e00000000005f82015250565b5f6141a4601b8361324e565b91506141af82614170565b602082019050919050565b5f6020820190508181035f8301526141d181614198565b9050919050565b5f6040820190506141eb5f830185613373565b6141f86020830184613373565b9392505050565b7f496e73756666696369656e7420746f6b656e20616c6c6f77616e63652e0000005f82015250565b5f614233601d8361324e565b915061423e826141ff565b602082019050919050565b5f6020820190508181035f83015261426081614227565b9050919050565b5f60608201905061427a5f830186613373565b6142876020830185613373565b6142946040830184613403565b949350505050565b5f815190506142aa8161367d565b92915050565b5f602082840312156142c5576142c4613189565b5b5f6142d28482850161429c565b91505092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f61430f601f8361324e565b915061431a826142db565b602082019050919050565b5f6020820190508181035f83015261433c81614303565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f61436782614343565b614371818561434d565b935061438181856020860161325e565b61438a81613286565b840191505092915050565b5f6080820190506143a85f830187613373565b6143b56020830186613373565b6143c26040830185613403565b81810360608301526143d4818461435d565b905095945050505050565b5f815190506143ed816131bc565b92915050565b5f6020828403121561440857614407613189565b5b5f614415848285016143df565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220910124ce1472feea374ec91d7c2d7065334b1858a65553dd7f0cec3249ada7a564736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007857becfad52aa32996dcb4425d74181c3bbcfa800000000000000000000000000000000000000000000021e19e0c9bab2400000
-----Decoded View---------------
Arg [0] : _paymentTokenAddress (address): 0x7857Becfad52AA32996dCb4425D74181C3BBCFa8
Arg [1] : _mintPrice (uint256): 10000000000000000000000
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007857becfad52aa32996dcb4425d74181c3bbcfa8
Arg [1] : 00000000000000000000000000000000000000000000021e19e0c9bab2400000
Deployed Bytecode Sourcemap
70473:7928:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72879:9;72858:17;;:30;;;;;;;:::i;:::-;;;;;;;;70473:7928;;;;64422:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47310:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48482:158;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48301:115;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75565:1102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70663:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65066:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71259:31;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;49151:588;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64730:260;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70754:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70706:41;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49810:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77065:759;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74817:736;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;65247:231;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47123:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70787:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46848:213;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76677:378;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47470:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72910:655;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77842:547;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;48712:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73588:1219;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50015:211;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47636:260;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70626:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72643:167;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48929:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71360:1031;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64422:224;64524:4;64563:35;64548:50;;;:11;:50;;;;:90;;;;64602:36;64626:11;64602:23;:36::i;:::-;64548:90;64541:97;;64422:224;;;:::o;47310:91::-;47355:13;47388:5;47381:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47310:91;:::o;48482:158::-;48549:7;48569:22;48583:7;48569:13;:22::i;:::-;;48611:21;48624:7;48611:12;:21::i;:::-;48604:28;;48482:158;;;:::o;48301:115::-;48373:35;48382:2;48386:7;48395:12;:10;:12::i;:::-;48373:8;:35::i;:::-;48301:115;;:::o;75565:1102::-;2411:21;:19;:21::i;:::-;75701:1:::1;75685:13;:17;:56;;;;;75723:11;:18;;;;75706:13;:35;;75685:56;75677:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;75817:10;75791:36;;:22;75799:13;75791:7;:22::i;:::-;:36;;;75783:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;75878:37;75918:11;75946:1;75930:13;:17;;;;:::i;:::-;75918:30;;;;;;;;:::i;:::-;;;;;;;;;;;;75878:70;;75995:1;75967:18;:24;;;;;;;;;;;;:29;;;;75959:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;76041:18;76062;:29;;;76041:50;;76123:1;76110:10;:14;76102:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;76185:1;76167:15;;:19;76159:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;76277:22;76329:15;;76323:2;76303:17;;:22;;;;:::i;:::-;76302:42;;;;:::i;:::-;76277:67;;76355:17;76388:14;76375:10;:27;;;;:::i;:::-;76355:47;;76453:9;76446:2;76422:21;:26;;;;:::i;:::-;76421:41;;76413:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;76556:1;76524:18;:29;;:33;;;;76587:10;76568:15;;:29;;;;;;;:::i;:::-;;;;;;;;76628:10;76620:28;;:39;76649:9;76620:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;75647:1020;;;;2455:20:::0;:18;:20::i;:::-;75565:1102;:::o;70663:32::-;;;;:::o;65066:104::-;65118:7;65145:10;:17;;;;65138:24;;65066:104;:::o;71259:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;49151:588::-;49260:1;49246:16;;:2;:16;;;49242:89;;49316:1;49286:33;;;;;;;;;;;:::i;:::-;;;;;;;;49242:89;49552:21;49576:34;49584:2;49588:7;49597:12;:10;:12::i;:::-;49576:7;:34::i;:::-;49552:58;;49642:4;49625:21;;:13;:21;;;49621:111;;49691:4;49697:7;49706:13;49670:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;49621:111;49231:508;49151:588;;;:::o;64730:260::-;64818:7;64851:16;64861:5;64851:9;:16::i;:::-;64842:5;:25;64838:101;;64914:5;64921;64891:36;;;;;;;;;;;;:::i;:::-;;;;;;;;64838:101;64956:12;:19;64969:5;64956:19;;;;;;;;;;;;;;;:26;64976:5;64956:26;;;;;;;;;;;;64949:33;;64730:260;;;;:::o;70754:26::-;;;;;;;;;;;;;:::o;70706:41::-;;;;;;;;;;;;;;;;;;;;;;:::o;49810:134::-;49897:39;49914:4;49920:2;49924:7;49897:39;;;;;;;;;;;;:16;:39::i;:::-;49810:134;;;:::o;77065:759::-;77134:7;77154:20;77177:17;77187:6;77177:9;:17::i;:::-;77154:40;;77205:25;77266:9;77261:517;77285:12;77281:1;:16;77261:517;;;77319:20;77342:30;77362:6;77370:1;77342:19;:30::i;:::-;77319:53;;77387:28;77418:11;77445:1;77430:12;:16;;;;:::i;:::-;77418:29;;;;;;;;:::i;:::-;;;;;;;;;;;;77387:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77486:1;77466:10;:16;;;:21;;;77462:305;;77508:18;77529:10;:21;;;77508:42;;77569:22;77621:15;;77615:2;77595:17;;:22;;;;:::i;:::-;77594:42;;;;:::i;:::-;77569:67;;77655:17;77688:14;77675:10;:27;;;;:::i;:::-;77655:47;;77742:9;77721:30;;;;;:::i;:::-;;;77489:278;;;77462:305;77304:474;;77299:3;;;;;;;77261:517;;;;77799:17;77792:24;;;;77065:759;;;:::o;74817:736::-;74880:13;74895:11;74908:16;74926:24;74952:18;74972:12;74986:24;75012:20;75049:12;:19;75062:5;75049:19;;;;;;;;;;;;;;;;75041:27;;75092:1;75083:5;:10;75079:467;;75110:29;75142:11;75162:1;75154:5;:9;;;;:::i;:::-;75142:22;;;;;;;;:::i;:::-;;;;;;;;;;;;75110:54;;75194:12;75179:27;;75231:5;75238:10;:16;;;;;;;;;;;;75256:10;:21;;;;;;;;;;;;75279:10;:29;;;;;;;;;;;;75310:10;:21;;;75333:10;:17;;;;;;;;;;;;75352:10;:27;;;75223:171;;;;;;;;;;;;;;;;;75079:467;75498:36;;;;;;;;;;:::i;:::-;;;;;;;;74817:736;;;;;;;;;;:::o;65247:231::-;65313:7;65346:13;:11;:13::i;:::-;65337:5;:22;65333:103;;65414:1;65418:5;65383:41;;;;;;;;;;;;:::i;:::-;;;;;;;;65333:103;65453:10;65464:5;65453:17;;;;;;;;:::i;:::-;;;;;;;;;;65446:24;;65247:231;;;:::o;47123:120::-;47186:7;47213:22;47227:7;47213:13;:22::i;:::-;47206:29;;47123:120;;;:::o;70787:24::-;;;;:::o;46848:213::-;46911:7;46952:1;46935:19;;:5;:19;;;46931:89;;47005:1;46978:30;;;;;;;;;;;:::i;:::-;;;;;;;;46931:89;47037:9;:16;47047:5;47037:16;;;;;;;;;;;;;;;;47030:23;;46848:213;;;:::o;76677:378::-;76727:7;76747:17;76767:1;76747:21;;76793:9;76788:231;76812:11;:18;;;;76808:1;:22;76788:231;;;76852:29;76884:11;76896:1;76884:14;;;;;;;;:::i;:::-;;;;;;;;;;;;76852:46;;76936:1;76917:10;:16;;;;;;;;;;;;:20;;;76913:95;;;76971:10;:21;;;76958:34;;;;;:::i;:::-;;;76913:95;76837:182;76832:3;;;;;;;76788:231;;;;77038:9;77031:16;;;76677:378;:::o;47470:95::-;47517:13;47550:7;47543:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47470:95;:::o;72910:655::-;72990:1;72974:13;:17;:56;;;;;73012:11;:18;;;;72995:13;:35;;72974:56;72966:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;73076:29;73108:11;73136:1;73120:13;:17;;;;:::i;:::-;73108:30;;;;;;;;:::i;:::-;;;;;;;;;;;;73076:62;;72443:3;73173:10;:27;;;:44;;;;:::i;:::-;73157:12;:60;;73149:120;;;;;;;;;;;;:::i;:::-;;;;;;;;;73338:19;73360:22;:20;:22::i;:::-;73338:44;;73437:1;73433;73419:11;:15;;;;:::i;:::-;:19;;;;:::i;:::-;73393:10;:17;;;:46;;;;;;;;;;;;;;;;;;73524:13;73510:47;73539:10;:17;;;;;;;;;;;;73510:47;;;;;;:::i;:::-;;;;;;;;72955:610;;72910:655;:::o;77842:547::-;77916:11;77929:16;77947:24;77973:18;77993:12;78007:24;78068:1;78052:13;:17;:56;;;;;78090:11;:18;;;;78073:13;:35;;78052:56;78044:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;78154:29;78186:11;78214:1;78198:13;:17;;;;:::i;:::-;78186:30;;;;;;;;:::i;:::-;;;;;;;;;;;;78154:62;;78239:10;:16;;;;;;;;;;;;78257:10;:21;;;;;;;;;;;;78280:10;:29;;;;;;;;;;;;78311:10;:21;;;78334:10;:17;;;;;;;;;;;;78353:10;:27;;;78231:150;;;;;;;;;;;;;77842:547;;;;;;;:::o;48712:146::-;48798:52;48817:12;:10;:12::i;:::-;48831:8;48841;48798:18;:52::i;:::-;48712:146;;:::o;73588:1219::-;73650:29;73682:11;73710:1;73694:13;:17;;;;:::i;:::-;73682:30;;;;;;;;:::i;:::-;;;;;;;;;;;;73650:62;;73751:1;73731:10;:17;;;;;;;;;;;;:21;;;73723:30;;;;;;72443:3;73788:10;:27;;;:44;;;;:::i;:::-;73772:12;:60;;73764:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;73987:1;73966:10;:17;;;;;;;;;;;;:22;;;;:48;;;;;74013:1;73992:10;:17;;;;;;;;;;;;:22;;;;73966:48;73962:459;;;74085:1;74060:10;:21;;;:26;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;73962:459;;;74143:1;74122:10;:17;;;;;;;;;;;;:22;;;74118:303;;72557:1;74193:10;:21;;;:50;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;74118:303;;;74286:1;74265:10;:17;;;;;;;;;;;;:22;;;74261:160;;74342:10;:16;;;;;;;;;;;;74317:41;;:10;:21;;;:41;;;;;;;:::i;:::-;;;;;;;;74392:10;:16;;;;;;;;;;;;74373:35;;:15;;:35;;;;;;;:::i;:::-;;;;;;;;74261:160;74118:303;73962:459;74528:10;:29;;;;;;;;;;;;74503:54;;:10;:21;;;;;;;;;;;;:54;;;74499:216;;74594:1;74574:10;:16;;;:21;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;74661:2;74642:10;:16;;;;;;;;;;;;:21;;;;:::i;:::-;74610:10;:29;;;:53;;;;;;;;;;;;;;;;;;74702:1;74678:10;:21;;;:25;;;;;;;;;;;;;;;;;;74499:216;74745:1;74725:10;:17;;;:21;;;;;;;;;;;;;;;;;;74787:12;74757:10;:27;;:42;;;;73639:1168;73588:1219;:::o;50015:211::-;50129:31;50142:4;50148:2;50152:7;50129:12;:31::i;:::-;50171:47;50194:4;50200:2;50204:7;50213:4;50171:22;:47::i;:::-;50015:211;;;;:::o;47636:260::-;47700:13;47726:22;47740:7;47726:13;:22::i;:::-;;47761:21;47785:10;:8;:10::i;:::-;47761:34;;47837:1;47819:7;47813:21;:25;:75;;;;;;;;;;;;;;;;;47855:7;47864:18;:7;:16;:18::i;:::-;47841:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;47813:75;47806:82;;;47636:260;;;:::o;70626:30::-;;;;:::o;72643:167::-;72696:7;72754:16;72772:15;72789:10;72737:63;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72727:74;;;;;;72719:83;;72712:90;;72643:167;:::o;48929:155::-;49017:4;49041:18;:25;49060:5;49041:25;;;;;;;;;;;;;;;:35;49067:8;49041:35;;;;;;;;;;;;;;;;;;;;;;;;;49034:42;;48929:155;;;;:::o;71360:1031::-;71423:9;:13;71433:2;71423:13;;;;;;;;;;;;;;;;;;;;;;;;;71422:14;71414:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;71538:9;;71500:12;;;;;;;;;;;:22;;;71523:10;71500:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;71492:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;71651:9;;71598:12;;;;;;;;;;;:22;;;71621:10;71641:4;71598:49;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:62;;71590:104;;;;;;;;;;;;:::i;:::-;;;;;;;;;71709:12;;;;;;;;;;;:25;;;71735:10;71755:4;71762:9;;71709:63;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;71783:21;:9;:19;:21::i;:::-;71815:20;71838:19;:9;:17;:19::i;:::-;71815:42;;71868:23;71874:2;71878:12;71868:5;:23::i;:::-;71960:31;71994:270;;;;;;;;72027:1;71994:270;;;;;;72092:1;71994:270;;;;;;72128:2;71994:270;;;;;;72157:1;71994:270;;;;72191:12;71994:270;;;;72226:1;71994:270;;;;;;72251:1;71994:270;;;;;71960:304;;72275:11;72292:13;72275:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72336:12;72317;:16;72330:2;72317:16;;;;;;;;;;;;;;;:31;;;;72379:4;72363:9;:13;72373:2;72363:13;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;;;;;;;71403:988;;71360:1031;:::o;46479:305::-;46581:4;46633:25;46618:40;;;:11;:40;;;;:105;;;;46690:33;46675:48;;;:11;:48;;;;46618:105;:158;;;;46740:36;46764:11;46740:23;:36::i;:::-;46618:158;46598:178;;46479:305;;;:::o;61457:247::-;61520:7;61540:13;61556:17;61565:7;61556:8;:17::i;:::-;61540:33;;61605:1;61588:19;;:5;:19;;;61584:90;;61654:7;61631:31;;;;;;;;;;;:::i;:::-;;;;;;;;61584:90;61691:5;61684:12;;;61457:247;;;:::o;50988:129::-;51058:7;51085:15;:24;51101:7;51085:24;;;;;;;;;;;;;;;;;;;;;51078:31;;50988:129;;;:::o;35148:98::-;35201:7;35228:10;35221:17;;35148:98;:::o;59689:122::-;59770:33;59779:2;59783:7;59792:4;59798;59770:8;:33::i;:::-;59689:122;;;:::o;2491:293::-;1893:1;2625:7;;:19;2617:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1893:1;2758:7;:18;;;;2491:293::o;2792:213::-;1849:1;2975:7;:22;;;;2792:213::o;65539:640::-;65634:7;65654:21;65678:32;65692:2;65696:7;65705:4;65678:13;:32::i;:::-;65654:56;;65752:1;65727:27;;:13;:27;;;65723:214;;65771:40;65803:7;65771:31;:40::i;:::-;65723:214;;;65850:2;65833:19;;:13;:19;;;65829:108;;65869:56;65902:13;65917:7;65869:32;:56::i;:::-;65829:108;65723:214;65965:1;65951:16;;:2;:16;;;65947:192;;65984:45;66021:7;65984:36;:45::i;:::-;65947:192;;;66068:2;66051:19;;:13;:19;;;66047:92;;66087:40;66115:2;66119:7;66087:27;:40::i;:::-;66047:92;65947:192;66158:13;66151:20;;;65539:640;;;;;:::o;60896:318::-;61024:1;61004:22;;:8;:22;;;61000:93;;61072:8;61050:31;;;;;;;;;;;:::i;:::-;;;;;;;;61000:93;61141:8;61103:18;:25;61122:5;61103:25;;;;;;;;;;;;;;;:35;61129:8;61103:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;61187:8;61165:41;;61180:5;61165:41;;;61197:8;61165:41;;;;;;:::i;:::-;;;;;;;;60896:318;;;:::o;62254:799::-;62388:1;62371:2;:14;;;:18;62367:679;;;62426:2;62410:36;;;62447:12;:10;:12::i;:::-;62461:4;62467:7;62476:4;62410:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;62406:629;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62741:1;62724:6;:13;:18;62720:300;;62796:2;62774:25;;;;;;;;;;;:::i;:::-;;;;;;;;62720:300;62970:6;62964:13;62955:6;62951:2;62947:15;62940:38;62406:629;62539:41;;;62529:51;;;:6;:51;;;;62525:132;;62634:2;62612:25;;;;;;;;;;;:::i;:::-;;;;;;;;62525:132;62482:190;62367:679;62254:799;;;;:::o;48145:94::-;48196:13;48222:9;;;;;;;;;;;;;;48145:94;:::o;31918:718::-;31974:13;32025:14;32062:1;32042:17;32053:5;32042:10;:17::i;:::-;:21;32025:38;;32078:20;32112:6;32101:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32078:41;;32134:11;32263:6;32259:2;32255:15;32247:6;32243:28;32236:35;;32300:290;32307:4;32300:290;;;32332:5;;;;;;;;32474:10;32469:2;32462:5;32458:14;32453:32;32448:3;32440:46;32532:2;32523:11;;;;;;:::i;:::-;;;;;32566:1;32557:5;:10;32300:290;32553:21;32300:290;32611:6;32604:13;;;;;31918:718;;;:::o;7222:127::-;7329:1;7311:7;:14;;;:19;;;;;;;;;;;7222:127;:::o;7100:114::-;7165:7;7192;:14;;;7185:21;;7100:114;;;:::o;55110:335::-;55192:1;55178:16;;:2;:16;;;55174:89;;55248:1;55218:33;;;;;;;;;;;:::i;:::-;;;;;;;;55174:89;55273:21;55297:32;55305:2;55309:7;55326:1;55297:7;:32::i;:::-;55273:56;;55369:1;55344:27;;:13;:27;;;55340:98;;55423:1;55395:31;;;;;;;;;;;:::i;:::-;;;;;;;;55340:98;55163:282;55110:335;;:::o;38139:148::-;38215:4;38254:25;38239:40;;;:11;:40;;;;38232:47;;38139:148;;;:::o;50750:117::-;50816:7;50843;:16;50851:7;50843:16;;;;;;;;;;;;;;;;;;;;;50836:23;;50750:117;;;:::o;59999:678::-;60161:9;:31;;;;60190:1;60174:18;;:4;:18;;;;60161:31;60157:471;;;60209:13;60225:22;60239:7;60225:13;:22::i;:::-;60209:38;;60394:1;60378:18;;:4;:18;;;;:35;;;;;60409:4;60400:13;;:5;:13;;;;60378:35;:69;;;;;60418:29;60435:5;60442:4;60418:16;:29::i;:::-;60417:30;60378:69;60374:144;;;60497:4;60475:27;;;;;;;;;;;:::i;:::-;;;;;;;;60374:144;60538:9;60534:83;;;60593:7;60589:2;60573:28;;60582:5;60573:28;;;;;;;;;;;;60534:83;60194:434;60157:471;60667:2;60640:15;:24;60656:7;60640:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;59999:678;;;;:::o;53950:824::-;54036:7;54056:12;54071:17;54080:7;54071:8;:17::i;:::-;54056:32;;54167:1;54151:18;;:4;:18;;;54147:88;;54186:37;54203:4;54209;54215:7;54186:16;:37::i;:::-;54147:88;54298:1;54282:18;;:4;:18;;;54278:263;;54400:48;54417:1;54421:7;54438:1;54442:5;54400:8;:48::i;:::-;54513:1;54494:9;:15;54504:4;54494:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;54278:263;54571:1;54557:16;;:2;:16;;;54553:111;;54636:1;54619:9;:13;54629:2;54619:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;54553:111;54695:2;54676:7;:16;54684:7;54676:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;54734:7;54730:2;54715:27;;54724:4;54715:27;;;;;;;;;;;;54762:4;54755:11;;;53950:824;;;;;:::o;66899:164::-;67003:10;:17;;;;66976:15;:24;66992:7;66976:24;;;;;;;;;;;:44;;;;67031:10;67047:7;67031:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66899:164;:::o;67690:977::-;67956:22;67981:15;67991:4;67981:9;:15::i;:::-;67956:40;;68007:18;68028:17;:26;68046:7;68028:26;;;;;;;;;;;;68007:47;;68175:14;68161:10;:28;68157:328;;68206:19;68228:12;:18;68241:4;68228:18;;;;;;;;;;;;;;;:34;68247:14;68228:34;;;;;;;;;;;;68206:56;;68312:11;68279:12;:18;68292:4;68279:18;;;;;;;;;;;;;;;:30;68298:10;68279:30;;;;;;;;;;;:44;;;;68429:10;68396:17;:30;68414:11;68396:30;;;;;;;;;;;:43;;;;68191:294;68157:328;68581:17;:26;68599:7;68581:26;;;;;;;;;;;68574:33;;;68625:12;:18;68638:4;68625:18;;;;;;;;;;;;;;;:34;68644:14;68625:34;;;;;;;;;;;68618:41;;;67771:896;;67690:977;;:::o;68962:1079::-;69215:22;69260:1;69240:10;:17;;;;:21;;;;:::i;:::-;69215:46;;69272:18;69293:15;:24;69309:7;69293:24;;;;;;;;;;;;69272:45;;69644:19;69666:10;69677:14;69666:26;;;;;;;;:::i;:::-;;;;;;;;;;69644:48;;69730:11;69705:10;69716;69705:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;69841:10;69810:15;:28;69826:11;69810:28;;;;;;;;;;;:41;;;;69982:15;:24;69998:7;69982:24;;;;;;;;;;;69975:31;;;70017:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;69033:1008;;;68962:1079;:::o;66480:218::-;66565:14;66598:1;66582:13;66592:2;66582:9;:13::i;:::-;:17;;;;:::i;:::-;66565:34;;66637:7;66610:12;:16;66623:2;66610:16;;;;;;;;;;;;;;;:24;66627:6;66610:24;;;;;;;;;;;:34;;;;66684:6;66655:17;:26;66673:7;66655:26;;;;;;;;;;;:35;;;;66554:144;66480:218;;:::o;28322:948::-;28375:7;28395:14;28412:1;28395:18;;28462:8;28453:5;:17;28449:106;;28500:8;28491:17;;;;;;:::i;:::-;;;;;28537:2;28527:12;;;;28449:106;28582:8;28573:5;:17;28569:106;;28620:8;28611:17;;;;;;:::i;:::-;;;;;28657:2;28647:12;;;;28569:106;28702:8;28693:5;:17;28689:106;;28740:8;28731:17;;;;;;:::i;:::-;;;;;28777:2;28767:12;;;;28689:106;28822:7;28813:5;:16;28809:103;;28859:7;28850:16;;;;;;:::i;:::-;;;;;28895:1;28885:11;;;;28809:103;28939:7;28930:5;:16;28926:103;;28976:7;28967:16;;;;;;:::i;:::-;;;;;29012:1;29002:11;;;;28926:103;29056:7;29047:5;:16;29043:103;;29093:7;29084:16;;;;;;:::i;:::-;;;;;29129:1;29119:11;;;;29043:103;29173:7;29164:5;:16;29160:68;;29211:1;29201:11;;;;29160:68;29256:6;29249:13;;;28322:948;;;:::o;52157:376::-;52270:38;52284:5;52291:7;52300;52270:13;:38::i;:::-;52265:261;;52346:1;52329:19;;:5;:19;;;52325:190;;52399:7;52376:31;;;;;;;;;;;:::i;:::-;;;;;;;;52325:190;52482:7;52491;52455:44;;;;;;;;;;;;:::i;:::-;;;;;;;;52265:261;52157:376;;;:::o;51437:276::-;51540:4;51596:1;51577:21;;:7;:21;;;;:128;;;;;51625:7;51616:16;;:5;:16;;;:52;;;;51636:32;51653:5;51660:7;51636:16;:32::i;:::-;51616:52;:88;;;;51697:7;51672:32;;:21;51685:7;51672:12;:21::i;:::-;:32;;;51616:88;51577:128;51557:148;;51437:276;;;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:180::-;138:77;135:1;128:88;235:4;232:1;225:15;259:4;256:1;249:15;276:191;316:3;335:20;353:1;335:20;:::i;:::-;330:25;;369:20;387:1;369:20;:::i;:::-;364:25;;412:1;409;405:9;398:16;;433:3;430:1;427:10;424:36;;;440:18;;:::i;:::-;424:36;276:191;;;;:::o;473:75::-;506:6;539:2;533:9;523:19;;473:75;:::o;554:117::-;663:1;660;653:12;677:117;786:1;783;776:12;800:149;836:7;876:66;869:5;865:78;854:89;;800:149;;;:::o;955:120::-;1027:23;1044:5;1027:23;:::i;:::-;1020:5;1017:34;1007:62;;1065:1;1062;1055:12;1007:62;955:120;:::o;1081:137::-;1126:5;1164:6;1151:20;1142:29;;1180:32;1206:5;1180:32;:::i;:::-;1081:137;;;;:::o;1224:327::-;1282:6;1331:2;1319:9;1310:7;1306:23;1302:32;1299:119;;;1337:79;;:::i;:::-;1299:119;1457:1;1482:52;1526:7;1517:6;1506:9;1502:22;1482:52;:::i;:::-;1472:62;;1428:116;1224:327;;;;:::o;1557:90::-;1591:7;1634:5;1627:13;1620:21;1609:32;;1557:90;;;:::o;1653:109::-;1734:21;1749:5;1734:21;:::i;:::-;1729:3;1722:34;1653:109;;:::o;1768:210::-;1855:4;1893:2;1882:9;1878:18;1870:26;;1906:65;1968:1;1957:9;1953:17;1944:6;1906:65;:::i;:::-;1768:210;;;;:::o;1984:99::-;2036:6;2070:5;2064:12;2054:22;;1984:99;;;:::o;2089:169::-;2173:11;2207:6;2202:3;2195:19;2247:4;2242:3;2238:14;2223:29;;2089:169;;;;:::o;2264:246::-;2345:1;2355:113;2369:6;2366:1;2363:13;2355:113;;;2454:1;2449:3;2445:11;2439:18;2435:1;2430:3;2426:11;2419:39;2391:2;2388:1;2384:10;2379:15;;2355:113;;;2502:1;2493:6;2488:3;2484:16;2477:27;2326:184;2264:246;;;:::o;2516:102::-;2557:6;2608:2;2604:7;2599:2;2592:5;2588:14;2584:28;2574:38;;2516:102;;;:::o;2624:377::-;2712:3;2740:39;2773:5;2740:39;:::i;:::-;2795:71;2859:6;2854:3;2795:71;:::i;:::-;2788:78;;2875:65;2933:6;2928:3;2921:4;2914:5;2910:16;2875:65;:::i;:::-;2965:29;2987:6;2965:29;:::i;:::-;2960:3;2956:39;2949:46;;2716:285;2624:377;;;;:::o;3007:313::-;3120:4;3158:2;3147:9;3143:18;3135:26;;3207:9;3201:4;3197:20;3193:1;3182:9;3178:17;3171:47;3235:78;3308:4;3299:6;3235:78;:::i;:::-;3227:86;;3007:313;;;;:::o;3326:122::-;3399:24;3417:5;3399:24;:::i;:::-;3392:5;3389:35;3379:63;;3438:1;3435;3428:12;3379:63;3326:122;:::o;3454:139::-;3500:5;3538:6;3525:20;3516:29;;3554:33;3581:5;3554:33;:::i;:::-;3454:139;;;;:::o;3599:329::-;3658:6;3707:2;3695:9;3686:7;3682:23;3678:32;3675:119;;;3713:79;;:::i;:::-;3675:119;3833:1;3858:53;3903:7;3894:6;3883:9;3879:22;3858:53;:::i;:::-;3848:63;;3804:117;3599:329;;;;:::o;3934:126::-;3971:7;4011:42;4004:5;4000:54;3989:65;;3934:126;;;:::o;4066:96::-;4103:7;4132:24;4150:5;4132:24;:::i;:::-;4121:35;;4066:96;;;:::o;4168:118::-;4255:24;4273:5;4255:24;:::i;:::-;4250:3;4243:37;4168:118;;:::o;4292:222::-;4385:4;4423:2;4412:9;4408:18;4400:26;;4436:71;4504:1;4493:9;4489:17;4480:6;4436:71;:::i;:::-;4292:222;;;;:::o;4520:122::-;4593:24;4611:5;4593:24;:::i;:::-;4586:5;4583:35;4573:63;;4632:1;4629;4622:12;4573:63;4520:122;:::o;4648:139::-;4694:5;4732:6;4719:20;4710:29;;4748:33;4775:5;4748:33;:::i;:::-;4648:139;;;;:::o;4793:474::-;4861:6;4869;4918:2;4906:9;4897:7;4893:23;4889:32;4886:119;;;4924:79;;:::i;:::-;4886:119;5044:1;5069:53;5114:7;5105:6;5094:9;5090:22;5069:53;:::i;:::-;5059:63;;5015:117;5171:2;5197:53;5242:7;5233:6;5222:9;5218:22;5197:53;:::i;:::-;5187:63;;5142:118;4793:474;;;;;:::o;5273:118::-;5360:24;5378:5;5360:24;:::i;:::-;5355:3;5348:37;5273:118;;:::o;5397:222::-;5490:4;5528:2;5517:9;5513:18;5505:26;;5541:71;5609:1;5598:9;5594:17;5585:6;5541:71;:::i;:::-;5397:222;;;;:::o;5625:86::-;5660:7;5700:4;5693:5;5689:16;5678:27;;5625:86;;;:::o;5717:112::-;5800:22;5816:5;5800:22;:::i;:::-;5795:3;5788:35;5717:112;;:::o;5835:846::-;6076:4;6114:3;6103:9;6099:19;6091:27;;6128:67;6192:1;6181:9;6177:17;6168:6;6128:67;:::i;:::-;6205:68;6269:2;6258:9;6254:18;6245:6;6205:68;:::i;:::-;6283;6347:2;6336:9;6332:18;6323:6;6283:68;:::i;:::-;6361:72;6429:2;6418:9;6414:18;6405:6;6361:72;:::i;:::-;6443:73;6511:3;6500:9;6496:19;6487:6;6443:73;:::i;:::-;6526:69;6590:3;6579:9;6575:19;6566:6;6526:69;:::i;:::-;6605;6669:3;6658:9;6654:19;6645:6;6605:69;:::i;:::-;5835:846;;;;;;;;;;:::o;6687:619::-;6764:6;6772;6780;6829:2;6817:9;6808:7;6804:23;6800:32;6797:119;;;6835:79;;:::i;:::-;6797:119;6955:1;6980:53;7025:7;7016:6;7005:9;7001:22;6980:53;:::i;:::-;6970:63;;6926:117;7082:2;7108:53;7153:7;7144:6;7133:9;7129:22;7108:53;:::i;:::-;7098:63;;7053:118;7210:2;7236:53;7281:7;7272:6;7261:9;7257:22;7236:53;:::i;:::-;7226:63;;7181:118;6687:619;;;;;:::o;7312:60::-;7340:3;7361:5;7354:12;;7312:60;;;:::o;7378:142::-;7428:9;7461:53;7479:34;7488:24;7506:5;7488:24;:::i;:::-;7479:34;:::i;:::-;7461:53;:::i;:::-;7448:66;;7378:142;;;:::o;7526:126::-;7576:9;7609:37;7640:5;7609:37;:::i;:::-;7596:50;;7526:126;;;:::o;7658:140::-;7722:9;7755:37;7786:5;7755:37;:::i;:::-;7742:50;;7658:140;;;:::o;7804:159::-;7905:51;7950:5;7905:51;:::i;:::-;7900:3;7893:64;7804:159;;:::o;7969:250::-;8076:4;8114:2;8103:9;8099:18;8091:26;;8127:85;8209:1;8198:9;8194:17;8185:6;8127:85;:::i;:::-;7969:250;;;;:::o;8225:329::-;8284:6;8333:2;8321:9;8312:7;8308:23;8304:32;8301:119;;;8339:79;;:::i;:::-;8301:119;8459:1;8484:53;8529:7;8520:6;8509:9;8505:22;8484:53;:::i;:::-;8474:63;;8430:117;8225:329;;;;:::o;8560:965::-;8833:4;8871:3;8860:9;8856:19;8848:27;;8885:71;8953:1;8942:9;8938:17;8929:6;8885:71;:::i;:::-;8966:68;9030:2;9019:9;9015:18;9006:6;8966:68;:::i;:::-;9044;9108:2;9097:9;9093:18;9084:6;9044:68;:::i;:::-;9122;9186:2;9175:9;9171:18;9162:6;9122:68;:::i;:::-;9200:73;9268:3;9257:9;9253:19;9244:6;9200:73;:::i;:::-;9283:69;9347:3;9336:9;9332:19;9323:6;9283:69;:::i;:::-;9362:73;9430:3;9419:9;9415:19;9406:6;9362:73;:::i;:::-;9445;9513:3;9502:9;9498:19;9489:6;9445:73;:::i;:::-;8560:965;;;;;;;;;;;:::o;9531:743::-;9748:4;9786:3;9775:9;9771:19;9763:27;;9800:67;9864:1;9853:9;9849:17;9840:6;9800:67;:::i;:::-;9877:68;9941:2;9930:9;9926:18;9917:6;9877:68;:::i;:::-;9955;10019:2;10008:9;10004:18;9995:6;9955:68;:::i;:::-;10033:72;10101:2;10090:9;10086:18;10077:6;10033:72;:::i;:::-;10115:69;10179:3;10168:9;10164:19;10155:6;10115:69;:::i;:::-;10194:73;10262:3;10251:9;10247:19;10238:6;10194:73;:::i;:::-;9531:743;;;;;;;;;:::o;10280:116::-;10350:21;10365:5;10350:21;:::i;:::-;10343:5;10340:32;10330:60;;10386:1;10383;10376:12;10330:60;10280:116;:::o;10402:133::-;10445:5;10483:6;10470:20;10461:29;;10499:30;10523:5;10499:30;:::i;:::-;10402:133;;;;:::o;10541:468::-;10606:6;10614;10663:2;10651:9;10642:7;10638:23;10634:32;10631:119;;;10669:79;;:::i;:::-;10631:119;10789:1;10814:53;10859:7;10850:6;10839:9;10835:22;10814:53;:::i;:::-;10804:63;;10760:117;10916:2;10942:50;10984:7;10975:6;10964:9;10960:22;10942:50;:::i;:::-;10932:60;;10887:115;10541:468;;;;;:::o;11015:117::-;11124:1;11121;11114:12;11138:117;11247:1;11244;11237:12;11261:180;11309:77;11306:1;11299:88;11406:4;11403:1;11396:15;11430:4;11427:1;11420:15;11447:281;11530:27;11552:4;11530:27;:::i;:::-;11522:6;11518:40;11660:6;11648:10;11645:22;11624:18;11612:10;11609:34;11606:62;11603:88;;;11671:18;;:::i;:::-;11603:88;11711:10;11707:2;11700:22;11490:238;11447:281;;:::o;11734:129::-;11768:6;11795:20;;:::i;:::-;11785:30;;11824:33;11852:4;11844:6;11824:33;:::i;:::-;11734:129;;;:::o;11869:307::-;11930:4;12020:18;12012:6;12009:30;12006:56;;;12042:18;;:::i;:::-;12006:56;12080:29;12102:6;12080:29;:::i;:::-;12072:37;;12164:4;12158;12154:15;12146:23;;11869:307;;;:::o;12182:146::-;12279:6;12274:3;12269;12256:30;12320:1;12311:6;12306:3;12302:16;12295:27;12182:146;;;:::o;12334:423::-;12411:5;12436:65;12452:48;12493:6;12452:48;:::i;:::-;12436:65;:::i;:::-;12427:74;;12524:6;12517:5;12510:21;12562:4;12555:5;12551:16;12600:3;12591:6;12586:3;12582:16;12579:25;12576:112;;;12607:79;;:::i;:::-;12576:112;12697:54;12744:6;12739:3;12734;12697:54;:::i;:::-;12417:340;12334:423;;;;;:::o;12776:338::-;12831:5;12880:3;12873:4;12865:6;12861:17;12857:27;12847:122;;12888:79;;:::i;:::-;12847:122;13005:6;12992:20;13030:78;13104:3;13096:6;13089:4;13081:6;13077:17;13030:78;:::i;:::-;13021:87;;12837:277;12776:338;;;;:::o;13120:943::-;13215:6;13223;13231;13239;13288:3;13276:9;13267:7;13263:23;13259:33;13256:120;;;13295:79;;:::i;:::-;13256:120;13415:1;13440:53;13485:7;13476:6;13465:9;13461:22;13440:53;:::i;:::-;13430:63;;13386:117;13542:2;13568:53;13613:7;13604:6;13593:9;13589:22;13568:53;:::i;:::-;13558:63;;13513:118;13670:2;13696:53;13741:7;13732:6;13721:9;13717:22;13696:53;:::i;:::-;13686:63;;13641:118;13826:2;13815:9;13811:18;13798:32;13857:18;13849:6;13846:30;13843:117;;;13879:79;;:::i;:::-;13843:117;13984:62;14038:7;14029:6;14018:9;14014:22;13984:62;:::i;:::-;13974:72;;13769:287;13120:943;;;;;;;:::o;14069:474::-;14137:6;14145;14194:2;14182:9;14173:7;14169:23;14165:32;14162:119;;;14200:79;;:::i;:::-;14162:119;14320:1;14345:53;14390:7;14381:6;14370:9;14366:22;14345:53;:::i;:::-;14335:63;;14291:117;14447:2;14473:53;14518:7;14509:6;14498:9;14494:22;14473:53;:::i;:::-;14463:63;;14418:118;14069:474;;;;;:::o;14549:180::-;14597:77;14594:1;14587:88;14694:4;14691:1;14684:15;14718:4;14715:1;14708:15;14735:320;14779:6;14816:1;14810:4;14806:12;14796:22;;14863:1;14857:4;14853:12;14884:18;14874:81;;14940:4;14932:6;14928:17;14918:27;;14874:81;15002:2;14994:6;14991:14;14971:18;14968:38;14965:84;;15021:18;;:::i;:::-;14965:84;14786:269;14735:320;;;:::o;15061:176::-;15201:28;15197:1;15189:6;15185:14;15178:52;15061:176;:::o;15243:366::-;15385:3;15406:67;15470:2;15465:3;15406:67;:::i;:::-;15399:74;;15482:93;15571:3;15482:93;:::i;:::-;15600:2;15595:3;15591:12;15584:19;;15243:366;;;:::o;15615:419::-;15781:4;15819:2;15808:9;15804:18;15796:26;;15868:9;15862:4;15858:20;15854:1;15843:9;15839:17;15832:47;15896:131;16022:4;15896:131;:::i;:::-;15888:139;;15615:419;;;:::o;16040:222::-;16180:34;16176:1;16168:6;16164:14;16157:58;16249:5;16244:2;16236:6;16232:15;16225:30;16040:222;:::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:194::-;17105:4;17125:20;17143:1;17125:20;:::i;:::-;17120:25;;17159:20;17177:1;17159:20;:::i;:::-;17154:25;;17203:1;17200;17196:9;17188:17;;17227:1;17221:4;17218:11;17215:37;;;17232:18;;:::i;:::-;17215:37;17065:194;;;;:::o;17265:180::-;17313:77;17310:1;17303:88;17410:4;17407:1;17400:15;17434:4;17431:1;17424:15;17451:179;17591:31;17587:1;17579:6;17575:14;17568:55;17451:179;:::o;17636:366::-;17778:3;17799:67;17863:2;17858:3;17799:67;:::i;:::-;17792:74;;17875:93;17964:3;17875:93;:::i;:::-;17993:2;17988:3;17984:12;17977:19;;17636:366;;;:::o;18008:419::-;18174:4;18212:2;18201:9;18197:18;18189:26;;18261:9;18255:4;18251:20;18247:1;18236:9;18232:17;18225:47;18289:131;18415:4;18289:131;:::i;:::-;18281:139;;18008:419;;;:::o;18433:169::-;18573:21;18569:1;18561:6;18557:14;18550:45;18433:169;:::o;18608:366::-;18750:3;18771:67;18835:2;18830:3;18771:67;:::i;:::-;18764:74;;18847:93;18936:3;18847:93;:::i;:::-;18965:2;18960:3;18956:12;18949:19;;18608:366;;;:::o;18980:419::-;19146:4;19184:2;19173:9;19169:18;19161:26;;19233:9;19227:4;19223:20;19219:1;19208:9;19204:17;19197:47;19261:131;19387:4;19261:131;:::i;:::-;19253:139;;18980:419;;;:::o;19405:240::-;19545:34;19541:1;19533:6;19529:14;19522:58;19614:23;19609:2;19601:6;19597:15;19590:48;19405:240;:::o;19651:366::-;19793:3;19814:67;19878:2;19873:3;19814:67;:::i;:::-;19807:74;;19890:93;19979:3;19890:93;:::i;:::-;20008:2;20003:3;19999:12;19992:19;;19651:366;;;:::o;20023:419::-;20189:4;20227:2;20216:9;20212:18;20204:26;;20276:9;20270:4;20266:20;20262:1;20251:9;20247:17;20240:47;20304:131;20430:4;20304:131;:::i;:::-;20296:139;;20023:419;;;:::o;20448:180::-;20496:77;20493:1;20486:88;20593:4;20590:1;20583:15;20617:4;20614:1;20607:15;20634:185;20674:1;20691:20;20709:1;20691:20;:::i;:::-;20686:25;;20725:20;20743:1;20725:20;:::i;:::-;20720:25;;20764:1;20754:35;;20769:18;;:::i;:::-;20754:35;20811:1;20808;20804:9;20799:14;;20634:185;;;;:::o;20825:410::-;20865:7;20888:20;20906:1;20888:20;:::i;:::-;20883:25;;20922:20;20940:1;20922:20;:::i;:::-;20917:25;;20977:1;20974;20970:9;20999:30;21017:11;20999:30;:::i;:::-;20988:41;;21178:1;21169:7;21165:15;21162:1;21159:22;21139:1;21132:9;21112:83;21089:139;;21208:18;;:::i;:::-;21089:139;20873:362;20825:410;;;;:::o;21241:231::-;21381:34;21377:1;21369:6;21365:14;21358:58;21450:14;21445:2;21437:6;21433:15;21426:39;21241:231;:::o;21478:366::-;21620:3;21641:67;21705:2;21700:3;21641:67;:::i;:::-;21634:74;;21717:93;21806:3;21717:93;:::i;:::-;21835:2;21830:3;21826:12;21819:19;;21478:366;;;:::o;21850:419::-;22016:4;22054:2;22043:9;22039:18;22031:26;;22103:9;22097:4;22093:20;22089:1;22078:9;22074:17;22067:47;22131:131;22257:4;22131:131;:::i;:::-;22123:139;;21850:419;;;:::o;22275:442::-;22424:4;22462:2;22451:9;22447:18;22439:26;;22475:71;22543:1;22532:9;22528:17;22519:6;22475:71;:::i;:::-;22556:72;22624:2;22613:9;22609:18;22600:6;22556:72;:::i;:::-;22638;22706:2;22695:9;22691:18;22682:6;22638:72;:::i;:::-;22275:442;;;;;;:::o;22723:332::-;22844:4;22882:2;22871:9;22867:18;22859:26;;22895:71;22963:1;22952:9;22948:17;22939:6;22895:71;:::i;:::-;22976:72;23044:2;23033:9;23029:18;23020:6;22976:72;:::i;:::-;22723:332;;;;;:::o;23061:176::-;23201:28;23197:1;23189:6;23185:14;23178:52;23061:176;:::o;23243:366::-;23385:3;23406:67;23470:2;23465:3;23406:67;:::i;:::-;23399:74;;23482:93;23571:3;23482:93;:::i;:::-;23600:2;23595:3;23591:12;23584:19;;23243:366;;;:::o;23615:419::-;23781:4;23819:2;23808:9;23804:18;23796:26;;23868:9;23862:4;23858:20;23854:1;23843:9;23839:17;23832:47;23896:131;24022:4;23896:131;:::i;:::-;23888:139;;23615:419;;;:::o;24040:234::-;24180:34;24176:1;24168:6;24164:14;24157:58;24249:17;24244:2;24236:6;24232:15;24225:42;24040:234;:::o;24280:366::-;24422:3;24443:67;24507:2;24502:3;24443:67;:::i;:::-;24436:74;;24519:93;24608:3;24519:93;:::i;:::-;24637:2;24632:3;24628:12;24621:19;;24280:366;;;:::o;24652:419::-;24818:4;24856:2;24845:9;24841:18;24833:26;;24905:9;24899:4;24895:20;24891:1;24880:9;24876:17;24869:47;24933:131;25059:4;24933:131;:::i;:::-;24925:139;;24652:419;;;:::o;25077:176::-;25109:1;25126:20;25144:1;25126:20;:::i;:::-;25121:25;;25160:20;25178:1;25160:20;:::i;:::-;25155:25;;25199:1;25189:35;;25204:18;;:::i;:::-;25189:35;25245:1;25242;25238:9;25233:14;;25077:176;;;;:::o;25259:214::-;25348:4;25386:2;25375:9;25371:18;25363:26;;25399:67;25463:1;25452:9;25448:17;25439:6;25399:67;:::i;:::-;25259:214;;;;:::o;25479:241::-;25619:34;25615:1;25607:6;25603:14;25596:58;25688:24;25683:2;25675:6;25671:15;25664:49;25479:241;:::o;25726:366::-;25868:3;25889:67;25953:2;25948:3;25889:67;:::i;:::-;25882:74;;25965:93;26054:3;25965:93;:::i;:::-;26083:2;26078:3;26074:12;26067:19;;25726:366;;;:::o;26098:419::-;26264:4;26302:2;26291:9;26287:18;26279:26;;26351:9;26345:4;26341:20;26337:1;26326:9;26322:17;26315:47;26379:131;26505:4;26379:131;:::i;:::-;26371:139;;26098:419;;;:::o;26523:188::-;26561:3;26580:18;26596:1;26580:18;:::i;:::-;26575:23;;26612:18;26628:1;26612:18;:::i;:::-;26607:23;;26653:1;26650;26646:9;26639:16;;26676:4;26671:3;26668:13;26665:39;;;26684:18;;:::i;:::-;26665:39;26523:188;;;;:::o;26717:271::-;26755:7;26778:18;26794:1;26778:18;:::i;:::-;26773:23;;26810:18;26826:1;26810:18;:::i;:::-;26805:23;;26863:1;26860;26856:9;26885:28;26901:11;26885:28;:::i;:::-;26874:39;;26945:11;26936:7;26933:24;26923:58;;26961:18;;:::i;:::-;26923:58;26763:225;26717:271;;;;:::o;26994:148::-;27096:11;27133:3;27118:18;;26994:148;;;;:::o;27148:390::-;27254:3;27282:39;27315:5;27282:39;:::i;:::-;27337:89;27419:6;27414:3;27337:89;:::i;:::-;27330:96;;27435:65;27493:6;27488:3;27481:4;27474:5;27470:16;27435:65;:::i;:::-;27525:6;27520:3;27516:16;27509:23;;27258:280;27148:390;;;;:::o;27544:435::-;27724:3;27746:95;27837:3;27828:6;27746:95;:::i;:::-;27739:102;;27858:95;27949:3;27940:6;27858:95;:::i;:::-;27851:102;;27970:3;27963:10;;27544:435;;;;;:::o;27985:79::-;28024:7;28053:5;28042:16;;27985:79;;;:::o;28070:157::-;28175:45;28195:24;28213:5;28195:24;:::i;:::-;28175:45;:::i;:::-;28170:3;28163:58;28070:157;;:::o;28233:94::-;28266:8;28314:5;28310:2;28306:14;28285:35;;28233:94;;;:::o;28333:::-;28372:7;28401:20;28415:5;28401:20;:::i;:::-;28390:31;;28333:94;;;:::o;28433:100::-;28472:7;28501:26;28521:5;28501:26;:::i;:::-;28490:37;;28433:100;;;:::o;28539:157::-;28644:45;28664:24;28682:5;28664:24;:::i;:::-;28644:45;:::i;:::-;28639:3;28632:58;28539:157;;:::o;28702:538::-;28870:3;28885:75;28956:3;28947:6;28885:75;:::i;:::-;28985:2;28980:3;28976:12;28969:19;;28998:75;29069:3;29060:6;28998:75;:::i;:::-;29098:2;29093:3;29089:12;29082:19;;29111:75;29182:3;29173:6;29111:75;:::i;:::-;29211:2;29206:3;29202:12;29195:19;;29231:3;29224:10;;28702:538;;;;;;:::o;29246:223::-;29386:34;29382:1;29374:6;29370:14;29363:58;29455:6;29450:2;29442:6;29438:15;29431:31;29246:223;:::o;29475:366::-;29617:3;29638:67;29702:2;29697:3;29638:67;:::i;:::-;29631:74;;29714:93;29803:3;29714:93;:::i;:::-;29832:2;29827:3;29823:12;29816:19;;29475:366;;;:::o;29847:419::-;30013:4;30051:2;30040:9;30036:18;30028:26;;30100:9;30094:4;30090:20;30086:1;30075:9;30071:17;30064:47;30128:131;30254:4;30128:131;:::i;:::-;30120:139;;29847:419;;;:::o;30272:143::-;30329:5;30360:6;30354:13;30345:22;;30376:33;30403:5;30376:33;:::i;:::-;30272:143;;;;:::o;30421:351::-;30491:6;30540:2;30528:9;30519:7;30515:23;30511:32;30508:119;;;30546:79;;:::i;:::-;30508:119;30666:1;30691:64;30747:7;30738:6;30727:9;30723:22;30691:64;:::i;:::-;30681:74;;30637:128;30421:351;;;;:::o;30778:177::-;30918:29;30914:1;30906:6;30902:14;30895:53;30778:177;:::o;30961:366::-;31103:3;31124:67;31188:2;31183:3;31124:67;:::i;:::-;31117:74;;31200:93;31289:3;31200:93;:::i;:::-;31318:2;31313:3;31309:12;31302:19;;30961:366;;;:::o;31333:419::-;31499:4;31537:2;31526:9;31522:18;31514:26;;31586:9;31580:4;31576:20;31572:1;31561:9;31557:17;31550:47;31614:131;31740:4;31614:131;:::i;:::-;31606:139;;31333:419;;;:::o;31758:332::-;31879:4;31917:2;31906:9;31902:18;31894:26;;31930:71;31998:1;31987:9;31983:17;31974:6;31930:71;:::i;:::-;32011:72;32079:2;32068:9;32064:18;32055:6;32011:72;:::i;:::-;31758:332;;;;;:::o;32096:179::-;32236:31;32232:1;32224:6;32220:14;32213:55;32096:179;:::o;32281:366::-;32423:3;32444:67;32508:2;32503:3;32444:67;:::i;:::-;32437:74;;32520:93;32609:3;32520:93;:::i;:::-;32638:2;32633:3;32629:12;32622:19;;32281:366;;;:::o;32653:419::-;32819:4;32857:2;32846:9;32842:18;32834:26;;32906:9;32900:4;32896:20;32892:1;32881:9;32877:17;32870:47;32934:131;33060:4;32934:131;:::i;:::-;32926:139;;32653:419;;;:::o;33078:442::-;33227:4;33265:2;33254:9;33250:18;33242:26;;33278:71;33346:1;33335:9;33331:17;33322:6;33278:71;:::i;:::-;33359:72;33427:2;33416:9;33412:18;33403:6;33359:72;:::i;:::-;33441;33509:2;33498:9;33494:18;33485:6;33441:72;:::i;:::-;33078:442;;;;;;:::o;33526:137::-;33580:5;33611:6;33605:13;33596:22;;33627:30;33651:5;33627:30;:::i;:::-;33526:137;;;;:::o;33669:345::-;33736:6;33785:2;33773:9;33764:7;33760:23;33756:32;33753:119;;;33791:79;;:::i;:::-;33753:119;33911:1;33936:61;33989:7;33980:6;33969:9;33965:22;33936:61;:::i;:::-;33926:71;;33882:125;33669:345;;;;:::o;34020:181::-;34160:33;34156:1;34148:6;34144:14;34137:57;34020:181;:::o;34207:366::-;34349:3;34370:67;34434:2;34429:3;34370:67;:::i;:::-;34363:74;;34446:93;34535:3;34446:93;:::i;:::-;34564:2;34559:3;34555:12;34548:19;;34207:366;;;:::o;34579:419::-;34745:4;34783:2;34772:9;34768:18;34760:26;;34832:9;34826:4;34822:20;34818:1;34807:9;34803:17;34796:47;34860:131;34986:4;34860:131;:::i;:::-;34852:139;;34579:419;;;:::o;35004:98::-;35055:6;35089:5;35083:12;35073:22;;35004:98;;;:::o;35108:168::-;35191:11;35225:6;35220:3;35213:19;35265:4;35260:3;35256:14;35241:29;;35108:168;;;;:::o;35282:373::-;35368:3;35396:38;35428:5;35396:38;:::i;:::-;35450:70;35513:6;35508:3;35450:70;:::i;:::-;35443:77;;35529:65;35587:6;35582:3;35575:4;35568:5;35564:16;35529:65;:::i;:::-;35619:29;35641:6;35619:29;:::i;:::-;35614:3;35610:39;35603:46;;35372:283;35282:373;;;;:::o;35661:640::-;35856:4;35894:3;35883:9;35879:19;35871:27;;35908:71;35976:1;35965:9;35961:17;35952:6;35908:71;:::i;:::-;35989:72;36057:2;36046:9;36042:18;36033:6;35989:72;:::i;:::-;36071;36139:2;36128:9;36124:18;36115:6;36071:72;:::i;:::-;36190:9;36184:4;36180:20;36175:2;36164:9;36160:18;36153:48;36218:76;36289:4;36280:6;36218:76;:::i;:::-;36210:84;;35661:640;;;;;;;:::o;36307:141::-;36363:5;36394:6;36388:13;36379:22;;36410:32;36436:5;36410:32;:::i;:::-;36307:141;;;;:::o;36454:349::-;36523:6;36572:2;36560:9;36551:7;36547:23;36543:32;36540:119;;;36578:79;;:::i;:::-;36540:119;36698:1;36723:63;36778:7;36769:6;36758:9;36754:22;36723:63;:::i;:::-;36713:73;;36669:127;36454:349;;;;:::o;36809:180::-;36857:77;36854:1;36847:88;36954:4;36951:1;36944:15;36978:4;36975:1;36968:15
Swarm Source
ipfs://910124ce1472feea374ec91d7c2d7065334b1858a65553dd7f0cec3249ada7a5
Loading...
Loading
Loading...
Loading
Net Worth in USD
$59.96
Net Worth in ETH
0.028624
Token Allocations
ETH
100.00%
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $2,094.74 | 0.0286 | $59.96 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.