Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
353 MLP
Holders
241
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
14 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
[{"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.