Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Source Code
Overview
Max Total Supply
361 MLP
Holders
245
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
4 MLPLoading...
Loading
Loading...
Loading
Loading...
Loading
| # | Exchange | Pair | Price | 24H Volume | % Volume |
|---|
Contract Name:
MetaLifeOgPets
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2023-07-06
*/
// File: @openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
// File: @openzeppelin/contracts/utils/Strings.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts (last updated v4.8.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;
}
}
// File: contracts/ERC721.sol
pragma solidity ^0.8.4;
/// @notice Simple ERC721 implementation with storage hitchhiking.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC721.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol)
///
/// @dev Note:
/// The ERC721 standard allows for self-approvals.
/// For performance, this implementation WILL NOT revert for such actions.
/// Please add any checks with overrides if desired.
abstract contract ERC721 {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev An account can hold up to 4294967295 tokens.
uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Only the token owner or an approved account can manage the token.
error NotOwnerNorApproved();
/// @dev The token does not exist.
error TokenDoesNotExist();
/// @dev The token already exists.
error TokenAlreadyExists();
/// @dev Cannot query the balance for the zero address.
error BalanceQueryForZeroAddress();
/// @dev Cannot mint or transfer to the zero address.
error TransferToZeroAddress();
/// @dev The token must be owned by `from`.
error TransferFromIncorrectOwner();
/// @dev The recipient's balance has overflowed.
error AccountBalanceOverflow();
/// @dev Cannot safely transfer to a contract that does not implement
/// the ERC721Receiver interface.
error TransferToNonERC721ReceiverImplementer();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Emitted when token `id` is transferred from `from` to `to`.
event Transfer(address indexed from, address indexed to, uint256 indexed id);
/// @dev Emitted when `owner` enables `account` to manage the `id` token.
event Approval(address indexed owner, address indexed account, uint256 indexed id);
/// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens.
event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved);
/// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`.
uint256 private constant _TRANSFER_EVENT_SIGNATURE =
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
/// @dev `keccak256(bytes("Approval(address,address,uint256)"))`.
uint256 private constant _APPROVAL_EVENT_SIGNATURE =
0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;
/// @dev `keccak256(bytes("ApprovalForAll(address,address,bool)"))`.
uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE =
0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ownership data slot of `id` is given by:
/// ```
/// mstore(0x00, id)
/// mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
/// let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
/// ```
/// Bits Layout:
// - [0..159] `addr`
// - [160..223] `extraData`
///
/// The approved address slot is given by: `add(1, ownershipSlot)`.
///
/// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip
///
/// The balance slot of `owner` is given by:
/// ```
/// mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
/// mstore(0x00, owner)
/// let balanceSlot := keccak256(0x0c, 0x1c)
/// ```
/// Bits Layout:
/// - [0..31] `balance`
/// - [32..225] `aux`
///
/// The `operator` approval slot of `owner` is given by:
/// ```
/// mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))
/// mstore(0x00, owner)
/// let operatorApprovalSlot := keccak256(0x0c, 0x30)
/// ```
uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192;
/// @dev Pre-shifted and pre-masked constant.
uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ERC721 METADATA */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the token collection name.
function name() public view virtual returns (string memory);
/// @dev Returns the token collection symbol.
function symbol() public view virtual returns (string memory);
/// @dev Returns the Uniform Resource Identifier (URI) for token `id`.
function tokenURI(uint256 id) public view virtual returns (string memory);
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ERC721 */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the owner of token `id`.
///
/// Requirements:
/// - Token `id` must exist.
function ownerOf(uint256 id) public view virtual returns (address result) {
result = _ownerOf(id);
/// @solidity memory-safe-assembly
assembly {
if iszero(result) {
mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Returns the number of tokens owned by `owner`.
///
/// Requirements:
/// - `owner` must not be the zero address.
function balanceOf(address owner) public view virtual returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
// Revert if the `owner` is the zero address.
if iszero(owner) {
mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`.
revert(0x1c, 0x04)
}
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
mstore(0x00, owner)
result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE)
}
}
/// @dev Returns the account approved to managed token `id`.
///
/// Requirements:
/// - Token `id` must exist.
function getApproved(uint256 id) public view virtual returns (address result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
if iszero(shr(96, shl(96, sload(ownershipSlot)))) {
mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
revert(0x1c, 0x04)
}
result := sload(add(1, ownershipSlot))
}
}
/// @dev Sets `account` as the approved account to manage token `id`.
///
/// Requirements:
/// - Token `id` must exist.
/// - The caller must be the owner of the token,
/// or an approved operator for the token owner.
///
/// Emits a {Approval} event.
function approve(address account, uint256 id) public payable virtual {
_approve(msg.sender, account, id);
}
/// @dev Returns whether `operator` is approved to manage the tokens of `owner`.
function isApprovedForAll(address owner, address operator)
public
view
virtual
returns (bool result)
{
/// @solidity memory-safe-assembly
assembly {
mstore(0x1c, operator)
mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)
mstore(0x00, owner)
result := sload(keccak256(0x0c, 0x30))
}
}
/// @dev Sets whether `operator` is approved to manage the tokens of the caller.
///
/// Emits a {ApprovalForAll} event.
function setApprovalForAll(address operator, bool isApproved) public virtual {
/// @solidity memory-safe-assembly
assembly {
// Convert to 0 or 1.
isApproved := iszero(iszero(isApproved))
// Update the `isApproved` for (`msg.sender`, `operator`).
mstore(0x1c, operator)
mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x30), isApproved)
// Emit the {ApprovalForAll} event.
mstore(0x00, isApproved)
log3(
0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator))
)
}
}
/// @dev Transfers token `id` from `from` to `to`.
///
/// Requirements:
///
/// - Token `id` must exist.
/// - `from` must be the owner of the token.
/// - `to` cannot be the zero address.
/// - The caller must be the owner of the token, or be approved to manage the token.
///
/// Emits a {Transfer} event.
function transferFrom(address from, address to, uint256 id) public payable virtual {
_beforeTokenTransfer(from, to, id);
/// @solidity memory-safe-assembly
assembly {
// Clear the upper 96 bits.
let bitmaskAddress := shr(96, not(0))
from := and(bitmaskAddress, from)
to := and(bitmaskAddress, to)
// Load the ownership data.
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller()))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let ownershipPacked := sload(ownershipSlot)
let owner := and(bitmaskAddress, ownershipPacked)
// Revert if `from` is not the owner, or does not exist.
if iszero(mul(owner, eq(owner, from))) {
if iszero(owner) {
mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
revert(0x1c, 0x04)
}
mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`.
revert(0x1c, 0x04)
}
// Revert if `to` is the zero address.
if iszero(to) {
mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
revert(0x1c, 0x04)
}
// Load, check, and update the token approval.
{
mstore(0x00, from)
let approvedAddress := sload(add(1, ownershipSlot))
// Revert if the caller is not the owner, nor approved.
if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) {
if iszero(sload(keccak256(0x0c, 0x30))) {
mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
revert(0x1c, 0x04)
}
}
// Delete the approved address if any.
if approvedAddress { sstore(add(1, ownershipSlot), 0) }
}
// Update with the new owner.
sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))
// Decrement the balance of `from`.
{
let fromBalanceSlot := keccak256(0x0c, 0x1c)
sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))
}
// Increment the balance of `to`.
{
mstore(0x00, to)
let toBalanceSlot := keccak256(0x0c, 0x1c)
let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
revert(0x1c, 0x04)
}
sstore(toBalanceSlot, toBalanceSlotPacked)
}
// Emit the {Transfer} event.
log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)
}
_afterTokenTransfer(from, to, id);
}
/// @dev Equivalent to `safeTransferFrom(from, to, id, "")`.
function safeTransferFrom(address from, address to, uint256 id) public payable virtual {
transferFrom(from, to, id);
if (_hasCode(to)) _checkOnERC721Received(from, to, id, "");
}
/// @dev Transfers token `id` from `from` to `to`.
///
/// Requirements:
///
/// - Token `id` must exist.
/// - `from` must be the owner of the token.
/// - `to` cannot be the zero address.
/// - The caller must be the owner of the token, or be approved to manage the token.
/// - 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 id, bytes calldata data)
public
payable
virtual
{
transferFrom(from, to, id);
if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
}
/// @dev Returns true if this contract implements the interface defined by `interfaceId`.
/// See: https://eips.ethereum.org/EIPS/eip-165
/// This function call must use less than 30000 gas.
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
let s := shr(224, interfaceId)
// ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f.
result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL QUERY FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns if token `id` exists.
function _exists(uint256 id) internal view virtual returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
result := shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))
}
}
/// @dev Returns the owner of token `id`.
/// Returns the zero address instead of reverting if the token does not exist.
function _ownerOf(uint256 id) internal view virtual returns (address result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL DATA HITCHHIKING FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the auxiliary data for `owner`.
/// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.
/// Auxiliary data can be set for any address, even if it does not have any tokens.
function _getAux(address owner) internal view virtual returns (uint224 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
mstore(0x00, owner)
result := shr(32, sload(keccak256(0x0c, 0x1c)))
}
}
/// @dev Set the auxiliary data for `owner` to `value`.
/// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.
/// Auxiliary data can be set for any address, even if it does not have any tokens.
function _setAux(address owner, uint224 value) internal virtual {
/// @solidity memory-safe-assembly
assembly {
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
mstore(0x00, owner)
let balanceSlot := keccak256(0x0c, 0x1c)
let packed := sload(balanceSlot)
sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed)))))
}
}
/// @dev Returns the extra data for token `id`.
/// Minting, transferring, burning a token will not change the extra data.
/// The extra data can be set on a non-existent token.
function _getExtraData(uint256 id) internal view virtual returns (uint96 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20)))))
}
}
/// @dev Sets the extra data for token `id` to `value`.
/// Minting, transferring, burning a token will not change the extra data.
/// The extra data can be set on a non-existent token.
function _setExtraData(uint256 id, uint96 value) internal virtual {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let packed := sload(ownershipSlot)
sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed)))))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL MINT FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Mints token `id` to `to`.
///
/// Requirements:
///
/// - Token `id` must not exist.
/// - `to` cannot be the zero address.
///
/// Emits a {Transfer} event.
function _mint(address to, uint256 id) internal virtual {
_beforeTokenTransfer(address(0), to, id);
/// @solidity memory-safe-assembly
assembly {
// Clear the upper 96 bits.
to := shr(96, shl(96, to))
// Revert if `to` is the zero address.
if iszero(to) {
mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
revert(0x1c, 0x04)
}
// Load the ownership data.
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let ownershipPacked := sload(ownershipSlot)
// Revert if the token already exists.
if shl(96, ownershipPacked) {
mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`.
revert(0x1c, 0x04)
}
// Update with the owner.
sstore(ownershipSlot, or(ownershipPacked, to))
// Increment the balance of the owner.
{
mstore(0x00, to)
let balanceSlot := keccak256(0x0c, 0x1c)
let balanceSlotPacked := add(sload(balanceSlot), 1)
if iszero(and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
revert(0x1c, 0x04)
}
sstore(balanceSlot, balanceSlotPacked)
}
// Emit the {Transfer} event.
log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)
}
_afterTokenTransfer(address(0), to, id);
}
/// @dev Equivalent to `_safeMint(to, id, "")`.
function _safeMint(address to, uint256 id) internal virtual {
_safeMint(to, id, "");
}
/// @dev Mints token `id` to `to`.
///
/// Requirements:
///
/// - Token `id` must not exist.
/// - `to` 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 _safeMint(address to, uint256 id, bytes memory data) internal virtual {
_mint(to, id);
if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL BURN FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Equivalent to `_burn(address(0), id)`.
function _burn(uint256 id) internal virtual {
_burn(address(0), id);
}
/// @dev Destroys token `id`, using `by`.
///
/// Requirements:
///
/// - Token `id` must exist.
/// - If `by` is not the zero address,
/// it must be the owner of the token, or be approved to manage the token.
///
/// Emits a {Transfer} event.
function _burn(address by, uint256 id) internal virtual {
address owner = ownerOf(id);
_beforeTokenTransfer(owner, address(0), id);
/// @solidity memory-safe-assembly
assembly {
// Clear the upper 96 bits.
by := shr(96, shl(96, by))
// Load the ownership data.
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let ownershipPacked := sload(ownershipSlot)
// Reload the owner in case it is changed in `_beforeTokenTransfer`.
owner := shr(96, shl(96, ownershipPacked))
// Revert if the token does not exist.
if iszero(owner) {
mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
revert(0x1c, 0x04)
}
// Load and check the token approval.
{
mstore(0x00, owner)
let approvedAddress := sload(add(1, ownershipSlot))
// If `by` is not the zero address, do the authorization check.
// Revert if the `by` is not the owner, nor approved.
if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) {
if iszero(sload(keccak256(0x0c, 0x30))) {
mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
revert(0x1c, 0x04)
}
}
// Delete the approved address if any.
if approvedAddress { sstore(add(1, ownershipSlot), 0) }
}
// Clear the owner.
sstore(ownershipSlot, xor(ownershipPacked, owner))
// Decrement the balance of `owner`.
{
let balanceSlot := keccak256(0x0c, 0x1c)
sstore(balanceSlot, sub(sload(balanceSlot), 1))
}
// Emit the {Transfer} event.
log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id)
}
_afterTokenTransfer(owner, address(0), id);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL APPROVAL FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns whether `account` is the owner of token `id`, or is approved to managed it.
///
/// Requirements:
/// - Token `id` must exist.
function _isApprovedOrOwner(address account, uint256 id)
internal
view
virtual
returns (bool result)
{
/// @solidity memory-safe-assembly
assembly {
result := 1
// Clear the upper 96 bits.
account := shr(96, shl(96, account))
// Load the ownership data.
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let owner := shr(96, shl(96, sload(ownershipSlot)))
// Revert if the token does not exist.
if iszero(owner) {
mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
revert(0x1c, 0x04)
}
// Check if `account` is the `owner`.
if iszero(eq(account, owner)) {
mstore(0x00, owner)
// Check if `account` is approved to
if iszero(sload(keccak256(0x0c, 0x30))) {
result := eq(account, sload(add(1, ownershipSlot)))
}
}
}
}
/// @dev Returns the account approved to manage token `id`.
/// Returns the zero address instead of reverting if the token does not exist.
function _getApproved(uint256 id) internal view virtual returns (address result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, id)
mstore(0x1c, _ERC721_MASTER_SLOT_SEED)
result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20)))))
}
}
/// @dev Equivalent to `_approve(address(0), account, id)`.
function _approve(address account, uint256 id) internal virtual {
_approve(address(0), account, id);
}
/// @dev Sets `account` as the approved account to manage token `id`, using `by`.
///
/// Requirements:
/// - Token `id` must exist.
/// - If `by` is not the zero address, `by` must be the owner
/// or an approved operator for the token owner.
///
/// Emits a {Transfer} event.
function _approve(address by, address account, uint256 id) internal virtual {
assembly {
// Clear the upper 96 bits.
let bitmaskAddress := shr(96, not(0))
account := and(bitmaskAddress, account)
by := and(bitmaskAddress, by)
// Load the owner of the token.
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let owner := and(bitmaskAddress, sload(ownershipSlot))
// Revert if the token does not exist.
if iszero(owner) {
mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
revert(0x1c, 0x04)
}
// If `by` is not the zero address, do the authorization check.
// Revert if `by` is not the owner, nor approved.
if iszero(or(iszero(by), eq(by, owner))) {
mstore(0x00, owner)
if iszero(sload(keccak256(0x0c, 0x30))) {
mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
revert(0x1c, 0x04)
}
}
// Sets `account` as the approved account to manage `id`.
sstore(add(1, ownershipSlot), account)
// Emit the {Approval} event.
log4(0x00, 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id)
}
}
/// @dev Approve or remove the `operator` as an operator for `by`,
/// without authorization checks.
///
/// Emits a {ApprovalForAll} event.
function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual {
/// @solidity memory-safe-assembly
assembly {
// Clear the upper 96 bits.
by := shr(96, shl(96, by))
operator := shr(96, shl(96, operator))
// Convert to 0 or 1.
isApproved := iszero(iszero(isApproved))
// Update the `isApproved` for (`by`, `operator`).
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))
mstore(0x00, by)
sstore(keccak256(0x0c, 0x30), isApproved)
// Emit the {ApprovalForAll} event.
mstore(0x00, isApproved)
log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL TRANSFER FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Equivalent to `_transfer(address(0), from, to, id)`.
function _transfer(address from, address to, uint256 id) internal virtual {
_transfer(address(0), from, to, id);
}
/// @dev Transfers token `id` from `from` to `to`.
///
/// Requirements:
///
/// - Token `id` must exist.
/// - `from` must be the owner of the token.
/// - `to` cannot be the zero address.
/// - If `by` is not the zero address,
/// it must be the owner of the token, or be approved to manage the token.
///
/// Emits a {Transfer} event.
function _transfer(address by, address from, address to, uint256 id) internal virtual {
_beforeTokenTransfer(from, to, id);
/// @solidity memory-safe-assembly
assembly {
// Clear the upper 96 bits.
let bitmaskAddress := shr(96, not(0))
from := and(bitmaskAddress, from)
to := and(bitmaskAddress, to)
by := and(bitmaskAddress, by)
// Load the ownership data.
mstore(0x00, id)
mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))
let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))
let ownershipPacked := sload(ownershipSlot)
let owner := and(bitmaskAddress, ownershipPacked)
// Revert if `from` is not the owner, or does not exist.
if iszero(mul(owner, eq(owner, from))) {
if iszero(owner) {
mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.
revert(0x1c, 0x04)
}
mstore(0x00, 0xa1148100) // `TransferFromIncorrectOwner()`.
revert(0x1c, 0x04)
}
// Revert if `to` is the zero address.
if iszero(to) {
mstore(0x00, 0xea553b34) // `TransferToZeroAddress()`.
revert(0x1c, 0x04)
}
// Load, check, and update the token approval.
{
mstore(0x00, from)
let approvedAddress := sload(add(1, ownershipSlot))
// If `by` is not the zero address, do the authorization check.
// Revert if the `by` is not the owner, nor approved.
if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) {
if iszero(sload(keccak256(0x0c, 0x30))) {
mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.
revert(0x1c, 0x04)
}
}
// Delete the approved address if any.
if approvedAddress { sstore(add(1, ownershipSlot), 0) }
}
// Update with the new owner.
sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))
// Decrement the balance of `from`.
{
let fromBalanceSlot := keccak256(0x0c, 0x1c)
sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))
}
// Increment the balance of `to`.
{
mstore(0x00, to)
let toBalanceSlot := keccak256(0x0c, 0x1c)
let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)
if iszero(and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE)) {
mstore(0x00, 0x01336cea) // `AccountBalanceOverflow()`.
revert(0x1c, 0x04)
}
sstore(toBalanceSlot, toBalanceSlotPacked)
}
// Emit the {Transfer} event.
log4(0x00, 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)
}
_afterTokenTransfer(from, to, id);
}
/// @dev Equivalent to `_safeTransfer(from, to, id, "")`.
function _safeTransfer(address from, address to, uint256 id) internal virtual {
_safeTransfer(from, to, id, "");
}
/// @dev Transfers token `id` from `from` to `to`.
///
/// Requirements:
///
/// - Token `id` must exist.
/// - `from` must be the owner of the token.
/// - `to` cannot be the zero address.
/// - The caller must be the owner of the token, or be approved to manage the token.
/// - 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 id, bytes memory data)
internal
virtual
{
_transfer(address(0), from, to, id);
if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
}
/// @dev Equivalent to `_safeTransfer(by, from, to, id, "")`.
function _safeTransfer(address by, address from, address to, uint256 id) internal virtual {
_safeTransfer(by, from, to, id, "");
}
/// @dev Transfers token `id` from `from` to `to`.
///
/// Requirements:
///
/// - Token `id` must exist.
/// - `from` must be the owner of the token.
/// - `to` cannot be the zero address.
/// - If `by` is not the zero address,
/// it must be the owner of the token, or be approved to manage the token.
/// - 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 by, address from, address to, uint256 id, bytes memory data)
internal
virtual
{
_transfer(by, from, to, id);
if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* HOOKS FOR OVERRIDING */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Hook that is called before any token transfers, including minting and burning.
function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {}
/// @dev Hook that is called after any token transfers, including minting and burning.
function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PRIVATE HELPERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns if `a` has bytecode of non-zero length.
function _hasCode(address a) private view returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
result := extcodesize(a) // Can handle dirty upper bits.
}
}
/// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`.
/// Reverts if the target does not support the function correctly.
function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data)
private
{
/// @solidity memory-safe-assembly
assembly {
// Prepare the calldata.
let m := mload(0x40)
let onERC721ReceivedSelector := 0x150b7a02
mstore(m, onERC721ReceivedSelector)
mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`.
mstore(add(m, 0x40), shr(96, shl(96, from)))
mstore(add(m, 0x60), id)
mstore(add(m, 0x80), 0x80)
let n := mload(data)
mstore(add(m, 0xa0), n)
if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) }
// Revert if the call reverts.
if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) {
if returndatasize() {
// Bubble up the revert if the call reverts.
returndatacopy(0x00, 0x00, returndatasize())
revert(0x00, returndatasize())
}
mstore(m, 0)
}
// Load the returndata and compare it.
if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) {
mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`.
revert(0x1c, 0x04)
}
}
}
}
// File: contracts/LibPRNG.sol
pragma solidity ^0.8.4;
/// @notice Library for generating psuedorandom numbers.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibPRNG.sol)
library LibPRNG {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STRUCTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev A psuedorandom number state in memory.
struct PRNG {
uint256 state;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Seeds the `prng` with `state`.
function seed(PRNG memory prng, uint256 state) internal pure {
/// @solidity memory-safe-assembly
assembly {
mstore(prng, state)
}
}
/// @dev Returns the next psuedorandom uint256.
/// All bits of the returned uint256 pass the NIST Statistical Test Suite.
function next(PRNG memory prng) internal pure returns (uint256 result) {
// We simply use `keccak256` for a great balance between
// runtime gas costs, bytecode size, and statistical properties.
//
// A high-quality LCG with a 32-byte state
// is only about 30% more gas efficient during runtime,
// but requires a 32-byte multiplier, which can cause bytecode bloat
// when this function is inlined.
//
// Using this method is about 2x more efficient than
// `nextRandomness = uint256(keccak256(abi.encode(randomness)))`.
/// @solidity memory-safe-assembly
assembly {
result := keccak256(prng, 0x20)
mstore(prng, result)
}
}
/// @dev Returns a psuedorandom uint256, uniformly distributed
/// between 0 (inclusive) and `upper` (exclusive).
/// If your modulus is big, this method is recommended
/// for uniform sampling to avoid modulo bias.
/// For uniform sampling across all uint256 values,
/// or for small enough moduli such that the bias is neligible,
/// use {next} instead.
function uniform(PRNG memory prng, uint256 upper) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
for {} 1 {} {
result := keccak256(prng, 0x20)
mstore(prng, result)
if iszero(lt(result, mod(sub(0, upper), upper))) { break }
}
result := mod(result, upper)
}
}
/// @dev Shuffles the array in-place with Fisher-Yates shuffle.
function shuffle(PRNG memory prng, uint256[] memory a) internal pure {
/// @solidity memory-safe-assembly
assembly {
let n := mload(a)
let w := not(0)
let mask := shr(128, w)
if n {
for { a := add(a, 0x20) } 1 {} {
// We can just directly use `keccak256`, cuz
// the other approaches don't save much.
let r := keccak256(prng, 0x20)
mstore(prng, r)
// Note that there will be a very tiny modulo bias
// if the length of the array is not a power of 2.
// For all practical purposes, it is negligible
// and will not be a fairness or security concern.
{
let j := add(a, shl(5, mod(shr(128, r), n)))
n := add(n, w) // `sub(n, 1)`.
if iszero(n) { break }
let i := add(a, shl(5, n))
let t := mload(i)
mstore(i, mload(j))
mstore(j, t)
}
{
let j := add(a, shl(5, mod(and(r, mask), n)))
n := add(n, w) // `sub(n, 1)`.
if iszero(n) { break }
let i := add(a, shl(5, n))
let t := mload(i)
mstore(i, mload(j))
mstore(j, t)
}
}
}
}
}
/// @dev Shuffles the bytes in-place with Fisher-Yates shuffle.
function shuffle(PRNG memory prng, bytes memory a) internal pure {
/// @solidity memory-safe-assembly
assembly {
let n := mload(a)
let w := not(0)
let mask := shr(128, w)
if n {
let b := add(a, 0x01)
for { a := add(a, 0x20) } 1 {} {
// We can just directly use `keccak256`, cuz
// the other approaches don't save much.
let r := keccak256(prng, 0x20)
mstore(prng, r)
// Note that there will be a very tiny modulo bias
// if the length of the array is not a power of 2.
// For all practical purposes, it is negligible
// and will not be a fairness or security concern.
{
let o := mod(shr(128, r), n)
n := add(n, w) // `sub(n, 1)`.
if iszero(n) { break }
let t := mload(add(b, n))
mstore8(add(a, n), mload(add(b, o)))
mstore8(add(a, o), t)
}
{
let o := mod(and(r, mask), n)
n := add(n, w) // `sub(n, 1)`.
if iszero(n) { break }
let t := mload(add(b, n))
mstore8(add(a, n), mload(add(b, o)))
mstore8(add(a, o), t)
}
}
}
}
}
}
// File: contracts/LibString.sol
pragma solidity ^0.8.4;
/// @notice Library for converting numbers into strings and other string operations.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)
library LibString {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The `length` of the output is too small to contain all the hex digits.
error HexLengthInsufficient();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The constant returned when the `search` is not found in the string.
uint256 internal constant NOT_FOUND = type(uint256).max;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* DECIMAL OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the base 10 decimal representation of `value`.
function toString(uint256 value) internal pure returns (string memory str) {
/// @solidity memory-safe-assembly
assembly {
// The maximum value of a uint256 contains 78 digits (1 byte per digit), but
// we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
// We will need 1 word for the trailing zeros padding, 1 word for the length,
// and 3 words for a maximum of 78 digits.
str := add(mload(0x40), 0x80)
// Update the free memory pointer to allocate.
mstore(0x40, add(str, 0x20))
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end of the memory to calculate the length later.
let end := str
let w := not(0) // Tsk.
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
for { let temp := value } 1 {} {
str := add(str, w) // `sub(str, 1)`.
// Write the character to the pointer.
// The ASCII index of the '0' character is 48.
mstore8(str, add(48, mod(temp, 10)))
// Keep dividing `temp` until zero.
temp := div(temp, 10)
if iszero(temp) { break }
}
let length := sub(end, str)
// Move the pointer 32 bytes leftwards to make room for the length.
str := sub(str, 0x20)
// Store the length.
mstore(str, length)
}
}
/// @dev Returns the base 10 decimal representation of `value`.
function toString(int256 value) internal pure returns (string memory str) {
if (value >= 0) {
return toString(uint256(value));
}
unchecked {
str = toString(uint256(-value));
}
/// @solidity memory-safe-assembly
assembly {
// We still have some spare memory space on the left,
// as we have allocated 3 words (96 bytes) for up to 78 digits.
let length := mload(str) // Load the string length.
mstore(str, 0x2d) // Store the '-' character.
str := sub(str, 1) // Move back the string pointer by a byte.
mstore(str, add(length, 1)) // Update the string length.
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* HEXADECIMAL OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the hexadecimal representation of `value`,
/// left-padded to an input length of `length` bytes.
/// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
/// giving a total length of `length * 2 + 2` bytes.
/// Reverts if `length` is too small for the output to contain all the digits.
function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) {
str = toHexStringNoPrefix(value, length);
/// @solidity memory-safe-assembly
assembly {
let strLength := add(mload(str), 2) // Compute the length.
mstore(str, 0x3078) // Write the "0x" prefix.
str := sub(str, 2) // Move the pointer.
mstore(str, strLength) // Write the length.
}
}
/// @dev Returns the hexadecimal representation of `value`,
/// left-padded to an input length of `length` bytes.
/// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
/// giving a total length of `length * 2` bytes.
/// Reverts if `length` is too small for the output to contain all the digits.
function toHexStringNoPrefix(uint256 value, uint256 length)
internal
pure
returns (string memory str)
{
/// @solidity memory-safe-assembly
assembly {
// We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes
// for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.
// We add 0x20 to the total and round down to a multiple of 0x20.
// (0x20 + 0x20 + 0x02 + 0x20) = 0x62.
str := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f)))
// Allocate the memory.
mstore(0x40, add(str, 0x20))
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end to calculate the length later.
let end := str
// Store "0123456789abcdef" in scratch space.
mstore(0x0f, 0x30313233343536373839616263646566)
let start := sub(str, add(length, length))
let w := not(1) // Tsk.
let temp := value
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
for {} 1 {} {
str := add(str, w) // `sub(str, 2)`.
mstore8(add(str, 1), mload(and(temp, 15)))
mstore8(str, mload(and(shr(4, temp), 15)))
temp := shr(8, temp)
if iszero(xor(str, start)) { break }
}
if temp {
// Store the function selector of `HexLengthInsufficient()`.
mstore(0x00, 0x2194895a)
// Revert with (offset, size).
revert(0x1c, 0x04)
}
// Compute the string's length.
let strLength := sub(end, str)
// Move the pointer and write the length.
str := sub(str, 0x20)
mstore(str, strLength)
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
/// As address are 20 bytes long, the output will left-padded to have
/// a length of `20 * 2 + 2` bytes.
function toHexString(uint256 value) internal pure returns (string memory str) {
str = toHexStringNoPrefix(value);
/// @solidity memory-safe-assembly
assembly {
let strLength := add(mload(str), 2) // Compute the length.
mstore(str, 0x3078) // Write the "0x" prefix.
str := sub(str, 2) // Move the pointer.
mstore(str, strLength) // Write the length.
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is encoded using 2 hexadecimal digits per byte.
/// As address are 20 bytes long, the output will left-padded to have
/// a length of `20 * 2` bytes.
function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {
/// @solidity memory-safe-assembly
assembly {
// We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
// 0x02 bytes for the prefix, and 0x40 bytes for the digits.
// The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.
str := add(mload(0x40), 0x80)
// Allocate the memory.
mstore(0x40, add(str, 0x20))
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end to calculate the length later.
let end := str
// Store "0123456789abcdef" in scratch space.
mstore(0x0f, 0x30313233343536373839616263646566)
let w := not(1) // Tsk.
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
for { let temp := value } 1 {} {
str := add(str, w) // `sub(str, 2)`.
mstore8(add(str, 1), mload(and(temp, 15)))
mstore8(str, mload(and(shr(4, temp), 15)))
temp := shr(8, temp)
if iszero(temp) { break }
}
// Compute the string's length.
let strLength := sub(end, str)
// Move the pointer and write the length.
str := sub(str, 0x20)
mstore(str, strLength)
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is prefixed with "0x", encoded using 2 hexadecimal digits per byte,
/// and the alphabets are capitalized conditionally according to
/// https://eips.ethereum.org/EIPS/eip-55
function toHexStringChecksummed(address value) internal pure returns (string memory str) {
str = toHexString(value);
/// @solidity memory-safe-assembly
assembly {
let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`
let o := add(str, 0x22)
let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `
let t := shl(240, 136) // `0b10001000 << 240`
for { let i := 0 } 1 {} {
mstore(add(i, i), mul(t, byte(i, hashed)))
i := add(i, 1)
if eq(i, 20) { break }
}
mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))
o := add(o, 0x20)
mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
function toHexString(address value) internal pure returns (string memory str) {
str = toHexStringNoPrefix(value);
/// @solidity memory-safe-assembly
assembly {
let strLength := add(mload(str), 2) // Compute the length.
mstore(str, 0x3078) // Write the "0x" prefix.
str := sub(str, 2) // Move the pointer.
mstore(str, strLength) // Write the length.
}
}
/// @dev Returns the hexadecimal representation of `value`.
/// The output is encoded using 2 hexadecimal digits per byte.
function toHexStringNoPrefix(address value) internal pure returns (string memory str) {
/// @solidity memory-safe-assembly
assembly {
str := mload(0x40)
// Allocate the memory.
// We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
// 0x02 bytes for the prefix, and 0x28 bytes for the digits.
// The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.
mstore(0x40, add(str, 0x80))
// Store "0123456789abcdef" in scratch space.
mstore(0x0f, 0x30313233343536373839616263646566)
str := add(str, 2)
mstore(str, 40)
let o := add(str, 0x20)
mstore(add(o, 40), 0)
value := shl(96, value)
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
for { let i := 0 } 1 {} {
let p := add(o, add(i, i))
let temp := byte(i, value)
mstore8(add(p, 1), mload(and(temp, 15)))
mstore8(p, mload(shr(4, temp)))
i := add(i, 1)
if eq(i, 20) { break }
}
}
}
/// @dev Returns the hex encoded string from the raw bytes.
/// The output is encoded using 2 hexadecimal digits per byte.
function toHexString(bytes memory raw) internal pure returns (string memory str) {
str = toHexStringNoPrefix(raw);
/// @solidity memory-safe-assembly
assembly {
let strLength := add(mload(str), 2) // Compute the length.
mstore(str, 0x3078) // Write the "0x" prefix.
str := sub(str, 2) // Move the pointer.
mstore(str, strLength) // Write the length.
}
}
/// @dev Returns the hex encoded string from the raw bytes.
/// The output is encoded using 2 hexadecimal digits per byte.
function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) {
/// @solidity memory-safe-assembly
assembly {
let length := mload(raw)
str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.
mstore(str, add(length, length)) // Store the length of the output.
// Store "0123456789abcdef" in scratch space.
mstore(0x0f, 0x30313233343536373839616263646566)
let o := add(str, 0x20)
let end := add(raw, length)
for {} iszero(eq(raw, end)) {} {
raw := add(raw, 1)
mstore8(add(o, 1), mload(and(mload(raw), 15)))
mstore8(o, mload(and(shr(4, mload(raw)), 15)))
o := add(o, 2)
}
mstore(o, 0) // Zeroize the slot after the string.
mstore(0x40, add(o, 0x20)) // Allocate the memory.
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* RUNE STRING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the number of UTF characters in the string.
function runeCount(string memory s) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
if mload(s) {
mstore(0x00, div(not(0), 255))
mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)
let o := add(s, 0x20)
let end := add(o, mload(s))
for { result := 1 } 1 { result := add(result, 1) } {
o := add(o, byte(0, mload(shr(250, mload(o)))))
if iszero(lt(o, end)) { break }
}
}
}
}
/// @dev Returns if this string is a 7-bit ASCII string.
/// (i.e. all characters codes are in [0..127])
function is7BitASCII(string memory s) internal pure returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
let mask := shl(7, div(not(0), 255))
result := 1
let n := mload(s)
if n {
let o := add(s, 0x20)
let end := add(o, n)
let last := mload(end)
mstore(end, 0)
for {} 1 {} {
if and(mask, mload(o)) {
result := 0
break
}
o := add(o, 0x20)
if iszero(lt(o, end)) { break }
}
mstore(end, last)
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BYTE STRING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
// For performance and bytecode compactness, all indices of the following operations
// are byte (ASCII) offsets, not UTF character offsets.
/// @dev Returns `subject` all occurrences of `search` replaced with `replacement`.
function replace(string memory subject, string memory search, string memory replacement)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let subjectLength := mload(subject)
let searchLength := mload(search)
let replacementLength := mload(replacement)
subject := add(subject, 0x20)
search := add(search, 0x20)
replacement := add(replacement, 0x20)
result := add(mload(0x40), 0x20)
let subjectEnd := add(subject, subjectLength)
if iszero(gt(searchLength, subjectLength)) {
let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1)
let h := 0
if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }
let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
let s := mload(search)
for {} 1 {} {
let t := mload(subject)
// Whether the first `searchLength % 32` bytes of
// `subject` and `search` matches.
if iszero(shr(m, xor(t, s))) {
if h {
if iszero(eq(keccak256(subject, searchLength), h)) {
mstore(result, t)
result := add(result, 1)
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
continue
}
}
// Copy the `replacement` one word at a time.
for { let o := 0 } 1 {} {
mstore(add(result, o), mload(add(replacement, o)))
o := add(o, 0x20)
if iszero(lt(o, replacementLength)) { break }
}
result := add(result, replacementLength)
subject := add(subject, searchLength)
if searchLength {
if iszero(lt(subject, subjectSearchEnd)) { break }
continue
}
}
mstore(result, t)
result := add(result, 1)
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
}
}
let resultRemainder := result
result := add(mload(0x40), 0x20)
let k := add(sub(resultRemainder, result), sub(subjectEnd, subject))
// Copy the rest of the string one word at a time.
for {} lt(subject, subjectEnd) {} {
mstore(resultRemainder, mload(subject))
resultRemainder := add(resultRemainder, 0x20)
subject := add(subject, 0x20)
}
result := sub(result, 0x20)
let last := add(add(result, 0x20), k) // Zeroize the slot after the string.
mstore(last, 0)
mstore(0x40, add(last, 0x20)) // Allocate the memory.
mstore(result, k) // Store the length.
}
}
/// @dev Returns the byte index of the first location of `search` in `subject`,
/// searching from left to right, starting from `from`.
/// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
function indexOf(string memory subject, string memory search, uint256 from)
internal
pure
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
for { let subjectLength := mload(subject) } 1 {} {
if iszero(mload(search)) {
if iszero(gt(from, subjectLength)) {
result := from
break
}
result := subjectLength
break
}
let searchLength := mload(search)
let subjectStart := add(subject, 0x20)
result := not(0) // Initialize to `NOT_FOUND`.
subject := add(subjectStart, from)
let end := add(sub(add(subjectStart, subjectLength), searchLength), 1)
let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
let s := mload(add(search, 0x20))
if iszero(and(lt(subject, end), lt(from, subjectLength))) { break }
if iszero(lt(searchLength, 0x20)) {
for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
if iszero(shr(m, xor(mload(subject), s))) {
if eq(keccak256(subject, searchLength), h) {
result := sub(subject, subjectStart)
break
}
}
subject := add(subject, 1)
if iszero(lt(subject, end)) { break }
}
break
}
for {} 1 {} {
if iszero(shr(m, xor(mload(subject), s))) {
result := sub(subject, subjectStart)
break
}
subject := add(subject, 1)
if iszero(lt(subject, end)) { break }
}
break
}
}
}
/// @dev Returns the byte index of the first location of `search` in `subject`,
/// searching from left to right.
/// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
function indexOf(string memory subject, string memory search)
internal
pure
returns (uint256 result)
{
result = indexOf(subject, search, 0);
}
/// @dev Returns the byte index of the first location of `search` in `subject`,
/// searching from right to left, starting from `from`.
/// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
function lastIndexOf(string memory subject, string memory search, uint256 from)
internal
pure
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
for {} 1 {} {
result := not(0) // Initialize to `NOT_FOUND`.
let searchLength := mload(search)
if gt(searchLength, mload(subject)) { break }
let w := result
let fromMax := sub(mload(subject), searchLength)
if iszero(gt(fromMax, from)) { from := fromMax }
let end := add(add(subject, 0x20), w)
subject := add(add(subject, 0x20), from)
if iszero(gt(subject, end)) { break }
// As this function is not too often used,
// we shall simply use keccak256 for smaller bytecode size.
for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
if eq(keccak256(subject, searchLength), h) {
result := sub(subject, add(end, 1))
break
}
subject := add(subject, w) // `sub(subject, 1)`.
if iszero(gt(subject, end)) { break }
}
break
}
}
}
/// @dev Returns the byte index of the first location of `search` in `subject`,
/// searching from right to left.
/// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
function lastIndexOf(string memory subject, string memory search)
internal
pure
returns (uint256 result)
{
result = lastIndexOf(subject, search, uint256(int256(-1)));
}
/// @dev Returns whether `subject` starts with `search`.
function startsWith(string memory subject, string memory search)
internal
pure
returns (bool result)
{
/// @solidity memory-safe-assembly
assembly {
let searchLength := mload(search)
// Just using keccak256 directly is actually cheaper.
// forgefmt: disable-next-item
result := and(
iszero(gt(searchLength, mload(subject))),
eq(
keccak256(add(subject, 0x20), searchLength),
keccak256(add(search, 0x20), searchLength)
)
)
}
}
/// @dev Returns whether `subject` ends with `search`.
function endsWith(string memory subject, string memory search)
internal
pure
returns (bool result)
{
/// @solidity memory-safe-assembly
assembly {
let searchLength := mload(search)
let subjectLength := mload(subject)
// Whether `search` is not longer than `subject`.
let withinRange := iszero(gt(searchLength, subjectLength))
// Just using keccak256 directly is actually cheaper.
// forgefmt: disable-next-item
result := and(
withinRange,
eq(
keccak256(
// `subject + 0x20 + max(subjectLength - searchLength, 0)`.
add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))),
searchLength
),
keccak256(add(search, 0x20), searchLength)
)
)
}
}
/// @dev Returns `subject` repeated `times`.
function repeat(string memory subject, uint256 times)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let subjectLength := mload(subject)
if iszero(or(iszero(times), iszero(subjectLength))) {
subject := add(subject, 0x20)
result := mload(0x40)
let output := add(result, 0x20)
for {} 1 {} {
// Copy the `subject` one word at a time.
for { let o := 0 } 1 {} {
mstore(add(output, o), mload(add(subject, o)))
o := add(o, 0x20)
if iszero(lt(o, subjectLength)) { break }
}
output := add(output, subjectLength)
times := sub(times, 1)
if iszero(times) { break }
}
mstore(output, 0) // Zeroize the slot after the string.
let resultLength := sub(output, add(result, 0x20))
mstore(result, resultLength) // Store the length.
// Allocate the memory.
mstore(0x40, add(result, add(resultLength, 0x20)))
}
}
}
/// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function slice(string memory subject, uint256 start, uint256 end)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let subjectLength := mload(subject)
if iszero(gt(subjectLength, end)) { end := subjectLength }
if iszero(gt(subjectLength, start)) { start := subjectLength }
if lt(start, end) {
result := mload(0x40)
let resultLength := sub(end, start)
mstore(result, resultLength)
subject := add(subject, start)
let w := not(0x1f)
// Copy the `subject` one word at a time, backwards.
for { let o := and(add(resultLength, 0x1f), w) } 1 {} {
mstore(add(result, o), mload(add(subject, o)))
o := add(o, w) // `sub(o, 0x20)`.
if iszero(o) { break }
}
// Zeroize the slot after the string.
mstore(add(add(result, 0x20), resultLength), 0)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, add(result, and(add(resultLength, 0x3f), w)))
}
}
}
/// @dev Returns a copy of `subject` sliced from `start` to the end of the string.
/// `start` is a byte offset.
function slice(string memory subject, uint256 start)
internal
pure
returns (string memory result)
{
result = slice(subject, start, uint256(int256(-1)));
}
/// @dev Returns all the indices of `search` in `subject`.
/// The indices are byte offsets.
function indicesOf(string memory subject, string memory search)
internal
pure
returns (uint256[] memory result)
{
/// @solidity memory-safe-assembly
assembly {
let subjectLength := mload(subject)
let searchLength := mload(search)
if iszero(gt(searchLength, subjectLength)) {
subject := add(subject, 0x20)
search := add(search, 0x20)
result := add(mload(0x40), 0x20)
let subjectStart := subject
let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1)
let h := 0
if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }
let m := shl(3, sub(0x20, and(searchLength, 0x1f)))
let s := mload(search)
for {} 1 {} {
let t := mload(subject)
// Whether the first `searchLength % 32` bytes of
// `subject` and `search` matches.
if iszero(shr(m, xor(t, s))) {
if h {
if iszero(eq(keccak256(subject, searchLength), h)) {
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
continue
}
}
// Append to `result`.
mstore(result, sub(subject, subjectStart))
result := add(result, 0x20)
// Advance `subject` by `searchLength`.
subject := add(subject, searchLength)
if searchLength {
if iszero(lt(subject, subjectSearchEnd)) { break }
continue
}
}
subject := add(subject, 1)
if iszero(lt(subject, subjectSearchEnd)) { break }
}
let resultEnd := result
// Assign `result` to the free memory pointer.
result := mload(0x40)
// Store the length of `result`.
mstore(result, shr(5, sub(resultEnd, add(result, 0x20))))
// Allocate memory for result.
// We allocate one more word, so this array can be recycled for {split}.
mstore(0x40, add(resultEnd, 0x20))
}
}
}
/// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string.
function split(string memory subject, string memory delimiter)
internal
pure
returns (string[] memory result)
{
uint256[] memory indices = indicesOf(subject, delimiter);
/// @solidity memory-safe-assembly
assembly {
let w := not(0x1f)
let indexPtr := add(indices, 0x20)
let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))
mstore(add(indicesEnd, w), mload(subject))
mstore(indices, add(mload(indices), 1))
let prevIndex := 0
for {} 1 {} {
let index := mload(indexPtr)
mstore(indexPtr, 0x60)
if iszero(eq(index, prevIndex)) {
let element := mload(0x40)
let elementLength := sub(index, prevIndex)
mstore(element, elementLength)
// Copy the `subject` one word at a time, backwards.
for { let o := and(add(elementLength, 0x1f), w) } 1 {} {
mstore(add(element, o), mload(add(add(subject, prevIndex), o)))
o := add(o, w) // `sub(o, 0x20)`.
if iszero(o) { break }
}
// Zeroize the slot after the string.
mstore(add(add(element, 0x20), elementLength), 0)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, add(element, and(add(elementLength, 0x3f), w)))
// Store the `element` into the array.
mstore(indexPtr, element)
}
prevIndex := add(index, mload(delimiter))
indexPtr := add(indexPtr, 0x20)
if iszero(lt(indexPtr, indicesEnd)) { break }
}
result := indices
if iszero(mload(delimiter)) {
result := add(indices, 0x20)
mstore(result, sub(mload(indices), 2))
}
}
}
/// @dev Returns a concatenated string of `a` and `b`.
/// Cheaper than `string.concat()` and does not de-align the free memory pointer.
function concat(string memory a, string memory b)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let w := not(0x1f)
result := mload(0x40)
let aLength := mload(a)
// Copy `a` one word at a time, backwards.
for { let o := and(add(mload(a), 0x20), w) } 1 {} {
mstore(add(result, o), mload(add(a, o)))
o := add(o, w) // `sub(o, 0x20)`.
if iszero(o) { break }
}
let bLength := mload(b)
let output := add(result, mload(a))
// Copy `b` one word at a time, backwards.
for { let o := and(add(bLength, 0x20), w) } 1 {} {
mstore(add(output, o), mload(add(b, o)))
o := add(o, w) // `sub(o, 0x20)`.
if iszero(o) { break }
}
let totalLength := add(aLength, bLength)
let last := add(add(result, 0x20), totalLength)
// Zeroize the slot after the string.
mstore(last, 0)
// Stores the length.
mstore(result, totalLength)
// Allocate memory for the length and the bytes,
// rounded up to a multiple of 32.
mstore(0x40, and(add(last, 0x1f), w))
}
}
/// @dev Returns a copy of the string in either lowercase or UPPERCASE.
/// WARNING! This function is only compatible with 7-bit ASCII strings.
function toCase(string memory subject, bool toUpper)
internal
pure
returns (string memory result)
{
/// @solidity memory-safe-assembly
assembly {
let length := mload(subject)
if length {
result := add(mload(0x40), 0x20)
subject := add(subject, 1)
let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff)
let w := not(0)
for { let o := length } 1 {} {
o := add(o, w)
let b := and(0xff, mload(add(subject, o)))
mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20)))
if iszero(o) { break }
}
result := mload(0x40)
mstore(result, length) // Store the length.
let last := add(add(result, 0x20), length)
mstore(last, 0) // Zeroize the slot after the string.
mstore(0x40, add(last, 0x20)) // Allocate the memory.
}
}
}
/// @dev Returns a lowercased copy of the string.
/// WARNING! This function is only compatible with 7-bit ASCII strings.
function lower(string memory subject) internal pure returns (string memory result) {
result = toCase(subject, false);
}
/// @dev Returns an UPPERCASED copy of the string.
/// WARNING! This function is only compatible with 7-bit ASCII strings.
function upper(string memory subject) internal pure returns (string memory result) {
result = toCase(subject, true);
}
/// @dev Escapes the string to be used within HTML tags.
function escapeHTML(string memory s) internal pure returns (string memory result) {
/// @solidity memory-safe-assembly
assembly {
for {
let end := add(s, mload(s))
result := add(mload(0x40), 0x20)
// Store the bytes of the packed offsets and strides into the scratch space.
// `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6.
mstore(0x1f, 0x900094)
mstore(0x08, 0xc0000000a6ab)
// Store ""&'<>" into the scratch space.
mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))
} iszero(eq(s, end)) {} {
s := add(s, 1)
let c := and(mload(s), 0xff)
// Not in `["\"","'","&","<",">"]`.
if iszero(and(shl(c, 1), 0x500000c400000000)) {
mstore8(result, c)
result := add(result, 1)
continue
}
let t := shr(248, mload(c))
mstore(result, mload(and(t, 0x1f)))
result := add(result, shr(5, t))
}
let last := result
mstore(last, 0) // Zeroize the slot after the string.
result := mload(0x40)
mstore(result, sub(last, add(result, 0x20))) // Store the length.
mstore(0x40, add(last, 0x20)) // Allocate the memory.
}
}
/// @dev Escapes the string to be used within double-quotes in a JSON.
function escapeJSON(string memory s) internal pure returns (string memory result) {
/// @solidity memory-safe-assembly
assembly {
for {
let end := add(s, mload(s))
result := add(mload(0x40), 0x20)
// Store "\\u0000" in scratch space.
// Store "0123456789abcdef" in scratch space.
// Also, store `{0x08:"b", 0x09:"t", 0x0a:"n", 0x0c:"f", 0x0d:"r"}`.
// into the scratch space.
mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)
// Bitmask for detecting `["\"","\\"]`.
let e := or(shl(0x22, 1), shl(0x5c, 1))
} iszero(eq(s, end)) {} {
s := add(s, 1)
let c := and(mload(s), 0xff)
if iszero(lt(c, 0x20)) {
if iszero(and(shl(c, 1), e)) {
// Not in `["\"","\\"]`.
mstore8(result, c)
result := add(result, 1)
continue
}
mstore8(result, 0x5c) // "\\".
mstore8(add(result, 1), c)
result := add(result, 2)
continue
}
if iszero(and(shl(c, 1), 0x3700)) {
// Not in `["\b","\t","\n","\f","\d"]`.
mstore8(0x1d, mload(shr(4, c))) // Hex value.
mstore8(0x1e, mload(and(c, 15))) // Hex value.
mstore(result, mload(0x19)) // "\\u00XX".
result := add(result, 6)
continue
}
mstore8(result, 0x5c) // "\\".
mstore8(add(result, 1), mload(add(c, 8)))
result := add(result, 2)
}
let last := result
mstore(last, 0) // Zeroize the slot after the string.
result := mload(0x40)
mstore(result, sub(last, add(result, 0x20))) // Store the length.
mstore(0x40, add(last, 0x20)) // Allocate the memory.
}
}
/// @dev Returns whether `a` equals `b`.
function eq(string memory a, string memory b) internal pure returns (bool result) {
assembly {
result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))
}
}
/// @dev Packs a single string with its length into a single word.
/// Returns `bytes32(0)` if the length is zero or greater than 31.
function packOne(string memory a) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
// We don't need to zero right pad the string,
// since this is our own custom non-standard packing scheme.
result :=
mul(
// Load the length and the bytes.
mload(add(a, 0x1f)),
// `length != 0 && length < 32`. Abuses underflow.
// Assumes that the length is valid and within the block gas limit.
lt(sub(mload(a), 1), 0x1f)
)
}
}
/// @dev Unpacks a string packed using {packOne}.
/// Returns the empty string if `packed` is `bytes32(0)`.
/// If `packed` is not an output of {packOne}, the output behaviour is undefined.
function unpackOne(bytes32 packed) internal pure returns (string memory result) {
/// @solidity memory-safe-assembly
assembly {
// Grab the free memory pointer.
result := mload(0x40)
// Allocate 2 words (1 for the length, 1 for the bytes).
mstore(0x40, add(result, 0x40))
// Zeroize the length slot.
mstore(result, 0)
// Store the length and bytes.
mstore(add(result, 0x1f), packed)
// Right pad with zeroes.
mstore(add(add(result, 0x20), mload(result)), 0)
}
}
/// @dev Packs two strings with their lengths into a single word.
/// Returns `bytes32(0)` if combined length is zero or greater than 30.
function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let aLength := mload(a)
// We don't need to zero right pad the strings,
// since this is our own custom non-standard packing scheme.
result :=
mul(
// Load the length and the bytes of `a` and `b`.
or(
shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))),
mload(sub(add(b, 0x1e), aLength))
),
// `totalLength != 0 && totalLength < 31`. Abuses underflow.
// Assumes that the lengths are valid and within the block gas limit.
lt(sub(add(aLength, mload(b)), 1), 0x1e)
)
}
}
/// @dev Unpacks strings packed using {packTwo}.
/// Returns the empty strings if `packed` is `bytes32(0)`.
/// If `packed` is not an output of {packTwo}, the output behaviour is undefined.
function unpackTwo(bytes32 packed)
internal
pure
returns (string memory resultA, string memory resultB)
{
/// @solidity memory-safe-assembly
assembly {
// Grab the free memory pointer.
resultA := mload(0x40)
resultB := add(resultA, 0x40)
// Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.
mstore(0x40, add(resultB, 0x40))
// Zeroize the length slots.
mstore(resultA, 0)
mstore(resultB, 0)
// Store the lengths and bytes.
mstore(add(resultA, 0x1f), packed)
mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))
// Right pad with zeroes.
mstore(add(add(resultA, 0x20), mload(resultA)), 0)
mstore(add(add(resultB, 0x20), mload(resultB)), 0)
}
}
/// @dev Directly returns `a` without copying.
function directReturn(string memory a) internal pure {
assembly {
// Assumes that the string does not start from the scratch space.
let retStart := sub(a, 0x20)
let retSize := add(mload(a), 0x40)
// Right pad with zeroes. Just in case the string is produced
// by a method that doesn't zero right pad.
mstore(add(retStart, retSize), 0)
// Store the return offset.
mstore(retStart, 0x20)
// End the transaction, returning the string.
return(retStart, retSize)
}
}
}
// File: contracts/ERC721r.sol
pragma solidity ^0.8.17;
//import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
//import {ERC721} from "solady/src/tokens/ERC721.sol";
//import {LibPRNG} from "solady/src/utils/LibPRNG.sol";
//import {LibString} from "solady/src/utils/LibString.sol";
abstract contract ERC721r is ERC721 {
using LibPRNG for LibPRNG.PRNG;
using LibString for uint256;
error ContractsCannotMint();
error MustMintAtLeastOneToken();
error NotEnoughAvailableTokens();
string private _name;
string private _symbol;
mapping(uint256 => uint256) private _availableTokens;
uint256 public remainingSupply;
uint256 public immutable maxSupply;
constructor(string memory name_, string memory symbol_, uint256 maxSupply_) {
_name = name_;
_symbol = symbol_;
maxSupply = maxSupply_;
remainingSupply = maxSupply_;
}
function totalSupply() public view virtual returns (uint256) {
return maxSupply - remainingSupply;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function numberMinted(address minter) public view virtual returns (uint32) {
return uint32(ERC721._getAux(minter) >> 192);
}
function _mintRandom(address to, uint256 _numToMint) internal virtual {
if (msg.sender != tx.origin) revert ContractsCannotMint();
if (_numToMint == 0) revert MustMintAtLeastOneToken();
if (remainingSupply < _numToMint) revert NotEnoughAvailableTokens();
LibPRNG.PRNG memory prng = LibPRNG.PRNG(uint256(keccak256(abi.encodePacked(
block.timestamp, block.prevrandao
))));
uint256 updatedRemainingSupply = remainingSupply;
for (uint256 i; i < _numToMint; ) {
uint256 randomIndex = prng.uniform(updatedRemainingSupply);
uint256 tokenId = getAvailableTokenAtIndex(randomIndex, updatedRemainingSupply);
_mint(to, tokenId);
--updatedRemainingSupply;
unchecked {++i;}
}
_incrementAmountMinted(to, uint32(_numToMint));
remainingSupply = updatedRemainingSupply;
}
// Must be called in descending order of index
function _mintAtIndex(address to, uint256 index) internal virtual {
if (msg.sender != tx.origin) revert ContractsCannotMint();
if (remainingSupply == 0) revert NotEnoughAvailableTokens();
uint256 tokenId = getAvailableTokenAtIndex(index, remainingSupply);
--remainingSupply;
_incrementAmountMinted(to, 1);
_mint(to, tokenId);
}
// Implements https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle. Code taken from CryptoPhunksV2
function getAvailableTokenAtIndex(uint256 indexToUse, uint256 updatedNumAvailableTokens)
private
returns (uint256 result)
{
uint256 valAtIndex = _availableTokens[indexToUse];
uint256 lastIndex = updatedNumAvailableTokens - 1;
uint256 lastValInArray = _availableTokens[lastIndex];
result = valAtIndex == 0 ? indexToUse : valAtIndex;
if (indexToUse != lastIndex) {
_availableTokens[indexToUse] = lastValInArray == 0 ? lastIndex : lastValInArray;
}
if (lastValInArray != 0) {
delete _availableTokens[lastIndex];
}
}
function _setExtraAddressData(address minter, uint192 extraData) internal virtual {
uint32 numMinted = numberMinted(minter);
ERC721._setAux(
minter,
uint224((uint256(numMinted) << 192)) | uint224(extraData)
);
}
function _getAddressExtraData(address minter) internal view virtual returns (uint192) {
return uint192(_getAux(minter));
}
function _incrementAmountMinted(address minter, uint32 newMints) private {
uint32 numMinted = numberMinted(minter);
uint32 newMintNumMinted = numMinted + uint32(newMints);
uint224 auxData = ERC721._getAux(minter);
ERC721._setAux(
minter,
uint224(uint256(newMintNumMinted) << 192) | uint224(uint192(auxData))
);
}
}
// File: contracts/MetaLifeOgPets.sol
pragma solidity 0.8.19;
contract MetaLifeOgPets is ReentrancyGuard, Ownable, ERC721r {
using Strings for uint256;
string public baseURI; // PUBLIC
uint16 public mainMaxSupply = 1500; // PRIVATE
uint16 public nbMintedCouncil = 0;
uint16 public nbMintedHonorary = 0;
uint16 public nbMintedGuardian = 0;
uint16 public nbMintedJudge = 0;
uint16 public nbMintedWhale = 0;
uint16 public maxSupplyCouncil = 305;
uint16 public maxSupplyHonorary = 66;
uint16 public maxSupplyGuardian = 36;
uint16 public maxSupplyJudge = 11;
uint16 public maxSupplyWhale = 26;
uint256 public limitMintSpecific = 0;
address payable private collector;
mapping(address => uint8) private addressesRandom;
event MintedRandom(address indexed from, uint256 timestamp);
uint16 private _tokenIdCurrentCouncil = 1057;
mapping(address => uint8) private addressesCouncil;
event MintedCouncil(address indexed from, uint256 timestamp, uint256[] tokenIds);
uint16 private _tokenIdCurrentHonorary = 1362;
mapping(address => uint8) private addressesHonorary;
event MintedHonorary(address indexed from, uint256 timestamp, uint256 tokenId);
uint16 private _tokenIdCurrentGuardian = 1428;
mapping(address => uint8) private addressesGuardian;
event MintedGuardian(address indexed from, uint256 timestamp, uint256 tokenId);
uint16 private _tokenIdCurrentJudge = 1464;
mapping(address => uint8) private addressesJudge;
event MintedJudge(address indexed from, uint256 timestamp, uint256 tokenId);
uint16 private _tokenIdCurrentWhale = 1475;
mapping(address => uint8) private addressesWhale;
event MintedWhale(address indexed from, uint256 timestamp, uint256 tokenId);
uint16 private tokenGivewayIndex = 0;
mapping(address => uint8) private addressesGiveway;
uint256[] private tokenAvailables;
event MintedGiveway(address indexed from, uint256 timestamp, uint256 tokenId);
constructor() ERC721r('MetaLife OG Pets', 'MLP', 10_56){
limitMintSpecific = block.timestamp + ((365/2) * 24 * 60 * 60);
}
function withdrawAll() public payable onlyOwner {
collector.transfer(address(this).balance);
}
function setCollector(address payable _newCollector) public onlyOwner {
collector = _newCollector;
}
function _setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function _baseURI() internal view virtual returns (string memory) {
return baseURI;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), 'unknow token');
string memory uri = _baseURI();
return bytes(uri).length > 0 ? string(abi.encodePacked(uri, tokenId.toString())) : "";
}
function addAddressesRandom(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner {
require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal');
for (uint i = 0; i < _toAddAddresses.length; i++) {
addressesRandom[_toAddAddresses[i]] = _quantities[i];
}
}
function addAddressesCouncil(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner {
require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal');
for (uint i = 0; i < _toAddAddresses.length; i++) {
addressesCouncil[_toAddAddresses[i]] = _quantities[i];
}
}
function addAddressesHonorary(address[] calldata _toAddAddresses) external onlyOwner {
for (uint i = 0; i < _toAddAddresses.length; i++) {
addressesHonorary[_toAddAddresses[i]] = 1;
}
}
function addAddressesGuardian(address[] calldata _toAddAddresses) external onlyOwner {
for (uint i = 0; i < _toAddAddresses.length; i++) {
addressesGuardian[_toAddAddresses[i]] = 1;
}
}
function addAddressesJudge(address[] calldata _toAddAddresses) external onlyOwner {
for (uint i = 0; i < _toAddAddresses.length; i++) {
addressesJudge[_toAddAddresses[i]] = 1;
}
}
function addAddressesWhale(address[] calldata _toAddAddresses, uint8[] calldata _quantities) external onlyOwner {
require(_toAddAddresses.length == _quantities.length, 'Nb address and nb quantities must be equal');
for (uint i = 0; i < _toAddAddresses.length; i++) {
addressesWhale[_toAddAddresses[i]] = _quantities[i];
}
}
function addressClaimbleRandom(address _wallet) public view returns(uint8) {
return addressesRandom[_wallet];
}
function addressClaimbleCouncil(address _wallet) public view returns(uint8) {
return addressesCouncil[_wallet];
}
function addressClaimbleHonorary(address _wallet) public view returns(uint8) {
return addressesHonorary[_wallet];
}
function addressClaimbleGuardian(address _wallet) public view returns(uint8) {
return addressesGuardian[_wallet];
}
function addressClaimbleJudge(address _wallet) public view returns(uint8) {
return addressesJudge[_wallet];
}
function addressClaimbleWhale(address _wallet) public view returns(uint8) {
return addressesWhale[_wallet];
}
function mintRandom(uint8 _nb) external {
require(addressesRandom[msg.sender] > 0, "Not eligible");
require(addressesRandom[msg.sender] >= _nb, "Not enough claimable tokens");
require(maxSupply >= totalSupply() + _nb, "Supply limit exeedx");
require(_nb <= 5, "Limit max");
addressesRandom[msg.sender] = addressesRandom[msg.sender] - _nb;
_mintRandom(msg.sender, _nb);
emit MintedRandom(msg.sender, block.timestamp);
}
function mainTotalSupply() public view returns (uint256){
return totalSupply() + nbMintedCouncil + nbMintedHonorary + nbMintedGuardian + nbMintedJudge + nbMintedWhale;
}
function mintCouncil(uint256 _nb) external {
require(block.timestamp < limitMintSpecific, "Council mint close");
require(addressesCouncil[msg.sender] > 0, "Not eligible");
require(addressesCouncil[msg.sender] >= _nb, "Not enough claimable tokens");
require(nbMintedCouncil + 1 <= maxSupplyCouncil, "Max supply council exceed");
require(_nb <= 5, "Limit max");
uint256[] memory _tokenIdsMinted = new uint256[](_nb);
for (uint32 i = 0; i < _nb; i++) {
addressesCouncil[msg.sender]--;
_safeMint(msg.sender, _tokenIdCurrentCouncil);
_tokenIdsMinted[i] = _tokenIdCurrentCouncil;
_tokenIdCurrentCouncil++;
nbMintedCouncil++;
}
emit MintedCouncil(msg.sender, block.timestamp, _tokenIdsMinted);
}
function mintHonorary() external {
require(block.timestamp < limitMintSpecific, "Honorary mint close");
require(addressesHonorary[msg.sender] > 0, "No giveway");
require(nbMintedHonorary + 1 <= maxSupplyHonorary, "Max supply honorary exceed");
addressesHonorary[msg.sender] = 0;
_safeMint(msg.sender, _tokenIdCurrentHonorary);
emit MintedHonorary(msg.sender, block.timestamp, _tokenIdCurrentHonorary);
_tokenIdCurrentHonorary++;
nbMintedHonorary++;
}
function mintGuardian() external {
require(block.timestamp < limitMintSpecific, "Guardian mint close");
require(addressesGuardian[msg.sender] > 0, "No giveway");
require(nbMintedGuardian + 1 <= maxSupplyGuardian, "Max supply guardian exceed");
addressesGuardian[msg.sender] = 0;
_safeMint(msg.sender, _tokenIdCurrentGuardian);
emit MintedGuardian(msg.sender, block.timestamp, _tokenIdCurrentGuardian);
_tokenIdCurrentGuardian++;
nbMintedGuardian++;
}
function mintJudge() external {
require(block.timestamp < limitMintSpecific, "Judge mint close");
require(addressesJudge[msg.sender] > 0, "Not eligible");
require(nbMintedJudge + 1 <= maxSupplyJudge, "Max supply judge exceed");
addressesJudge[msg.sender] = 0;
_safeMint(msg.sender, _tokenIdCurrentJudge);
emit MintedJudge(msg.sender, block.timestamp, _tokenIdCurrentJudge);
_tokenIdCurrentJudge++;
nbMintedJudge++;
}
function mintWhale() external {
require(block.timestamp < limitMintSpecific, "Whale mint close");
require(addressesWhale[msg.sender] > 0, "No giveway");
require(nbMintedWhale + 1 <= maxSupplyWhale, "Max supply whale exceed");
addressesWhale[msg.sender] = 0;
_safeMint(msg.sender, _tokenIdCurrentWhale);
emit MintedWhale(msg.sender, block.timestamp, _tokenIdCurrentWhale);
_tokenIdCurrentWhale++;
nbMintedWhale++;
}
function tokenExist(uint256 tokenId) public view returns(bool) {
return _exists(tokenId);
}
function setTokenAvailables(uint256[] calldata _tokenIdsAvailable) external onlyOwner {
require(block.timestamp > limitMintSpecific, "Giveway not activate");
tokenAvailables = _tokenIdsAvailable;
}
function getTokenAvailables() public view returns(uint256[] memory) {
return tokenAvailables;
}
function countTokenAvailables() public view returns(uint256) {
return tokenAvailables.length;
}
function addAddressesGiveway(address[] calldata _toAddAddresses) external onlyOwner {
for (uint i = 0; i < _toAddAddresses.length; i++) {
addressesGiveway[_toAddAddresses[i]] = 1;
}
}
function mintGiveway() external {
require(addressesGiveway[msg.sender] > 0, "No giveway");
require(mainMaxSupply >= mainTotalSupply() + 1, "Max supply exceed");
addressesGiveway[msg.sender] = 0;
_safeMint(msg.sender, tokenAvailables[tokenGivewayIndex]);
emit MintedGiveway(msg.sender, block.timestamp, tokenAvailables[tokenGivewayIndex]);
tokenGivewayIndex++;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountBalanceOverflow","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"ContractsCannotMint","type":"error"},{"inputs":[],"name":"MustMintAtLeastOneToken","type":"error"},{"inputs":[],"name":"NotEnoughAvailableTokens","type":"error"},{"inputs":[],"name":"NotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","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":"isApproved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"MintedCouncil","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintedGiveway","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintedGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintedHonorary","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintedJudge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MintedRandom","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintedWhale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"_setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAddressesCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"}],"name":"addAddressesGiveway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"}],"name":"addAddressesGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"}],"name":"addAddressesHonorary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"}],"name":"addAddressesJudge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAddressesRandom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_toAddAddresses","type":"address[]"},{"internalType":"uint8[]","name":"_quantities","type":"uint8[]"}],"name":"addAddressesWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"addressClaimbleCouncil","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"addressClaimbleGuardian","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"addressClaimbleHonorary","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"addressClaimbleJudge","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"addressClaimbleRandom","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"addressClaimbleWhale","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"countTokenAvailables","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenAvailables","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitMintSpecific","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainMaxSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyCouncil","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyGuardian","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyHonorary","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyJudge","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyWhale","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nb","type":"uint256"}],"name":"mintCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintGiveway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintHonorary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintJudge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_nb","type":"uint8"}],"name":"mintRandom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedCouncil","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedGuardian","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedHonorary","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedJudge","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nbMintedWhale","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remainingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"isApproved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_newCollector","type":"address"}],"name":"setCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIdsAvailable","type":"uint256[]"}],"name":"setTokenAvailables","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenExist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
60a06040526105dc600760006101000a81548161ffff021916908361ffff1602179055506000600760026101000a81548161ffff021916908361ffff1602179055506000600760046101000a81548161ffff021916908361ffff1602179055506000600760066101000a81548161ffff021916908361ffff1602179055506000600760086101000a81548161ffff021916908361ffff16021790555060006007600a6101000a81548161ffff021916908361ffff1602179055506101316007600c6101000a81548161ffff021916908361ffff16021790555060426007600e6101000a81548161ffff021916908361ffff1602179055506024600760106101000a81548161ffff021916908361ffff160217905550600b600760126101000a81548161ffff021916908361ffff160217905550601a600760146101000a81548161ffff021916908361ffff1602179055506000600855610421600b60006101000a81548161ffff021916908361ffff160217905550610552600d60006101000a81548161ffff021916908361ffff160217905550610594600f60006101000a81548161ffff021916908361ffff1602179055506105b8601160006101000a81548161ffff021916908361ffff1602179055506105c3601360006101000a81548161ffff021916908361ffff1602179055506000601560006101000a81548161ffff021916908361ffff1602179055503480156200021b57600080fd5b506040518060400160405280601081526020017f4d6574614c696665204f472050657473000000000000000000000000000000008152506040518060400160405280600381526020017f4d4c5000000000000000000000000000000000000000000000000000000000008152506104206001600081905550620002b3620002a76200030660201b60201c565b6200030e60201b60201c565b8260029081620002c491906200064e565b508160039081620002d691906200064e565b5080608081815250508060058190555050505062f099c042620002fa919062000764565b6008819055506200079f565b600033905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200045657607f821691505b6020821081036200046c576200046b6200040e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004d67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000497565b620004e2868362000497565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200052f620005296200052384620004fa565b62000504565b620004fa565b9050919050565b6000819050919050565b6200054b836200050e565b620005636200055a8262000536565b848454620004a4565b825550505050565b600090565b6200057a6200056b565b6200058781848462000540565b505050565b5b81811015620005af57620005a360008262000570565b6001810190506200058d565b5050565b601f821115620005fe57620005c88162000472565b620005d38462000487565b81016020851015620005e3578190505b620005fb620005f28562000487565b8301826200058c565b50505b505050565b600082821c905092915050565b6000620006236000198460080262000603565b1980831691505092915050565b60006200063e838362000610565b9150826002028217905092915050565b6200065982620003d4565b67ffffffffffffffff811115620006755762000674620003df565b5b6200068182546200043d565b6200068e828285620005b3565b600060209050601f831160018114620006c65760008415620006b1578287015190505b620006bd858262000630565b8655506200072d565b601f198416620006d68662000472565b60005b828110156200070057848901518255600182019150602085019450602081019050620006d9565b868310156200072057848901516200071c601f89168262000610565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200077182620004fa565b91506200077e83620004fa565b925082820190508082111562000799576200079862000735565b5b92915050565b6080516159e3620007c9600039600081816115d701528181611a720152612f1401526159e36000f3fe6080604052600436106103a15760003560e01c8063715018a6116101e7578063b88d4fde1161010d578063dcc4d445116100a0578063f2fde38b1161006f578063f2fde38b14610d5c578063f6d8853614610d85578063fb5b82d014610d9c578063fc89067914610dc5576103a1565b8063dcc4d44514610c8e578063e985e9c514610cb7578063ea3d741814610cf4578063f058a4d114610d1f576103a1565b8063d5abeb01116100dc578063d5abeb0114610bd2578063d8ae7c9d14610bfd578063da0239a614610c26578063dc33e68114610c51576103a1565b8063b88d4fde14610b25578063c733fe0d14610b41578063c87b56dd14610b58578063cc0c523614610b95576103a1565b8063916ec2c611610185578063a2cd568911610154578063a2cd568914610a67578063a58a426d14610a92578063a7c7021314610abd578063acc34a3e14610ae8576103a1565b8063916ec2c6146109bd57806391ec4b4c146109e857806395d89b4114610a13578063a22cb46514610a3e576103a1565b8063853828b6116101c1578063853828b6146109205780638b4303a61461092a5780638b4f6325146109555780638da5cb5b14610992576103a1565b8063715018a6146108b5578063787b9712146108cc5780637ca470b1146108f5576103a1565b80632db5b8e7116102cc578063468409ce1161026a5780636902e20d116102395780636902e20d146107e75780636c0360eb146108105780636d632d891461083b57806370a0823114610878576103a1565b8063468409ce1461072b57806346fbed6f146107545780636352211e1461077f5780636802e529146107bc576103a1565b8063376dde7f116102a6578063376dde7f14610692578063376e1b1f146106bb57806337e49eed146106d257806342842e0e1461070f576103a1565b80632db5b8e71461061557806331b5b9071461063e57806333a3600714610667576103a1565b8063095ea7b31161034457806322d1464c1161031357806322d1464c1461057c57806323b872dd146105a5578063257e7ff4146105c15780632b9c3bf4146105ec576103a1565b8063095ea7b3146104e15780630ff9cc6b146104fd57806318160ddd146105265780631d490ee314610551576103a1565b806306fdde031161038057806306fdde031461041157806307c3841d1461043c57806307edf9ef14610479578063081812fc146104a4576103a1565b80627c3566146103a657806301ffc9a7146103bd578063022c0199146103fa575b600080fd5b3480156103b257600080fd5b506103bb610df0565b005b3480156103c957600080fd5b506103e460048036038101906103df9190613f59565b61108c565b6040516103f19190613fa1565b60405180910390f35b34801561040657600080fd5b5061040f6110b1565b005b34801561041d57600080fd5b5061042661134d565b604051610433919061404c565b60405180910390f35b34801561044857600080fd5b50610463600480360381019061045e91906140cc565b6113df565b6040516104709190614115565b60405180910390f35b34801561048557600080fd5b5061048e611435565b60405161049b919061414d565b60405180910390f35b3480156104b057600080fd5b506104cb60048036038101906104c6919061419e565b611449565b6040516104d891906141da565b60405180910390f35b6104fb60048036038101906104f691906141f5565b6114a3565b005b34801561050957600080fd5b50610524600480360381019061051f91906142f0565b6114b2565b005b34801561053257600080fd5b5061053b6115d0565b6040516105489190614380565b60405180910390f35b34801561055d57600080fd5b50610566611605565b604051610573919061414d565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e919061439b565b611619565b005b6105bf60048036038101906105ba91906143e8565b6116c7565b005b3480156105cd57600080fd5b506105d661180f565b6040516105e39190614380565b60405180910390f35b3480156105f857600080fd5b50610613600480360381019061060e91906142f0565b611815565b005b34801561062157600080fd5b5061063c60048036038101906106379190614467565b611933565b005b34801561064a57600080fd5b50610665600480360381019061066091906145c4565b611c26565b005b34801561067357600080fd5b5061067c611c41565b6040516106899190614380565b60405180910390f35b34801561069e57600080fd5b506106b960048036038101906106b4919061439b565b611ceb565b005b3480156106c757600080fd5b506106d0611d99565b005b3480156106de57600080fd5b506106f960048036038101906106f491906140cc565b612035565b6040516107069190614115565b60405180910390f35b610729600480360381019061072491906143e8565b61208b565b005b34801561073757600080fd5b50610752600480360381019061074d919061439b565b6120c5565b005b34801561076057600080fd5b50610769612173565b604051610776919061414d565b60405180910390f35b34801561078b57600080fd5b506107a660048036038101906107a1919061419e565b612187565b6040516107b391906141da565b60405180910390f35b3480156107c857600080fd5b506107d16121ac565b6040516107de919061414d565b60405180910390f35b3480156107f357600080fd5b5061080e6004803603810190610809919061419e565b6121c0565b005b34801561081c57600080fd5b506108256125ec565b604051610832919061404c565b60405180910390f35b34801561084757600080fd5b50610862600480360381019061085d91906140cc565b61267a565b60405161086f9190614115565b60405180910390f35b34801561088457600080fd5b5061089f600480360381019061089a91906140cc565b6126d0565b6040516108ac9190614380565b60405180910390f35b3480156108c157600080fd5b506108ca612720565b005b3480156108d857600080fd5b506108f360048036038101906108ee91906142f0565b612734565b005b34801561090157600080fd5b5061090a612852565b604051610917919061414d565b60405180910390f35b610928612866565b005b34801561093657600080fd5b5061093f6128d9565b60405161094c919061414d565b60405180910390f35b34801561096157600080fd5b5061097c600480360381019061097791906140cc565b6128ed565b6040516109899190614115565b60405180910390f35b34801561099e57600080fd5b506109a7612943565b6040516109b491906141da565b60405180910390f35b3480156109c957600080fd5b506109d261296d565b6040516109df919061414d565b60405180910390f35b3480156109f457600080fd5b506109fd612981565b604051610a0a919061414d565b60405180910390f35b348015610a1f57600080fd5b50610a28612995565b604051610a35919061404c565b60405180910390f35b348015610a4a57600080fd5b50610a656004803603810190610a609190614639565b612a27565b005b348015610a7357600080fd5b50610a7c612a7d565b604051610a89919061414d565b60405180910390f35b348015610a9e57600080fd5b50610aa7612a91565b604051610ab49190614380565b60405180910390f35b348015610ac957600080fd5b50610ad2612a9e565b604051610adf9190614737565b60405180910390f35b348015610af457600080fd5b50610b0f6004803603810190610b0a91906140cc565b612af6565b604051610b1c9190614115565b60405180910390f35b610b3f6004803603810190610b3a91906147af565b612b4c565b005b348015610b4d57600080fd5b50610b56612bbd565b005b348015610b6457600080fd5b50610b7f6004803603810190610b7a919061419e565b612e59565b604051610b8c919061404c565b60405180910390f35b348015610ba157600080fd5b50610bbc6004803603810190610bb7919061419e565b612f00565b604051610bc99190613fa1565b60405180910390f35b348015610bde57600080fd5b50610be7612f12565b604051610bf49190614380565b60405180910390f35b348015610c0957600080fd5b50610c246004803603810190610c1f919061439b565b612f36565b005b348015610c3257600080fd5b50610c3b612fe4565b604051610c489190614380565b60405180910390f35b348015610c5d57600080fd5b50610c786004803603810190610c7391906140cc565b612fea565b604051610c859190614856565b60405180910390f35b348015610c9a57600080fd5b50610cb56004803603810190610cb091906148c7565b61301e565b005b348015610cc357600080fd5b50610cde6004803603810190610cd99190614914565b613080565b604051610ceb9190613fa1565b60405180910390f35b348015610d0057600080fd5b50610d096130a4565b604051610d16919061414d565b60405180910390f35b348015610d2b57600080fd5b50610d466004803603810190610d4191906140cc565b6130b8565b604051610d539190614115565b60405180910390f35b348015610d6857600080fd5b50610d836004803603810190610d7e91906140cc565b61310e565b005b348015610d9157600080fd5b50610d9a613191565b005b348015610da857600080fd5b50610dc36004803603810190610dbe9190614992565b6133e1565b005b348015610dd157600080fd5b50610dda61342d565b604051610de7919061414d565b60405180910390f35b6008544210610e34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2b90614a0b565b60405180910390fd5b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611610ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebd90614a77565b60405180910390fd5b6007600e9054906101000a900461ffff1661ffff166001600760049054906101000a900461ffff16610ef89190614ac6565b61ffff161115610f3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3490614b48565b60405180910390fd5b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550610fb433600d60009054906101000a900461ffff1661ffff16613441565b3373ffffffffffffffffffffffffffffffffffffffff167ff70b403b1d50cef877cafdc0f6c3c47f58a42f1e5f5f17173f255ef7b00762a042600d60009054906101000a900461ffff1660405161100c929190614ba3565b60405180910390a2600d600081819054906101000a900461ffff168092919061103490614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600481819054906101000a900461ffff168092919061106f90614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b60008160e01c635b5e139f81146380ac58cd82146301ffc9a783141717915050919050565b60085442106110f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ec90614c42565b60405180910390fd5b6000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611611187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117e90614cae565b60405180910390fd5b600760129054906101000a900461ffff1661ffff166001600760089054906101000a900461ffff166111b99190614ac6565b61ffff1611156111fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f590614d1a565b60405180910390fd5b6000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555061127533601160009054906101000a900461ffff1661ffff16613441565b3373ffffffffffffffffffffffffffffffffffffffff167f76f9e85ff7722d043b09d71ddb1f2e240963d9f9072c84082432fd9efd24677642601160009054906101000a900461ffff166040516112cd929190614ba3565b60405180910390a26011600081819054906101000a900461ffff16809291906112f590614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600881819054906101000a900461ffff168092919061133090614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b60606002805461135c90614d69565b80601f016020809104026020016040519081016040528092919081815260200182805461138890614d69565b80156113d55780601f106113aa576101008083540402835291602001916113d5565b820191906000526020600020905b8154815290600101906020018083116113b857829003601f168201915b5050505050905090565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600760029054906101000a900461ffff1681565b6000816000527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52602060002082018201805460601b60601c6114965763ceea21b66000526004601cfd5b8060010154915050919050565b6114ae33838361345f565b5050565b6114ba613516565b818190508484905014611502576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f990614e0c565b60405180910390fd5b60005b848490508110156115c95782828281811061152357611522614e2c565b5b90506020020160208101906115389190614467565b600a600087878581811061154f5761154e614e2c565b5b905060200201602081019061156491906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555080806115c190614e5b565b915050611505565b5050505050565b60006005547f00000000000000000000000000000000000000000000000000000000000000006116009190614ea3565b905090565b6007600e9054906101000a900461ffff1681565b611621613516565b60005b828290508110156116c25760016010600085858581811061164857611647614e2c565b5b905060200201602081019061165d91906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555080806116ba90614e5b565b915050611624565b505050565b6116d2838383613594565b60001960601c8381169350828116925081600052337f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c526020600020820182018054808316868114810261174457806117365763ceea21b66000526004601cfd5b63a11481006000526004601cfd5b856117575763ea553b346000526004601cfd5b86600052826001015480331488331417611784576030600c205461178357634b6e7f186000526004601cfd5b5b801561179257600084600101555b5085871882188355601c600c20600181540381555085600052601c600c20600181540163ffffffff81166117ce576301336cea6000526004601cfd5b80825550508486887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a45050505061180a838383613599565b505050565b60085481565b61181d613516565b818190508484905014611865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185c90614e0c565b60405180910390fd5b60005b8484905081101561192c5782828281811061188657611885614e2c565b5b905060200201602081019061189b9190614467565b601460008787858181106118b2576118b1614e2c565b5b90506020020160208101906118c791906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550808061192490614e5b565b915050611868565b5050505050565b6000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff16116119c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bc90614cae565b60405180910390fd5b8060ff16600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff161015611a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5190614f23565b60405180910390fd5b8060ff16611a666115d0565b611a709190614f43565b7f00000000000000000000000000000000000000000000000000000000000000001015611ad2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac990614fc3565b60405180910390fd5b60058160ff161115611b19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b109061502f565b60405180910390fd5b80600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b71919061504f565b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550611bd5338260ff1661359e565b3373ffffffffffffffffffffffffffffffffffffffff167f30603f56befad35715d530ed1090c153118f6822d031c1e03fc5bc0e3f30808942604051611c1b9190614380565b60405180910390a250565b611c2e613516565b8060069081611c3d9190615226565b5050565b60006007600a9054906101000a900461ffff1661ffff16600760089054906101000a900461ffff1661ffff16600760069054906101000a900461ffff1661ffff16600760049054906101000a900461ffff1661ffff16600760029054906101000a900461ffff1661ffff16611cb46115d0565b611cbe9190614f43565b611cc89190614f43565b611cd29190614f43565b611cdc9190614f43565b611ce69190614f43565b905090565b611cf3613516565b60005b82829050811015611d9457600160166000858585818110611d1a57611d19614e2c565b5b9050602002016020810190611d2f91906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff1602179055508080611d8c90614e5b565b915050611cf6565b505050565b6008544210611ddd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd490615344565b60405180910390fd5b6000601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611611e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6690614a77565b60405180910390fd5b600760109054906101000a900461ffff1661ffff166001600760069054906101000a900461ffff16611ea19190614ac6565b61ffff161115611ee6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611edd906153b0565b60405180910390fd5b6000601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550611f5d33600f60009054906101000a900461ffff1661ffff16613441565b3373ffffffffffffffffffffffffffffffffffffffff167f3068eb10a9f5bc0a2d97cbc29c967a612136c9d03efe312432d0cff3ece88d5542600f60009054906101000a900461ffff16604051611fb5929190614ba3565b60405180910390a2600f600081819054906101000a900461ffff1680929190611fdd90614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600681819054906101000a900461ffff168092919061201890614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6120968383836116c7565b61209f82613729565b156120c0576120bf83838360405180602001604052806000815250613734565b5b505050565b6120cd613516565b60005b8282905081101561216e576001600e60008585858181106120f4576120f3614e2c565b5b905060200201602081019061210991906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550808061216690614e5b565b9150506120d0565b505050565b600760049054906101000a900461ffff1681565b6000612192826137c6565b9050806121a75763ceea21b66000526004601cfd5b919050565b6007600a9054906101000a900461ffff1681565b6008544210612204576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121fb9061541c565b60405180910390fd5b6000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611612296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228d90614cae565b60405180910390fd5b80600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff161015612328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231f90614f23565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff166001600760029054906101000a900461ffff1661235a9190614ac6565b61ffff16111561239f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239690615488565b60405180910390fd5b60058111156123e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123da9061502f565b60405180910390fd5b60008167ffffffffffffffff8111156123ff576123fe614499565b5b60405190808252806020026020018201604052801561242d5781602001602082028036833780820191505090505b50905060005b828163ffffffff16101561259757600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081819054906101000a900460ff168092919061249d906154a8565b91906101000a81548160ff021916908360ff160217905550506124d433600b60009054906101000a900461ffff1661ffff16613441565b600b60009054906101000a900461ffff1661ffff16828263ffffffff168151811061250257612501614e2c565b5b602002602001018181525050600b600081819054906101000a900461ffff168092919061252e90614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600281819054906101000a900461ffff168092919061256990614bcc565b91906101000a81548161ffff021916908361ffff16021790555050808061258f906154d1565b915050612433565b503373ffffffffffffffffffffffffffffffffffffffff167f925a1c03df0f625e3645b782d2a6fc1ccee76de332fba5dc74ad672526a0d39942836040516125e09291906154fd565b60405180910390a25050565b600680546125f990614d69565b80601f016020809104026020016040519081016040528092919081815260200182805461262590614d69565b80156126725780601f1061264757610100808354040283529160200191612672565b820191906000526020600020905b81548152906001019060200180831161265557829003601f168201915b505050505081565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000816126e557638f4eb6046000526004601cfd5b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c528160005263ffffffff601c600c2054169050919050565b612728613516565b6127326000613807565b565b61273c613516565b818190508484905014612784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161277b90614e0c565b60405180910390fd5b60005b8484905081101561284b578282828181106127a5576127a4614e2c565b5b90506020020160208101906127ba9190614467565b600c60008787858181106127d1576127d0614e2c565b5b90506020020160208101906127e691906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550808061284390614e5b565b915050612787565b5050505050565b600760149054906101000a900461ffff1681565b61286e613516565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050501580156128d6573d6000803e3d6000fd5b50565b600760009054906101000a900461ffff1681565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6007600c9054906101000a900461ffff1681565b600760089054906101000a900461ffff1681565b6060600380546129a490614d69565b80601f01602080910402602001604051908101604052809291908181526020018280546129d090614d69565b8015612a1d5780601f106129f257610100808354040283529160200191612a1d565b820191906000526020600020905b815481529060010190602001808311612a0057829003601f168201915b5050505050905090565b801515905081601c52670a5a2e7a0000000060085233600052806030600c2055806000528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b600760069054906101000a900461ffff1681565b6000601780549050905090565b60606017805480602002602001604051908101604052809291908181526020018280548015612aec57602002820191906000526020600020905b815481526020019060010190808311612ad8575b5050505050905090565b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b612b578585856116c7565b612b6084613729565b15612bb657612bb585858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613734565b5b5050505050565b6008544210612c01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bf890615579565b60405180910390fd5b6000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611612c93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8a90614a77565b60405180910390fd5b600760149054906101000a900461ffff1661ffff1660016007600a9054906101000a900461ffff16612cc59190614ac6565b61ffff161115612d0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d01906155e5565b60405180910390fd5b6000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550612d8133601360009054906101000a900461ffff1661ffff16613441565b3373ffffffffffffffffffffffffffffffffffffffff167f11f17ae42a0904709076e999b53fe5d9a2094552d1e26167334b0a1df43db8bd42601360009054906101000a900461ffff16604051612dd9929190614ba3565b60405180910390a26013600081819054906101000a900461ffff1680929190612e0190614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600a81819054906101000a900461ffff1680929190612e3c90614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b6060612e64826138cd565b612ea3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9a90615651565b60405180910390fd5b6000612ead61390b565b90506000815111612ecd5760405180602001604052806000815250612ef8565b80612ed78461399d565b604051602001612ee89291906156ad565b6040516020818303038152906040525b915050919050565b6000612f0b826138cd565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b612f3e613516565b60005b82829050811015612fdf57600160126000858585818110612f6557612f64614e2c565b5b9050602002016020810190612f7a91906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff1602179055508080612fd790614e5b565b915050612f41565b505050565b60055481565b600060c0612ff783613a6b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050919050565b613026613516565b600854421161306a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130619061571d565b60405180910390fd5b81816017919061307b929190613e83565b505050565b600081601c52670a5a2e7a00000000600852826000526030600c2054905092915050565b600760109054906101000a900461ffff1681565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b613116613516565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161317c906157af565b60405180910390fd5b61318e81613807565b50565b6000601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611613223576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321a90614a77565b60405180910390fd5b600161322d611c41565b6132379190614f43565b600760009054906101000a900461ffff1661ffff16101561328d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132849061581b565b60405180910390fd5b6000601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550613322336017601560009054906101000a900461ffff1661ffff168154811061331257613311614e2c565b5b9060005260206000200154613441565b3373ffffffffffffffffffffffffffffffffffffffff167fa72aa19bfd87e001e03ac6bf966e0f914e84e90c84f842017e87ffc32547505f426017601560009054906101000a900461ffff1661ffff168154811061338357613382614e2c565b5b906000526020600020015460405161339c92919061583b565b60405180910390a26015600081819054906101000a900461ffff16809291906133c490614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b6133e9613516565b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600760129054906101000a900461ffff1681565b61345b828260405180602001604052806000815250613aa5565b5050565b60001960601c8281169250838116935081600052837f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260206000208201820180548216806134b95763ceea21b66000526004601cfd5b8086148615176134e057806000526030600c20546134df57634b6e7f186000526004601cfd5b5b8482600101558385827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a4505050505050565b61351e613ad0565b73ffffffffffffffffffffffffffffffffffffffff1661353c612943565b73ffffffffffffffffffffffffffffffffffffffff1614613592576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613589906158b0565b60405180910390fd5b565b505050565b505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613603576040517fd9d552c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000810361363d576040517f4600cfe900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806005541015613679576040517f7775abdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604051806020016040528042446040516020016136999291906158f1565b6040516020818303038152906040528051906020012060001c81525090506000600554905060005b838110156137115760006136de8385613ad890919063ffffffff16565b905060006136ec8285613b03565b90506136f88782613baf565b836137029061591d565b935082600101925050506136c1565b5061371c8484613c8d565b8060058190555050505050565b6000813b9050919050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a0840152801561377b578060c08401826020870160045afa505b60208360a48301601c860160008a5af16137a4573d1561379f573d6000803e3d6000fd5b600083525b8160e01b8351146137bd5763d1a57ed66000526004601cfd5b50505050505050565b6000816000527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c526020600020820182015460601b60601c9050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000816000527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c526020600020820182015460601b9050919050565b60606006805461391a90614d69565b80601f016020809104026020016040519081016040528092919081815260200182805461394690614d69565b80156139935780601f1061396857610100808354040283529160200191613993565b820191906000526020600020905b81548152906001019060200180831161397657829003601f168201915b5050505050905090565b6060600060016139ac84613cee565b01905060008167ffffffffffffffff8111156139cb576139ca614499565b5b6040519080825280601f01601f1916602001820160405280156139fd5781602001600182028036833780820191505090505b509050600082602001820190505b600115613a60578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581613a5457613a53615946565b5b04945060008503613a0b575b819350505050919050565b60007f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5281600052601c600c205460201c9050919050565b613aaf8383613baf565b613ab883613729565b15613acb57613aca6000848484613734565b5b505050565b600033905090565b60005b600115613af8576020832090508083528182600003068110613adb575b818106905092915050565b600080600460008581526020019081526020016000205490506000600184613b2b9190614ea3565b905060006004600083815260200190815260200160002054905060008314613b535782613b55565b855b9350818614613b865760008114613b6c5780613b6e565b815b60046000888152602001908152602001600020819055505b60008114613ba65760046000838152602001908152602001600020600090555b50505092915050565b613bbb60008383613594565b8160601b60601c915081613bd75763ea553b346000526004601cfd5b806000527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260206000208101810180548060601b15613c215763c991cbb16000526004601cfd5b838117825583600052601c600c20600181540163ffffffff8116613c4d576301336cea6000526004601cfd5b8082555050828460007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a45050613c8960008383613599565b5050565b6000613c9883612fea565b905060008282613ca89190615975565b90506000613cb585613a6b565b9050613ce7858277ffffffffffffffffffffffffffffffffffffffffffffffff1660c08563ffffffff16901b17613e41565b5050505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613d4c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613d4257613d41615946565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613d89576d04ee2d6d415b85acef81000000008381613d7f57613d7e615946565b5b0492506020810190505b662386f26fc100008310613db857662386f26fc100008381613dae57613dad615946565b5b0492506010810190505b6305f5e1008310613de1576305f5e1008381613dd757613dd6615946565b5b0492506008810190505b6127108310613e06576127108381613dfc57613dfb615946565b5b0492506004810190505b60648310613e295760648381613e1f57613e1e615946565b5b0492506002810190505b600a8310613e38576001810190505b80915050919050565b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5281600052601c600c2080548060201c831860201b8118825550505050565b828054828255906000526020600020908101928215613ebf579160200282015b82811115613ebe578235825591602001919060010190613ea3565b5b509050613ecc9190613ed0565b5090565b5b80821115613ee9576000816000905550600101613ed1565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613f3681613f01565b8114613f4157600080fd5b50565b600081359050613f5381613f2d565b92915050565b600060208284031215613f6f57613f6e613ef7565b5b6000613f7d84828501613f44565b91505092915050565b60008115159050919050565b613f9b81613f86565b82525050565b6000602082019050613fb66000830184613f92565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613ff6578082015181840152602081019050613fdb565b60008484015250505050565b6000601f19601f8301169050919050565b600061401e82613fbc565b6140288185613fc7565b9350614038818560208601613fd8565b61404181614002565b840191505092915050565b600060208201905081810360008301526140668184614013565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006140998261406e565b9050919050565b6140a98161408e565b81146140b457600080fd5b50565b6000813590506140c6816140a0565b92915050565b6000602082840312156140e2576140e1613ef7565b5b60006140f0848285016140b7565b91505092915050565b600060ff82169050919050565b61410f816140f9565b82525050565b600060208201905061412a6000830184614106565b92915050565b600061ffff82169050919050565b61414781614130565b82525050565b6000602082019050614162600083018461413e565b92915050565b6000819050919050565b61417b81614168565b811461418657600080fd5b50565b60008135905061419881614172565b92915050565b6000602082840312156141b4576141b3613ef7565b5b60006141c284828501614189565b91505092915050565b6141d48161408e565b82525050565b60006020820190506141ef60008301846141cb565b92915050565b6000806040838503121561420c5761420b613ef7565b5b600061421a858286016140b7565b925050602061422b85828601614189565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f84011261425a57614259614235565b5b8235905067ffffffffffffffff8111156142775761427661423a565b5b6020830191508360208202830111156142935761429261423f565b5b9250929050565b60008083601f8401126142b0576142af614235565b5b8235905067ffffffffffffffff8111156142cd576142cc61423a565b5b6020830191508360208202830111156142e9576142e861423f565b5b9250929050565b6000806000806040858703121561430a57614309613ef7565b5b600085013567ffffffffffffffff81111561432857614327613efc565b5b61433487828801614244565b9450945050602085013567ffffffffffffffff81111561435757614356613efc565b5b6143638782880161429a565b925092505092959194509250565b61437a81614168565b82525050565b60006020820190506143956000830184614371565b92915050565b600080602083850312156143b2576143b1613ef7565b5b600083013567ffffffffffffffff8111156143d0576143cf613efc565b5b6143dc85828601614244565b92509250509250929050565b60008060006060848603121561440157614400613ef7565b5b600061440f868287016140b7565b9350506020614420868287016140b7565b925050604061443186828701614189565b9150509250925092565b614444816140f9565b811461444f57600080fd5b50565b6000813590506144618161443b565b92915050565b60006020828403121561447d5761447c613ef7565b5b600061448b84828501614452565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6144d182614002565b810181811067ffffffffffffffff821117156144f0576144ef614499565b5b80604052505050565b6000614503613eed565b905061450f82826144c8565b919050565b600067ffffffffffffffff82111561452f5761452e614499565b5b61453882614002565b9050602081019050919050565b82818337600083830152505050565b600061456761456284614514565b6144f9565b90508281526020810184848401111561458357614582614494565b5b61458e848285614545565b509392505050565b600082601f8301126145ab576145aa614235565b5b81356145bb848260208601614554565b91505092915050565b6000602082840312156145da576145d9613ef7565b5b600082013567ffffffffffffffff8111156145f8576145f7613efc565b5b61460484828501614596565b91505092915050565b61461681613f86565b811461462157600080fd5b50565b6000813590506146338161460d565b92915050565b600080604083850312156146505761464f613ef7565b5b600061465e858286016140b7565b925050602061466f85828601614624565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6146ae81614168565b82525050565b60006146c083836146a5565b60208301905092915050565b6000602082019050919050565b60006146e482614679565b6146ee8185614684565b93506146f983614695565b8060005b8381101561472a57815161471188826146b4565b975061471c836146cc565b9250506001810190506146fd565b5085935050505092915050565b6000602082019050818103600083015261475181846146d9565b905092915050565b60008083601f84011261476f5761476e614235565b5b8235905067ffffffffffffffff81111561478c5761478b61423a565b5b6020830191508360018202830111156147a8576147a761423f565b5b9250929050565b6000806000806000608086880312156147cb576147ca613ef7565b5b60006147d9888289016140b7565b95505060206147ea888289016140b7565b94505060406147fb88828901614189565b935050606086013567ffffffffffffffff81111561481c5761481b613efc565b5b61482888828901614759565b92509250509295509295909350565b600063ffffffff82169050919050565b61485081614837565b82525050565b600060208201905061486b6000830184614847565b92915050565b60008083601f84011261488757614886614235565b5b8235905067ffffffffffffffff8111156148a4576148a361423a565b5b6020830191508360208202830111156148c0576148bf61423f565b5b9250929050565b600080602083850312156148de576148dd613ef7565b5b600083013567ffffffffffffffff8111156148fc576148fb613efc565b5b61490885828601614871565b92509250509250929050565b6000806040838503121561492b5761492a613ef7565b5b6000614939858286016140b7565b925050602061494a858286016140b7565b9150509250929050565b600061495f8261406e565b9050919050565b61496f81614954565b811461497a57600080fd5b50565b60008135905061498c81614966565b92915050565b6000602082840312156149a8576149a7613ef7565b5b60006149b68482850161497d565b91505092915050565b7f486f6e6f72617279206d696e7420636c6f736500000000000000000000000000600082015250565b60006149f5601383613fc7565b9150614a00826149bf565b602082019050919050565b60006020820190508181036000830152614a24816149e8565b9050919050565b7f4e6f206769766577617900000000000000000000000000000000000000000000600082015250565b6000614a61600a83613fc7565b9150614a6c82614a2b565b602082019050919050565b60006020820190508181036000830152614a9081614a54565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614ad182614130565b9150614adc83614130565b9250828201905061ffff811115614af657614af5614a97565b5b92915050565b7f4d617820737570706c7920686f6e6f7261727920657863656564000000000000600082015250565b6000614b32601a83613fc7565b9150614b3d82614afc565b602082019050919050565b60006020820190508181036000830152614b6181614b25565b9050919050565b6000819050919050565b6000614b8d614b88614b8384614130565b614b68565b614168565b9050919050565b614b9d81614b72565b82525050565b6000604082019050614bb86000830185614371565b614bc56020830184614b94565b9392505050565b6000614bd782614130565b915061ffff8203614beb57614bea614a97565b5b600182019050919050565b7f4a75646765206d696e7420636c6f736500000000000000000000000000000000600082015250565b6000614c2c601083613fc7565b9150614c3782614bf6565b602082019050919050565b60006020820190508181036000830152614c5b81614c1f565b9050919050565b7f4e6f7420656c696769626c650000000000000000000000000000000000000000600082015250565b6000614c98600c83613fc7565b9150614ca382614c62565b602082019050919050565b60006020820190508181036000830152614cc781614c8b565b9050919050565b7f4d617820737570706c79206a7564676520657863656564000000000000000000600082015250565b6000614d04601783613fc7565b9150614d0f82614cce565b602082019050919050565b60006020820190508181036000830152614d3381614cf7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614d8157607f821691505b602082108103614d9457614d93614d3a565b5b50919050565b7f4e62206164647265737320616e64206e62207175616e746974696573206d757360008201527f7420626520657175616c00000000000000000000000000000000000000000000602082015250565b6000614df6602a83613fc7565b9150614e0182614d9a565b604082019050919050565b60006020820190508181036000830152614e2581614de9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614e6682614168565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e9857614e97614a97565b5b600182019050919050565b6000614eae82614168565b9150614eb983614168565b9250828203905081811115614ed157614ed0614a97565b5b92915050565b7f4e6f7420656e6f75676820636c61696d61626c6520746f6b656e730000000000600082015250565b6000614f0d601b83613fc7565b9150614f1882614ed7565b602082019050919050565b60006020820190508181036000830152614f3c81614f00565b9050919050565b6000614f4e82614168565b9150614f5983614168565b9250828201905080821115614f7157614f70614a97565b5b92915050565b7f537570706c79206c696d69742065786565647800000000000000000000000000600082015250565b6000614fad601383613fc7565b9150614fb882614f77565b602082019050919050565b60006020820190508181036000830152614fdc81614fa0565b9050919050565b7f4c696d6974206d61780000000000000000000000000000000000000000000000600082015250565b6000615019600983613fc7565b915061502482614fe3565b602082019050919050565b600060208201905081810360008301526150488161500c565b9050919050565b600061505a826140f9565b9150615065836140f9565b9250828203905060ff81111561507e5761507d614a97565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026150e67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826150a9565b6150f086836150a9565b95508019841693508086168417925050509392505050565b600061512361511e61511984614168565b614b68565b614168565b9050919050565b6000819050919050565b61513d83615108565b6151516151498261512a565b8484546150b6565b825550505050565b600090565b615166615159565b615171818484615134565b505050565b5b818110156151955761518a60008261515e565b600181019050615177565b5050565b601f8211156151da576151ab81615084565b6151b484615099565b810160208510156151c3578190505b6151d76151cf85615099565b830182615176565b50505b505050565b600082821c905092915050565b60006151fd600019846008026151df565b1980831691505092915050565b600061521683836151ec565b9150826002028217905092915050565b61522f82613fbc565b67ffffffffffffffff81111561524857615247614499565b5b6152528254614d69565b61525d828285615199565b600060209050601f831160018114615290576000841561527e578287015190505b615288858261520a565b8655506152f0565b601f19841661529e86615084565b60005b828110156152c6578489015182556001820191506020850194506020810190506152a1565b868310156152e357848901516152df601f8916826151ec565b8355505b6001600288020188555050505b505050505050565b7f477561726469616e206d696e7420636c6f736500000000000000000000000000600082015250565b600061532e601383613fc7565b9150615339826152f8565b602082019050919050565b6000602082019050818103600083015261535d81615321565b9050919050565b7f4d617820737570706c7920677561726469616e20657863656564000000000000600082015250565b600061539a601a83613fc7565b91506153a582615364565b602082019050919050565b600060208201905081810360008301526153c98161538d565b9050919050565b7f436f756e63696c206d696e7420636c6f73650000000000000000000000000000600082015250565b6000615406601283613fc7565b9150615411826153d0565b602082019050919050565b60006020820190508181036000830152615435816153f9565b9050919050565b7f4d617820737570706c7920636f756e63696c2065786365656400000000000000600082015250565b6000615472601983613fc7565b915061547d8261543c565b602082019050919050565b600060208201905081810360008301526154a181615465565b9050919050565b60006154b3826140f9565b9150600082036154c6576154c5614a97565b5b600182039050919050565b60006154dc82614837565b915063ffffffff82036154f2576154f1614a97565b5b600182019050919050565b60006040820190506155126000830185614371565b818103602083015261552481846146d9565b90509392505050565b7f5768616c65206d696e7420636c6f736500000000000000000000000000000000600082015250565b6000615563601083613fc7565b915061556e8261552d565b602082019050919050565b6000602082019050818103600083015261559281615556565b9050919050565b7f4d617820737570706c79207768616c6520657863656564000000000000000000600082015250565b60006155cf601783613fc7565b91506155da82615599565b602082019050919050565b600060208201905081810360008301526155fe816155c2565b9050919050565b7f756e6b6e6f7720746f6b656e0000000000000000000000000000000000000000600082015250565b600061563b600c83613fc7565b915061564682615605565b602082019050919050565b6000602082019050818103600083015261566a8161562e565b9050919050565b600081905092915050565b600061568782613fbc565b6156918185615671565b93506156a1818560208601613fd8565b80840191505092915050565b60006156b9828561567c565b91506156c5828461567c565b91508190509392505050565b7f47697665776179206e6f74206163746976617465000000000000000000000000600082015250565b6000615707601483613fc7565b9150615712826156d1565b602082019050919050565b60006020820190508181036000830152615736816156fa565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615799602683613fc7565b91506157a48261573d565b604082019050919050565b600060208201905081810360008301526157c88161578c565b9050919050565b7f4d617820737570706c7920657863656564000000000000000000000000000000600082015250565b6000615805601183613fc7565b9150615810826157cf565b602082019050919050565b60006020820190508181036000830152615834816157f8565b9050919050565b60006040820190506158506000830185614371565b61585d6020830184614371565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061589a602083613fc7565b91506158a582615864565b602082019050919050565b600060208201905081810360008301526158c98161588d565b9050919050565b6000819050919050565b6158eb6158e682614168565b6158d0565b82525050565b60006158fd82856158da565b60208201915061590d82846158da565b6020820191508190509392505050565b600061592882614168565b91506000820361593b5761593a614a97565b5b600182039050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061598082614837565b915061598b83614837565b9250828201905063ffffffff8111156159a7576159a6614a97565b5b9291505056fea2646970667358221220e02f5df0ed0ae0fb3113d47cc2f981cc746571691c69ab197f38679537e2689b64736f6c63430008130033
Deployed Bytecode
0x6080604052600436106103a15760003560e01c8063715018a6116101e7578063b88d4fde1161010d578063dcc4d445116100a0578063f2fde38b1161006f578063f2fde38b14610d5c578063f6d8853614610d85578063fb5b82d014610d9c578063fc89067914610dc5576103a1565b8063dcc4d44514610c8e578063e985e9c514610cb7578063ea3d741814610cf4578063f058a4d114610d1f576103a1565b8063d5abeb01116100dc578063d5abeb0114610bd2578063d8ae7c9d14610bfd578063da0239a614610c26578063dc33e68114610c51576103a1565b8063b88d4fde14610b25578063c733fe0d14610b41578063c87b56dd14610b58578063cc0c523614610b95576103a1565b8063916ec2c611610185578063a2cd568911610154578063a2cd568914610a67578063a58a426d14610a92578063a7c7021314610abd578063acc34a3e14610ae8576103a1565b8063916ec2c6146109bd57806391ec4b4c146109e857806395d89b4114610a13578063a22cb46514610a3e576103a1565b8063853828b6116101c1578063853828b6146109205780638b4303a61461092a5780638b4f6325146109555780638da5cb5b14610992576103a1565b8063715018a6146108b5578063787b9712146108cc5780637ca470b1146108f5576103a1565b80632db5b8e7116102cc578063468409ce1161026a5780636902e20d116102395780636902e20d146107e75780636c0360eb146108105780636d632d891461083b57806370a0823114610878576103a1565b8063468409ce1461072b57806346fbed6f146107545780636352211e1461077f5780636802e529146107bc576103a1565b8063376dde7f116102a6578063376dde7f14610692578063376e1b1f146106bb57806337e49eed146106d257806342842e0e1461070f576103a1565b80632db5b8e71461061557806331b5b9071461063e57806333a3600714610667576103a1565b8063095ea7b31161034457806322d1464c1161031357806322d1464c1461057c57806323b872dd146105a5578063257e7ff4146105c15780632b9c3bf4146105ec576103a1565b8063095ea7b3146104e15780630ff9cc6b146104fd57806318160ddd146105265780631d490ee314610551576103a1565b806306fdde031161038057806306fdde031461041157806307c3841d1461043c57806307edf9ef14610479578063081812fc146104a4576103a1565b80627c3566146103a657806301ffc9a7146103bd578063022c0199146103fa575b600080fd5b3480156103b257600080fd5b506103bb610df0565b005b3480156103c957600080fd5b506103e460048036038101906103df9190613f59565b61108c565b6040516103f19190613fa1565b60405180910390f35b34801561040657600080fd5b5061040f6110b1565b005b34801561041d57600080fd5b5061042661134d565b604051610433919061404c565b60405180910390f35b34801561044857600080fd5b50610463600480360381019061045e91906140cc565b6113df565b6040516104709190614115565b60405180910390f35b34801561048557600080fd5b5061048e611435565b60405161049b919061414d565b60405180910390f35b3480156104b057600080fd5b506104cb60048036038101906104c6919061419e565b611449565b6040516104d891906141da565b60405180910390f35b6104fb60048036038101906104f691906141f5565b6114a3565b005b34801561050957600080fd5b50610524600480360381019061051f91906142f0565b6114b2565b005b34801561053257600080fd5b5061053b6115d0565b6040516105489190614380565b60405180910390f35b34801561055d57600080fd5b50610566611605565b604051610573919061414d565b60405180910390f35b34801561058857600080fd5b506105a3600480360381019061059e919061439b565b611619565b005b6105bf60048036038101906105ba91906143e8565b6116c7565b005b3480156105cd57600080fd5b506105d661180f565b6040516105e39190614380565b60405180910390f35b3480156105f857600080fd5b50610613600480360381019061060e91906142f0565b611815565b005b34801561062157600080fd5b5061063c60048036038101906106379190614467565b611933565b005b34801561064a57600080fd5b50610665600480360381019061066091906145c4565b611c26565b005b34801561067357600080fd5b5061067c611c41565b6040516106899190614380565b60405180910390f35b34801561069e57600080fd5b506106b960048036038101906106b4919061439b565b611ceb565b005b3480156106c757600080fd5b506106d0611d99565b005b3480156106de57600080fd5b506106f960048036038101906106f491906140cc565b612035565b6040516107069190614115565b60405180910390f35b610729600480360381019061072491906143e8565b61208b565b005b34801561073757600080fd5b50610752600480360381019061074d919061439b565b6120c5565b005b34801561076057600080fd5b50610769612173565b604051610776919061414d565b60405180910390f35b34801561078b57600080fd5b506107a660048036038101906107a1919061419e565b612187565b6040516107b391906141da565b60405180910390f35b3480156107c857600080fd5b506107d16121ac565b6040516107de919061414d565b60405180910390f35b3480156107f357600080fd5b5061080e6004803603810190610809919061419e565b6121c0565b005b34801561081c57600080fd5b506108256125ec565b604051610832919061404c565b60405180910390f35b34801561084757600080fd5b50610862600480360381019061085d91906140cc565b61267a565b60405161086f9190614115565b60405180910390f35b34801561088457600080fd5b5061089f600480360381019061089a91906140cc565b6126d0565b6040516108ac9190614380565b60405180910390f35b3480156108c157600080fd5b506108ca612720565b005b3480156108d857600080fd5b506108f360048036038101906108ee91906142f0565b612734565b005b34801561090157600080fd5b5061090a612852565b604051610917919061414d565b60405180910390f35b610928612866565b005b34801561093657600080fd5b5061093f6128d9565b60405161094c919061414d565b60405180910390f35b34801561096157600080fd5b5061097c600480360381019061097791906140cc565b6128ed565b6040516109899190614115565b60405180910390f35b34801561099e57600080fd5b506109a7612943565b6040516109b491906141da565b60405180910390f35b3480156109c957600080fd5b506109d261296d565b6040516109df919061414d565b60405180910390f35b3480156109f457600080fd5b506109fd612981565b604051610a0a919061414d565b60405180910390f35b348015610a1f57600080fd5b50610a28612995565b604051610a35919061404c565b60405180910390f35b348015610a4a57600080fd5b50610a656004803603810190610a609190614639565b612a27565b005b348015610a7357600080fd5b50610a7c612a7d565b604051610a89919061414d565b60405180910390f35b348015610a9e57600080fd5b50610aa7612a91565b604051610ab49190614380565b60405180910390f35b348015610ac957600080fd5b50610ad2612a9e565b604051610adf9190614737565b60405180910390f35b348015610af457600080fd5b50610b0f6004803603810190610b0a91906140cc565b612af6565b604051610b1c9190614115565b60405180910390f35b610b3f6004803603810190610b3a91906147af565b612b4c565b005b348015610b4d57600080fd5b50610b56612bbd565b005b348015610b6457600080fd5b50610b7f6004803603810190610b7a919061419e565b612e59565b604051610b8c919061404c565b60405180910390f35b348015610ba157600080fd5b50610bbc6004803603810190610bb7919061419e565b612f00565b604051610bc99190613fa1565b60405180910390f35b348015610bde57600080fd5b50610be7612f12565b604051610bf49190614380565b60405180910390f35b348015610c0957600080fd5b50610c246004803603810190610c1f919061439b565b612f36565b005b348015610c3257600080fd5b50610c3b612fe4565b604051610c489190614380565b60405180910390f35b348015610c5d57600080fd5b50610c786004803603810190610c7391906140cc565b612fea565b604051610c859190614856565b60405180910390f35b348015610c9a57600080fd5b50610cb56004803603810190610cb091906148c7565b61301e565b005b348015610cc357600080fd5b50610cde6004803603810190610cd99190614914565b613080565b604051610ceb9190613fa1565b60405180910390f35b348015610d0057600080fd5b50610d096130a4565b604051610d16919061414d565b60405180910390f35b348015610d2b57600080fd5b50610d466004803603810190610d4191906140cc565b6130b8565b604051610d539190614115565b60405180910390f35b348015610d6857600080fd5b50610d836004803603810190610d7e91906140cc565b61310e565b005b348015610d9157600080fd5b50610d9a613191565b005b348015610da857600080fd5b50610dc36004803603810190610dbe9190614992565b6133e1565b005b348015610dd157600080fd5b50610dda61342d565b604051610de7919061414d565b60405180910390f35b6008544210610e34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2b90614a0b565b60405180910390fd5b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611610ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebd90614a77565b60405180910390fd5b6007600e9054906101000a900461ffff1661ffff166001600760049054906101000a900461ffff16610ef89190614ac6565b61ffff161115610f3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3490614b48565b60405180910390fd5b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550610fb433600d60009054906101000a900461ffff1661ffff16613441565b3373ffffffffffffffffffffffffffffffffffffffff167ff70b403b1d50cef877cafdc0f6c3c47f58a42f1e5f5f17173f255ef7b00762a042600d60009054906101000a900461ffff1660405161100c929190614ba3565b60405180910390a2600d600081819054906101000a900461ffff168092919061103490614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600481819054906101000a900461ffff168092919061106f90614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b60008160e01c635b5e139f81146380ac58cd82146301ffc9a783141717915050919050565b60085442106110f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ec90614c42565b60405180910390fd5b6000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611611187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117e90614cae565b60405180910390fd5b600760129054906101000a900461ffff1661ffff166001600760089054906101000a900461ffff166111b99190614ac6565b61ffff1611156111fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f590614d1a565b60405180910390fd5b6000601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555061127533601160009054906101000a900461ffff1661ffff16613441565b3373ffffffffffffffffffffffffffffffffffffffff167f76f9e85ff7722d043b09d71ddb1f2e240963d9f9072c84082432fd9efd24677642601160009054906101000a900461ffff166040516112cd929190614ba3565b60405180910390a26011600081819054906101000a900461ffff16809291906112f590614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600881819054906101000a900461ffff168092919061133090614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b60606002805461135c90614d69565b80601f016020809104026020016040519081016040528092919081815260200182805461138890614d69565b80156113d55780601f106113aa576101008083540402835291602001916113d5565b820191906000526020600020905b8154815290600101906020018083116113b857829003601f168201915b5050505050905090565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600760029054906101000a900461ffff1681565b6000816000527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c52602060002082018201805460601b60601c6114965763ceea21b66000526004601cfd5b8060010154915050919050565b6114ae33838361345f565b5050565b6114ba613516565b818190508484905014611502576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f990614e0c565b60405180910390fd5b60005b848490508110156115c95782828281811061152357611522614e2c565b5b90506020020160208101906115389190614467565b600a600087878581811061154f5761154e614e2c565b5b905060200201602081019061156491906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555080806115c190614e5b565b915050611505565b5050505050565b60006005547f00000000000000000000000000000000000000000000000000000000000004206116009190614ea3565b905090565b6007600e9054906101000a900461ffff1681565b611621613516565b60005b828290508110156116c25760016010600085858581811061164857611647614e2c565b5b905060200201602081019061165d91906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555080806116ba90614e5b565b915050611624565b505050565b6116d2838383613594565b60001960601c8381169350828116925081600052337f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c526020600020820182018054808316868114810261174457806117365763ceea21b66000526004601cfd5b63a11481006000526004601cfd5b856117575763ea553b346000526004601cfd5b86600052826001015480331488331417611784576030600c205461178357634b6e7f186000526004601cfd5b5b801561179257600084600101555b5085871882188355601c600c20600181540381555085600052601c600c20600181540163ffffffff81166117ce576301336cea6000526004601cfd5b80825550508486887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a45050505061180a838383613599565b505050565b60085481565b61181d613516565b818190508484905014611865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185c90614e0c565b60405180910390fd5b60005b8484905081101561192c5782828281811061188657611885614e2c565b5b905060200201602081019061189b9190614467565b601460008787858181106118b2576118b1614e2c565b5b90506020020160208101906118c791906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550808061192490614e5b565b915050611868565b5050505050565b6000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff16116119c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bc90614cae565b60405180910390fd5b8060ff16600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff161015611a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5190614f23565b60405180910390fd5b8060ff16611a666115d0565b611a709190614f43565b7f00000000000000000000000000000000000000000000000000000000000004201015611ad2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac990614fc3565b60405180910390fd5b60058160ff161115611b19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b109061502f565b60405180910390fd5b80600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b71919061504f565b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550611bd5338260ff1661359e565b3373ffffffffffffffffffffffffffffffffffffffff167f30603f56befad35715d530ed1090c153118f6822d031c1e03fc5bc0e3f30808942604051611c1b9190614380565b60405180910390a250565b611c2e613516565b8060069081611c3d9190615226565b5050565b60006007600a9054906101000a900461ffff1661ffff16600760089054906101000a900461ffff1661ffff16600760069054906101000a900461ffff1661ffff16600760049054906101000a900461ffff1661ffff16600760029054906101000a900461ffff1661ffff16611cb46115d0565b611cbe9190614f43565b611cc89190614f43565b611cd29190614f43565b611cdc9190614f43565b611ce69190614f43565b905090565b611cf3613516565b60005b82829050811015611d9457600160166000858585818110611d1a57611d19614e2c565b5b9050602002016020810190611d2f91906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff1602179055508080611d8c90614e5b565b915050611cf6565b505050565b6008544210611ddd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd490615344565b60405180910390fd5b6000601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611611e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6690614a77565b60405180910390fd5b600760109054906101000a900461ffff1661ffff166001600760069054906101000a900461ffff16611ea19190614ac6565b61ffff161115611ee6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611edd906153b0565b60405180910390fd5b6000601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550611f5d33600f60009054906101000a900461ffff1661ffff16613441565b3373ffffffffffffffffffffffffffffffffffffffff167f3068eb10a9f5bc0a2d97cbc29c967a612136c9d03efe312432d0cff3ece88d5542600f60009054906101000a900461ffff16604051611fb5929190614ba3565b60405180910390a2600f600081819054906101000a900461ffff1680929190611fdd90614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600681819054906101000a900461ffff168092919061201890614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6120968383836116c7565b61209f82613729565b156120c0576120bf83838360405180602001604052806000815250613734565b5b505050565b6120cd613516565b60005b8282905081101561216e576001600e60008585858181106120f4576120f3614e2c565b5b905060200201602081019061210991906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550808061216690614e5b565b9150506120d0565b505050565b600760049054906101000a900461ffff1681565b6000612192826137c6565b9050806121a75763ceea21b66000526004601cfd5b919050565b6007600a9054906101000a900461ffff1681565b6008544210612204576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121fb9061541c565b60405180910390fd5b6000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611612296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228d90614cae565b60405180910390fd5b80600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff161015612328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231f90614f23565b60405180910390fd5b6007600c9054906101000a900461ffff1661ffff166001600760029054906101000a900461ffff1661235a9190614ac6565b61ffff16111561239f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239690615488565b60405180910390fd5b60058111156123e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123da9061502f565b60405180910390fd5b60008167ffffffffffffffff8111156123ff576123fe614499565b5b60405190808252806020026020018201604052801561242d5781602001602082028036833780820191505090505b50905060005b828163ffffffff16101561259757600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081819054906101000a900460ff168092919061249d906154a8565b91906101000a81548160ff021916908360ff160217905550506124d433600b60009054906101000a900461ffff1661ffff16613441565b600b60009054906101000a900461ffff1661ffff16828263ffffffff168151811061250257612501614e2c565b5b602002602001018181525050600b600081819054906101000a900461ffff168092919061252e90614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600281819054906101000a900461ffff168092919061256990614bcc565b91906101000a81548161ffff021916908361ffff16021790555050808061258f906154d1565b915050612433565b503373ffffffffffffffffffffffffffffffffffffffff167f925a1c03df0f625e3645b782d2a6fc1ccee76de332fba5dc74ad672526a0d39942836040516125e09291906154fd565b60405180910390a25050565b600680546125f990614d69565b80601f016020809104026020016040519081016040528092919081815260200182805461262590614d69565b80156126725780601f1061264757610100808354040283529160200191612672565b820191906000526020600020905b81548152906001019060200180831161265557829003601f168201915b505050505081565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000816126e557638f4eb6046000526004601cfd5b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c528160005263ffffffff601c600c2054169050919050565b612728613516565b6127326000613807565b565b61273c613516565b818190508484905014612784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161277b90614e0c565b60405180910390fd5b60005b8484905081101561284b578282828181106127a5576127a4614e2c565b5b90506020020160208101906127ba9190614467565b600c60008787858181106127d1576127d0614e2c565b5b90506020020160208101906127e691906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550808061284390614e5b565b915050612787565b5050505050565b600760149054906101000a900461ffff1681565b61286e613516565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050501580156128d6573d6000803e3d6000fd5b50565b600760009054906101000a900461ffff1681565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6007600c9054906101000a900461ffff1681565b600760089054906101000a900461ffff1681565b6060600380546129a490614d69565b80601f01602080910402602001604051908101604052809291908181526020018280546129d090614d69565b8015612a1d5780601f106129f257610100808354040283529160200191612a1d565b820191906000526020600020905b815481529060010190602001808311612a0057829003601f168201915b5050505050905090565b801515905081601c52670a5a2e7a0000000060085233600052806030600c2055806000528160601b60601c337f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160206000a35050565b600760069054906101000a900461ffff1681565b6000601780549050905090565b60606017805480602002602001604051908101604052809291908181526020018280548015612aec57602002820191906000526020600020905b815481526020019060010190808311612ad8575b5050505050905090565b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b612b578585856116c7565b612b6084613729565b15612bb657612bb585858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613734565b5b5050505050565b6008544210612c01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bf890615579565b60405180910390fd5b6000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611612c93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8a90614a77565b60405180910390fd5b600760149054906101000a900461ffff1661ffff1660016007600a9054906101000a900461ffff16612cc59190614ac6565b61ffff161115612d0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d01906155e5565b60405180910390fd5b6000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550612d8133601360009054906101000a900461ffff1661ffff16613441565b3373ffffffffffffffffffffffffffffffffffffffff167f11f17ae42a0904709076e999b53fe5d9a2094552d1e26167334b0a1df43db8bd42601360009054906101000a900461ffff16604051612dd9929190614ba3565b60405180910390a26013600081819054906101000a900461ffff1680929190612e0190614bcc565b91906101000a81548161ffff021916908361ffff160217905550506007600a81819054906101000a900461ffff1680929190612e3c90614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b6060612e64826138cd565b612ea3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9a90615651565b60405180910390fd5b6000612ead61390b565b90506000815111612ecd5760405180602001604052806000815250612ef8565b80612ed78461399d565b604051602001612ee89291906156ad565b6040516020818303038152906040525b915050919050565b6000612f0b826138cd565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000042081565b612f3e613516565b60005b82829050811015612fdf57600160126000858585818110612f6557612f64614e2c565b5b9050602002016020810190612f7a91906140cc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff1602179055508080612fd790614e5b565b915050612f41565b505050565b60055481565b600060c0612ff783613a6b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050919050565b613026613516565b600854421161306a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130619061571d565b60405180910390fd5b81816017919061307b929190613e83565b505050565b600081601c52670a5a2e7a00000000600852826000526030600c2054905092915050565b600760109054906101000a900461ffff1681565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b613116613516565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161317c906157af565b60405180910390fd5b61318e81613807565b50565b6000601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff1611613223576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321a90614a77565b60405180910390fd5b600161322d611c41565b6132379190614f43565b600760009054906101000a900461ffff1661ffff16101561328d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132849061581b565b60405180910390fd5b6000601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff160217905550613322336017601560009054906101000a900461ffff1661ffff168154811061331257613311614e2c565b5b9060005260206000200154613441565b3373ffffffffffffffffffffffffffffffffffffffff167fa72aa19bfd87e001e03ac6bf966e0f914e84e90c84f842017e87ffc32547505f426017601560009054906101000a900461ffff1661ffff168154811061338357613382614e2c565b5b906000526020600020015460405161339c92919061583b565b60405180910390a26015600081819054906101000a900461ffff16809291906133c490614bcc565b91906101000a81548161ffff021916908361ffff16021790555050565b6133e9613516565b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600760129054906101000a900461ffff1681565b61345b828260405180602001604052806000815250613aa5565b5050565b60001960601c8281169250838116935081600052837f7d8825530a5a2e7a00000000000000000000000000000000000000000000000017601c5260206000208201820180548216806134b95763ceea21b66000526004601cfd5b8086148615176134e057806000526030600c20546134df57634b6e7f186000526004601cfd5b5b8482600101558385827f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a4505050505050565b61351e613ad0565b73ffffffffffffffffffffffffffffffffffffffff1661353c612943565b73ffffffffffffffffffffffffffffffffffffffff1614613592576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613589906158b0565b60405180910390fd5b565b505050565b505050565b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613603576040517fd9d552c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000810361363d576040517f4600cfe900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806005541015613679576040517f7775abdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604051806020016040528042446040516020016136999291906158f1565b6040516020818303038152906040528051906020012060001c81525090506000600554905060005b838110156137115760006136de8385613ad890919063ffffffff16565b905060006136ec8285613b03565b90506136f88782613baf565b836137029061591d565b935082600101925050506136c1565b5061371c8484613c8d565b8060058190555050505050565b6000813b9050919050565b60405163150b7a028082523360208301528560601b60601c604083015283606083015260808083015282518060a0840152801561377b578060c08401826020870160045afa505b60208360a48301601c860160008a5af16137a4573d1561379f573d6000803e3d6000fd5b600083525b8160e01b8351146137bd5763d1a57ed66000526004601cfd5b50505050505050565b6000816000527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c526020600020820182015460601b60601c9050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000816000527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c526020600020820182015460601b9050919050565b60606006805461391a90614d69565b80601f016020809104026020016040519081016040528092919081815260200182805461394690614d69565b80156139935780601f1061396857610100808354040283529160200191613993565b820191906000526020600020905b81548152906001019060200180831161397657829003601f168201915b5050505050905090565b6060600060016139ac84613cee565b01905060008167ffffffffffffffff8111156139cb576139ca614499565b5b6040519080825280601f01601f1916602001820160405280156139fd5781602001600182028036833780820191505090505b509050600082602001820190505b600115613a60578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581613a5457613a53615946565b5b04945060008503613a0b575b819350505050919050565b60007f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5281600052601c600c205460201c9050919050565b613aaf8383613baf565b613ab883613729565b15613acb57613aca6000848484613734565b5b505050565b600033905090565b60005b600115613af8576020832090508083528182600003068110613adb575b818106905092915050565b600080600460008581526020019081526020016000205490506000600184613b2b9190614ea3565b905060006004600083815260200190815260200160002054905060008314613b535782613b55565b855b9350818614613b865760008114613b6c5780613b6e565b815b60046000888152602001908152602001600020819055505b60008114613ba65760046000838152602001908152602001600020600090555b50505092915050565b613bbb60008383613594565b8160601b60601c915081613bd75763ea553b346000526004601cfd5b806000527f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5260206000208101810180548060601b15613c215763c991cbb16000526004601cfd5b838117825583600052601c600c20600181540163ffffffff8116613c4d576301336cea6000526004601cfd5b8082555050828460007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a45050613c8960008383613599565b5050565b6000613c9883612fea565b905060008282613ca89190615975565b90506000613cb585613a6b565b9050613ce7858277ffffffffffffffffffffffffffffffffffffffffffffffff1660c08563ffffffff16901b17613e41565b5050505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613d4c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613d4257613d41615946565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613d89576d04ee2d6d415b85acef81000000008381613d7f57613d7e615946565b5b0492506020810190505b662386f26fc100008310613db857662386f26fc100008381613dae57613dad615946565b5b0492506010810190505b6305f5e1008310613de1576305f5e1008381613dd757613dd6615946565b5b0492506008810190505b6127108310613e06576127108381613dfc57613dfb615946565b5b0492506004810190505b60648310613e295760648381613e1f57613e1e615946565b5b0492506002810190505b600a8310613e38576001810190505b80915050919050565b7f7d8825530a5a2e7a000000000000000000000000000000000000000000000000601c5281600052601c600c2080548060201c831860201b8118825550505050565b828054828255906000526020600020908101928215613ebf579160200282015b82811115613ebe578235825591602001919060010190613ea3565b5b509050613ecc9190613ed0565b5090565b5b80821115613ee9576000816000905550600101613ed1565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613f3681613f01565b8114613f4157600080fd5b50565b600081359050613f5381613f2d565b92915050565b600060208284031215613f6f57613f6e613ef7565b5b6000613f7d84828501613f44565b91505092915050565b60008115159050919050565b613f9b81613f86565b82525050565b6000602082019050613fb66000830184613f92565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613ff6578082015181840152602081019050613fdb565b60008484015250505050565b6000601f19601f8301169050919050565b600061401e82613fbc565b6140288185613fc7565b9350614038818560208601613fd8565b61404181614002565b840191505092915050565b600060208201905081810360008301526140668184614013565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006140998261406e565b9050919050565b6140a98161408e565b81146140b457600080fd5b50565b6000813590506140c6816140a0565b92915050565b6000602082840312156140e2576140e1613ef7565b5b60006140f0848285016140b7565b91505092915050565b600060ff82169050919050565b61410f816140f9565b82525050565b600060208201905061412a6000830184614106565b92915050565b600061ffff82169050919050565b61414781614130565b82525050565b6000602082019050614162600083018461413e565b92915050565b6000819050919050565b61417b81614168565b811461418657600080fd5b50565b60008135905061419881614172565b92915050565b6000602082840312156141b4576141b3613ef7565b5b60006141c284828501614189565b91505092915050565b6141d48161408e565b82525050565b60006020820190506141ef60008301846141cb565b92915050565b6000806040838503121561420c5761420b613ef7565b5b600061421a858286016140b7565b925050602061422b85828601614189565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f84011261425a57614259614235565b5b8235905067ffffffffffffffff8111156142775761427661423a565b5b6020830191508360208202830111156142935761429261423f565b5b9250929050565b60008083601f8401126142b0576142af614235565b5b8235905067ffffffffffffffff8111156142cd576142cc61423a565b5b6020830191508360208202830111156142e9576142e861423f565b5b9250929050565b6000806000806040858703121561430a57614309613ef7565b5b600085013567ffffffffffffffff81111561432857614327613efc565b5b61433487828801614244565b9450945050602085013567ffffffffffffffff81111561435757614356613efc565b5b6143638782880161429a565b925092505092959194509250565b61437a81614168565b82525050565b60006020820190506143956000830184614371565b92915050565b600080602083850312156143b2576143b1613ef7565b5b600083013567ffffffffffffffff8111156143d0576143cf613efc565b5b6143dc85828601614244565b92509250509250929050565b60008060006060848603121561440157614400613ef7565b5b600061440f868287016140b7565b9350506020614420868287016140b7565b925050604061443186828701614189565b9150509250925092565b614444816140f9565b811461444f57600080fd5b50565b6000813590506144618161443b565b92915050565b60006020828403121561447d5761447c613ef7565b5b600061448b84828501614452565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6144d182614002565b810181811067ffffffffffffffff821117156144f0576144ef614499565b5b80604052505050565b6000614503613eed565b905061450f82826144c8565b919050565b600067ffffffffffffffff82111561452f5761452e614499565b5b61453882614002565b9050602081019050919050565b82818337600083830152505050565b600061456761456284614514565b6144f9565b90508281526020810184848401111561458357614582614494565b5b61458e848285614545565b509392505050565b600082601f8301126145ab576145aa614235565b5b81356145bb848260208601614554565b91505092915050565b6000602082840312156145da576145d9613ef7565b5b600082013567ffffffffffffffff8111156145f8576145f7613efc565b5b61460484828501614596565b91505092915050565b61461681613f86565b811461462157600080fd5b50565b6000813590506146338161460d565b92915050565b600080604083850312156146505761464f613ef7565b5b600061465e858286016140b7565b925050602061466f85828601614624565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6146ae81614168565b82525050565b60006146c083836146a5565b60208301905092915050565b6000602082019050919050565b60006146e482614679565b6146ee8185614684565b93506146f983614695565b8060005b8381101561472a57815161471188826146b4565b975061471c836146cc565b9250506001810190506146fd565b5085935050505092915050565b6000602082019050818103600083015261475181846146d9565b905092915050565b60008083601f84011261476f5761476e614235565b5b8235905067ffffffffffffffff81111561478c5761478b61423a565b5b6020830191508360018202830111156147a8576147a761423f565b5b9250929050565b6000806000806000608086880312156147cb576147ca613ef7565b5b60006147d9888289016140b7565b95505060206147ea888289016140b7565b94505060406147fb88828901614189565b935050606086013567ffffffffffffffff81111561481c5761481b613efc565b5b61482888828901614759565b92509250509295509295909350565b600063ffffffff82169050919050565b61485081614837565b82525050565b600060208201905061486b6000830184614847565b92915050565b60008083601f84011261488757614886614235565b5b8235905067ffffffffffffffff8111156148a4576148a361423a565b5b6020830191508360208202830111156148c0576148bf61423f565b5b9250929050565b600080602083850312156148de576148dd613ef7565b5b600083013567ffffffffffffffff8111156148fc576148fb613efc565b5b61490885828601614871565b92509250509250929050565b6000806040838503121561492b5761492a613ef7565b5b6000614939858286016140b7565b925050602061494a858286016140b7565b9150509250929050565b600061495f8261406e565b9050919050565b61496f81614954565b811461497a57600080fd5b50565b60008135905061498c81614966565b92915050565b6000602082840312156149a8576149a7613ef7565b5b60006149b68482850161497d565b91505092915050565b7f486f6e6f72617279206d696e7420636c6f736500000000000000000000000000600082015250565b60006149f5601383613fc7565b9150614a00826149bf565b602082019050919050565b60006020820190508181036000830152614a24816149e8565b9050919050565b7f4e6f206769766577617900000000000000000000000000000000000000000000600082015250565b6000614a61600a83613fc7565b9150614a6c82614a2b565b602082019050919050565b60006020820190508181036000830152614a9081614a54565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614ad182614130565b9150614adc83614130565b9250828201905061ffff811115614af657614af5614a97565b5b92915050565b7f4d617820737570706c7920686f6e6f7261727920657863656564000000000000600082015250565b6000614b32601a83613fc7565b9150614b3d82614afc565b602082019050919050565b60006020820190508181036000830152614b6181614b25565b9050919050565b6000819050919050565b6000614b8d614b88614b8384614130565b614b68565b614168565b9050919050565b614b9d81614b72565b82525050565b6000604082019050614bb86000830185614371565b614bc56020830184614b94565b9392505050565b6000614bd782614130565b915061ffff8203614beb57614bea614a97565b5b600182019050919050565b7f4a75646765206d696e7420636c6f736500000000000000000000000000000000600082015250565b6000614c2c601083613fc7565b9150614c3782614bf6565b602082019050919050565b60006020820190508181036000830152614c5b81614c1f565b9050919050565b7f4e6f7420656c696769626c650000000000000000000000000000000000000000600082015250565b6000614c98600c83613fc7565b9150614ca382614c62565b602082019050919050565b60006020820190508181036000830152614cc781614c8b565b9050919050565b7f4d617820737570706c79206a7564676520657863656564000000000000000000600082015250565b6000614d04601783613fc7565b9150614d0f82614cce565b602082019050919050565b60006020820190508181036000830152614d3381614cf7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614d8157607f821691505b602082108103614d9457614d93614d3a565b5b50919050565b7f4e62206164647265737320616e64206e62207175616e746974696573206d757360008201527f7420626520657175616c00000000000000000000000000000000000000000000602082015250565b6000614df6602a83613fc7565b9150614e0182614d9a565b604082019050919050565b60006020820190508181036000830152614e2581614de9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614e6682614168565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e9857614e97614a97565b5b600182019050919050565b6000614eae82614168565b9150614eb983614168565b9250828203905081811115614ed157614ed0614a97565b5b92915050565b7f4e6f7420656e6f75676820636c61696d61626c6520746f6b656e730000000000600082015250565b6000614f0d601b83613fc7565b9150614f1882614ed7565b602082019050919050565b60006020820190508181036000830152614f3c81614f00565b9050919050565b6000614f4e82614168565b9150614f5983614168565b9250828201905080821115614f7157614f70614a97565b5b92915050565b7f537570706c79206c696d69742065786565647800000000000000000000000000600082015250565b6000614fad601383613fc7565b9150614fb882614f77565b602082019050919050565b60006020820190508181036000830152614fdc81614fa0565b9050919050565b7f4c696d6974206d61780000000000000000000000000000000000000000000000600082015250565b6000615019600983613fc7565b915061502482614fe3565b602082019050919050565b600060208201905081810360008301526150488161500c565b9050919050565b600061505a826140f9565b9150615065836140f9565b9250828203905060ff81111561507e5761507d614a97565b5b92915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026150e67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826150a9565b6150f086836150a9565b95508019841693508086168417925050509392505050565b600061512361511e61511984614168565b614b68565b614168565b9050919050565b6000819050919050565b61513d83615108565b6151516151498261512a565b8484546150b6565b825550505050565b600090565b615166615159565b615171818484615134565b505050565b5b818110156151955761518a60008261515e565b600181019050615177565b5050565b601f8211156151da576151ab81615084565b6151b484615099565b810160208510156151c3578190505b6151d76151cf85615099565b830182615176565b50505b505050565b600082821c905092915050565b60006151fd600019846008026151df565b1980831691505092915050565b600061521683836151ec565b9150826002028217905092915050565b61522f82613fbc565b67ffffffffffffffff81111561524857615247614499565b5b6152528254614d69565b61525d828285615199565b600060209050601f831160018114615290576000841561527e578287015190505b615288858261520a565b8655506152f0565b601f19841661529e86615084565b60005b828110156152c6578489015182556001820191506020850194506020810190506152a1565b868310156152e357848901516152df601f8916826151ec565b8355505b6001600288020188555050505b505050505050565b7f477561726469616e206d696e7420636c6f736500000000000000000000000000600082015250565b600061532e601383613fc7565b9150615339826152f8565b602082019050919050565b6000602082019050818103600083015261535d81615321565b9050919050565b7f4d617820737570706c7920677561726469616e20657863656564000000000000600082015250565b600061539a601a83613fc7565b91506153a582615364565b602082019050919050565b600060208201905081810360008301526153c98161538d565b9050919050565b7f436f756e63696c206d696e7420636c6f73650000000000000000000000000000600082015250565b6000615406601283613fc7565b9150615411826153d0565b602082019050919050565b60006020820190508181036000830152615435816153f9565b9050919050565b7f4d617820737570706c7920636f756e63696c2065786365656400000000000000600082015250565b6000615472601983613fc7565b915061547d8261543c565b602082019050919050565b600060208201905081810360008301526154a181615465565b9050919050565b60006154b3826140f9565b9150600082036154c6576154c5614a97565b5b600182039050919050565b60006154dc82614837565b915063ffffffff82036154f2576154f1614a97565b5b600182019050919050565b60006040820190506155126000830185614371565b818103602083015261552481846146d9565b90509392505050565b7f5768616c65206d696e7420636c6f736500000000000000000000000000000000600082015250565b6000615563601083613fc7565b915061556e8261552d565b602082019050919050565b6000602082019050818103600083015261559281615556565b9050919050565b7f4d617820737570706c79207768616c6520657863656564000000000000000000600082015250565b60006155cf601783613fc7565b91506155da82615599565b602082019050919050565b600060208201905081810360008301526155fe816155c2565b9050919050565b7f756e6b6e6f7720746f6b656e0000000000000000000000000000000000000000600082015250565b600061563b600c83613fc7565b915061564682615605565b602082019050919050565b6000602082019050818103600083015261566a8161562e565b9050919050565b600081905092915050565b600061568782613fbc565b6156918185615671565b93506156a1818560208601613fd8565b80840191505092915050565b60006156b9828561567c565b91506156c5828461567c565b91508190509392505050565b7f47697665776179206e6f74206163746976617465000000000000000000000000600082015250565b6000615707601483613fc7565b9150615712826156d1565b602082019050919050565b60006020820190508181036000830152615736816156fa565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615799602683613fc7565b91506157a48261573d565b604082019050919050565b600060208201905081810360008301526157c88161578c565b9050919050565b7f4d617820737570706c7920657863656564000000000000000000000000000000600082015250565b6000615805601183613fc7565b9150615810826157cf565b602082019050919050565b60006020820190508181036000830152615834816157f8565b9050919050565b60006040820190506158506000830185614371565b61585d6020830184614371565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061589a602083613fc7565b91506158a582615864565b602082019050919050565b600060208201905081810360008301526158c98161588d565b9050919050565b6000819050919050565b6158eb6158e682614168565b6158d0565b82525050565b60006158fd82856158da565b60208201915061590d82846158da565b6020820191508190509392505050565b600061592882614168565b91506000820361593b5761593a614a97565b5b600182039050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061598082614837565b915061598b83614837565b9250828201905063ffffffff8111156159a7576159a6614a97565b5b9291505056fea2646970667358221220e02f5df0ed0ae0fb3113d47cc2f981cc746571691c69ab197f38679537e2689b64736f6c63430008130033
Deployed Bytecode Sourcemap
117414:9752:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124095:493;;;;;;;;;;;;;:::i;:::-;;36158:383;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125093:459;;;;;;;;;;;;;:::i;:::-;;113999:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;121917:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117644:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29209:553;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30065:121;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120222:350;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113877:114;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117875:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;121147:205;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31893:3015;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118035:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;121563:348;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;122673:456;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;119739:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123135:177;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126560:203;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124594:493;;;;;;;;;;;;;:::i;:::-;;122169:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34982:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;120936:205;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117682:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28037:341;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117796:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123318:771;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117512:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122550:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28528:541;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17971:103;;;;;;;;;;;;;:::i;:::-;;120578:352;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117995:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119517:102;;;:::i;:::-;;117577:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122042:121;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17323:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117834:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117760:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;114107:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30813:713;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117721:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126451:103;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126342;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122298:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35700:244;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;125558:457;;;;;;;;;;;;;:::i;:::-;;119943:273;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126021:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113618:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;121358:199;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113579:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;114219:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;126126:210;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30280:389;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117916:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122427:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18229:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;126769:394;;;;;;;;;;;;;:::i;:::-;;119625:108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117957:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124095:493;124161:17;;124143:15;:35;124135:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;124249:1;124217:17;:29;124235:10;124217:29;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;124209:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;124304:17;;;;;;;;;;;124280:41;;124299:1;124280:16;;;;;;;;;;;:20;;;;:::i;:::-;:41;;;;124272:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;124391:1;124359:17;:29;124377:10;124359:29;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;124399:46;124409:10;124421:23;;;;;;;;;;;124399:46;;:9;:46::i;:::-;124472:10;124457:68;;;124484:15;124501:23;;;;;;;;;;;124457:68;;;;;;;:::i;:::-;;;;;;;;124532:23;;:25;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;124564:16;;:18;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;124095:493::o;36158:383::-;36234:11;36344;36339:3;36335:21;36511:10;36508:1;36505:17;36491:10;36488:1;36485:17;36472:10;36469:1;36466:17;36463:40;36460:63;36450:73;;36311:223;36158:383;;;:::o;125093:459::-;125156:17;;125138:15;:35;125130:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;125238:1;125209:14;:26;125224:10;125209:26;;;;;;;;;;;;;;;;;;;;;;;;;:30;;;125201:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;125292:14;;;;;;;;;;;125271:35;;125287:1;125271:13;;;;;;;;;;;:17;;;;:::i;:::-;:35;;;;125263:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;125370:1;125341:14;:26;125356:10;125341:26;;;;;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;125378:43;125388:10;125400:20;;;;;;;;;;;125378:43;;:9;:43::i;:::-;125445:10;125433:62;;;125457:15;125474:20;;;;;;;;;;;125433:62;;;;;;;:::i;:::-;;;;;;;;125502:20;;:22;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;125531:13;;:15;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;125093:459::o;113999:100::-;114053:13;114086:5;114079:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113999:100;:::o;121917:119::-;121985:5;122006:15;:24;122022:7;122006:24;;;;;;;;;;;;;;;;;;;;;;;;;121999:31;;121917:119;;;:::o;117644:33::-;;;;;;;;;;;;;:::o;29209:553::-;29271:14;29379:2;29373:4;29366:16;29409:24;29403:4;29396:38;29501:4;29495;29485:21;29481:2;29477:30;29473:2;29469:39;29554:13;29548:20;29544:2;29540:29;29536:2;29532:38;29522:170;;29604:10;29598:4;29591:24;29672:4;29666;29659:18;29522:170;29729:13;29726:1;29722:21;29716:28;29706:38;;29351:404;29209:553;;;:::o;30065:121::-;30145:33;30154:10;30166:7;30175:2;30145:8;:33::i;:::-;30065:121;;:::o;120222:350::-;17209:13;:11;:13::i;:::-;120376:11:::1;;:18;;120350:15;;:22;;:44;120342:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;120453:6;120448:119;120469:15;;:22;;120465:1;:26;120448:119;;;120545:11;;120557:1;120545:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;120507:15;:35;120523:15;;120539:1;120523:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;120507:35;;;;;;;;;;;;;;;;:52;;;;;;;;;;;;;;;;;;120493:3;;;;;:::i;:::-;;;;120448:119;;;;120222:350:::0;;;;:::o;113877:114::-;113929:7;113968:15;;113956:9;:27;;;;:::i;:::-;113949:34;;113877:114;:::o;117875:36::-;;;;;;;;;;;;;:::o;121147:205::-;17209:13;:11;:13::i;:::-;121244:6:::1;121239:108;121260:15;;:22;;121256:1;:26;121239:108;;;121338:1;121298:17;:37;121316:15;;121332:1;121316:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;121298:37;;;;;;;;;;;;;;;;:41;;;;;;;;;;;;;;;;;;121284:3;;;;;:::i;:::-;;;;121239:108;;;;121147:205:::0;;:::o;31893:3015::-;31987:34;32008:4;32014:2;32018;31987:20;:34::i;:::-;32171:1;32167:6;32163:2;32159:15;32216:4;32200:14;32196:25;32188:33;;32261:2;32245:14;32241:23;32235:29;;32328:2;32322:4;32315:16;32387:8;32361:24;32358:38;32352:4;32345:52;32464:4;32458;32448:21;32444:2;32440:30;32436:2;32432:39;32514:13;32508:20;32575:15;32559:14;32555:36;32702:4;32695:5;32692:15;32685:5;32681:27;32671:335;;32739:5;32729:149;;32782:10;32776:4;32769:24;32854:4;32848;32841:18;32729:149;32909:10;32903:4;32896:24;32986:4;32980;32973:18;32671:335;33078:2;33068:138;;33114:10;33108:4;33101:24;33186:4;33180;33173:18;33068:138;33308:4;33302;33295:18;33367:13;33364:1;33360:21;33354:28;33515:15;33505:8;33502:29;33495:4;33485:8;33482:18;33479:53;33469:293;;33589:4;33583;33573:21;33567:28;33557:186;;33637:10;33631:4;33624:24;33715:4;33709;33702:18;33557:186;33469:293;33835:15;33832:55;;;33883:1;33867:13;33864:1;33860:21;33853:32;33832:55;33276:626;34008:2;34002:4;33998:13;33981:15;33977:35;33962:13;33955:58;34130:4;34124;34114:21;34205:1;34187:15;34181:22;34177:30;34160:15;34153:55;34072:151;34312:2;34306:4;34299:16;34370:4;34364;34354:21;34446:1;34430:13;34424:20;34420:28;34501:20;34480:19;34476:46;34466:195;;34560:10;34554:4;34547:24;34637:4;34631;34624:18;34466:195;34701:19;34686:13;34679:42;34280:456;;34843:2;34839;34833:4;34806:25;34800:4;34794;34789:57;32085:2772;;;;34867:33;34887:4;34893:2;34897;34867:19;:33::i;:::-;31893:3015;;;:::o;118035:36::-;;;;:::o;121563:348::-;17209:13;:11;:13::i;:::-;121716:11:::1;;:18;;121690:15;;:22;;:44;121682:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;121793:6;121788:118;121809:15;;:22;;121805:1;:26;121788:118;;;121884:11;;121896:1;121884:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;121847;:34;121862:15;;121878:1;121862:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;121847:34;;;;;;;;;;;;;;;;:51;;;;;;;;;;;;;;;;;;121833:3;;;;;:::i;:::-;;;;121788:118;;;;121563:348:::0;;;;:::o;122673:456::-;122758:1;122728:15;:27;122744:10;122728:27;;;;;;;;;;;;;;;;;;;;;;;;;:31;;;122720:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;122822:3;122791:34;;:15;:27;122807:10;122791:27;;;;;;;;;;;;;;;;;;;;;;;;;:34;;;;122783:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;122901:3;122885:19;;:13;:11;:13::i;:::-;:19;;;;:::i;:::-;122872:9;:32;;122864:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;122950:1;122943:3;:8;;;;122935:30;;;;;;;;;;;;:::i;:::-;;;;;;;;;123032:3;123002:15;:27;123018:10;123002:27;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;;:::i;:::-;122972:15;:27;122988:10;122972:27;;;;;;;;;;;;;;;;:63;;;;;;;;;;;;;;;;;;123042:28;123054:10;123066:3;123042:28;;:11;:28::i;:::-;123095:10;123082:41;;;123107:15;123082:41;;;;;;:::i;:::-;;;;;;;;122673:456;:::o;119739:99::-;17209:13;:11;:13::i;:::-;119821:11:::1;119811:7;:21;;;;;;:::i;:::-;;119739:99:::0;:::o;123135:177::-;123183:7;123293:13;;;;;;;;;;;123205:101;;123277:13;;;;;;;;;;;123205:85;;123258:16;;;;;;;;;;;123205:69;;123239:16;;;;;;;;;;;123205:50;;123221:15;;;;;;;;;;;123205:31;;:13;:11;:13::i;:::-;:31;;;;:::i;:::-;:50;;;;:::i;:::-;:69;;;;:::i;:::-;:85;;;;:::i;:::-;:101;;;;:::i;:::-;123198:108;;123135:177;:::o;126560:203::-;17209:13;:11;:13::i;:::-;126656:6:::1;126651:107;126672:15;;:22;;126668:1;:26;126651:107;;;126749:1;126710:16;:36;126727:15;;126743:1;126727:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;126710:36;;;;;;;;;;;;;;;;:40;;;;;;;;;;;;;;;;;;126696:3;;;;;:::i;:::-;;;;126651:107;;;;126560:203:::0;;:::o;124594:493::-;124660:17;;124642:15;:35;124634:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;124748:1;124716:17;:29;124734:10;124716:29;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;124708:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;124803:17;;;;;;;;;;;124779:41;;124798:1;124779:16;;;;;;;;;;;:20;;;;:::i;:::-;:41;;;;124771:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;124890:1;124858:17;:29;124876:10;124858:29;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;124898:46;124908:10;124920:23;;;;;;;;;;;124898:46;;:9;:46::i;:::-;124971:10;124956:68;;;124983:15;125000:23;;;;;;;;;;;124956:68;;;;;;;:::i;:::-;;;;;;;;125031:23;;:25;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;125063:16;;:18;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;124594:493::o;122169:123::-;122239:5;122260:17;:26;122278:7;122260:26;;;;;;;;;;;;;;;;;;;;;;;;;122253:33;;122169:123;;;:::o;34982:201::-;35080:26;35093:4;35099:2;35103;35080:12;:26::i;:::-;35121:12;35130:2;35121:8;:12::i;:::-;35117:58;;;35135:40;35158:4;35164:2;35168;35135:40;;;;;;;;;;;;:22;:40::i;:::-;35117:58;34982:201;;;:::o;120936:205::-;17209:13;:11;:13::i;:::-;121033:6:::1;121028:108;121049:15;;:22;;121045:1;:26;121028:108;;;121127:1;121087:17;:37;121105:15;;121121:1;121105:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;121087:37;;;;;;;;;;;;;;;;:41;;;;;;;;;;;;;;;;;;121073:3;;;;;:::i;:::-;;;;121028:108;;;;120936:205:::0;;:::o;117682:34::-;;;;;;;;;;;;;:::o;28037:341::-;28095:14;28131:12;28140:2;28131:8;:12::i;:::-;28122:21;;28232:6;28222:138;;28272:10;28266:4;28259:24;28340:4;28334;28327:18;28222:138;28037:341;;;:::o;117796:31::-;;;;;;;;;;;;;:::o;123318:771::-;123394:17;;123376:15;:35;123368:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;123480:1;123449:16;:28;123466:10;123449:28;;;;;;;;;;;;;;;;;;;;;;;;;:32;;;123441:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;123545:3;123513:16;:28;123530:10;123513:28;;;;;;;;;;;;;;;;;;;;;;;;;:35;;;;123505:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;123618:16;;;;;;;;;;;123595:39;;123613:1;123595:15;;;;;;;;;;;:19;;;;:::i;:::-;:39;;;;123587:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;123686:1;123679:3;:8;;123671:30;;;;;;;;;;;;:::i;:::-;;;;;;;;;123708:32;123757:3;123743:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123708:53;;123773:8;123768:245;123791:3;123787:1;:7;;;123768:245;;;123810:16;:28;123827:10;123810:28;;;;;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;123849:45;123859:10;123871:22;;;;;;;;;;;123849:45;;:9;:45::i;:::-;123924:22;;;;;;;;;;;123903:43;;:15;123919:1;123903:18;;;;;;;;;;:::i;:::-;;;;;;;:43;;;;;123955:22;;:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;123988:15;;:17;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;123796:3;;;;;:::i;:::-;;;;123768:245;;;;124038:10;124024:59;;;124050:15;124067;124024:59;;;;;;;:::i;:::-;;;;;;;;123361:728;123318:771;:::o;117512:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;122550:117::-;122617:5;122638:14;:23;122653:7;122638:23;;;;;;;;;;;;;;;;;;;;;;;;;122631:30;;122550:117;;;:::o;28528:541::-;28591:14;28751:5;28741:146;;28790:10;28784:4;28777:24;28867:4;28861;28854:18;28741:146;28914:24;28908:4;28901:38;28966:5;28960:4;28953:19;29030:20;29022:4;29016;29006:21;29000:28;28996:55;28986:65;;28528:541;;;:::o;17971:103::-;17209:13;:11;:13::i;:::-;18036:30:::1;18063:1;18036:18;:30::i;:::-;17971:103::o:0;120578:352::-;17209:13;:11;:13::i;:::-;120733:11:::1;;:18;;120707:15;;:22;;:44;120699:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;120810:6;120805:120;120826:15;;:22;;120822:1;:26;120805:120;;;120903:11;;120915:1;120903:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;120864:16;:36;120881:15;;120897:1;120881:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;120864:36;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;120850:3;;;;;:::i;:::-;;;;120805:120;;;;120578:352:::0;;;;:::o;117995:33::-;;;;;;;;;;;;;:::o;119517:102::-;17209:13;:11;:13::i;:::-;119572:9:::1;;;;;;;;;;;:18;;:41;119591:21;119572:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;119517:102::o:0;117577:34::-;;;;;;;;;;;;;:::o;122042:121::-;122111:5;122132:16;:25;122149:7;122132:25;;;;;;;;;;;;;;;;;;;;;;;;;122125:32;;122042:121;;;:::o;17323:87::-;17369:7;17396:6;;;;;;;;;;;17389:13;;17323:87;:::o;117834:36::-;;;;;;;;;;;;;:::o;117760:31::-;;;;;;;;;;;;;:::o;114107:104::-;114163:13;114196:7;114189:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114107:104;:::o;30813:713::-;31028:10;31021:18;31014:26;31000:40;;31135:8;31129:4;31122:22;31171:31;31165:4;31158:45;31230:8;31224:4;31217:22;31283:10;31276:4;31270;31260:21;31253:41;31366:10;31360:4;31353:24;31483:8;31479:2;31475:17;31471:2;31467:26;31457:8;31422:33;31416:4;31410;31391:117;30813:713;;:::o;117721:34::-;;;;;;;;;;;;;:::o;126451:103::-;126503:7;126526:15;:22;;;;126519:29;;126451:103;:::o;126342:::-;126392:16;126424:15;126417:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126342:103;:::o;122298:123::-;122368:5;122389:17;:26;122407:7;122389:26;;;;;;;;;;;;;;;;;;;;;;;;;122382:33;;122298:123;;;:::o;35700:244::-;35839:26;35852:4;35858:2;35862;35839:12;:26::i;:::-;35880:12;35889:2;35880:8;:12::i;:::-;35876:60;;;35894:42;35917:4;35923:2;35927;35931:4;;35894:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:22;:42::i;:::-;35876:60;35700:244;;;;;:::o;125558:457::-;125621:17;;125603:15;:35;125595:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;125703:1;125674:14;:26;125689:10;125674:26;;;;;;;;;;;;;;;;;;;;;;;;;:30;;;125666:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;125755:14;;;;;;;;;;;125734:35;;125750:1;125734:13;;;;;;;;;;;:17;;;;:::i;:::-;:35;;;;125726:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;125833:1;125804:14;:26;125819:10;125804:26;;;;;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;125841:43;125851:10;125863:20;;;;;;;;;;;125841:43;;:9;:43::i;:::-;125908:10;125896:62;;;125920:15;125937:20;;;;;;;;;;;125896:62;;;;;;;:::i;:::-;;;;;;;;125965:20;;:22;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;125994:13;;:15;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;125558:457::o;119943:273::-;120016:13;120046:16;120054:7;120046;:16::i;:::-;120038:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;120088:17;120108:10;:8;:10::i;:::-;120088:30;;120152:1;120138:3;120132:17;:21;:78;;;;;;;;;;;;;;;;;120180:3;120185:18;:7;:16;:18::i;:::-;120163:41;;;;;;;;;:::i;:::-;;;;;;;;;;;;;120132:78;120125:85;;;119943:273;;;:::o;126021:99::-;126078:4;126098:16;126106:7;126098;:16::i;:::-;126091:23;;126021:99;;;:::o;113618:34::-;;;:::o;121358:199::-;17209:13;:11;:13::i;:::-;121452:6:::1;121447:105;121468:15;;:22;;121464:1;:26;121447:105;;;121543:1;121506:14;:34;121521:15;;121537:1;121521:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;121506:34;;;;;;;;;;;;;;;;:38;;;;;;;;;;;;;;;;;;121492:3;;;;;:::i;:::-;;;;121447:105;;;;121358:199:::0;;:::o;113579:30::-;;;;:::o;114219:138::-;114286:6;114345:3;114319:22;114334:6;114319:14;:22::i;:::-;:29;;;;114305:44;;114219:138;;;:::o;126126:210::-;17209:13;:11;:13::i;:::-;126245:17:::1;;126227:15;:35;126219:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;126312:18;;126294:15;:36;;;;;;;:::i;:::-;;126126:210:::0;;:::o;30280:389::-;30388:11;30498:8;30492:4;30485:22;30534:31;30528:4;30521:45;30593:5;30587:4;30580:19;30645:4;30639;30629:21;30623:28;30613:38;;30280:389;;;;:::o;117916:36::-;;;;;;;;;;;;;:::o;122427:117::-;122494:5;122515:14;:23;122530:7;122515:23;;;;;;;;;;;;;;;;;;;;;;;;;122508:30;;122427:117;;;:::o;18229:201::-;17209:13;:11;:13::i;:::-;18338:1:::1;18318:22;;:8;:22;;::::0;18310:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;18394:28;18413:8;18394:18;:28::i;:::-;18229:201:::0;:::o;126769:394::-;126847:1;126816:16;:28;126833:10;126816:28;;;;;;;;;;;;;;;;;;;;;;;;;:32;;;126808:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;126915:1;126895:17;:15;:17::i;:::-;:21;;;;:::i;:::-;126878:13;;;;;;;;;;;:38;;;;126870:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;126976:1;126945:16;:28;126962:10;126945:28;;;;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;126984:57;126994:10;127006:15;127022:17;;;;;;;;;;;127006:34;;;;;;;;;;:::i;:::-;;;;;;;;;;126984:9;:57::i;:::-;127067:10;127053:78;;;127079:15;127096;127112:17;;;;;;;;;;;127096:34;;;;;;;;;;:::i;:::-;;;;;;;;;;127053:78;;;;;;;:::i;:::-;;;;;;;;127138:17;;:19;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;126769:394::o;119625:108::-;17209:13;:11;:13::i;:::-;119714::::1;119702:9;;:25;;;;;;;;;;;;;;;;;;119625:108:::0;:::o;117957:33::-;;;;;;;;;;;;;:::o;42608:100::-;42679:21;42689:2;42693;42679:21;;;;;;;;;;;;:9;:21::i;:::-;42608:100;;:::o;48708:1438::-;48890:1;48886:6;48882:2;48878:15;48938:7;48922:14;48918:28;48907:39;;48986:2;48970:14;48966:23;48960:29;;49057:2;49051:4;49044:16;49116:2;49090:24;49087:32;49081:4;49074:46;49187:4;49181;49171:21;49167:2;49163:30;49159:2;49155:39;49247:13;49241:20;49225:14;49221:41;49334:5;49324:137;;49373:10;49367:4;49360:24;49441:4;49435;49428:18;49324:137;49639:5;49635:2;49632:13;49627:2;49620:10;49617:29;49607:286;;49680:5;49674:4;49667:19;49736:4;49730;49720:21;49714:28;49704:174;;49780:10;49774:4;49767:24;49854:4;49848;49841:18;49704:174;49607:286;50004:7;49988:13;49985:1;49981:21;49974:38;50125:2;50116:7;50109:5;50082:25;50076:4;50070;50065:63;48804:1335;;;48708:1438;;;:::o;17488:132::-;17563:12;:10;:12::i;:::-;17552:23;;:7;:5;:7::i;:::-;:23;;;17544:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;17488:132::o;57458:87::-;;;;:::o;57645:86::-;;;;:::o;114365:939::-;114464:9;114450:23;;:10;:23;;;114446:57;;114482:21;;;;;;;;;;;;;;114446:57;114532:1;114518:10;:15;114514:53;;114542:25;;;;;;;;;;;;;;114514:53;114600:10;114582:15;;:28;114578:67;;;114619:26;;;;;;;;;;;;;;114578:67;114658:24;114685:109;;;;;;;;114747:15;114764:16;114716:75;;;;;;;;;:::i;:::-;;;;;;;;;;;;;114706:86;;;;;;114698:95;;114685:109;;;114658:136;;114807:30;114840:15;;114807:48;;114873:9;114868:319;114888:10;114884:1;:14;114868:319;;;114917:19;114939:36;114952:22;114939:4;:12;;:36;;;;:::i;:::-;114917:58;;114992:15;115010:61;115035:11;115048:22;115010:24;:61::i;:::-;114992:79;;115088:18;115094:2;115098:7;115088:5;:18::i;:::-;115123:24;;;;:::i;:::-;;;115171:3;;;;;114902:285;;114868:319;;;;115199:46;115222:2;115233:10;115199:22;:46::i;:::-;115274:22;115256:15;:40;;;;114435:869;;114365:939;;:::o;58088:217::-;58139:11;58253:1;58241:14;58231:24;;58088:217;;;:::o;58468:1416::-;58703:4;58697:11;58754:10;58788:24;58785:1;58778:35;58848:8;58841:4;58838:1;58834:12;58827:30;58957:4;58953:2;58949:13;58945:2;58941:22;58934:4;58931:1;58927:12;58920:44;58999:2;58992:4;58989:1;58985:12;58978:24;59037:4;59030;59027:1;59023:12;59016:26;59071:4;59065:11;59111:1;59104:4;59101:1;59097:12;59090:23;59130:1;59127:71;;;59193:1;59186:4;59183:1;59179:12;59176:1;59169:4;59163;59159:15;59156:1;59149:5;59138:57;59134:62;59127:71;59312:4;59309:1;59302:4;59299:1;59295:12;59288:4;59285:1;59281:12;59278:1;59274:2;59267:5;59262:55;59252:351;;59341:16;59338:220;;;59470:16;59464:4;59458;59443:44;59522:16;59516:4;59509:30;59338:220;59586:1;59583;59576:12;59252:351;59697:24;59692:3;59688:34;59684:1;59678:8;59675:48;59665:201;;59757:10;59751:4;59744:24;59846:4;59840;59833:18;59665:201;58639:1238;;;58468:1416;;;;:::o;37336:330::-;37397:14;37505:2;37499:4;37492:16;37535:24;37529:4;37522:38;37638:4;37632;37622:21;37618:2;37614:30;37610:2;37606:39;37600:46;37596:2;37592:55;37588:2;37584:64;37574:74;;37336:330;;;:::o;18590:191::-;18664:16;18683:6;;;;;;;;;;;18664:25;;18709:8;18700:6;;:17;;;;;;;;;;;;;;;;;;18764:8;18733:40;;18754:8;18733:40;;;;;;;;;;;;18653:128;18590:191;:::o;36880:317::-;36940:11;37045:2;37039:4;37032:16;37075:24;37069:4;37062:38;37170:4;37164;37154:21;37150:2;37146:30;37142:2;37138:39;37132:46;37128:2;37124:55;37114:65;;36880:317;;;:::o;119844:93::-;119895:13;119924:7;119917:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119844:93;:::o;13303:716::-;13359:13;13410:14;13447:1;13427:17;13438:5;13427:10;:17::i;:::-;:21;13410:38;;13463:20;13497:6;13486:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13463:41;;13519:11;13648:6;13644:2;13640:15;13632:6;13628:28;13621:35;;13685:288;13692:4;13685:288;;;13717:5;;;;;;;;13859:8;13854:2;13847:5;13843:14;13838:30;13833:3;13825:44;13915:2;13906:11;;;;;;:::i;:::-;;;;;13949:1;13940:5;:10;13685:288;13936:21;13685:288;13994:6;13987:13;;;;;13303:716;;;:::o;38202:308::-;38265:14;38373:24;38367:4;38360:38;38425:5;38419:4;38412:19;38485:4;38479;38469:21;38463:28;38459:2;38455:37;38445:47;;38202:308;;;:::o;43073:188::-;43163:13;43169:2;43173;43163:5;:13::i;:::-;43191:12;43200:2;43191:8;:12::i;:::-;43187:66;;;43205:48;43236:1;43240:2;43244;43248:4;43205:22;:48::i;:::-;43187:66;43073:188;;;:::o;15876:98::-;15929:7;15956:10;15949:17;;15876:98;:::o;62339:419::-;62412:14;62507:191;62514:1;62507:191;;;62564:4;62558;62548:21;62538:31;;62600:6;62594:4;62587:20;62665:5;62657;62654:1;62650:13;62646:25;62638:6;62635:37;62507:191;62625:58;62507:191;62734:5;62726:6;62722:18;62712:28;;62339:419;;;;:::o;115874:636::-;115990:14;116022:18;116043:16;:28;116060:10;116043:28;;;;;;;;;;;;116022:49;;116082:17;116130:1;116102:25;:29;;;;:::i;:::-;116082:49;;116142:22;116167:16;:27;116184:9;116167:27;;;;;;;;;;;;116142:52;;116230:1;116216:10;:15;:41;;116247:10;116216:41;;;116234:10;116216:41;116207:50;;116288:9;116274:10;:23;116270:135;;116363:1;116345:14;:19;:48;;116379:14;116345:48;;;116367:9;116345:48;116314:16;:28;116331:10;116314:28;;;;;;;;;;;:79;;;;116270:135;116439:1;116421:14;:19;116417:86;;116464:16;:27;116481:9;116464:27;;;;;;;;;;;116457:34;;;116417:86;116011:499;;;115874:636;;;;:::o;40861:1686::-;40928:40;40957:1;40961:2;40965;40928:20;:40::i;:::-;41106:2;41102;41098:11;41094:2;41090:20;41084:26;;41182:2;41172:138;;41218:10;41212:4;41205:24;41290:4;41284;41277:18;41172:138;41374:2;41368:4;41361:16;41404:24;41398:4;41391:38;41496:4;41490;41480:21;41476:2;41472:30;41468:2;41464:39;41546:13;41540:20;41633:15;41629:2;41625:24;41622:149;;;41682:10;41676:4;41669:24;41751:4;41745;41738:18;41622:149;41862:2;41845:15;41842:23;41827:13;41820:46;41960:2;41954:4;41947:16;42016:4;42010;42000:21;42088:1;42074:11;42068:18;42064:26;42141:20;42122:17;42118:44;42108:193;;42200:10;42194:4;42187:24;42277:4;42271;42264:18;42108:193;42339:17;42326:11;42319:38;41928:444;;42476:2;42472;42469:1;42442:25;42436:4;42430;42425:54;41032:1458;;42500:39;42528:1;42532:2;42536;42500:19;:39::i;:::-;40861:1686;;:::o;116941:390::-;117025:16;117044:20;117057:6;117044:12;:20::i;:::-;117025:39;;117075:23;117120:8;117101:9;:28;;;;:::i;:::-;117075:54;;117140:15;117158:22;117173:6;117158:14;:22::i;:::-;117140:40;;117193:130;117222:6;117303:7;117287:25;;117280:3;117259:16;117251:25;;:32;;117243:69;117193:14;:130::i;:::-;117014:317;;;116941:390;;:::o;10171:922::-;10224:7;10244:14;10261:1;10244:18;;10311:6;10302:5;:15;10298:102;;10347:6;10338:15;;;;;;:::i;:::-;;;;;10382:2;10372:12;;;;10298:102;10427:6;10418:5;:15;10414:102;;10463:6;10454:15;;;;;;:::i;:::-;;;;;10498:2;10488:12;;;;10414:102;10543:6;10534:5;:15;10530:102;;10579:6;10570:15;;;;;;:::i;:::-;;;;;10614:2;10604:12;;;;10530:102;10659:5;10650;:14;10646:99;;10694:5;10685:14;;;;;;:::i;:::-;;;;;10728:1;10718:11;;;;10646:99;10772:5;10763;:14;10759:99;;10807:5;10798:14;;;;;;:::i;:::-;;;;;10841:1;10831:11;;;;10759:99;10885:5;10876;:14;10872:99;;10920:5;10911:14;;;;;;:::i;:::-;;;;;10954:1;10944:11;;;;10872:99;10998:5;10989;:14;10985:66;;11034:1;11024:11;;;;10985:66;11079:6;11072:13;;;10171:922;;;:::o;38766:416::-;38922:24;38916:4;38909:38;38974:5;38968:4;38961:19;39029:4;39023;39013:21;39068:11;39062:18;39153:6;39149:2;39145:15;39138:5;39134:27;39130:2;39126:36;39118:6;39114:49;39101:11;39094:70;38894:281;;38766:416;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:126::-;2897:7;2937:42;2930:5;2926:54;2915:65;;2860:126;;;:::o;2992:96::-;3029:7;3058:24;3076:5;3058:24;:::i;:::-;3047:35;;2992:96;;;:::o;3094:122::-;3167:24;3185:5;3167:24;:::i;:::-;3160:5;3157:35;3147:63;;3206:1;3203;3196:12;3147:63;3094:122;:::o;3222:139::-;3268:5;3306:6;3293:20;3284:29;;3322:33;3349:5;3322:33;:::i;:::-;3222:139;;;;:::o;3367:329::-;3426:6;3475:2;3463:9;3454:7;3450:23;3446:32;3443:119;;;3481:79;;:::i;:::-;3443:119;3601:1;3626:53;3671:7;3662:6;3651:9;3647:22;3626:53;:::i;:::-;3616:63;;3572:117;3367:329;;;;:::o;3702:86::-;3737:7;3777:4;3770:5;3766:16;3755:27;;3702:86;;;:::o;3794:112::-;3877:22;3893:5;3877:22;:::i;:::-;3872:3;3865:35;3794:112;;:::o;3912:214::-;4001:4;4039:2;4028:9;4024:18;4016:26;;4052:67;4116:1;4105:9;4101:17;4092:6;4052:67;:::i;:::-;3912:214;;;;:::o;4132:89::-;4168:7;4208:6;4201:5;4197:18;4186:29;;4132:89;;;:::o;4227:115::-;4312:23;4329:5;4312:23;:::i;:::-;4307:3;4300:36;4227:115;;:::o;4348:218::-;4439:4;4477:2;4466:9;4462:18;4454:26;;4490:69;4556:1;4545:9;4541:17;4532:6;4490:69;:::i;:::-;4348:218;;;;:::o;4572:77::-;4609:7;4638:5;4627:16;;4572:77;;;:::o;4655:122::-;4728:24;4746:5;4728:24;:::i;:::-;4721:5;4718:35;4708:63;;4767:1;4764;4757:12;4708:63;4655:122;:::o;4783:139::-;4829:5;4867:6;4854:20;4845:29;;4883:33;4910:5;4883:33;:::i;:::-;4783:139;;;;:::o;4928:329::-;4987:6;5036:2;5024:9;5015:7;5011:23;5007:32;5004:119;;;5042:79;;:::i;:::-;5004:119;5162:1;5187:53;5232:7;5223:6;5212:9;5208:22;5187:53;:::i;:::-;5177:63;;5133:117;4928:329;;;;:::o;5263:118::-;5350:24;5368:5;5350:24;:::i;:::-;5345:3;5338:37;5263:118;;:::o;5387:222::-;5480:4;5518:2;5507:9;5503:18;5495:26;;5531:71;5599:1;5588:9;5584:17;5575:6;5531:71;:::i;:::-;5387:222;;;;:::o;5615:474::-;5683:6;5691;5740:2;5728:9;5719:7;5715:23;5711:32;5708:119;;;5746:79;;:::i;:::-;5708:119;5866:1;5891:53;5936:7;5927:6;5916:9;5912:22;5891:53;:::i;:::-;5881:63;;5837:117;5993:2;6019:53;6064:7;6055:6;6044:9;6040:22;6019:53;:::i;:::-;6009:63;;5964:118;5615:474;;;;;:::o;6095:117::-;6204:1;6201;6194:12;6218:117;6327:1;6324;6317:12;6341:117;6450:1;6447;6440:12;6481:568;6554:8;6564:6;6614:3;6607:4;6599:6;6595:17;6591:27;6581:122;;6622:79;;:::i;:::-;6581:122;6735:6;6722:20;6712:30;;6765:18;6757:6;6754:30;6751:117;;;6787:79;;:::i;:::-;6751:117;6901:4;6893:6;6889:17;6877:29;;6955:3;6947:4;6939:6;6935:17;6925:8;6921:32;6918:41;6915:128;;;6962:79;;:::i;:::-;6915:128;6481:568;;;;;:::o;7070:566::-;7141:8;7151:6;7201:3;7194:4;7186:6;7182:17;7178:27;7168:122;;7209:79;;:::i;:::-;7168:122;7322:6;7309:20;7299:30;;7352:18;7344:6;7341:30;7338:117;;;7374:79;;:::i;:::-;7338:117;7488:4;7480:6;7476:17;7464:29;;7542:3;7534:4;7526:6;7522:17;7512:8;7508:32;7505:41;7502:128;;;7549:79;;:::i;:::-;7502:128;7070:566;;;;;:::o;7642:930::-;7762:6;7770;7778;7786;7835:2;7823:9;7814:7;7810:23;7806:32;7803:119;;;7841:79;;:::i;:::-;7803:119;7989:1;7978:9;7974:17;7961:31;8019:18;8011:6;8008:30;8005:117;;;8041:79;;:::i;:::-;8005:117;8154:80;8226:7;8217:6;8206:9;8202:22;8154:80;:::i;:::-;8136:98;;;;7932:312;8311:2;8300:9;8296:18;8283:32;8342:18;8334:6;8331:30;8328:117;;;8364:79;;:::i;:::-;8328:117;8477:78;8547:7;8538:6;8527:9;8523:22;8477:78;:::i;:::-;8459:96;;;;8254:311;7642:930;;;;;;;:::o;8578:118::-;8665:24;8683:5;8665:24;:::i;:::-;8660:3;8653:37;8578:118;;:::o;8702:222::-;8795:4;8833:2;8822:9;8818:18;8810:26;;8846:71;8914:1;8903:9;8899:17;8890:6;8846:71;:::i;:::-;8702:222;;;;:::o;8930:559::-;9016:6;9024;9073:2;9061:9;9052:7;9048:23;9044:32;9041:119;;;9079:79;;:::i;:::-;9041:119;9227:1;9216:9;9212:17;9199:31;9257:18;9249:6;9246:30;9243:117;;;9279:79;;:::i;:::-;9243:117;9392:80;9464:7;9455:6;9444:9;9440:22;9392:80;:::i;:::-;9374:98;;;;9170:312;8930:559;;;;;:::o;9495:619::-;9572:6;9580;9588;9637:2;9625:9;9616:7;9612:23;9608:32;9605:119;;;9643:79;;:::i;:::-;9605:119;9763:1;9788:53;9833:7;9824:6;9813:9;9809:22;9788:53;:::i;:::-;9778:63;;9734:117;9890:2;9916:53;9961:7;9952:6;9941:9;9937:22;9916:53;:::i;:::-;9906:63;;9861:118;10018:2;10044:53;10089:7;10080:6;10069:9;10065:22;10044:53;:::i;:::-;10034:63;;9989:118;9495:619;;;;;:::o;10120:118::-;10191:22;10207:5;10191:22;:::i;:::-;10184:5;10181:33;10171:61;;10228:1;10225;10218:12;10171:61;10120:118;:::o;10244:135::-;10288:5;10326:6;10313:20;10304:29;;10342:31;10367:5;10342:31;:::i;:::-;10244:135;;;;:::o;10385:325::-;10442:6;10491:2;10479:9;10470:7;10466:23;10462:32;10459:119;;;10497:79;;:::i;:::-;10459:119;10617:1;10642:51;10685:7;10676:6;10665:9;10661:22;10642:51;:::i;:::-;10632:61;;10588:115;10385:325;;;;:::o;10716:117::-;10825:1;10822;10815:12;10839:180;10887:77;10884:1;10877:88;10984:4;10981:1;10974:15;11008:4;11005:1;10998:15;11025:281;11108:27;11130:4;11108:27;:::i;:::-;11100:6;11096:40;11238:6;11226:10;11223:22;11202:18;11190:10;11187:34;11184:62;11181:88;;;11249:18;;:::i;:::-;11181:88;11289:10;11285:2;11278:22;11068:238;11025:281;;:::o;11312:129::-;11346:6;11373:20;;:::i;:::-;11363:30;;11402:33;11430:4;11422:6;11402:33;:::i;:::-;11312:129;;;:::o;11447:308::-;11509:4;11599:18;11591:6;11588:30;11585:56;;;11621:18;;:::i;:::-;11585:56;11659:29;11681:6;11659:29;:::i;:::-;11651:37;;11743:4;11737;11733:15;11725:23;;11447:308;;;:::o;11761:146::-;11858:6;11853:3;11848;11835:30;11899:1;11890:6;11885:3;11881:16;11874:27;11761:146;;;:::o;11913:425::-;11991:5;12016:66;12032:49;12074:6;12032:49;:::i;:::-;12016:66;:::i;:::-;12007:75;;12105:6;12098:5;12091:21;12143:4;12136:5;12132:16;12181:3;12172:6;12167:3;12163:16;12160:25;12157:112;;;12188:79;;:::i;:::-;12157:112;12278:54;12325:6;12320:3;12315;12278:54;:::i;:::-;11997:341;11913:425;;;;;:::o;12358:340::-;12414:5;12463:3;12456:4;12448:6;12444:17;12440:27;12430:122;;12471:79;;:::i;:::-;12430:122;12588:6;12575:20;12613:79;12688:3;12680:6;12673:4;12665:6;12661:17;12613:79;:::i;:::-;12604:88;;12420:278;12358:340;;;;:::o;12704:509::-;12773:6;12822:2;12810:9;12801:7;12797:23;12793:32;12790:119;;;12828:79;;:::i;:::-;12790:119;12976:1;12965:9;12961:17;12948:31;13006:18;12998:6;12995:30;12992:117;;;13028:79;;:::i;:::-;12992:117;13133:63;13188:7;13179:6;13168:9;13164:22;13133:63;:::i;:::-;13123:73;;12919:287;12704:509;;;;:::o;13219:116::-;13289:21;13304:5;13289:21;:::i;:::-;13282:5;13279:32;13269:60;;13325:1;13322;13315:12;13269:60;13219:116;:::o;13341:133::-;13384:5;13422:6;13409:20;13400:29;;13438:30;13462:5;13438:30;:::i;:::-;13341:133;;;;:::o;13480:468::-;13545:6;13553;13602:2;13590:9;13581:7;13577:23;13573:32;13570:119;;;13608:79;;:::i;:::-;13570:119;13728:1;13753:53;13798:7;13789:6;13778:9;13774:22;13753:53;:::i;:::-;13743:63;;13699:117;13855:2;13881:50;13923:7;13914:6;13903:9;13899:22;13881:50;:::i;:::-;13871:60;;13826:115;13480:468;;;;;:::o;13954:114::-;14021:6;14055:5;14049:12;14039:22;;13954:114;;;:::o;14074:184::-;14173:11;14207:6;14202:3;14195:19;14247:4;14242:3;14238:14;14223:29;;14074:184;;;;:::o;14264:132::-;14331:4;14354:3;14346:11;;14384:4;14379:3;14375:14;14367:22;;14264:132;;;:::o;14402:108::-;14479:24;14497:5;14479:24;:::i;:::-;14474:3;14467:37;14402:108;;:::o;14516:179::-;14585:10;14606:46;14648:3;14640:6;14606:46;:::i;:::-;14684:4;14679:3;14675:14;14661:28;;14516:179;;;;:::o;14701:113::-;14771:4;14803;14798:3;14794:14;14786:22;;14701:113;;;:::o;14850:732::-;14969:3;14998:54;15046:5;14998:54;:::i;:::-;15068:86;15147:6;15142:3;15068:86;:::i;:::-;15061:93;;15178:56;15228:5;15178:56;:::i;:::-;15257:7;15288:1;15273:284;15298:6;15295:1;15292:13;15273:284;;;15374:6;15368:13;15401:63;15460:3;15445:13;15401:63;:::i;:::-;15394:70;;15487:60;15540:6;15487:60;:::i;:::-;15477:70;;15333:224;15320:1;15317;15313:9;15308:14;;15273:284;;;15277:14;15573:3;15566:10;;14974:608;;;14850:732;;;;:::o;15588:373::-;15731:4;15769:2;15758:9;15754:18;15746:26;;15818:9;15812:4;15808:20;15804:1;15793:9;15789:17;15782:47;15846:108;15949:4;15940:6;15846:108;:::i;:::-;15838:116;;15588:373;;;;:::o;15980:552::-;16037:8;16047:6;16097:3;16090:4;16082:6;16078:17;16074:27;16064:122;;16105:79;;:::i;:::-;16064:122;16218:6;16205:20;16195:30;;16248:18;16240:6;16237:30;16234:117;;;16270:79;;:::i;:::-;16234:117;16384:4;16376:6;16372:17;16360:29;;16438:3;16430:4;16422:6;16418:17;16408:8;16404:32;16401:41;16398:128;;;16445:79;;:::i;:::-;16398:128;15980:552;;;;;:::o;16538:963::-;16635:6;16643;16651;16659;16667;16716:3;16704:9;16695:7;16691:23;16687:33;16684:120;;;16723:79;;:::i;:::-;16684:120;16843:1;16868:53;16913:7;16904:6;16893:9;16889:22;16868:53;:::i;:::-;16858:63;;16814:117;16970:2;16996:53;17041:7;17032:6;17021:9;17017:22;16996:53;:::i;:::-;16986:63;;16941:118;17098:2;17124:53;17169:7;17160:6;17149:9;17145:22;17124:53;:::i;:::-;17114:63;;17069:118;17254:2;17243:9;17239:18;17226:32;17285:18;17277:6;17274:30;17271:117;;;17307:79;;:::i;:::-;17271:117;17420:64;17476:7;17467:6;17456:9;17452:22;17420:64;:::i;:::-;17402:82;;;;17197:297;16538:963;;;;;;;;:::o;17507:93::-;17543:7;17583:10;17576:5;17572:22;17561:33;;17507:93;;;:::o;17606:115::-;17691:23;17708:5;17691:23;:::i;:::-;17686:3;17679:36;17606:115;;:::o;17727:218::-;17818:4;17856:2;17845:9;17841:18;17833:26;;17869:69;17935:1;17924:9;17920:17;17911:6;17869:69;:::i;:::-;17727:218;;;;:::o;17968:568::-;18041:8;18051:6;18101:3;18094:4;18086:6;18082:17;18078:27;18068:122;;18109:79;;:::i;:::-;18068:122;18222:6;18209:20;18199:30;;18252:18;18244:6;18241:30;18238:117;;;18274:79;;:::i;:::-;18238:117;18388:4;18380:6;18376:17;18364:29;;18442:3;18434:4;18426:6;18422:17;18412:8;18408:32;18405:41;18402:128;;;18449:79;;:::i;:::-;18402:128;17968:568;;;;;:::o;18542:559::-;18628:6;18636;18685:2;18673:9;18664:7;18660:23;18656:32;18653:119;;;18691:79;;:::i;:::-;18653:119;18839:1;18828:9;18824:17;18811:31;18869:18;18861:6;18858:30;18855:117;;;18891:79;;:::i;:::-;18855:117;19004:80;19076:7;19067:6;19056:9;19052:22;19004:80;:::i;:::-;18986:98;;;;18782:312;18542:559;;;;;:::o;19107:474::-;19175:6;19183;19232:2;19220:9;19211:7;19207:23;19203:32;19200:119;;;19238:79;;:::i;:::-;19200:119;19358:1;19383:53;19428:7;19419:6;19408:9;19404:22;19383:53;:::i;:::-;19373:63;;19329:117;19485:2;19511:53;19556:7;19547:6;19536:9;19532:22;19511:53;:::i;:::-;19501:63;;19456:118;19107:474;;;;;:::o;19587:104::-;19632:7;19661:24;19679:5;19661:24;:::i;:::-;19650:35;;19587:104;;;:::o;19697:138::-;19778:32;19804:5;19778:32;:::i;:::-;19771:5;19768:43;19758:71;;19825:1;19822;19815:12;19758:71;19697:138;:::o;19841:155::-;19895:5;19933:6;19920:20;19911:29;;19949:41;19984:5;19949:41;:::i;:::-;19841:155;;;;:::o;20002:345::-;20069:6;20118:2;20106:9;20097:7;20093:23;20089:32;20086:119;;;20124:79;;:::i;:::-;20086:119;20244:1;20269:61;20322:7;20313:6;20302:9;20298:22;20269:61;:::i;:::-;20259:71;;20215:125;20002:345;;;;:::o;20353:169::-;20493:21;20489:1;20481:6;20477:14;20470:45;20353:169;:::o;20528:366::-;20670:3;20691:67;20755:2;20750:3;20691:67;:::i;:::-;20684:74;;20767:93;20856:3;20767:93;:::i;:::-;20885:2;20880:3;20876:12;20869:19;;20528:366;;;:::o;20900:419::-;21066:4;21104:2;21093:9;21089:18;21081:26;;21153:9;21147:4;21143:20;21139:1;21128:9;21124:17;21117:47;21181:131;21307:4;21181:131;:::i;:::-;21173:139;;20900:419;;;:::o;21325:160::-;21465:12;21461:1;21453:6;21449:14;21442:36;21325:160;:::o;21491:366::-;21633:3;21654:67;21718:2;21713:3;21654:67;:::i;:::-;21647:74;;21730:93;21819:3;21730:93;:::i;:::-;21848:2;21843:3;21839:12;21832:19;;21491:366;;;:::o;21863:419::-;22029:4;22067:2;22056:9;22052:18;22044:26;;22116:9;22110:4;22106:20;22102:1;22091:9;22087:17;22080:47;22144:131;22270:4;22144:131;:::i;:::-;22136:139;;21863:419;;;:::o;22288:180::-;22336:77;22333:1;22326:88;22433:4;22430:1;22423:15;22457:4;22454:1;22447:15;22474:193;22513:3;22532:19;22549:1;22532:19;:::i;:::-;22527:24;;22565:19;22582:1;22565:19;:::i;:::-;22560:24;;22607:1;22604;22600:9;22593:16;;22630:6;22625:3;22622:15;22619:41;;;22640:18;;:::i;:::-;22619:41;22474:193;;;;:::o;22673:176::-;22813:28;22809:1;22801:6;22797:14;22790:52;22673:176;:::o;22855:366::-;22997:3;23018:67;23082:2;23077:3;23018:67;:::i;:::-;23011:74;;23094:93;23183:3;23094:93;:::i;:::-;23212:2;23207:3;23203:12;23196:19;;22855:366;;;:::o;23227:419::-;23393:4;23431:2;23420:9;23416:18;23408:26;;23480:9;23474:4;23470:20;23466:1;23455:9;23451:17;23444:47;23508:131;23634:4;23508:131;:::i;:::-;23500:139;;23227:419;;;:::o;23652:60::-;23680:3;23701:5;23694:12;;23652:60;;;:::o;23718:140::-;23767:9;23800:52;23818:33;23827:23;23844:5;23827:23;:::i;:::-;23818:33;:::i;:::-;23800:52;:::i;:::-;23787:65;;23718:140;;;:::o;23864:129::-;23950:36;23980:5;23950:36;:::i;:::-;23945:3;23938:49;23864:129;;:::o;23999:330::-;24119:4;24157:2;24146:9;24142:18;24134:26;;24170:71;24238:1;24227:9;24223:17;24214:6;24170:71;:::i;:::-;24251;24318:2;24307:9;24303:18;24294:6;24251:71;:::i;:::-;23999:330;;;;;:::o;24335:171::-;24373:3;24396:23;24413:5;24396:23;:::i;:::-;24387:32;;24441:6;24434:5;24431:17;24428:43;;24451:18;;:::i;:::-;24428:43;24498:1;24491:5;24487:13;24480:20;;24335:171;;;:::o;24512:166::-;24652:18;24648:1;24640:6;24636:14;24629:42;24512:166;:::o;24684:366::-;24826:3;24847:67;24911:2;24906:3;24847:67;:::i;:::-;24840:74;;24923:93;25012:3;24923:93;:::i;:::-;25041:2;25036:3;25032:12;25025:19;;24684:366;;;:::o;25056:419::-;25222:4;25260:2;25249:9;25245:18;25237:26;;25309:9;25303:4;25299:20;25295:1;25284:9;25280:17;25273:47;25337:131;25463:4;25337:131;:::i;:::-;25329:139;;25056:419;;;:::o;25481:162::-;25621:14;25617:1;25609:6;25605:14;25598:38;25481:162;:::o;25649:366::-;25791:3;25812:67;25876:2;25871:3;25812:67;:::i;:::-;25805:74;;25888:93;25977:3;25888:93;:::i;:::-;26006:2;26001:3;25997:12;25990:19;;25649:366;;;:::o;26021:419::-;26187:4;26225:2;26214:9;26210:18;26202:26;;26274:9;26268:4;26264:20;26260:1;26249:9;26245:17;26238:47;26302:131;26428:4;26302:131;:::i;:::-;26294:139;;26021:419;;;:::o;26446:173::-;26586:25;26582:1;26574:6;26570:14;26563:49;26446:173;:::o;26625:366::-;26767:3;26788:67;26852:2;26847:3;26788:67;:::i;:::-;26781:74;;26864:93;26953:3;26864:93;:::i;:::-;26982:2;26977:3;26973:12;26966:19;;26625:366;;;:::o;26997:419::-;27163:4;27201:2;27190:9;27186:18;27178:26;;27250:9;27244:4;27240:20;27236:1;27225:9;27221:17;27214:47;27278:131;27404:4;27278:131;:::i;:::-;27270:139;;26997:419;;;:::o;27422:180::-;27470:77;27467:1;27460:88;27567:4;27564:1;27557:15;27591:4;27588:1;27581:15;27608:320;27652:6;27689:1;27683:4;27679:12;27669:22;;27736:1;27730:4;27726:12;27757:18;27747:81;;27813:4;27805:6;27801:17;27791:27;;27747:81;27875:2;27867:6;27864:14;27844:18;27841:38;27838:84;;27894:18;;:::i;:::-;27838:84;27659:269;27608:320;;;:::o;27934:229::-;28074:34;28070:1;28062:6;28058:14;28051:58;28143:12;28138:2;28130:6;28126:15;28119:37;27934:229;:::o;28169:366::-;28311:3;28332:67;28396:2;28391:3;28332:67;:::i;:::-;28325:74;;28408:93;28497:3;28408:93;:::i;:::-;28526:2;28521:3;28517:12;28510:19;;28169:366;;;:::o;28541:419::-;28707:4;28745:2;28734:9;28730:18;28722:26;;28794:9;28788:4;28784:20;28780:1;28769:9;28765:17;28758:47;28822:131;28948:4;28822:131;:::i;:::-;28814:139;;28541:419;;;:::o;28966:180::-;29014:77;29011:1;29004:88;29111:4;29108:1;29101:15;29135:4;29132:1;29125:15;29152:233;29191:3;29214:24;29232:5;29214:24;:::i;:::-;29205:33;;29260:66;29253:5;29250:77;29247:103;;29330:18;;:::i;:::-;29247:103;29377:1;29370:5;29366:13;29359:20;;29152:233;;;:::o;29391:194::-;29431:4;29451:20;29469:1;29451:20;:::i;:::-;29446:25;;29485:20;29503:1;29485:20;:::i;:::-;29480:25;;29529:1;29526;29522:9;29514:17;;29553:1;29547:4;29544:11;29541:37;;;29558:18;;:::i;:::-;29541:37;29391:194;;;;:::o;29591:177::-;29731:29;29727:1;29719:6;29715:14;29708:53;29591:177;:::o;29774:366::-;29916:3;29937:67;30001:2;29996:3;29937:67;:::i;:::-;29930:74;;30013:93;30102:3;30013:93;:::i;:::-;30131:2;30126:3;30122:12;30115:19;;29774:366;;;:::o;30146:419::-;30312:4;30350:2;30339:9;30335:18;30327:26;;30399:9;30393:4;30389:20;30385:1;30374:9;30370:17;30363:47;30427:131;30553:4;30427:131;:::i;:::-;30419:139;;30146:419;;;:::o;30571:191::-;30611:3;30630:20;30648:1;30630:20;:::i;:::-;30625:25;;30664:20;30682:1;30664:20;:::i;:::-;30659:25;;30707:1;30704;30700:9;30693:16;;30728:3;30725:1;30722:10;30719:36;;;30735:18;;:::i;:::-;30719:36;30571:191;;;;:::o;30768:169::-;30908:21;30904:1;30896:6;30892:14;30885:45;30768:169;:::o;30943:366::-;31085:3;31106:67;31170:2;31165:3;31106:67;:::i;:::-;31099:74;;31182:93;31271:3;31182:93;:::i;:::-;31300:2;31295:3;31291:12;31284:19;;30943:366;;;:::o;31315:419::-;31481:4;31519:2;31508:9;31504:18;31496:26;;31568:9;31562:4;31558:20;31554:1;31543:9;31539:17;31532:47;31596:131;31722:4;31596:131;:::i;:::-;31588:139;;31315:419;;;:::o;31740:159::-;31880:11;31876:1;31868:6;31864:14;31857:35;31740:159;:::o;31905:365::-;32047:3;32068:66;32132:1;32127:3;32068:66;:::i;:::-;32061:73;;32143:93;32232:3;32143:93;:::i;:::-;32261:2;32256:3;32252:12;32245:19;;31905:365;;;:::o;32276:419::-;32442:4;32480:2;32469:9;32465:18;32457:26;;32529:9;32523:4;32519:20;32515:1;32504:9;32500:17;32493:47;32557:131;32683:4;32557:131;:::i;:::-;32549:139;;32276:419;;;:::o;32701:191::-;32739:4;32759:18;32775:1;32759:18;:::i;:::-;32754:23;;32791:18;32807:1;32791:18;:::i;:::-;32786:23;;32833:1;32830;32826:9;32818:17;;32857:4;32851;32848:14;32845:40;;;32865:18;;:::i;:::-;32845:40;32701:191;;;;:::o;32898:141::-;32947:4;32970:3;32962:11;;32993:3;32990:1;32983:14;33027:4;33024:1;33014:18;33006:26;;32898:141;;;:::o;33045:93::-;33082:6;33129:2;33124;33117:5;33113:14;33109:23;33099:33;;33045:93;;;:::o;33144:107::-;33188:8;33238:5;33232:4;33228:16;33207:37;;33144:107;;;;:::o;33257:393::-;33326:6;33376:1;33364:10;33360:18;33399:97;33429:66;33418:9;33399:97;:::i;:::-;33517:39;33547:8;33536:9;33517:39;:::i;:::-;33505:51;;33589:4;33585:9;33578:5;33574:21;33565:30;;33638:4;33628:8;33624:19;33617:5;33614:30;33604:40;;33333:317;;33257:393;;;;;:::o;33656:142::-;33706:9;33739:53;33757:34;33766:24;33784:5;33766:24;:::i;:::-;33757:34;:::i;:::-;33739:53;:::i;:::-;33726:66;;33656:142;;;:::o;33804:75::-;33847:3;33868:5;33861:12;;33804:75;;;:::o;33885:269::-;33995:39;34026:7;33995:39;:::i;:::-;34056:91;34105:41;34129:16;34105:41;:::i;:::-;34097:6;34090:4;34084:11;34056:91;:::i;:::-;34050:4;34043:105;33961:193;33885:269;;;:::o;34160:73::-;34205:3;34160:73;:::o;34239:189::-;34316:32;;:::i;:::-;34357:65;34415:6;34407;34401:4;34357:65;:::i;:::-;34292:136;34239:189;;:::o;34434:186::-;34494:120;34511:3;34504:5;34501:14;34494:120;;;34565:39;34602:1;34595:5;34565:39;:::i;:::-;34538:1;34531:5;34527:13;34518:22;;34494:120;;;34434:186;;:::o;34626:543::-;34727:2;34722:3;34719:11;34716:446;;;34761:38;34793:5;34761:38;:::i;:::-;34845:29;34863:10;34845:29;:::i;:::-;34835:8;34831:44;35028:2;35016:10;35013:18;35010:49;;;35049:8;35034:23;;35010:49;35072:80;35128:22;35146:3;35128:22;:::i;:::-;35118:8;35114:37;35101:11;35072:80;:::i;:::-;34731:431;;34716:446;34626:543;;;:::o;35175:117::-;35229:8;35279:5;35273:4;35269:16;35248:37;;35175:117;;;;:::o;35298:169::-;35342:6;35375:51;35423:1;35419:6;35411:5;35408:1;35404:13;35375:51;:::i;:::-;35371:56;35456:4;35450;35446:15;35436:25;;35349:118;35298:169;;;;:::o;35472:295::-;35548:4;35694:29;35719:3;35713:4;35694:29;:::i;:::-;35686:37;;35756:3;35753:1;35749:11;35743:4;35740:21;35732:29;;35472:295;;;;:::o;35772:1395::-;35889:37;35922:3;35889:37;:::i;:::-;35991:18;35983:6;35980:30;35977:56;;;36013:18;;:::i;:::-;35977:56;36057:38;36089:4;36083:11;36057:38;:::i;:::-;36142:67;36202:6;36194;36188:4;36142:67;:::i;:::-;36236:1;36260:4;36247:17;;36292:2;36284:6;36281:14;36309:1;36304:618;;;;36966:1;36983:6;36980:77;;;37032:9;37027:3;37023:19;37017:26;37008:35;;36980:77;37083:67;37143:6;37136:5;37083:67;:::i;:::-;37077:4;37070:81;36939:222;36274:887;;36304:618;36356:4;36352:9;36344:6;36340:22;36390:37;36422:4;36390:37;:::i;:::-;36449:1;36463:208;36477:7;36474:1;36471:14;36463:208;;;36556:9;36551:3;36547:19;36541:26;36533:6;36526:42;36607:1;36599:6;36595:14;36585:24;;36654:2;36643:9;36639:18;36626:31;;36500:4;36497:1;36493:12;36488:17;;36463:208;;;36699:6;36690:7;36687:19;36684:179;;;36757:9;36752:3;36748:19;36742:26;36800:48;36842:4;36834:6;36830:17;36819:9;36800:48;:::i;:::-;36792:6;36785:64;36707:156;36684:179;36909:1;36905;36897:6;36893:14;36889:22;36883:4;36876:36;36311:611;;;36274:887;;35864:1303;;;35772:1395;;:::o;37173:169::-;37313:21;37309:1;37301:6;37297:14;37290:45;37173:169;:::o;37348:366::-;37490:3;37511:67;37575:2;37570:3;37511:67;:::i;:::-;37504:74;;37587:93;37676:3;37587:93;:::i;:::-;37705:2;37700:3;37696:12;37689:19;;37348:366;;;:::o;37720:419::-;37886:4;37924:2;37913:9;37909:18;37901:26;;37973:9;37967:4;37963:20;37959:1;37948:9;37944:17;37937:47;38001:131;38127:4;38001:131;:::i;:::-;37993:139;;37720:419;;;:::o;38145:176::-;38285:28;38281:1;38273:6;38269:14;38262:52;38145:176;:::o;38327:366::-;38469:3;38490:67;38554:2;38549:3;38490:67;:::i;:::-;38483:74;;38566:93;38655:3;38566:93;:::i;:::-;38684:2;38679:3;38675:12;38668:19;;38327:366;;;:::o;38699:419::-;38865:4;38903:2;38892:9;38888:18;38880:26;;38952:9;38946:4;38942:20;38938:1;38927:9;38923:17;38916:47;38980:131;39106:4;38980:131;:::i;:::-;38972:139;;38699:419;;;:::o;39124:168::-;39264:20;39260:1;39252:6;39248:14;39241:44;39124:168;:::o;39298:366::-;39440:3;39461:67;39525:2;39520:3;39461:67;:::i;:::-;39454:74;;39537:93;39626:3;39537:93;:::i;:::-;39655:2;39650:3;39646:12;39639:19;;39298:366;;;:::o;39670:419::-;39836:4;39874:2;39863:9;39859:18;39851:26;;39923:9;39917:4;39913:20;39909:1;39898:9;39894:17;39887:47;39951:131;40077:4;39951:131;:::i;:::-;39943:139;;39670:419;;;:::o;40095:175::-;40235:27;40231:1;40223:6;40219:14;40212:51;40095:175;:::o;40276:366::-;40418:3;40439:67;40503:2;40498:3;40439:67;:::i;:::-;40432:74;;40515:93;40604:3;40515:93;:::i;:::-;40633:2;40628:3;40624:12;40617:19;;40276:366;;;:::o;40648:419::-;40814:4;40852:2;40841:9;40837:18;40829:26;;40901:9;40895:4;40891:20;40887:1;40876:9;40872:17;40865:47;40929:131;41055:4;40929:131;:::i;:::-;40921:139;;40648:419;;;:::o;41073:167::-;41110:3;41133:22;41149:5;41133:22;:::i;:::-;41124:31;;41177:4;41170:5;41167:15;41164:41;;41185:18;;:::i;:::-;41164:41;41232:1;41225:5;41221:13;41214:20;;41073:167;;;:::o;41246:175::-;41284:3;41307:23;41324:5;41307:23;:::i;:::-;41298:32;;41352:10;41345:5;41342:21;41339:47;;41366:18;;:::i;:::-;41339:47;41413:1;41406:5;41402:13;41395:20;;41246:175;;;:::o;41427:483::-;41598:4;41636:2;41625:9;41621:18;41613:26;;41649:71;41717:1;41706:9;41702:17;41693:6;41649:71;:::i;:::-;41767:9;41761:4;41757:20;41752:2;41741:9;41737:18;41730:48;41795:108;41898:4;41889:6;41795:108;:::i;:::-;41787:116;;41427:483;;;;;:::o;41916:166::-;42056:18;42052:1;42044:6;42040:14;42033:42;41916:166;:::o;42088:366::-;42230:3;42251:67;42315:2;42310:3;42251:67;:::i;:::-;42244:74;;42327:93;42416:3;42327:93;:::i;:::-;42445:2;42440:3;42436:12;42429:19;;42088:366;;;:::o;42460:419::-;42626:4;42664:2;42653:9;42649:18;42641:26;;42713:9;42707:4;42703:20;42699:1;42688:9;42684:17;42677:47;42741:131;42867:4;42741:131;:::i;:::-;42733:139;;42460:419;;;:::o;42885:173::-;43025:25;43021:1;43013:6;43009:14;43002:49;42885:173;:::o;43064:366::-;43206:3;43227:67;43291:2;43286:3;43227:67;:::i;:::-;43220:74;;43303:93;43392:3;43303:93;:::i;:::-;43421:2;43416:3;43412:12;43405:19;;43064:366;;;:::o;43436:419::-;43602:4;43640:2;43629:9;43625:18;43617:26;;43689:9;43683:4;43679:20;43675:1;43664:9;43660:17;43653:47;43717:131;43843:4;43717:131;:::i;:::-;43709:139;;43436:419;;;:::o;43861:162::-;44001:14;43997:1;43989:6;43985:14;43978:38;43861:162;:::o;44029:366::-;44171:3;44192:67;44256:2;44251:3;44192:67;:::i;:::-;44185:74;;44268:93;44357:3;44268:93;:::i;:::-;44386:2;44381:3;44377:12;44370:19;;44029:366;;;:::o;44401:419::-;44567:4;44605:2;44594:9;44590:18;44582:26;;44654:9;44648:4;44644:20;44640:1;44629:9;44625:17;44618:47;44682:131;44808:4;44682:131;:::i;:::-;44674:139;;44401:419;;;:::o;44826:148::-;44928:11;44965:3;44950:18;;44826:148;;;;:::o;44980:390::-;45086:3;45114:39;45147:5;45114:39;:::i;:::-;45169:89;45251:6;45246:3;45169:89;:::i;:::-;45162:96;;45267:65;45325:6;45320:3;45313:4;45306:5;45302:16;45267:65;:::i;:::-;45357:6;45352:3;45348:16;45341:23;;45090:280;44980:390;;;;:::o;45376:435::-;45556:3;45578:95;45669:3;45660:6;45578:95;:::i;:::-;45571:102;;45690:95;45781:3;45772:6;45690:95;:::i;:::-;45683:102;;45802:3;45795:10;;45376:435;;;;;:::o;45817:170::-;45957:22;45953:1;45945:6;45941:14;45934:46;45817:170;:::o;45993:366::-;46135:3;46156:67;46220:2;46215:3;46156:67;:::i;:::-;46149:74;;46232:93;46321:3;46232:93;:::i;:::-;46350:2;46345:3;46341:12;46334:19;;45993:366;;;:::o;46365:419::-;46531:4;46569:2;46558:9;46554:18;46546:26;;46618:9;46612:4;46608:20;46604:1;46593:9;46589:17;46582:47;46646:131;46772:4;46646:131;:::i;:::-;46638:139;;46365:419;;;:::o;46790:225::-;46930:34;46926:1;46918:6;46914:14;46907:58;46999:8;46994:2;46986:6;46982:15;46975:33;46790:225;:::o;47021:366::-;47163:3;47184:67;47248:2;47243:3;47184:67;:::i;:::-;47177:74;;47260:93;47349:3;47260:93;:::i;:::-;47378:2;47373:3;47369:12;47362:19;;47021:366;;;:::o;47393:419::-;47559:4;47597:2;47586:9;47582:18;47574:26;;47646:9;47640:4;47636:20;47632:1;47621:9;47617:17;47610:47;47674:131;47800:4;47674:131;:::i;:::-;47666:139;;47393:419;;;:::o;47818:167::-;47958:19;47954:1;47946:6;47942:14;47935:43;47818:167;:::o;47991:366::-;48133:3;48154:67;48218:2;48213:3;48154:67;:::i;:::-;48147:74;;48230:93;48319:3;48230:93;:::i;:::-;48348:2;48343:3;48339:12;48332:19;;47991:366;;;:::o;48363:419::-;48529:4;48567:2;48556:9;48552:18;48544:26;;48616:9;48610:4;48606:20;48602:1;48591:9;48587:17;48580:47;48644:131;48770:4;48644:131;:::i;:::-;48636:139;;48363:419;;;:::o;48788:332::-;48909:4;48947:2;48936:9;48932:18;48924:26;;48960:71;49028:1;49017:9;49013:17;49004:6;48960:71;:::i;:::-;49041:72;49109:2;49098:9;49094:18;49085:6;49041:72;:::i;:::-;48788:332;;;;;:::o;49126:182::-;49266:34;49262:1;49254:6;49250:14;49243:58;49126:182;:::o;49314:366::-;49456:3;49477:67;49541:2;49536:3;49477:67;:::i;:::-;49470:74;;49553:93;49642:3;49553:93;:::i;:::-;49671:2;49666:3;49662:12;49655:19;;49314:366;;;:::o;49686:419::-;49852:4;49890:2;49879:9;49875:18;49867:26;;49939:9;49933:4;49929:20;49925:1;49914:9;49910:17;49903:47;49967:131;50093:4;49967:131;:::i;:::-;49959:139;;49686:419;;;:::o;50111:79::-;50150:7;50179:5;50168:16;;50111:79;;;:::o;50196:157::-;50301:45;50321:24;50339:5;50321:24;:::i;:::-;50301:45;:::i;:::-;50296:3;50289:58;50196:157;;:::o;50359:397::-;50499:3;50514:75;50585:3;50576:6;50514:75;:::i;:::-;50614:2;50609:3;50605:12;50598:19;;50627:75;50698:3;50689:6;50627:75;:::i;:::-;50727:2;50722:3;50718:12;50711:19;;50747:3;50740:10;;50359:397;;;;;:::o;50762:171::-;50801:3;50824:24;50842:5;50824:24;:::i;:::-;50815:33;;50870:4;50863:5;50860:15;50857:41;;50878:18;;:::i;:::-;50857:41;50925:1;50918:5;50914:13;50907:20;;50762:171;;;:::o;50939:180::-;50987:77;50984:1;50977:88;51084:4;51081:1;51074:15;51108:4;51105:1;51098:15;51125:197;51164:3;51183:19;51200:1;51183:19;:::i;:::-;51178:24;;51216:19;51233:1;51216:19;:::i;:::-;51211:24;;51258:1;51255;51251:9;51244:16;;51281:10;51276:3;51273:19;51270:45;;;51295:18;;:::i;:::-;51270:45;51125:197;;;;:::o
Swarm Source
ipfs://e02f5df0ed0ae0fb3113d47cc2f981cc746571691c69ab197f38679537e2689b
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.