ERC-721
Overview
Max Total Supply
888 SBG
Holders
460
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
0 SBGLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
SaiboguHei
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-01-13 */ // File: contracts/IOperatorFilterRegistry.sol pragma solidity ^0.8.13; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); } // File: contracts/OperatorFilterer.sol pragma solidity ^0.8.13; abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry constant operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(operatorFilterRegistry).code.length > 0) { if (subscribe) { operatorFilterRegistry.registerAndSubscribe( address(this), subscriptionOrRegistrantToCopy ); } else { if (subscriptionOrRegistrantToCopy != address(0)) { operatorFilterRegistry.registerAndCopyEntries( address(this), subscriptionOrRegistrantToCopy ); } else { operatorFilterRegistry.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(operatorFilterRegistry).code.length > 0) { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from == msg.sender) { _; return; } if ( !(operatorFilterRegistry.isOperatorAllowed( address(this), msg.sender ) && operatorFilterRegistry.isOperatorAllowed( address(this), from )) ) { revert OperatorNotAllowed(msg.sender); } } _; } } // File: contracts/DefaultOperatorFilterer.sol pragma solidity ^0.8.13; abstract contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} } // File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } // 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: contracts/IERC721A.sol // ERC721A Contracts v4.0.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of an ERC721A compliant contract. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * The caller cannot approve to their own address. */ error ApproveToCaller(); /** * The caller cannot approve to the current owner. */ error ApprovalToCurrentOwner(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); struct TokenOwnership { // The address of the owner. address addr; // Keeps track of the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; } /** * @dev Returns the total amount of tokens stored by the contract. * * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens. */ function totalSupply() external view returns (uint256); // ============================== // IERC165 // ============================== /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================== // IERC721 // ============================== /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================== // IERC721Metadata // ============================== /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: contracts/ERC721A.sol // ERC721A Contracts v4.0.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev ERC721 token receiver interface. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension. Built to optimize for lower gas during batch mints. * * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..). * * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Mask of an entry in packed address data. uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225; // The tokenId of the next token to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See `_packedOwnershipOf` implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see `_totalMinted`. */ function totalSupply() public view override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view returns (uint256) { // Counter underflow is impossible as _currentIndex does not decrement, // and it is initialized to `_startTokenId()` unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view returns (uint256) { return _burnCounter; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes of the XOR of // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165 // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)` return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view override returns (uint256) { if (_addressToUint256(owner) == 0) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) & BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> BITPOS_AUX); } /** * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; assembly { // Cast aux without masking. auxCasted := aux } packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX); _packedAddressData[owner] = packed; } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & BITMASK_BURNED == 0) { // Invariant: // There will always be an ownership that has an address and is not burned // before an ownership that does not have an address and is not burned. // Hence, curr will not underflow. // // We can directly compare the packed value. // If the address is zero, packed is zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP); ownership.burned = packed & BITMASK_BURNED != 0; } /** * Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around in the collection over time. */ function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } /** * @dev Casts the address to uint256 without masking. */ function _addressToUint256(address value) private pure returns (uint256 result) { assembly { result := value } } /** * @dev Casts the boolean to uint256 without branching. */ function _boolToUint256(bool value) private pure returns (uint256 result) { assembly { result := value } } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public override { address owner = address(uint160(_packedOwnershipOf(tokenId))); if (to == owner) revert ApprovalToCurrentOwner(); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { if (operator == _msgSenderERC721A()) revert ApproveToCaller(); _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { _transfer(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), */ function _exists(uint256 tokenId) internal view returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned. } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal { _safeMint(to, quantity, ''); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal { uint256 startTokenId = _currentIndex; if (_addressToUint256(to) == 0) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1 // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1 unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the balance and number minted. _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _addressToUint256(to) | (block.timestamp << BITPOS_START_TIMESTAMP) | (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED); uint256 updatedIndex = startTokenId; uint256 end = updatedIndex + quantity; if (to.code.length != 0) { do { emit Transfer(address(0), to, updatedIndex); if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (updatedIndex < end); // Reentrancy protection if (_currentIndex != startTokenId) revert(); } else { do { emit Transfer(address(0), to, updatedIndex++); } while (updatedIndex < end); } _currentIndex = updatedIndex; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _mint(address to, uint256 quantity) internal { uint256 startTokenId = _currentIndex; if (_addressToUint256(to) == 0) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1 // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1 unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the balance and number minted. _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _addressToUint256(to) | (block.timestamp << BITPOS_START_TIMESTAMP) | (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED); uint256 updatedIndex = startTokenId; uint256 end = updatedIndex + quantity; do { emit Transfer(address(0), to, updatedIndex++); } while (updatedIndex < end); _currentIndex = updatedIndex; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) private { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); address approvedAddress = _tokenApprovals[tokenId]; bool isApprovedOrOwner = (_msgSenderERC721A() == from || isApprovedForAll(from, _msgSenderERC721A()) || approvedAddress == _msgSenderERC721A()); if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved(); if (_addressToUint256(to) == 0) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. if (_addressToUint256(approvedAddress) != 0) { delete _tokenApprovals[tokenId]; } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _addressToUint256(to) | (block.timestamp << BITPOS_START_TIMESTAMP) | BITMASK_NEXT_INITIALIZED; // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); address approvedAddress = _tokenApprovals[tokenId]; if (approvalCheck) { bool isApprovedOrOwner = (_msgSenderERC721A() == from || isApprovedForAll(from, _msgSenderERC721A()) || approvedAddress == _msgSenderERC721A()); if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. if (_addressToUint256(approvedAddress) != 0) { delete _tokenApprovals[tokenId]; } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _addressToUint256(from) | (block.timestamp << BITPOS_START_TIMESTAMP) | BITMASK_BURNED | BITMASK_NEXT_INITIALIZED; // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } /** * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting. * And also called before burning one token. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes * minting. * And also called after one token has been burned. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function _toString(uint256 value) internal pure returns (string memory ptr) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged. // We will need 1 32-byte word to store the length, // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128. ptr := add(mload(0x40), 128) // Update the free memory pointer to allocate. mstore(0x40, ptr) // Cache the end of the memory to calculate the length later. let end := ptr // We write the string from the rightmost digit to the leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // Costs a bit more than early returning for the zero case, // but cheaper in terms of deployment and overall runtime costs. for { // Initialize and perform the first pass without check. let temp := value // Move the pointer 1 byte leftwards to point to an empty character slot. ptr := sub(ptr, 1) // Write the character to the pointer. 48 is the ASCII index of '0'. mstore8(ptr, add(48, mod(temp, 10))) temp := div(temp, 10) } temp { // Keep dividing `temp` until zero. temp := div(temp, 10) } { // Body of the for loop. ptr := sub(ptr, 1) mstore8(ptr, add(48, mod(temp, 10))) } let length := sub(end, ptr) // Move the pointer 32 bytes leftwards to make room for the length. ptr := sub(ptr, 32) // Store the length. mstore(ptr, length) } } } // File: contracts/saibogu-hei.sol // pragma solidity ^0.8.9; pragma solidity >=0.7.0 <0.9.0; contract SaiboguHei is ERC721A, Ownable, DefaultOperatorFilterer { using Strings for uint256; uint256 public constant MAX_SUPPLY = 888; uint256 public phase = 0; bytes32 public merkleRoot; uint256 public salePrice = 0 ether; uint256 public maxMintPerTx = 2; uint256 public maxMintPerWallet = 2; string public baseURI; bool private reveal = false; mapping(address => uint) public accountMinted; constructor() ERC721A("SaiboguHei", "SBG") {} /** * @notice token start from id 1 */ function _startTokenId() internal view virtual override returns (uint256) { return 1; } /** * @notice whitelist mint */ function whitelistMint(uint quantity, bytes32[] memory proof) external payable { require(phase == 1, "whitelist is close."); require(MerkleProof.verify(proof, merkleRoot, keccak256(abi.encodePacked(msg.sender))), "Not whitelisted."); _mint(quantity); } /** * @notice public mint */ function publicMint(uint quantity) external payable { require(phase == 2 , "Public Sales is close."); _mint(quantity); } /** * @notice mint */ function _mint(uint quantity) internal { require(accountMinted[_msgSender()] + quantity <= maxMintPerWallet, "Account reached the max mint."); require(quantity <= maxMintPerTx && quantity > 0, "Max two per transaction."); require(quantity + totalSupply() <= MAX_SUPPLY, "Total Sold out"); require(msg.value >= salePrice * quantity, "Not enough ETH to mint"); accountMinted[_msgSender()] += quantity; _mint(_msgSender(), quantity); } /** * @notice set whitelist merkle root */ function setMerkleRoot(bytes32 _rootHash) external onlyOwner { merkleRoot = _rootHash; } /** * @notice set max mint per transaction */ function setMaxMintPerTx(uint256 _setMaxTx) external onlyOwner { maxMintPerTx = _setMaxTx; } /** * @notice set max mint per wallet */ function setMaxMintPerWallet(uint256 _setMaxMint) external onlyOwner { maxMintPerWallet = _setMaxMint; } /** * @notice set sale price */ function setSalePrice(uint256 _salePrice) external onlyOwner { salePrice = _salePrice; } /** * @notice set reveal */ function switchReveal() external onlyOwner { reveal = !reveal; } /** * @notice set rea uri */ function setBaseURI(string memory uri) external onlyOwner { baseURI = uri; } /** * @notice switch phase */ function switchPhase(uint256 phaseNumber) external onlyOwner { require(phaseNumber >= 0 && phaseNumber < 3 , "Phase out of range 0 - 2"); phase = phaseNumber; } /** * @notice token URI */ function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token"); if (reveal) { return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _tokenId.toString())) : ''; } else { return string(abi.encodePacked(baseURI)); } } /** * @notice transfer funds */ function withdrawal() external onlyOwner { uint256 balance = address(this).balance; payable(msg.sender).transfer(balance); } function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accountMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"salePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_setMaxTx","type":"uint256"}],"name":"setMaxMintPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_setMaxMint","type":"uint256"}],"name":"setMaxMintPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_rootHash","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"setSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"phaseNumber","type":"uint256"}],"name":"switchPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"switchReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260006009556000600b556002600c556002600d556000600f60006101000a81548160ff0219169083151502179055503480156200004057600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600a81526020017f536169626f6775486569000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f53424700000000000000000000000000000000000000000000000000000000008152508160029081620000d591906200066e565b508060039081620000e791906200066e565b50620000f86200031d60201b60201c565b600081905550505062000120620001146200032660201b60201c565b6200032e60201b60201c565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111562000315578015620001db576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001a19291906200079a565b600060405180830381600087803b158015620001bc57600080fd5b505af1158015620001d1573d6000803e3d6000fd5b5050505062000314565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000295576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200025b9291906200079a565b600060405180830381600087803b1580156200027657600080fd5b505af11580156200028b573d6000803e3d6000fd5b5050505062000313565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620002de9190620007c7565b600060405180830381600087803b158015620002f957600080fd5b505af11580156200030e573d6000803e3d6000fd5b505050505b5b5b5050620007e4565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200047657607f821691505b6020821081036200048c576200048b6200042e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004f67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620004b7565b620005028683620004b7565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200054f6200054962000543846200051a565b62000524565b6200051a565b9050919050565b6000819050919050565b6200056b836200052e565b620005836200057a8262000556565b848454620004c4565b825550505050565b600090565b6200059a6200058b565b620005a781848462000560565b505050565b5b81811015620005cf57620005c360008262000590565b600181019050620005ad565b5050565b601f8211156200061e57620005e88162000492565b620005f384620004a7565b8101602085101562000603578190505b6200061b6200061285620004a7565b830182620005ac565b50505b505050565b600082821c905092915050565b6000620006436000198460080262000623565b1980831691505092915050565b60006200065e838362000630565b9150826002028217905092915050565b6200067982620003f4565b67ffffffffffffffff811115620006955762000694620003ff565b5b620006a182546200045d565b620006ae828285620005d3565b600060209050601f831160018114620006e65760008415620006d1578287015190505b620006dd858262000650565b8655506200074d565b601f198416620006f68662000492565b60005b828110156200072057848901518255600182019150602085019450602081019050620006f9565b868310156200074057848901516200073c601f89168262000630565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620007828262000755565b9050919050565b620007948162000775565b82525050565b6000604082019050620007b1600083018562000789565b620007c0602083018462000789565b9392505050565b6000602082019050620007de600083018462000789565b92915050565b613c4d80620007f46000396000f3fe6080604052600436106102045760003560e01c8063715018a611610118578063c87b56dd116100a0578063de7fcb1d1161006f578063de7fcb1d14610723578063e985e9c51461074e578063ec5a2d451461078b578063f2fde38b146107a2578063f51f96dd146107cb57610204565b8063c87b56dd14610676578063c9eb7060146106b3578063d2cab056146106f0578063d4e932921461070c57610204565b8063a22cb465116100e7578063a22cb465146105a5578063afdf6134146105ce578063b1c9fe6e146105f7578063b228d92514610622578063b88d4fde1461064d57610204565b8063715018a61461050f5780637cb64759146105265780638da5cb5b1461054f57806395d89b411461057a57610204565b80632eb4a7ab1161019b578063616cdb1e1161016a578063616cdb1e146104185780636352211e1461044157806363e547171461047e5780636c0360eb146104a757806370a08231146104d257610204565b80632eb4a7ab1461037057806332cb6b0c1461039b57806342842e0e146103c657806355f804b3146103ef57610204565b806318160ddd116101d757806318160ddd146102d75780631919fed71461030257806323b872dd1461032b5780632db115441461035457610204565b806301ffc9a71461020957806306fdde0314610246578063081812fc14610271578063095ea7b3146102ae575b600080fd5b34801561021557600080fd5b50610230600480360381019061022b919061286a565b6107f6565b60405161023d91906128b2565b60405180910390f35b34801561025257600080fd5b5061025b610888565b604051610268919061295d565b60405180910390f35b34801561027d57600080fd5b50610298600480360381019061029391906129b5565b61091a565b6040516102a59190612a23565b60405180910390f35b3480156102ba57600080fd5b506102d560048036038101906102d09190612a6a565b610996565b005b3480156102e357600080fd5b506102ec610b3c565b6040516102f99190612ab9565b60405180910390f35b34801561030e57600080fd5b50610329600480360381019061032491906129b5565b610b53565b005b34801561033757600080fd5b50610352600480360381019061034d9190612ad4565b610b65565b005b61036e600480360381019061036991906129b5565b610d4b565b005b34801561037c57600080fd5b50610385610d9c565b6040516103929190612b40565b60405180910390f35b3480156103a757600080fd5b506103b0610da2565b6040516103bd9190612ab9565b60405180910390f35b3480156103d257600080fd5b506103ed60048036038101906103e89190612ad4565b610da8565b005b3480156103fb57600080fd5b5061041660048036038101906104119190612c90565b610f8e565b005b34801561042457600080fd5b5061043f600480360381019061043a91906129b5565b610fa9565b005b34801561044d57600080fd5b50610468600480360381019061046391906129b5565b610fbb565b6040516104759190612a23565b60405180910390f35b34801561048a57600080fd5b506104a560048036038101906104a091906129b5565b610fcd565b005b3480156104b357600080fd5b506104bc61102f565b6040516104c9919061295d565b60405180910390f35b3480156104de57600080fd5b506104f960048036038101906104f49190612cd9565b6110bd565b6040516105069190612ab9565b60405180910390f35b34801561051b57600080fd5b50610524611151565b005b34801561053257600080fd5b5061054d60048036038101906105489190612d32565b611165565b005b34801561055b57600080fd5b50610564611177565b6040516105719190612a23565b60405180910390f35b34801561058657600080fd5b5061058f6111a1565b60405161059c919061295d565b60405180910390f35b3480156105b157600080fd5b506105cc60048036038101906105c79190612d8b565b611233565b005b3480156105da57600080fd5b506105f560048036038101906105f091906129b5565b6113aa565b005b34801561060357600080fd5b5061060c6113bc565b6040516106199190612ab9565b60405180910390f35b34801561062e57600080fd5b506106376113c2565b6040516106449190612ab9565b60405180910390f35b34801561065957600080fd5b50610674600480360381019061066f9190612e6c565b6113c8565b005b34801561068257600080fd5b5061069d600480360381019061069891906129b5565b6115b1565b6040516106aa919061295d565b60405180910390f35b3480156106bf57600080fd5b506106da60048036038101906106d59190612cd9565b611697565b6040516106e79190612ab9565b60405180910390f35b61070a60048036038101906107059190612fb7565b6116af565b005b34801561071857600080fd5b50610721611773565b005b34801561072f57600080fd5b506107386117ca565b6040516107459190612ab9565b60405180910390f35b34801561075a57600080fd5b5061077560048036038101906107709190613013565b6117d0565b60405161078291906128b2565b60405180910390f35b34801561079757600080fd5b506107a0611864565b005b3480156107ae57600080fd5b506107c960048036038101906107c49190612cd9565b611898565b005b3480156107d757600080fd5b506107e061191b565b6040516107ed9190612ab9565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061085157506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108815750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461089790613082565b80601f01602080910402602001604051908101604052809291908181526020018280546108c390613082565b80156109105780601f106108e557610100808354040283529160200191610910565b820191906000526020600020905b8154815290600101906020018083116108f357829003601f168201915b5050505050905090565b600061092582611921565b61095b576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109a182611980565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a08576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a27611a4c565b73ffffffffffffffffffffffffffffffffffffffff1614610a8a57610a5381610a4e611a4c565b6117d0565b610a89576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610b46611a54565b6001546000540303905090565b610b5b611a5d565b80600b8190555050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d39573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610bd757610bd2848484611adb565b610d45565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610c209291906130b3565b6020604051808303816000875af1158015610c3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6391906130f1565b8015610cf757506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610cb39291906130b3565b6020604051808303816000875af1158015610cd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf691906130f1565b5b610d3857336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d2f9190612a23565b60405180910390fd5b5b610d44848484611adb565b5b50505050565b600260095414610d90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d879061316a565b60405180910390fd5b610d9981611aeb565b50565b600a5481565b61037881565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610f7c573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e1a57610e15848484611cea565b610f88565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610e639291906130b3565b6020604051808303816000875af1158015610e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea691906130f1565b8015610f3a57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610ef69291906130b3565b6020604051808303816000875af1158015610f15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3991906130f1565b5b610f7b57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610f729190612a23565b60405180910390fd5b5b610f87848484611cea565b5b50505050565b610f96611a5d565b80600e9081610fa59190613336565b5050565b610fb1611a5d565b80600c8190555050565b6000610fc682611980565b9050919050565b610fd5611a5d565b60008110158015610fe65750600381105b611025576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101c90613454565b60405180910390fd5b8060098190555050565b600e805461103c90613082565b80601f016020809104026020016040519081016040528092919081815260200182805461106890613082565b80156110b55780601f1061108a576101008083540402835291602001916110b5565b820191906000526020600020905b81548152906001019060200180831161109857829003601f168201915b505050505081565b6000806110c983611d0a565b03611100576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611159611a5d565b6111636000611d14565b565b61116d611a5d565b80600a8190555050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546111b090613082565b80601f01602080910402602001604051908101604052809291908181526020018280546111dc90613082565b80156112295780601f106111fe57610100808354040283529160200191611229565b820191906000526020600020905b81548152906001019060200180831161120c57829003601f168201915b5050505050905090565b61123b611a4c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361129f576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006112ac611a4c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611359611a4c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161139e91906128b2565b60405180910390a35050565b6113b2611a5d565b80600d8190555050565b60095481565b600d5481565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561159d573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361143b5761143685858585611dda565b6115aa565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016114849291906130b3565b6020604051808303816000875af11580156114a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c791906130f1565b801561155b57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016115179291906130b3565b6020604051808303816000875af1158015611536573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155a91906130f1565b5b61159c57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016115939190612a23565b60405180910390fd5b5b6115a985858585611dda565b5b5050505050565b60606115bc82611921565b6115fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f2906134e6565b60405180910390fd5b600f60009054906101000a900460ff161561166e576000600e805461161f90613082565b90500361163b5760405180602001604052806000815250611667565b600e61164683611e4d565b6040516020016116579291906135c5565b6040516020818303038152906040525b9050611692565b600e60405160200161168091906135e9565b60405160208183030381529060405290505b919050565b60106020528060005260406000206000915090505481565b6001600954146116f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116eb9061364c565b60405180910390fd5b61172781600a543360405160200161170c91906136b4565b60405160208183030381529060405280519060200120611f1b565b611766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175d9061371b565b60405180910390fd5b61176f82611aeb565b5050565b61177b611a5d565b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156117c6573d6000803e3d6000fd5b5050565b600c5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61186c611a5d565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b6118a0611a5d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361190f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611906906137ad565b60405180910390fd5b61191881611d14565b50565b600b5481565b60008161192c611a54565b1115801561193b575060005482105b8015611979575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b6000808290508061198f611a54565b11611a1557600054811015611a145760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611a12575b60008103611a085760046000836001900393508381526020019081526020016000205490506119de565b8092505050611a47565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b60006001905090565b611a65611f32565b73ffffffffffffffffffffffffffffffffffffffff16611a83611177565b73ffffffffffffffffffffffffffffffffffffffff1614611ad9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ad090613819565b60405180910390fd5b565b611ae6838383611f3a565b505050565b600d548160106000611afb611f32565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611b409190613868565b1115611b81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b78906138e8565b60405180910390fd5b600c548111158015611b935750600081115b611bd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc990613954565b60405180910390fd5b610378611bdd610b3c565b82611be89190613868565b1115611c29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c20906139c0565b60405180910390fd5b80600b54611c3791906139e0565b341015611c79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7090613a6e565b60405180910390fd5b8060106000611c86611f32565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ccf9190613868565b92505081905550611ce7611ce1611f32565b826122ff565b50565b611d05838383604051806020016040528060008152506113c8565b505050565b6000819050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611de5848484611f3a565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611e4757611e10848484846124ad565b611e46576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b606060006001611e5c846125fd565b01905060008167ffffffffffffffff811115611e7b57611e7a612b65565b5b6040519080825280601f01601f191660200182016040528015611ead5781602001600182028036833780820191505090505b509050600082602001820190505b600115611f10578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611f0457611f03613a8e565b5b04945060008503611ebb575b819350505050919050565b600082611f288584612750565b1490509392505050565b600033905090565b6000611f4582611980565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611fac576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006006600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008573ffffffffffffffffffffffffffffffffffffffff16612005611a4c565b73ffffffffffffffffffffffffffffffffffffffff16148061203457506120338661202e611a4c565b6117d0565b5b806120715750612042611a4c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050806120aa576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006120b586611d0a565b036120ec576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120f986868660016127a6565b600061210483611d0a565b14612140576006600085815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b61220787611d0a565b1717600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361228f576000600185019050600060046000838152602001908152602001600020540361228d57600054811461228c578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46122f786868660016127ac565b505050505050565b600080549050600061231084611d0a565b03612347576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612381576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61238e60008483856127a6565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16123f3600184146127b2565b901b60a042901b61240385611d0a565b171760046000838152602001908152602001600020819055506000819050600083820190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612429578160008190555050506124a860008483856127ac565b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026124d3611a4c565b8786866040518563ffffffff1660e01b81526004016124f59493929190613b12565b6020604051808303816000875af192505050801561253157506040513d601f19601f8201168201806040525081019061252e9190613b73565b60015b6125aa573d8060008114612561576040519150601f19603f3d011682016040523d82523d6000602084013e612566565b606091505b5060008151036125a2576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061265b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161265157612650613a8e565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612698576d04ee2d6d415b85acef8100000000838161268e5761268d613a8e565b5b0492506020810190505b662386f26fc1000083106126c757662386f26fc1000083816126bd576126bc613a8e565b5b0492506010810190505b6305f5e10083106126f0576305f5e10083816126e6576126e5613a8e565b5b0492506008810190505b612710831061271557612710838161270b5761270a613a8e565b5b0492506004810190505b60648310612738576064838161272e5761272d613a8e565b5b0492506002810190505b600a8310612747576001810190505b80915050919050565b60008082905060005b845181101561279b576127868286838151811061277957612778613ba0565b5b60200260200101516127bc565b9150808061279390613bcf565b915050612759565b508091505092915050565b50505050565b50505050565b6000819050919050565b60008183106127d4576127cf82846127e7565b6127df565b6127de83836127e7565b5b905092915050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61284781612812565b811461285257600080fd5b50565b6000813590506128648161283e565b92915050565b6000602082840312156128805761287f612808565b5b600061288e84828501612855565b91505092915050565b60008115159050919050565b6128ac81612897565b82525050565b60006020820190506128c760008301846128a3565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156129075780820151818401526020810190506128ec565b60008484015250505050565b6000601f19601f8301169050919050565b600061292f826128cd565b61293981856128d8565b93506129498185602086016128e9565b61295281612913565b840191505092915050565b600060208201905081810360008301526129778184612924565b905092915050565b6000819050919050565b6129928161297f565b811461299d57600080fd5b50565b6000813590506129af81612989565b92915050565b6000602082840312156129cb576129ca612808565b5b60006129d9848285016129a0565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612a0d826129e2565b9050919050565b612a1d81612a02565b82525050565b6000602082019050612a386000830184612a14565b92915050565b612a4781612a02565b8114612a5257600080fd5b50565b600081359050612a6481612a3e565b92915050565b60008060408385031215612a8157612a80612808565b5b6000612a8f85828601612a55565b9250506020612aa0858286016129a0565b9150509250929050565b612ab38161297f565b82525050565b6000602082019050612ace6000830184612aaa565b92915050565b600080600060608486031215612aed57612aec612808565b5b6000612afb86828701612a55565b9350506020612b0c86828701612a55565b9250506040612b1d868287016129a0565b9150509250925092565b6000819050919050565b612b3a81612b27565b82525050565b6000602082019050612b556000830184612b31565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612b9d82612913565b810181811067ffffffffffffffff82111715612bbc57612bbb612b65565b5b80604052505050565b6000612bcf6127fe565b9050612bdb8282612b94565b919050565b600067ffffffffffffffff821115612bfb57612bfa612b65565b5b612c0482612913565b9050602081019050919050565b82818337600083830152505050565b6000612c33612c2e84612be0565b612bc5565b905082815260208101848484011115612c4f57612c4e612b60565b5b612c5a848285612c11565b509392505050565b600082601f830112612c7757612c76612b5b565b5b8135612c87848260208601612c20565b91505092915050565b600060208284031215612ca657612ca5612808565b5b600082013567ffffffffffffffff811115612cc457612cc361280d565b5b612cd084828501612c62565b91505092915050565b600060208284031215612cef57612cee612808565b5b6000612cfd84828501612a55565b91505092915050565b612d0f81612b27565b8114612d1a57600080fd5b50565b600081359050612d2c81612d06565b92915050565b600060208284031215612d4857612d47612808565b5b6000612d5684828501612d1d565b91505092915050565b612d6881612897565b8114612d7357600080fd5b50565b600081359050612d8581612d5f565b92915050565b60008060408385031215612da257612da1612808565b5b6000612db085828601612a55565b9250506020612dc185828601612d76565b9150509250929050565b600067ffffffffffffffff821115612de657612de5612b65565b5b612def82612913565b9050602081019050919050565b6000612e0f612e0a84612dcb565b612bc5565b905082815260208101848484011115612e2b57612e2a612b60565b5b612e36848285612c11565b509392505050565b600082601f830112612e5357612e52612b5b565b5b8135612e63848260208601612dfc565b91505092915050565b60008060008060808587031215612e8657612e85612808565b5b6000612e9487828801612a55565b9450506020612ea587828801612a55565b9350506040612eb6878288016129a0565b925050606085013567ffffffffffffffff811115612ed757612ed661280d565b5b612ee387828801612e3e565b91505092959194509250565b600067ffffffffffffffff821115612f0a57612f09612b65565b5b602082029050602081019050919050565b600080fd5b6000612f33612f2e84612eef565b612bc5565b90508083825260208201905060208402830185811115612f5657612f55612f1b565b5b835b81811015612f7f5780612f6b8882612d1d565b845260208401935050602081019050612f58565b5050509392505050565b600082601f830112612f9e57612f9d612b5b565b5b8135612fae848260208601612f20565b91505092915050565b60008060408385031215612fce57612fcd612808565b5b6000612fdc858286016129a0565b925050602083013567ffffffffffffffff811115612ffd57612ffc61280d565b5b61300985828601612f89565b9150509250929050565b6000806040838503121561302a57613029612808565b5b600061303885828601612a55565b925050602061304985828601612a55565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061309a57607f821691505b6020821081036130ad576130ac613053565b5b50919050565b60006040820190506130c86000830185612a14565b6130d56020830184612a14565b9392505050565b6000815190506130eb81612d5f565b92915050565b60006020828403121561310757613106612808565b5b6000613115848285016130dc565b91505092915050565b7f5075626c69632053616c657320697320636c6f73652e00000000000000000000600082015250565b60006131546016836128d8565b915061315f8261311e565b602082019050919050565b6000602082019050818103600083015261318381613147565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026131ec7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826131af565b6131f686836131af565b95508019841693508086168417925050509392505050565b6000819050919050565b600061323361322e6132298461297f565b61320e565b61297f565b9050919050565b6000819050919050565b61324d83613218565b6132616132598261323a565b8484546131bc565b825550505050565b600090565b613276613269565b613281818484613244565b505050565b5b818110156132a55761329a60008261326e565b600181019050613287565b5050565b601f8211156132ea576132bb8161318a565b6132c48461319f565b810160208510156132d3578190505b6132e76132df8561319f565b830182613286565b50505b505050565b600082821c905092915050565b600061330d600019846008026132ef565b1980831691505092915050565b600061332683836132fc565b9150826002028217905092915050565b61333f826128cd565b67ffffffffffffffff81111561335857613357612b65565b5b6133628254613082565b61336d8282856132a9565b600060209050601f8311600181146133a0576000841561338e578287015190505b613398858261331a565b865550613400565b601f1984166133ae8661318a565b60005b828110156133d6578489015182556001820191506020850194506020810190506133b1565b868310156133f357848901516133ef601f8916826132fc565b8355505b6001600288020188555050505b505050505050565b7f5068617365206f7574206f662072616e67652030202d20320000000000000000600082015250565b600061343e6018836128d8565b915061344982613408565b602082019050919050565b6000602082019050818103600083015261346d81613431565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006134d0602f836128d8565b91506134db82613474565b604082019050919050565b600060208201905081810360008301526134ff816134c3565b9050919050565b600081905092915050565b6000815461351e81613082565b6135288186613506565b9450600182166000811461354357600181146135585761358b565b60ff198316865281151582028601935061358b565b6135618561318a565b60005b8381101561358357815481890152600182019150602081019050613564565b838801955050505b50505092915050565b600061359f826128cd565b6135a98185613506565b93506135b98185602086016128e9565b80840191505092915050565b60006135d18285613511565b91506135dd8284613594565b91508190509392505050565b60006135f58284613511565b915081905092915050565b7f77686974656c69737420697320636c6f73652e00000000000000000000000000600082015250565b60006136366013836128d8565b915061364182613600565b602082019050919050565b6000602082019050818103600083015261366581613629565b9050919050565b60008160601b9050919050565b60006136848261366c565b9050919050565b600061369682613679565b9050919050565b6136ae6136a982612a02565b61368b565b82525050565b60006136c0828461369d565b60148201915081905092915050565b7f4e6f742077686974656c69737465642e00000000000000000000000000000000600082015250565b60006137056010836128d8565b9150613710826136cf565b602082019050919050565b60006020820190508181036000830152613734816136f8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006137976026836128d8565b91506137a28261373b565b604082019050919050565b600060208201905081810360008301526137c68161378a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006138036020836128d8565b915061380e826137cd565b602082019050919050565b60006020820190508181036000830152613832816137f6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138738261297f565b915061387e8361297f565b925082820190508082111561389657613895613839565b5b92915050565b7f4163636f756e74207265616368656420746865206d6178206d696e742e000000600082015250565b60006138d2601d836128d8565b91506138dd8261389c565b602082019050919050565b60006020820190508181036000830152613901816138c5565b9050919050565b7f4d61782074776f20706572207472616e73616374696f6e2e0000000000000000600082015250565b600061393e6018836128d8565b915061394982613908565b602082019050919050565b6000602082019050818103600083015261396d81613931565b9050919050565b7f546f74616c20536f6c64206f7574000000000000000000000000000000000000600082015250565b60006139aa600e836128d8565b91506139b582613974565b602082019050919050565b600060208201905081810360008301526139d98161399d565b9050919050565b60006139eb8261297f565b91506139f68361297f565b9250828202613a048161297f565b91508282048414831517613a1b57613a1a613839565b5b5092915050565b7f4e6f7420656e6f7567682045544820746f206d696e7400000000000000000000600082015250565b6000613a586016836128d8565b9150613a6382613a22565b602082019050919050565b60006020820190508181036000830152613a8781613a4b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000613ae482613abd565b613aee8185613ac8565b9350613afe8185602086016128e9565b613b0781612913565b840191505092915050565b6000608082019050613b276000830187612a14565b613b346020830186612a14565b613b416040830185612aaa565b8181036060830152613b538184613ad9565b905095945050505050565b600081519050613b6d8161283e565b92915050565b600060208284031215613b8957613b88612808565b5b6000613b9784828501613b5e565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000613bda8261297f565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613c0c57613c0b613839565b5b60018201905091905056fea26469706673582212207ae8eff1b6ad496fea5f7b4661e7099b0dadb1a63027e59468c88bd57d8251f764736f6c63430008110033
Deployed Bytecode
0x6080604052600436106102045760003560e01c8063715018a611610118578063c87b56dd116100a0578063de7fcb1d1161006f578063de7fcb1d14610723578063e985e9c51461074e578063ec5a2d451461078b578063f2fde38b146107a2578063f51f96dd146107cb57610204565b8063c87b56dd14610676578063c9eb7060146106b3578063d2cab056146106f0578063d4e932921461070c57610204565b8063a22cb465116100e7578063a22cb465146105a5578063afdf6134146105ce578063b1c9fe6e146105f7578063b228d92514610622578063b88d4fde1461064d57610204565b8063715018a61461050f5780637cb64759146105265780638da5cb5b1461054f57806395d89b411461057a57610204565b80632eb4a7ab1161019b578063616cdb1e1161016a578063616cdb1e146104185780636352211e1461044157806363e547171461047e5780636c0360eb146104a757806370a08231146104d257610204565b80632eb4a7ab1461037057806332cb6b0c1461039b57806342842e0e146103c657806355f804b3146103ef57610204565b806318160ddd116101d757806318160ddd146102d75780631919fed71461030257806323b872dd1461032b5780632db115441461035457610204565b806301ffc9a71461020957806306fdde0314610246578063081812fc14610271578063095ea7b3146102ae575b600080fd5b34801561021557600080fd5b50610230600480360381019061022b919061286a565b6107f6565b60405161023d91906128b2565b60405180910390f35b34801561025257600080fd5b5061025b610888565b604051610268919061295d565b60405180910390f35b34801561027d57600080fd5b50610298600480360381019061029391906129b5565b61091a565b6040516102a59190612a23565b60405180910390f35b3480156102ba57600080fd5b506102d560048036038101906102d09190612a6a565b610996565b005b3480156102e357600080fd5b506102ec610b3c565b6040516102f99190612ab9565b60405180910390f35b34801561030e57600080fd5b50610329600480360381019061032491906129b5565b610b53565b005b34801561033757600080fd5b50610352600480360381019061034d9190612ad4565b610b65565b005b61036e600480360381019061036991906129b5565b610d4b565b005b34801561037c57600080fd5b50610385610d9c565b6040516103929190612b40565b60405180910390f35b3480156103a757600080fd5b506103b0610da2565b6040516103bd9190612ab9565b60405180910390f35b3480156103d257600080fd5b506103ed60048036038101906103e89190612ad4565b610da8565b005b3480156103fb57600080fd5b5061041660048036038101906104119190612c90565b610f8e565b005b34801561042457600080fd5b5061043f600480360381019061043a91906129b5565b610fa9565b005b34801561044d57600080fd5b50610468600480360381019061046391906129b5565b610fbb565b6040516104759190612a23565b60405180910390f35b34801561048a57600080fd5b506104a560048036038101906104a091906129b5565b610fcd565b005b3480156104b357600080fd5b506104bc61102f565b6040516104c9919061295d565b60405180910390f35b3480156104de57600080fd5b506104f960048036038101906104f49190612cd9565b6110bd565b6040516105069190612ab9565b60405180910390f35b34801561051b57600080fd5b50610524611151565b005b34801561053257600080fd5b5061054d60048036038101906105489190612d32565b611165565b005b34801561055b57600080fd5b50610564611177565b6040516105719190612a23565b60405180910390f35b34801561058657600080fd5b5061058f6111a1565b60405161059c919061295d565b60405180910390f35b3480156105b157600080fd5b506105cc60048036038101906105c79190612d8b565b611233565b005b3480156105da57600080fd5b506105f560048036038101906105f091906129b5565b6113aa565b005b34801561060357600080fd5b5061060c6113bc565b6040516106199190612ab9565b60405180910390f35b34801561062e57600080fd5b506106376113c2565b6040516106449190612ab9565b60405180910390f35b34801561065957600080fd5b50610674600480360381019061066f9190612e6c565b6113c8565b005b34801561068257600080fd5b5061069d600480360381019061069891906129b5565b6115b1565b6040516106aa919061295d565b60405180910390f35b3480156106bf57600080fd5b506106da60048036038101906106d59190612cd9565b611697565b6040516106e79190612ab9565b60405180910390f35b61070a60048036038101906107059190612fb7565b6116af565b005b34801561071857600080fd5b50610721611773565b005b34801561072f57600080fd5b506107386117ca565b6040516107459190612ab9565b60405180910390f35b34801561075a57600080fd5b5061077560048036038101906107709190613013565b6117d0565b60405161078291906128b2565b60405180910390f35b34801561079757600080fd5b506107a0611864565b005b3480156107ae57600080fd5b506107c960048036038101906107c49190612cd9565b611898565b005b3480156107d757600080fd5b506107e061191b565b6040516107ed9190612ab9565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061085157506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108815750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461089790613082565b80601f01602080910402602001604051908101604052809291908181526020018280546108c390613082565b80156109105780601f106108e557610100808354040283529160200191610910565b820191906000526020600020905b8154815290600101906020018083116108f357829003601f168201915b5050505050905090565b600061092582611921565b61095b576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109a182611980565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a08576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a27611a4c565b73ffffffffffffffffffffffffffffffffffffffff1614610a8a57610a5381610a4e611a4c565b6117d0565b610a89576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610b46611a54565b6001546000540303905090565b610b5b611a5d565b80600b8190555050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d39573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610bd757610bd2848484611adb565b610d45565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610c209291906130b3565b6020604051808303816000875af1158015610c3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6391906130f1565b8015610cf757506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610cb39291906130b3565b6020604051808303816000875af1158015610cd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf691906130f1565b5b610d3857336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d2f9190612a23565b60405180910390fd5b5b610d44848484611adb565b5b50505050565b600260095414610d90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d879061316a565b60405180910390fd5b610d9981611aeb565b50565b600a5481565b61037881565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610f7c573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e1a57610e15848484611cea565b610f88565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610e639291906130b3565b6020604051808303816000875af1158015610e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea691906130f1565b8015610f3a57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610ef69291906130b3565b6020604051808303816000875af1158015610f15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3991906130f1565b5b610f7b57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610f729190612a23565b60405180910390fd5b5b610f87848484611cea565b5b50505050565b610f96611a5d565b80600e9081610fa59190613336565b5050565b610fb1611a5d565b80600c8190555050565b6000610fc682611980565b9050919050565b610fd5611a5d565b60008110158015610fe65750600381105b611025576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101c90613454565b60405180910390fd5b8060098190555050565b600e805461103c90613082565b80601f016020809104026020016040519081016040528092919081815260200182805461106890613082565b80156110b55780601f1061108a576101008083540402835291602001916110b5565b820191906000526020600020905b81548152906001019060200180831161109857829003601f168201915b505050505081565b6000806110c983611d0a565b03611100576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611159611a5d565b6111636000611d14565b565b61116d611a5d565b80600a8190555050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546111b090613082565b80601f01602080910402602001604051908101604052809291908181526020018280546111dc90613082565b80156112295780601f106111fe57610100808354040283529160200191611229565b820191906000526020600020905b81548152906001019060200180831161120c57829003601f168201915b5050505050905090565b61123b611a4c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361129f576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006112ac611a4c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611359611a4c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161139e91906128b2565b60405180910390a35050565b6113b2611a5d565b80600d8190555050565b60095481565b600d5481565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561159d573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361143b5761143685858585611dda565b6115aa565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016114849291906130b3565b6020604051808303816000875af11580156114a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c791906130f1565b801561155b57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016115179291906130b3565b6020604051808303816000875af1158015611536573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155a91906130f1565b5b61159c57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016115939190612a23565b60405180910390fd5b5b6115a985858585611dda565b5b5050505050565b60606115bc82611921565b6115fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f2906134e6565b60405180910390fd5b600f60009054906101000a900460ff161561166e576000600e805461161f90613082565b90500361163b5760405180602001604052806000815250611667565b600e61164683611e4d565b6040516020016116579291906135c5565b6040516020818303038152906040525b9050611692565b600e60405160200161168091906135e9565b60405160208183030381529060405290505b919050565b60106020528060005260406000206000915090505481565b6001600954146116f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116eb9061364c565b60405180910390fd5b61172781600a543360405160200161170c91906136b4565b60405160208183030381529060405280519060200120611f1b565b611766576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161175d9061371b565b60405180910390fd5b61176f82611aeb565b5050565b61177b611a5d565b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156117c6573d6000803e3d6000fd5b5050565b600c5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61186c611a5d565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b6118a0611a5d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361190f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611906906137ad565b60405180910390fd5b61191881611d14565b50565b600b5481565b60008161192c611a54565b1115801561193b575060005482105b8015611979575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b6000808290508061198f611a54565b11611a1557600054811015611a145760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611a12575b60008103611a085760046000836001900393508381526020019081526020016000205490506119de565b8092505050611a47565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b60006001905090565b611a65611f32565b73ffffffffffffffffffffffffffffffffffffffff16611a83611177565b73ffffffffffffffffffffffffffffffffffffffff1614611ad9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ad090613819565b60405180910390fd5b565b611ae6838383611f3a565b505050565b600d548160106000611afb611f32565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611b409190613868565b1115611b81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b78906138e8565b60405180910390fd5b600c548111158015611b935750600081115b611bd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc990613954565b60405180910390fd5b610378611bdd610b3c565b82611be89190613868565b1115611c29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c20906139c0565b60405180910390fd5b80600b54611c3791906139e0565b341015611c79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7090613a6e565b60405180910390fd5b8060106000611c86611f32565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ccf9190613868565b92505081905550611ce7611ce1611f32565b826122ff565b50565b611d05838383604051806020016040528060008152506113c8565b505050565b6000819050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611de5848484611f3a565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611e4757611e10848484846124ad565b611e46576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b606060006001611e5c846125fd565b01905060008167ffffffffffffffff811115611e7b57611e7a612b65565b5b6040519080825280601f01601f191660200182016040528015611ead5781602001600182028036833780820191505090505b509050600082602001820190505b600115611f10578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611f0457611f03613a8e565b5b04945060008503611ebb575b819350505050919050565b600082611f288584612750565b1490509392505050565b600033905090565b6000611f4582611980565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611fac576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006006600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008573ffffffffffffffffffffffffffffffffffffffff16612005611a4c565b73ffffffffffffffffffffffffffffffffffffffff16148061203457506120338661202e611a4c565b6117d0565b5b806120715750612042611a4c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b9050806120aa576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006120b586611d0a565b036120ec576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120f986868660016127a6565b600061210483611d0a565b14612140576006600085815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b61220787611d0a565b1717600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361228f576000600185019050600060046000838152602001908152602001600020540361228d57600054811461228c578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46122f786868660016127ac565b505050505050565b600080549050600061231084611d0a565b03612347576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612381576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61238e60008483856127a6565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16123f3600184146127b2565b901b60a042901b61240385611d0a565b171760046000838152602001908152602001600020819055506000819050600083820190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612429578160008190555050506124a860008483856127ac565b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026124d3611a4c565b8786866040518563ffffffff1660e01b81526004016124f59493929190613b12565b6020604051808303816000875af192505050801561253157506040513d601f19601f8201168201806040525081019061252e9190613b73565b60015b6125aa573d8060008114612561576040519150601f19603f3d011682016040523d82523d6000602084013e612566565b606091505b5060008151036125a2576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061265b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161265157612650613a8e565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612698576d04ee2d6d415b85acef8100000000838161268e5761268d613a8e565b5b0492506020810190505b662386f26fc1000083106126c757662386f26fc1000083816126bd576126bc613a8e565b5b0492506010810190505b6305f5e10083106126f0576305f5e10083816126e6576126e5613a8e565b5b0492506008810190505b612710831061271557612710838161270b5761270a613a8e565b5b0492506004810190505b60648310612738576064838161272e5761272d613a8e565b5b0492506002810190505b600a8310612747576001810190505b80915050919050565b60008082905060005b845181101561279b576127868286838151811061277957612778613ba0565b5b60200260200101516127bc565b9150808061279390613bcf565b915050612759565b508091505092915050565b50505050565b50505050565b6000819050919050565b60008183106127d4576127cf82846127e7565b6127df565b6127de83836127e7565b5b905092915050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61284781612812565b811461285257600080fd5b50565b6000813590506128648161283e565b92915050565b6000602082840312156128805761287f612808565b5b600061288e84828501612855565b91505092915050565b60008115159050919050565b6128ac81612897565b82525050565b60006020820190506128c760008301846128a3565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156129075780820151818401526020810190506128ec565b60008484015250505050565b6000601f19601f8301169050919050565b600061292f826128cd565b61293981856128d8565b93506129498185602086016128e9565b61295281612913565b840191505092915050565b600060208201905081810360008301526129778184612924565b905092915050565b6000819050919050565b6129928161297f565b811461299d57600080fd5b50565b6000813590506129af81612989565b92915050565b6000602082840312156129cb576129ca612808565b5b60006129d9848285016129a0565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612a0d826129e2565b9050919050565b612a1d81612a02565b82525050565b6000602082019050612a386000830184612a14565b92915050565b612a4781612a02565b8114612a5257600080fd5b50565b600081359050612a6481612a3e565b92915050565b60008060408385031215612a8157612a80612808565b5b6000612a8f85828601612a55565b9250506020612aa0858286016129a0565b9150509250929050565b612ab38161297f565b82525050565b6000602082019050612ace6000830184612aaa565b92915050565b600080600060608486031215612aed57612aec612808565b5b6000612afb86828701612a55565b9350506020612b0c86828701612a55565b9250506040612b1d868287016129a0565b9150509250925092565b6000819050919050565b612b3a81612b27565b82525050565b6000602082019050612b556000830184612b31565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612b9d82612913565b810181811067ffffffffffffffff82111715612bbc57612bbb612b65565b5b80604052505050565b6000612bcf6127fe565b9050612bdb8282612b94565b919050565b600067ffffffffffffffff821115612bfb57612bfa612b65565b5b612c0482612913565b9050602081019050919050565b82818337600083830152505050565b6000612c33612c2e84612be0565b612bc5565b905082815260208101848484011115612c4f57612c4e612b60565b5b612c5a848285612c11565b509392505050565b600082601f830112612c7757612c76612b5b565b5b8135612c87848260208601612c20565b91505092915050565b600060208284031215612ca657612ca5612808565b5b600082013567ffffffffffffffff811115612cc457612cc361280d565b5b612cd084828501612c62565b91505092915050565b600060208284031215612cef57612cee612808565b5b6000612cfd84828501612a55565b91505092915050565b612d0f81612b27565b8114612d1a57600080fd5b50565b600081359050612d2c81612d06565b92915050565b600060208284031215612d4857612d47612808565b5b6000612d5684828501612d1d565b91505092915050565b612d6881612897565b8114612d7357600080fd5b50565b600081359050612d8581612d5f565b92915050565b60008060408385031215612da257612da1612808565b5b6000612db085828601612a55565b9250506020612dc185828601612d76565b9150509250929050565b600067ffffffffffffffff821115612de657612de5612b65565b5b612def82612913565b9050602081019050919050565b6000612e0f612e0a84612dcb565b612bc5565b905082815260208101848484011115612e2b57612e2a612b60565b5b612e36848285612c11565b509392505050565b600082601f830112612e5357612e52612b5b565b5b8135612e63848260208601612dfc565b91505092915050565b60008060008060808587031215612e8657612e85612808565b5b6000612e9487828801612a55565b9450506020612ea587828801612a55565b9350506040612eb6878288016129a0565b925050606085013567ffffffffffffffff811115612ed757612ed661280d565b5b612ee387828801612e3e565b91505092959194509250565b600067ffffffffffffffff821115612f0a57612f09612b65565b5b602082029050602081019050919050565b600080fd5b6000612f33612f2e84612eef565b612bc5565b90508083825260208201905060208402830185811115612f5657612f55612f1b565b5b835b81811015612f7f5780612f6b8882612d1d565b845260208401935050602081019050612f58565b5050509392505050565b600082601f830112612f9e57612f9d612b5b565b5b8135612fae848260208601612f20565b91505092915050565b60008060408385031215612fce57612fcd612808565b5b6000612fdc858286016129a0565b925050602083013567ffffffffffffffff811115612ffd57612ffc61280d565b5b61300985828601612f89565b9150509250929050565b6000806040838503121561302a57613029612808565b5b600061303885828601612a55565b925050602061304985828601612a55565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061309a57607f821691505b6020821081036130ad576130ac613053565b5b50919050565b60006040820190506130c86000830185612a14565b6130d56020830184612a14565b9392505050565b6000815190506130eb81612d5f565b92915050565b60006020828403121561310757613106612808565b5b6000613115848285016130dc565b91505092915050565b7f5075626c69632053616c657320697320636c6f73652e00000000000000000000600082015250565b60006131546016836128d8565b915061315f8261311e565b602082019050919050565b6000602082019050818103600083015261318381613147565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026131ec7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826131af565b6131f686836131af565b95508019841693508086168417925050509392505050565b6000819050919050565b600061323361322e6132298461297f565b61320e565b61297f565b9050919050565b6000819050919050565b61324d83613218565b6132616132598261323a565b8484546131bc565b825550505050565b600090565b613276613269565b613281818484613244565b505050565b5b818110156132a55761329a60008261326e565b600181019050613287565b5050565b601f8211156132ea576132bb8161318a565b6132c48461319f565b810160208510156132d3578190505b6132e76132df8561319f565b830182613286565b50505b505050565b600082821c905092915050565b600061330d600019846008026132ef565b1980831691505092915050565b600061332683836132fc565b9150826002028217905092915050565b61333f826128cd565b67ffffffffffffffff81111561335857613357612b65565b5b6133628254613082565b61336d8282856132a9565b600060209050601f8311600181146133a0576000841561338e578287015190505b613398858261331a565b865550613400565b601f1984166133ae8661318a565b60005b828110156133d6578489015182556001820191506020850194506020810190506133b1565b868310156133f357848901516133ef601f8916826132fc565b8355505b6001600288020188555050505b505050505050565b7f5068617365206f7574206f662072616e67652030202d20320000000000000000600082015250565b600061343e6018836128d8565b915061344982613408565b602082019050919050565b6000602082019050818103600083015261346d81613431565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006134d0602f836128d8565b91506134db82613474565b604082019050919050565b600060208201905081810360008301526134ff816134c3565b9050919050565b600081905092915050565b6000815461351e81613082565b6135288186613506565b9450600182166000811461354357600181146135585761358b565b60ff198316865281151582028601935061358b565b6135618561318a565b60005b8381101561358357815481890152600182019150602081019050613564565b838801955050505b50505092915050565b600061359f826128cd565b6135a98185613506565b93506135b98185602086016128e9565b80840191505092915050565b60006135d18285613511565b91506135dd8284613594565b91508190509392505050565b60006135f58284613511565b915081905092915050565b7f77686974656c69737420697320636c6f73652e00000000000000000000000000600082015250565b60006136366013836128d8565b915061364182613600565b602082019050919050565b6000602082019050818103600083015261366581613629565b9050919050565b60008160601b9050919050565b60006136848261366c565b9050919050565b600061369682613679565b9050919050565b6136ae6136a982612a02565b61368b565b82525050565b60006136c0828461369d565b60148201915081905092915050565b7f4e6f742077686974656c69737465642e00000000000000000000000000000000600082015250565b60006137056010836128d8565b9150613710826136cf565b602082019050919050565b60006020820190508181036000830152613734816136f8565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006137976026836128d8565b91506137a28261373b565b604082019050919050565b600060208201905081810360008301526137c68161378a565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006138036020836128d8565b915061380e826137cd565b602082019050919050565b60006020820190508181036000830152613832816137f6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138738261297f565b915061387e8361297f565b925082820190508082111561389657613895613839565b5b92915050565b7f4163636f756e74207265616368656420746865206d6178206d696e742e000000600082015250565b60006138d2601d836128d8565b91506138dd8261389c565b602082019050919050565b60006020820190508181036000830152613901816138c5565b9050919050565b7f4d61782074776f20706572207472616e73616374696f6e2e0000000000000000600082015250565b600061393e6018836128d8565b915061394982613908565b602082019050919050565b6000602082019050818103600083015261396d81613931565b9050919050565b7f546f74616c20536f6c64206f7574000000000000000000000000000000000000600082015250565b60006139aa600e836128d8565b91506139b582613974565b602082019050919050565b600060208201905081810360008301526139d98161399d565b9050919050565b60006139eb8261297f565b91506139f68361297f565b9250828202613a048161297f565b91508282048414831517613a1b57613a1a613839565b5b5092915050565b7f4e6f7420656e6f7567682045544820746f206d696e7400000000000000000000600082015250565b6000613a586016836128d8565b9150613a6382613a22565b602082019050919050565b60006020820190508181036000830152613a8781613a4b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000613ae482613abd565b613aee8185613ac8565b9350613afe8185602086016128e9565b613b0781612913565b840191505092915050565b6000608082019050613b276000830187612a14565b613b346020830186612a14565b613b416040830185612aaa565b8181036060830152613b538184613ad9565b905095945050505050565b600081519050613b6d8161283e565b92915050565b600060208284031215613b8957613b88612808565b5b6000613b9784828501613b5e565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000613bda8261297f565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613c0c57613c0b613839565b5b60018201905091905056fea26469706673582212207ae8eff1b6ad496fea5f7b4661e7099b0dadb1a63027e59468c88bd57d8251f764736f6c63430008110033
Deployed Bytecode Sourcemap
71888:4274:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46207:615;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51230:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53298:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52758:474;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45261:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74275:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75613:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72985:143;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72080:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71998:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75784:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74562:90;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73924:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51019:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74708:183;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72241:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46886:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32335:103;;;;;;;;;;;;;:::i;:::-;;73751:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31687:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51399:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53574:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74096:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72047:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72193:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75963:196;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74943:454;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72307:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72628:303;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75454:147;;;;;;;;;;;;;:::i;:::-;;72155:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53953:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74430:78;;;;;;;;;;;;;:::i;:::-;;32593:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72114:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46207:615;46292:4;46607:10;46592:25;;:11;:25;;;;:102;;;;46684:10;46669:25;;:11;:25;;;;46592:102;:179;;;;46761:10;46746:25;;:11;:25;;;;46592:179;46572:199;;46207:615;;;:::o;51230:100::-;51284:13;51317:5;51310:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51230:100;:::o;53298:204::-;53366:7;53391:16;53399:7;53391;:16::i;:::-;53386:64;;53416:34;;;;;;;;;;;;;;53386:64;53470:15;:24;53486:7;53470:24;;;;;;;;;;;;;;;;;;;;;53463:31;;53298:204;;;:::o;52758:474::-;52831:13;52863:27;52882:7;52863:18;:27::i;:::-;52831:61;;52913:5;52907:11;;:2;:11;;;52903:48;;52927:24;;;;;;;;;;;;;;52903:48;52991:5;52968:28;;:19;:17;:19::i;:::-;:28;;;52964:175;;53016:44;53033:5;53040:19;:17;:19::i;:::-;53016:16;:44::i;:::-;53011:128;;53088:35;;;;;;;;;;;;;;53011:128;52964:175;53178:2;53151:15;:24;53167:7;53151:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;53216:7;53212:2;53196:28;;53205:5;53196:28;;;;;;;;;;;;52820:412;52758:474;;:::o;45261:315::-;45314:7;45542:15;:13;:15::i;:::-;45527:12;;45511:13;;:28;:46;45504:53;;45261:315;:::o;74275:102::-;31573:13;:11;:13::i;:::-;74359:10:::1;74347:9;:22;;;;74275:102:::0;:::o;75613:163::-;75714:4;3719:1;2399:42;3673:43;;;:47;3669:789;;;3960:10;3952:18;;:4;:18;;;3948:85;;75731:37:::1;75750:4;75756:2;75760:7;75731:18;:37::i;:::-;4011:7:::0;;3948:85;2399:42;4071:40;;;4142:4;4170:10;4071:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:287;;;;;2399:42;4224:40;;;4299:4;4331;4224:134;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4071:287;4047:400;;4420:10;4401:30;;;;;;;;;;;:::i;:::-;;;;;;;;4047:400;3669:789;75731:37:::1;75750:4;75756:2;75760:7;75731:18;:37::i;:::-;75613:163:::0;;;;;:::o;72985:143::-;73065:1;73056:5;;:10;73048:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;73105:15;73111:8;73105:5;:15::i;:::-;72985:143;:::o;72080:25::-;;;;:::o;71998:40::-;72035:3;71998:40;:::o;75784:171::-;75889:4;3719:1;2399:42;3673:43;;;:47;3669:789;;;3960:10;3952:18;;:4;:18;;;3948:85;;75906:41:::1;75929:4;75935:2;75939:7;75906:22;:41::i;:::-;4011:7:::0;;3948:85;2399:42;4071:40;;;4142:4;4170:10;4071:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:287;;;;;2399:42;4224:40;;;4299:4;4331;4224:134;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4071:287;4047:400;;4420:10;4401:30;;;;;;;;;;;:::i;:::-;;;;;;;;4047:400;3669:789;75906:41:::1;75929:4;75935:2;75939:7;75906:22;:41::i;:::-;75784:171:::0;;;;;:::o;74562:90::-;31573:13;:11;:13::i;:::-;74641:3:::1;74631:7;:13;;;;;;:::i;:::-;;74562:90:::0;:::o;73924:106::-;31573:13;:11;:13::i;:::-;74013:9:::1;73998:12;:24;;;;73924:106:::0;:::o;51019:144::-;51083:7;51126:27;51145:7;51126:18;:27::i;:::-;51103:52;;51019:144;;;:::o;74708:183::-;31573:13;:11;:13::i;:::-;74803:1:::1;74788:11;:16;;:35;;;;;74822:1;74808:11;:15;74788:35;74780:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;74872:11;74864:5;:19;;;;74708:183:::0;:::o;72241:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;46886:234::-;46950:7;47002:1;46974:24;46992:5;46974:17;:24::i;:::-;:29;46970:70;;47012:28;;;;;;;;;;;;;;46970:70;42225:13;47058:18;:25;47077:5;47058:25;;;;;;;;;;;;;;;;:54;47051:61;;46886:234;;;:::o;32335:103::-;31573:13;:11;:13::i;:::-;32400:30:::1;32427:1;32400:18;:30::i;:::-;32335:103::o:0;73751:102::-;31573:13;:11;:13::i;:::-;73836:9:::1;73823:10;:22;;;;73751:102:::0;:::o;31687:87::-;31733:7;31760:6;;;;;;;;;;;31753:13;;31687:87;:::o;51399:104::-;51455:13;51488:7;51481:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51399:104;:::o;53574:308::-;53685:19;:17;:19::i;:::-;53673:31;;:8;:31;;;53669:61;;53713:17;;;;;;;;;;;;;;53669:61;53795:8;53743:18;:39;53762:19;:17;:19::i;:::-;53743:39;;;;;;;;;;;;;;;:49;53783:8;53743:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;53855:8;53819:55;;53834:19;:17;:19::i;:::-;53819:55;;;53865:8;53819:55;;;;;;:::i;:::-;;;;;;;;53574:308;;:::o;74096:118::-;31573:13;:11;:13::i;:::-;74195:11:::1;74176:16;:30;;;;74096:118:::0;:::o;72047:24::-;;;;:::o;72193:35::-;;;;:::o;75963:196::-;76087:4;3719:1;2399:42;3673:43;;;:47;3669:789;;;3960:10;3952:18;;:4;:18;;;3948:85;;76104:47:::1;76127:4;76133:2;76137:7;76146:4;76104:22;:47::i;:::-;4011:7:::0;;3948:85;2399:42;4071:40;;;4142:4;4170:10;4071:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:287;;;;;2399:42;4224:40;;;4299:4;4331;4224:134;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4071:287;4047:400;;4420:10;4401:30;;;;;;;;;;;:::i;:::-;;;;;;;;4047:400;3669:789;76104:47:::1;76127:4;76133:2;76137:7;76146:4;76104:22;:47::i;:::-;75963:196:::0;;;;;;:::o;74943:454::-;75062:13;75101:17;75109:8;75101:7;:17::i;:::-;75093:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;75187:6;;;;;;;;;;;75183:207;;;75242:1;75223:7;75217:21;;;;;:::i;:::-;;;:26;:88;;;;;;;;;;;;;;;;;75270:7;75279:19;:8;:17;:19::i;:::-;75253:46;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75217:88;75210:95;;;;75183:207;75369:7;75352:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;75338:40;;74943:454;;;;:::o;72307:45::-;;;;;;;;;;;;;;;;;:::o;72628:303::-;72735:1;72726:5;;:10;72718:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;72781:78;72800:5;72807:10;;72846;72829:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;72819:39;;;;;;72781:18;:78::i;:::-;72773:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;72908:15;72914:8;72908:5;:15::i;:::-;72628:303;;:::o;75454:147::-;31573:13;:11;:13::i;:::-;75506:15:::1;75524:21;75506:39;;75564:10;75556:28;;:37;75585:7;75556:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;75495:106;75454:147::o:0;72155:31::-;;;;:::o;53953:164::-;54050:4;54074:18;:25;54093:5;54074:25;;;;;;;;;;;;;;;:35;54100:8;54074:35;;;;;;;;;;;;;;;;;;;;;;;;;54067:42;;53953:164;;;;:::o;74430:78::-;31573:13;:11;:13::i;:::-;74494:6:::1;;;;;;;;;;;74493:7;74484:6;;:16;;;;;;;;;;;;;;;;;;74430:78::o:0;32593:201::-;31573:13;:11;:13::i;:::-;32702:1:::1;32682:22;;:8;:22;;::::0;32674:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;32758:28;32777:8;32758:18;:28::i;:::-;32593:201:::0;:::o;72114:34::-;;;;:::o;55332:273::-;55389:4;55445:7;55426:15;:13;:15::i;:::-;:26;;:66;;;;;55479:13;;55469:7;:23;55426:66;:152;;;;;55577:1;42995:8;55530:17;:26;55548:7;55530:26;;;;;;;;;;;;:43;:48;55426:152;55406:172;;55332:273;;;:::o;48534:1129::-;48601:7;48621:12;48636:7;48621:22;;48704:4;48685:15;:13;:15::i;:::-;:23;48681:915;;48738:13;;48731:4;:20;48727:869;;;48776:14;48793:17;:23;48811:4;48793:23;;;;;;;;;;;;48776:40;;48909:1;42995:8;48882:6;:23;:28;48878:699;;49401:113;49418:1;49408:6;:11;49401:113;;49461:17;:25;49479:6;;;;;;;49461:25;;;;;;;;;;;;49452:34;;49401:113;;;49547:6;49540:13;;;;;;48878:699;48753:843;48727:869;48681:915;49624:31;;;;;;;;;;;;;;48534:1129;;;;:::o;69600:105::-;69660:7;69687:10;69680:17;;69600:105;:::o;72470:101::-;72535:7;72562:1;72555:8;;72470:101;:::o;31852:132::-;31927:12;:10;:12::i;:::-;31916:23;;:7;:5;:7::i;:::-;:23;;;31908:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;31852:132::o;54184:170::-;54318:28;54328:4;54334:2;54338:7;54318:9;:28::i;:::-;54184:170;;;:::o;73175:508::-;73275:16;;73263:8;73233:13;:27;73247:12;:10;:12::i;:::-;73233:27;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;:58;;73225:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;73358:12;;73346:8;:24;;:40;;;;;73385:1;73374:8;:12;73346:40;73338:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;72035:3;73447:13;:11;:13::i;:::-;73436:8;:24;;;;:::i;:::-;:38;;73428:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;73539:8;73527:9;;:20;;;;:::i;:::-;73514:9;:33;;73506:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;73618:8;73587:13;:27;73601:12;:10;:12::i;:::-;73587:27;;;;;;;;;;;;;;;;:39;;;;;;;:::i;:::-;;;;;;;;73646:29;73652:12;:10;:12::i;:::-;73666:8;73646:5;:29::i;:::-;73175:508;:::o;54425:185::-;54563:39;54580:4;54586:2;54590:7;54563:39;;;;;;;;;;;;:16;:39::i;:::-;54425:185;;;:::o;52319:148::-;52383:14;52444:5;52434:15;;52319:148;;;:::o;32954:191::-;33028:16;33047:6;;;;;;;;;;;33028:25;;33073:8;33064:6;;:17;;;;;;;;;;;;;;;;;;33128:8;33097:40;;33118:8;33097:40;;;;;;;;;;;;33017:128;32954:191;:::o;54681:396::-;54848:28;54858:4;54864:2;54868:7;54848:9;:28::i;:::-;54909:1;54891:2;:14;;;:19;54887:183;;54930:56;54961:4;54967:2;54971:7;54980:5;54930:30;:56::i;:::-;54925:145;;55014:40;;;;;;;;;;;;;;54925:145;54887:183;54681:396;;;;:::o;27665:716::-;27721:13;27772:14;27809:1;27789:17;27800:5;27789:10;:17::i;:::-;:21;27772:38;;27825:20;27859:6;27848:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27825:41;;27881:11;28010:6;28006:2;28002:15;27994:6;27990:28;27983:35;;28047:288;28054:4;28047:288;;;28079:5;;;;;;;;28221:8;28216:2;28209:5;28205:14;28200:30;28195:3;28187:44;28277:2;28268:11;;;;;;:::i;:::-;;;;;28311:1;28302:5;:10;28047:288;28298:21;28047:288;28356:6;28349:13;;;;;27665:716;;;:::o;6021:190::-;6146:4;6199;6170:25;6183:5;6190:4;6170:12;:25::i;:::-;:33;6163:40;;6021:190;;;;;:::o;30238:98::-;30291:7;30318:10;30311:17;;30238:98;:::o;60591:2654::-;60706:27;60736;60755:7;60736:18;:27::i;:::-;60706:57;;60821:4;60780:45;;60796:19;60780:45;;;60776:86;;60834:28;;;;;;;;;;;;;;60776:86;60875:23;60901:15;:24;60917:7;60901:24;;;;;;;;;;;;;;;;;;;;;60875:50;;60938:22;60987:4;60964:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;61008:43;61025:4;61031:19;:17;:19::i;:::-;61008:16;:43::i;:::-;60964:87;:142;;;;61087:19;:17;:19::i;:::-;61068:38;;:15;:38;;;60964:142;60938:169;;61125:17;61120:66;;61151:35;;;;;;;;;;;;;;61120:66;61226:1;61201:21;61219:2;61201:17;:21::i;:::-;:26;61197:62;;61236:23;;;;;;;;;;;;;;61197:62;61272:43;61294:4;61300:2;61304:7;61313:1;61272:21;:43::i;:::-;61423:1;61385:34;61403:15;61385:17;:34::i;:::-;:39;61381:103;;61448:15;:24;61464:7;61448:24;;;;;;;;;;;;61441:31;;;;;;;;;;;61381:103;61851:18;:24;61870:4;61851:24;;;;;;;;;;;;;;;;61849:26;;;;;;;;;;;;61920:18;:22;61939:2;61920:22;;;;;;;;;;;;;;;;61918:24;;;;;;;;;;;43277:8;42879:3;62301:15;:41;;62259:21;62277:2;62259:17;:21::i;:::-;:84;:128;62213:17;:26;62231:7;62213:26;;;;;;;;;;;:174;;;;62557:1;43277:8;62507:19;:46;:51;62503:626;;62579:19;62611:1;62601:7;:11;62579:33;;62768:1;62734:17;:30;62752:11;62734:30;;;;;;;;;;;;:35;62730:384;;62872:13;;62857:11;:28;62853:242;;63052:19;63019:17;:30;63037:11;63019:30;;;;;;;;;;;:52;;;;62853:242;62730:384;62560:569;62503:626;63176:7;63172:2;63157:27;;63166:4;63157:27;;;;;;;;;;;;63195:42;63216:4;63222:2;63226:7;63235:1;63195:20;:42::i;:::-;60695:2550;;;60591:2654;;;:::o;58671:1666::-;58736:20;58759:13;;58736:36;;58812:1;58787:21;58805:2;58787:17;:21::i;:::-;:26;58783:58;;58822:19;;;;;;;;;;;;;;58783:58;58868:1;58856:8;:13;58852:44;;58878:18;;;;;;;;;;;;;;58852:44;58909:61;58939:1;58943:2;58947:12;58961:8;58909:21;:61::i;:::-;59513:1;42362:2;59484:1;:25;;59483:31;59471:8;:44;59445:18;:22;59464:2;59445:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;43142:3;59914:29;59941:1;59929:8;:13;59914:14;:29::i;:::-;:56;;42879:3;59851:15;:41;;59809:21;59827:2;59809:17;:21::i;:::-;:84;:162;59758:17;:31;59776:12;59758:31;;;;;;;;;;;:213;;;;59988:20;60011:12;59988:35;;60038:11;60067:8;60052:12;:23;60038:37;;60092:111;60144:14;;;;;;60140:2;60119:40;;60136:1;60119:40;;;;;;;;;;;;60198:3;60183:12;:18;60092:111;;60235:12;60219:13;:28;;;;59222:1037;;60269:60;60298:1;60302:2;60306:12;60320:8;60269:20;:60::i;:::-;58725:1612;58671:1666;;:::o;67069:716::-;67232:4;67278:2;67253:45;;;67299:19;:17;:19::i;:::-;67320:4;67326:7;67335:5;67253:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;67249:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67553:1;67536:6;:13;:18;67532:235;;67582:40;;;;;;;;;;;;;;67532:235;67725:6;67719:13;67710:6;67706:2;67702:15;67695:38;67249:529;67422:54;;;67412:64;;;:6;:64;;;;67405:71;;;67069:716;;;;;;:::o;24531:922::-;24584:7;24604:14;24621:1;24604:18;;24671:6;24662:5;:15;24658:102;;24707:6;24698:15;;;;;;:::i;:::-;;;;;24742:2;24732:12;;;;24658:102;24787:6;24778:5;:15;24774:102;;24823:6;24814:15;;;;;;:::i;:::-;;;;;24858:2;24848:12;;;;24774:102;24903:6;24894:5;:15;24890:102;;24939:6;24930:15;;;;;;:::i;:::-;;;;;24974:2;24964:12;;;;24890:102;25019:5;25010;:14;25006:99;;25054:5;25045:14;;;;;;:::i;:::-;;;;;25088:1;25078:11;;;;25006:99;25132:5;25123;:14;25119:99;;25167:5;25158:14;;;;;;:::i;:::-;;;;;25201:1;25191:11;;;;25119:99;25245:5;25236;:14;25232:99;;25280:5;25271:14;;;;;;:::i;:::-;;;;;25314:1;25304:11;;;;25232:99;25358:5;25349;:14;25345:66;;25394:1;25384:11;;;;25345:66;25439:6;25432:13;;;24531:922;;;:::o;6888:296::-;6971:7;6991:20;7014:4;6991:27;;7034:9;7029:118;7053:5;:12;7049:1;:16;7029:118;;;7102:33;7112:12;7126:5;7132:1;7126:8;;;;;;;;:::i;:::-;;;;;;;;7102:9;:33::i;:::-;7087:48;;7067:3;;;;;:::i;:::-;;;;7029:118;;;;7164:12;7157:19;;;6888:296;;;;:::o;68433:159::-;;;;;:::o;69251:158::-;;;;;:::o;52554:142::-;52612:14;52673:5;52663:15;;52554:142;;;:::o;13928:149::-;13991:7;14022:1;14018;:5;:51;;14049:20;14064:1;14067;14049:14;:20::i;:::-;14018:51;;;14026:20;14041:1;14044;14026:14;:20::i;:::-;14018:51;14011:58;;13928:149;;;;:::o;14085:268::-;14153:13;14260:1;14254:4;14247:15;14289:1;14283:4;14276:15;14330:4;14324;14314:21;14305:30;;14085:268;;;;:::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:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:77::-;5904:7;5933:5;5922:16;;5867:77;;;:::o;5950:118::-;6037:24;6055:5;6037:24;:::i;:::-;6032:3;6025:37;5950:118;;:::o;6074:222::-;6167:4;6205:2;6194:9;6190:18;6182:26;;6218:71;6286:1;6275:9;6271:17;6262:6;6218:71;:::i;:::-;6074:222;;;;:::o;6302:117::-;6411:1;6408;6401:12;6425:117;6534:1;6531;6524:12;6548:180;6596:77;6593:1;6586:88;6693:4;6690:1;6683:15;6717:4;6714:1;6707:15;6734:281;6817:27;6839:4;6817:27;:::i;:::-;6809:6;6805:40;6947:6;6935:10;6932:22;6911:18;6899:10;6896:34;6893:62;6890:88;;;6958:18;;:::i;:::-;6890:88;6998:10;6994:2;6987:22;6777:238;6734:281;;:::o;7021:129::-;7055:6;7082:20;;:::i;:::-;7072:30;;7111:33;7139:4;7131:6;7111:33;:::i;:::-;7021:129;;;:::o;7156:308::-;7218:4;7308:18;7300:6;7297:30;7294:56;;;7330:18;;:::i;:::-;7294:56;7368:29;7390:6;7368:29;:::i;:::-;7360:37;;7452:4;7446;7442:15;7434:23;;7156:308;;;:::o;7470:146::-;7567:6;7562:3;7557;7544:30;7608:1;7599:6;7594:3;7590:16;7583:27;7470:146;;;:::o;7622:425::-;7700:5;7725:66;7741:49;7783:6;7741:49;:::i;:::-;7725:66;:::i;:::-;7716:75;;7814:6;7807:5;7800:21;7852:4;7845:5;7841:16;7890:3;7881:6;7876:3;7872:16;7869:25;7866:112;;;7897:79;;:::i;:::-;7866:112;7987:54;8034:6;8029:3;8024;7987:54;:::i;:::-;7706:341;7622:425;;;;;:::o;8067:340::-;8123:5;8172:3;8165:4;8157:6;8153:17;8149:27;8139:122;;8180:79;;:::i;:::-;8139:122;8297:6;8284:20;8322:79;8397:3;8389:6;8382:4;8374:6;8370:17;8322:79;:::i;:::-;8313:88;;8129:278;8067:340;;;;:::o;8413:509::-;8482:6;8531:2;8519:9;8510:7;8506:23;8502:32;8499:119;;;8537:79;;:::i;:::-;8499:119;8685:1;8674:9;8670:17;8657:31;8715:18;8707:6;8704:30;8701:117;;;8737:79;;:::i;:::-;8701:117;8842:63;8897:7;8888:6;8877:9;8873:22;8842:63;:::i;:::-;8832:73;;8628:287;8413:509;;;;:::o;8928:329::-;8987:6;9036:2;9024:9;9015:7;9011:23;9007:32;9004:119;;;9042:79;;:::i;:::-;9004:119;9162:1;9187:53;9232:7;9223:6;9212:9;9208:22;9187:53;:::i;:::-;9177:63;;9133:117;8928:329;;;;:::o;9263:122::-;9336:24;9354:5;9336:24;:::i;:::-;9329:5;9326:35;9316:63;;9375:1;9372;9365:12;9316:63;9263:122;:::o;9391:139::-;9437:5;9475:6;9462:20;9453:29;;9491:33;9518:5;9491:33;:::i;:::-;9391:139;;;;:::o;9536:329::-;9595:6;9644:2;9632:9;9623:7;9619:23;9615:32;9612:119;;;9650:79;;:::i;:::-;9612:119;9770:1;9795:53;9840:7;9831:6;9820:9;9816:22;9795:53;:::i;:::-;9785:63;;9741:117;9536:329;;;;:::o;9871:116::-;9941:21;9956:5;9941:21;:::i;:::-;9934:5;9931:32;9921:60;;9977:1;9974;9967:12;9921:60;9871:116;:::o;9993:133::-;10036:5;10074:6;10061:20;10052:29;;10090:30;10114:5;10090:30;:::i;:::-;9993:133;;;;:::o;10132:468::-;10197:6;10205;10254:2;10242:9;10233:7;10229:23;10225:32;10222:119;;;10260:79;;:::i;:::-;10222:119;10380:1;10405:53;10450:7;10441:6;10430:9;10426:22;10405:53;:::i;:::-;10395:63;;10351:117;10507:2;10533:50;10575:7;10566:6;10555:9;10551:22;10533:50;:::i;:::-;10523:60;;10478:115;10132:468;;;;;:::o;10606:307::-;10667:4;10757:18;10749:6;10746:30;10743:56;;;10779:18;;:::i;:::-;10743:56;10817:29;10839:6;10817:29;:::i;:::-;10809:37;;10901:4;10895;10891:15;10883:23;;10606:307;;;:::o;10919:423::-;10996:5;11021:65;11037:48;11078:6;11037:48;:::i;:::-;11021:65;:::i;:::-;11012:74;;11109:6;11102:5;11095:21;11147:4;11140:5;11136:16;11185:3;11176:6;11171:3;11167:16;11164:25;11161:112;;;11192:79;;:::i;:::-;11161:112;11282:54;11329:6;11324:3;11319;11282:54;:::i;:::-;11002:340;10919:423;;;;;:::o;11361:338::-;11416:5;11465:3;11458:4;11450:6;11446:17;11442:27;11432:122;;11473:79;;:::i;:::-;11432:122;11590:6;11577:20;11615:78;11689:3;11681:6;11674:4;11666:6;11662:17;11615:78;:::i;:::-;11606:87;;11422:277;11361:338;;;;:::o;11705:943::-;11800:6;11808;11816;11824;11873:3;11861:9;11852:7;11848:23;11844:33;11841:120;;;11880:79;;:::i;:::-;11841:120;12000:1;12025:53;12070:7;12061:6;12050:9;12046:22;12025:53;:::i;:::-;12015:63;;11971:117;12127:2;12153:53;12198:7;12189:6;12178:9;12174:22;12153:53;:::i;:::-;12143:63;;12098:118;12255:2;12281:53;12326:7;12317:6;12306:9;12302:22;12281:53;:::i;:::-;12271:63;;12226:118;12411:2;12400:9;12396:18;12383:32;12442:18;12434:6;12431:30;12428:117;;;12464:79;;:::i;:::-;12428:117;12569:62;12623:7;12614:6;12603:9;12599:22;12569:62;:::i;:::-;12559:72;;12354:287;11705:943;;;;;;;:::o;12654:311::-;12731:4;12821:18;12813:6;12810:30;12807:56;;;12843:18;;:::i;:::-;12807:56;12893:4;12885:6;12881:17;12873:25;;12953:4;12947;12943:15;12935:23;;12654:311;;;:::o;12971:117::-;13080:1;13077;13070:12;13111:710;13207:5;13232:81;13248:64;13305:6;13248:64;:::i;:::-;13232:81;:::i;:::-;13223:90;;13333:5;13362:6;13355:5;13348:21;13396:4;13389:5;13385:16;13378:23;;13449:4;13441:6;13437:17;13429:6;13425:30;13478:3;13470:6;13467:15;13464:122;;;13497:79;;:::i;:::-;13464:122;13612:6;13595:220;13629:6;13624:3;13621:15;13595:220;;;13704:3;13733:37;13766:3;13754:10;13733:37;:::i;:::-;13728:3;13721:50;13800:4;13795:3;13791:14;13784:21;;13671:144;13655:4;13650:3;13646:14;13639:21;;13595:220;;;13599:21;13213:608;;13111:710;;;;;:::o;13844:370::-;13915:5;13964:3;13957:4;13949:6;13945:17;13941:27;13931:122;;13972:79;;:::i;:::-;13931:122;14089:6;14076:20;14114:94;14204:3;14196:6;14189:4;14181:6;14177:17;14114:94;:::i;:::-;14105:103;;13921:293;13844:370;;;;:::o;14220:684::-;14313:6;14321;14370:2;14358:9;14349:7;14345:23;14341:32;14338:119;;;14376:79;;:::i;:::-;14338:119;14496:1;14521:53;14566:7;14557:6;14546:9;14542:22;14521:53;:::i;:::-;14511:63;;14467:117;14651:2;14640:9;14636:18;14623:32;14682:18;14674:6;14671:30;14668:117;;;14704:79;;:::i;:::-;14668:117;14809:78;14879:7;14870:6;14859:9;14855:22;14809:78;:::i;:::-;14799:88;;14594:303;14220:684;;;;;:::o;14910:474::-;14978:6;14986;15035:2;15023:9;15014:7;15010:23;15006:32;15003:119;;;15041:79;;:::i;:::-;15003:119;15161:1;15186:53;15231:7;15222:6;15211:9;15207:22;15186:53;:::i;:::-;15176:63;;15132:117;15288:2;15314:53;15359:7;15350:6;15339:9;15335:22;15314:53;:::i;:::-;15304:63;;15259:118;14910:474;;;;;:::o;15390:180::-;15438:77;15435:1;15428:88;15535:4;15532:1;15525:15;15559:4;15556:1;15549:15;15576:320;15620:6;15657:1;15651:4;15647:12;15637:22;;15704:1;15698:4;15694:12;15725:18;15715:81;;15781:4;15773:6;15769:17;15759:27;;15715:81;15843:2;15835:6;15832:14;15812:18;15809:38;15806:84;;15862:18;;:::i;:::-;15806:84;15627:269;15576:320;;;:::o;15902:332::-;16023:4;16061:2;16050:9;16046:18;16038:26;;16074:71;16142:1;16131:9;16127:17;16118:6;16074:71;:::i;:::-;16155:72;16223:2;16212:9;16208:18;16199:6;16155:72;:::i;:::-;15902:332;;;;;:::o;16240:137::-;16294:5;16325:6;16319:13;16310:22;;16341:30;16365:5;16341:30;:::i;:::-;16240:137;;;;:::o;16383:345::-;16450:6;16499:2;16487:9;16478:7;16474:23;16470:32;16467:119;;;16505:79;;:::i;:::-;16467:119;16625:1;16650:61;16703:7;16694:6;16683:9;16679:22;16650:61;:::i;:::-;16640:71;;16596:125;16383:345;;;;:::o;16734:172::-;16874:24;16870:1;16862:6;16858:14;16851:48;16734:172;:::o;16912:366::-;17054:3;17075:67;17139:2;17134:3;17075:67;:::i;:::-;17068:74;;17151:93;17240:3;17151:93;:::i;:::-;17269:2;17264:3;17260:12;17253:19;;16912:366;;;:::o;17284:419::-;17450:4;17488:2;17477:9;17473:18;17465:26;;17537:9;17531:4;17527:20;17523:1;17512:9;17508:17;17501:47;17565:131;17691:4;17565:131;:::i;:::-;17557:139;;17284:419;;;:::o;17709:141::-;17758:4;17781:3;17773:11;;17804:3;17801:1;17794:14;17838:4;17835:1;17825:18;17817:26;;17709:141;;;:::o;17856:93::-;17893:6;17940:2;17935;17928:5;17924:14;17920:23;17910:33;;17856:93;;;:::o;17955:107::-;17999:8;18049:5;18043:4;18039:16;18018:37;;17955:107;;;;:::o;18068:393::-;18137:6;18187:1;18175:10;18171:18;18210:97;18240:66;18229:9;18210:97;:::i;:::-;18328:39;18358:8;18347:9;18328:39;:::i;:::-;18316:51;;18400:4;18396:9;18389:5;18385:21;18376:30;;18449:4;18439:8;18435:19;18428:5;18425:30;18415:40;;18144:317;;18068:393;;;;;:::o;18467:60::-;18495:3;18516:5;18509:12;;18467:60;;;:::o;18533:142::-;18583:9;18616:53;18634:34;18643:24;18661:5;18643:24;:::i;:::-;18634:34;:::i;:::-;18616:53;:::i;:::-;18603:66;;18533:142;;;:::o;18681:75::-;18724:3;18745:5;18738:12;;18681:75;;;:::o;18762:269::-;18872:39;18903:7;18872:39;:::i;:::-;18933:91;18982:41;19006:16;18982:41;:::i;:::-;18974:6;18967:4;18961:11;18933:91;:::i;:::-;18927:4;18920:105;18838:193;18762:269;;;:::o;19037:73::-;19082:3;19037:73;:::o;19116:189::-;19193:32;;:::i;:::-;19234:65;19292:6;19284;19278:4;19234:65;:::i;:::-;19169:136;19116:189;;:::o;19311:186::-;19371:120;19388:3;19381:5;19378:14;19371:120;;;19442:39;19479:1;19472:5;19442:39;:::i;:::-;19415:1;19408:5;19404:13;19395:22;;19371:120;;;19311:186;;:::o;19503:543::-;19604:2;19599:3;19596:11;19593:446;;;19638:38;19670:5;19638:38;:::i;:::-;19722:29;19740:10;19722:29;:::i;:::-;19712:8;19708:44;19905:2;19893:10;19890:18;19887:49;;;19926:8;19911:23;;19887:49;19949:80;20005:22;20023:3;20005:22;:::i;:::-;19995:8;19991:37;19978:11;19949:80;:::i;:::-;19608:431;;19593:446;19503:543;;;:::o;20052:117::-;20106:8;20156:5;20150:4;20146:16;20125:37;;20052:117;;;;:::o;20175:169::-;20219:6;20252:51;20300:1;20296:6;20288:5;20285:1;20281:13;20252:51;:::i;:::-;20248:56;20333:4;20327;20323:15;20313:25;;20226:118;20175:169;;;;:::o;20349:295::-;20425:4;20571:29;20596:3;20590:4;20571:29;:::i;:::-;20563:37;;20633:3;20630:1;20626:11;20620:4;20617:21;20609:29;;20349:295;;;;:::o;20649:1395::-;20766:37;20799:3;20766:37;:::i;:::-;20868:18;20860:6;20857:30;20854:56;;;20890:18;;:::i;:::-;20854:56;20934:38;20966:4;20960:11;20934:38;:::i;:::-;21019:67;21079:6;21071;21065:4;21019:67;:::i;:::-;21113:1;21137:4;21124:17;;21169:2;21161:6;21158:14;21186:1;21181:618;;;;21843:1;21860:6;21857:77;;;21909:9;21904:3;21900:19;21894:26;21885:35;;21857:77;21960:67;22020:6;22013:5;21960:67;:::i;:::-;21954:4;21947:81;21816:222;21151:887;;21181:618;21233:4;21229:9;21221:6;21217:22;21267:37;21299:4;21267:37;:::i;:::-;21326:1;21340:208;21354:7;21351:1;21348:14;21340:208;;;21433:9;21428:3;21424:19;21418:26;21410:6;21403:42;21484:1;21476:6;21472:14;21462:24;;21531:2;21520:9;21516:18;21503:31;;21377:4;21374:1;21370:12;21365:17;;21340:208;;;21576:6;21567:7;21564:19;21561:179;;;21634:9;21629:3;21625:19;21619:26;21677:48;21719:4;21711:6;21707:17;21696:9;21677:48;:::i;:::-;21669:6;21662:64;21584:156;21561:179;21786:1;21782;21774:6;21770:14;21766:22;21760:4;21753:36;21188:611;;;21151:887;;20741:1303;;;20649:1395;;:::o;22050:174::-;22190:26;22186:1;22178:6;22174:14;22167:50;22050:174;:::o;22230:366::-;22372:3;22393:67;22457:2;22452:3;22393:67;:::i;:::-;22386:74;;22469:93;22558:3;22469:93;:::i;:::-;22587:2;22582:3;22578:12;22571:19;;22230:366;;;:::o;22602:419::-;22768:4;22806:2;22795:9;22791:18;22783:26;;22855:9;22849:4;22845:20;22841:1;22830:9;22826:17;22819:47;22883:131;23009:4;22883:131;:::i;:::-;22875:139;;22602:419;;;:::o;23027:234::-;23167:34;23163:1;23155:6;23151:14;23144:58;23236:17;23231:2;23223:6;23219:15;23212:42;23027:234;:::o;23267:366::-;23409:3;23430:67;23494:2;23489:3;23430:67;:::i;:::-;23423:74;;23506:93;23595:3;23506:93;:::i;:::-;23624:2;23619:3;23615:12;23608:19;;23267:366;;;:::o;23639:419::-;23805:4;23843:2;23832:9;23828:18;23820:26;;23892:9;23886:4;23882:20;23878:1;23867:9;23863:17;23856:47;23920:131;24046:4;23920:131;:::i;:::-;23912:139;;23639:419;;;:::o;24064:148::-;24166:11;24203:3;24188:18;;24064:148;;;;:::o;24242:874::-;24345:3;24382:5;24376:12;24411:36;24437:9;24411:36;:::i;:::-;24463:89;24545:6;24540:3;24463:89;:::i;:::-;24456:96;;24583:1;24572:9;24568:17;24599:1;24594:166;;;;24774:1;24769:341;;;;24561:549;;24594:166;24678:4;24674:9;24663;24659:25;24654:3;24647:38;24740:6;24733:14;24726:22;24718:6;24714:35;24709:3;24705:45;24698:52;;24594:166;;24769:341;24836:38;24868:5;24836:38;:::i;:::-;24896:1;24910:154;24924:6;24921:1;24918:13;24910:154;;;24998:7;24992:14;24988:1;24983:3;24979:11;24972:35;25048:1;25039:7;25035:15;25024:26;;24946:4;24943:1;24939:12;24934:17;;24910:154;;;25093:6;25088:3;25084:16;25077:23;;24776:334;;24561:549;;24349:767;;24242:874;;;;:::o;25122:390::-;25228:3;25256:39;25289:5;25256:39;:::i;:::-;25311:89;25393:6;25388:3;25311:89;:::i;:::-;25304:96;;25409:65;25467:6;25462:3;25455:4;25448:5;25444:16;25409:65;:::i;:::-;25499:6;25494:3;25490:16;25483:23;;25232:280;25122:390;;;;:::o;25518:429::-;25695:3;25717:92;25805:3;25796:6;25717:92;:::i;:::-;25710:99;;25826:95;25917:3;25908:6;25826:95;:::i;:::-;25819:102;;25938:3;25931:10;;25518:429;;;;;:::o;25953:269::-;26082:3;26104:92;26192:3;26183:6;26104:92;:::i;:::-;26097:99;;26213:3;26206:10;;25953:269;;;;:::o;26228:169::-;26368:21;26364:1;26356:6;26352:14;26345:45;26228:169;:::o;26403:366::-;26545:3;26566:67;26630:2;26625:3;26566:67;:::i;:::-;26559:74;;26642:93;26731:3;26642:93;:::i;:::-;26760:2;26755:3;26751:12;26744:19;;26403:366;;;:::o;26775:419::-;26941:4;26979:2;26968:9;26964:18;26956:26;;27028:9;27022:4;27018:20;27014:1;27003:9;26999:17;26992:47;27056:131;27182:4;27056:131;:::i;:::-;27048:139;;26775:419;;;:::o;27200:94::-;27233:8;27281:5;27277:2;27273:14;27252:35;;27200:94;;;:::o;27300:::-;27339:7;27368:20;27382:5;27368:20;:::i;:::-;27357:31;;27300:94;;;:::o;27400:100::-;27439:7;27468:26;27488:5;27468:26;:::i;:::-;27457:37;;27400:100;;;:::o;27506:157::-;27611:45;27631:24;27649:5;27631:24;:::i;:::-;27611:45;:::i;:::-;27606:3;27599:58;27506:157;;:::o;27669:256::-;27781:3;27796:75;27867:3;27858:6;27796:75;:::i;:::-;27896:2;27891:3;27887:12;27880:19;;27916:3;27909:10;;27669:256;;;;:::o;27931:166::-;28071:18;28067:1;28059:6;28055:14;28048:42;27931:166;:::o;28103:366::-;28245:3;28266:67;28330:2;28325:3;28266:67;:::i;:::-;28259:74;;28342:93;28431:3;28342:93;:::i;:::-;28460:2;28455:3;28451:12;28444:19;;28103:366;;;:::o;28475:419::-;28641:4;28679:2;28668:9;28664:18;28656:26;;28728:9;28722:4;28718:20;28714:1;28703:9;28699:17;28692:47;28756:131;28882:4;28756:131;:::i;:::-;28748:139;;28475:419;;;:::o;28900:225::-;29040:34;29036:1;29028:6;29024:14;29017:58;29109:8;29104:2;29096:6;29092:15;29085:33;28900:225;:::o;29131:366::-;29273:3;29294:67;29358:2;29353:3;29294:67;:::i;:::-;29287:74;;29370:93;29459:3;29370:93;:::i;:::-;29488:2;29483:3;29479:12;29472:19;;29131:366;;;:::o;29503:419::-;29669:4;29707:2;29696:9;29692:18;29684:26;;29756:9;29750:4;29746:20;29742:1;29731:9;29727:17;29720:47;29784:131;29910:4;29784:131;:::i;:::-;29776:139;;29503:419;;;:::o;29928:182::-;30068:34;30064:1;30056:6;30052:14;30045:58;29928:182;:::o;30116:366::-;30258:3;30279:67;30343:2;30338:3;30279:67;:::i;:::-;30272:74;;30355:93;30444:3;30355:93;:::i;:::-;30473:2;30468:3;30464:12;30457:19;;30116:366;;;:::o;30488:419::-;30654:4;30692:2;30681:9;30677:18;30669:26;;30741:9;30735:4;30731:20;30727:1;30716:9;30712:17;30705:47;30769:131;30895:4;30769:131;:::i;:::-;30761:139;;30488:419;;;:::o;30913:180::-;30961:77;30958:1;30951:88;31058:4;31055:1;31048:15;31082:4;31079:1;31072:15;31099:191;31139:3;31158:20;31176:1;31158:20;:::i;:::-;31153:25;;31192:20;31210:1;31192:20;:::i;:::-;31187:25;;31235:1;31232;31228:9;31221:16;;31256:3;31253:1;31250:10;31247:36;;;31263:18;;:::i;:::-;31247:36;31099:191;;;;:::o;31296:179::-;31436:31;31432:1;31424:6;31420:14;31413:55;31296:179;:::o;31481:366::-;31623:3;31644:67;31708:2;31703:3;31644:67;:::i;:::-;31637:74;;31720:93;31809:3;31720:93;:::i;:::-;31838:2;31833:3;31829:12;31822:19;;31481:366;;;:::o;31853:419::-;32019:4;32057:2;32046:9;32042:18;32034:26;;32106:9;32100:4;32096:20;32092:1;32081:9;32077:17;32070:47;32134:131;32260:4;32134:131;:::i;:::-;32126:139;;31853:419;;;:::o;32278:174::-;32418:26;32414:1;32406:6;32402:14;32395:50;32278:174;:::o;32458:366::-;32600:3;32621:67;32685:2;32680:3;32621:67;:::i;:::-;32614:74;;32697:93;32786:3;32697:93;:::i;:::-;32815:2;32810:3;32806:12;32799:19;;32458:366;;;:::o;32830:419::-;32996:4;33034:2;33023:9;33019:18;33011:26;;33083:9;33077:4;33073:20;33069:1;33058:9;33054:17;33047:47;33111:131;33237:4;33111:131;:::i;:::-;33103:139;;32830:419;;;:::o;33255:164::-;33395:16;33391:1;33383:6;33379:14;33372:40;33255:164;:::o;33425:366::-;33567:3;33588:67;33652:2;33647:3;33588:67;:::i;:::-;33581:74;;33664:93;33753:3;33664:93;:::i;:::-;33782:2;33777:3;33773:12;33766:19;;33425:366;;;:::o;33797:419::-;33963:4;34001:2;33990:9;33986:18;33978:26;;34050:9;34044:4;34040:20;34036:1;34025:9;34021:17;34014:47;34078:131;34204:4;34078:131;:::i;:::-;34070:139;;33797:419;;;:::o;34222:410::-;34262:7;34285:20;34303:1;34285:20;:::i;:::-;34280:25;;34319:20;34337:1;34319:20;:::i;:::-;34314:25;;34374:1;34371;34367:9;34396:30;34414:11;34396:30;:::i;:::-;34385:41;;34575:1;34566:7;34562:15;34559:1;34556:22;34536:1;34529:9;34509:83;34486:139;;34605:18;;:::i;:::-;34486:139;34270:362;34222:410;;;;:::o;34638:172::-;34778:24;34774:1;34766:6;34762:14;34755:48;34638:172;:::o;34816:366::-;34958:3;34979:67;35043:2;35038:3;34979:67;:::i;:::-;34972:74;;35055:93;35144:3;35055:93;:::i;:::-;35173:2;35168:3;35164:12;35157:19;;34816:366;;;:::o;35188:419::-;35354:4;35392:2;35381:9;35377:18;35369:26;;35441:9;35435:4;35431:20;35427:1;35416:9;35412:17;35405:47;35469:131;35595:4;35469:131;:::i;:::-;35461:139;;35188:419;;;:::o;35613:180::-;35661:77;35658:1;35651:88;35758:4;35755:1;35748:15;35782:4;35779:1;35772:15;35799:98;35850:6;35884:5;35878:12;35868:22;;35799:98;;;:::o;35903:168::-;35986:11;36020:6;36015:3;36008:19;36060:4;36055:3;36051:14;36036:29;;35903:168;;;;:::o;36077:373::-;36163:3;36191:38;36223:5;36191:38;:::i;:::-;36245:70;36308:6;36303:3;36245:70;:::i;:::-;36238:77;;36324:65;36382:6;36377:3;36370:4;36363:5;36359:16;36324:65;:::i;:::-;36414:29;36436:6;36414:29;:::i;:::-;36409:3;36405:39;36398:46;;36167:283;36077:373;;;;:::o;36456:640::-;36651:4;36689:3;36678:9;36674:19;36666:27;;36703:71;36771:1;36760:9;36756:17;36747:6;36703:71;:::i;:::-;36784:72;36852:2;36841:9;36837:18;36828:6;36784:72;:::i;:::-;36866;36934:2;36923:9;36919:18;36910:6;36866:72;:::i;:::-;36985:9;36979:4;36975:20;36970:2;36959:9;36955:18;36948:48;37013:76;37084:4;37075:6;37013:76;:::i;:::-;37005:84;;36456:640;;;;;;;:::o;37102:141::-;37158:5;37189:6;37183:13;37174:22;;37205:32;37231:5;37205:32;:::i;:::-;37102:141;;;;:::o;37249:349::-;37318:6;37367:2;37355:9;37346:7;37342:23;37338:32;37335:119;;;37373:79;;:::i;:::-;37335:119;37493:1;37518:63;37573:7;37564:6;37553:9;37549:22;37518:63;:::i;:::-;37508:73;;37464:127;37249:349;;;;:::o;37604:180::-;37652:77;37649:1;37642:88;37749:4;37746:1;37739:15;37773:4;37770:1;37763:15;37790:233;37829:3;37852:24;37870:5;37852:24;:::i;:::-;37843:33;;37898:66;37891:5;37888:77;37885:103;;37968:18;;:::i;:::-;37885:103;38015:1;38008:5;38004:13;37997:20;;37790:233;;;:::o
Swarm Source
ipfs://7ae8eff1b6ad496fea5f7b4661e7099b0dadb1a63027e59468c88bd57d8251f7
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.