More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 5 from a total of 5 transactions
Latest 23 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19809201 | 159 days ago | 0.00063957 ETH | ||||
18944167 | 281 days ago | 0.00266107 ETH | ||||
18865235 | 292 days ago | 0.0009198 ETH | ||||
18848732 | 294 days ago | 0.00133582 ETH | ||||
18837318 | 296 days ago | 0.00281954 ETH | ||||
18816303 | 299 days ago | 0.00333355 ETH | ||||
18815463 | 299 days ago | 0.01339547 ETH | ||||
18815270 | 299 days ago | 0.00759199 ETH | ||||
18815185 | 299 days ago | 0.01289466 ETH | ||||
18814800 | 299 days ago | 0.00541953 ETH | ||||
18814684 | 299 days ago | 0.00605641 ETH | ||||
18814486 | 299 days ago | 0.00523874 ETH | ||||
18814472 | 299 days ago | 0.00879675 ETH | ||||
18814435 | 299 days ago | 0.01187874 ETH | ||||
18814342 | 299 days ago | 0.00611512 ETH | ||||
18814278 | 299 days ago | 0.01480233 ETH | ||||
18814178 | 299 days ago | 0.00418193 ETH | ||||
18814146 | 299 days ago | 0.00433584 ETH | ||||
18814115 | 299 days ago | 0.00804707 ETH | ||||
18814082 | 299 days ago | 0.00975432 ETH | ||||
18814066 | 299 days ago | 0.00612777 ETH | ||||
18814055 | 299 days ago | 0.01314954 ETH | ||||
18814045 | 299 days ago | 0.05425685 ETH |
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
[{"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
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $2,465.64 | 0.2038 | $502.38 |
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.