Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 61 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Approval For... | 19490926 | 153 days ago | IN | 0 ETH | 0.00246449 | ||||
Set Approval For... | 17679865 | 407 days ago | IN | 0 ETH | 0.00169748 | ||||
Safe Transfer Fr... | 17528500 | 428 days ago | IN | 0 ETH | 0.00098602 | ||||
Safe Transfer Fr... | 16449599 | 580 days ago | IN | 0 ETH | 0.00120432 | ||||
Transfer From | 16440707 | 581 days ago | IN | 0 ETH | 0.00068569 | ||||
Safe Transfer Fr... | 16414748 | 585 days ago | IN | 0 ETH | 0.00131223 | ||||
Safe Transfer Fr... | 16407477 | 586 days ago | IN | 0 ETH | 0.00072699 | ||||
Safe Transfer Fr... | 16400096 | 587 days ago | IN | 0 ETH | 0.00119378 | ||||
Safe Transfer Fr... | 16397236 | 588 days ago | IN | 0 ETH | 0.00076631 | ||||
Safe Transfer Fr... | 16394006 | 588 days ago | IN | 0 ETH | 0.00094483 | ||||
Safe Transfer Fr... | 16392667 | 588 days ago | IN | 0 ETH | 0.00249757 | ||||
Safe Transfer Fr... | 16392499 | 588 days ago | IN | 0 ETH | 0.00133247 | ||||
Safe Transfer Fr... | 16392488 | 588 days ago | IN | 0 ETH | 0.00142472 | ||||
Safe Transfer Fr... | 16392478 | 588 days ago | IN | 0 ETH | 0.00148961 | ||||
Transfer From | 16392457 | 588 days ago | IN | 0 ETH | 0.00135803 | ||||
Safe Transfer Fr... | 16392437 | 588 days ago | IN | 0 ETH | 0.00158495 | ||||
Safe Transfer Fr... | 16392325 | 588 days ago | IN | 0 ETH | 0.00148718 | ||||
Safe Transfer Fr... | 16392009 | 588 days ago | IN | 0 ETH | 0.00093039 | ||||
Set Approval For... | 16387753 | 589 days ago | IN | 0 ETH | 0.00118007 | ||||
Safe Transfer Fr... | 16386503 | 589 days ago | IN | 0 ETH | 0.0014108 | ||||
Set Approval For... | 16377356 | 590 days ago | IN | 0 ETH | 0.00148596 | ||||
Safe Transfer Fr... | 16375755 | 591 days ago | IN | 0 ETH | 0.00108501 | ||||
Safe Transfer Fr... | 16368294 | 592 days ago | IN | 0 ETH | 0.00145586 | ||||
Set Approval For... | 16299218 | 601 days ago | IN | 0 ETH | 0.00116156 | ||||
Safe Transfer Fr... | 16299209 | 601 days ago | IN | 0 ETH | 0.00117362 |
Loading...
Loading
Contract Name:
NFTouringGenesis
Compiler Version
v0.8.16+commit.07a7930e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-12-06 */ // 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/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/token/common/ERC2981.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // 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/IAccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File: @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File: contracts/openSea/IOperatorFilterRegistry.sol pragma solidity ^0.8.13; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function unregister(address addr) 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/openSea/OperatorFilterer.sol pragma solidity ^0.8.13; /** * @title OperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. * @dev This smart contract is meant to be inherited by token contracts so they can use the following: * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. */ abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = 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(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (subscribe) { OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { OPERATOR_FILTER_REGISTRY.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // 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) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } function _checkFilterOperator(address operator) internal view virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } } // File: contracts/openSea/DefaultOperatorFilterer.sol pragma solidity ^0.8.13; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} } // File: erc721a/contracts/IERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * 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(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @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() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 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`, * 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, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` 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 payable; /** * @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 payable; /** * @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); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: erc721a/contracts/ERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // 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 bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID 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` // - [232..255] `extraData` 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 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @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 virtual 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 virtual 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 virtual 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 virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(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 auxiliary 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 auxiliary 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 virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ 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: [ERC165](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. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ 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, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * 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 initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev 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; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @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) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @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) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @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. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // 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] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // 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 `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @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 memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @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 Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns 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)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @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 for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _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] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _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] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, 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. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @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)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // 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] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // 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++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * 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 _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @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 virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: contracts/NFTouringGenesis.sol /** __ _ ______ _______ _____ _ _ ______ _____ __ _ ______ | \ | |_____ | | | | | |_____/ | | \ | | ____ | \_| | | |_____| |_____| | \_ __|__ | \_| |_____| */ pragma solidity 0.8.16; contract NFTouringGenesis is ERC721A, AccessControl, ERC2981, DefaultOperatorFilterer { //======= SALE STATUS ======== enum SaleStatus { Locked, //0 WhitelistSale, //1 PublicSale //2 } SaleStatus public saleStatus; //========== SUPPLY ========== uint256 public maxSupply = 1500; uint256 public initialMints = 300; uint256 public whitelistSale = 500; //======= MINTING PRICE ======= uint256 public price = 1 ether; //========= ROYALTIES ========= uint96 public royaltyFees = 800; // 8% //======== SPLIT FUNDS ======== address payable public paymentContract; address public addrSD = 0x34022e74d35414b439e22C153489c4f3e0d293a2; //======== WITHDRAWERS ======== address public addrEB = 0xC91629E0459E15911082c78b9A9773887e93f5d0; address public addrMS = 0xF1896b2c93e50fF81E610971de80f64594DE4E87; address public addrDC = 0x4020cD1086A9Edaa2B9a61A1138F7e005bD87152; //======= COLLECTION URI ====== string public baseUri = "https://arweave.net/f3w2Mp32hTGPU13fnTvLY84CJclnspBZJxCgJWV-CsQ/"; //======== MERKLE ROOT ======== bytes32 public merkleRoot; //=========== ROLES =========== bytes32 public constant MODERATOR_ROLE = keccak256("MODERATOR_ROLE"); bytes32 public constant WITHDRAWER_ROLE = keccak256("WITHDRAWER_ROLE"); //======= CONSTRUCTOR ========= constructor( bytes32 _merkleRoot, address _payments ) ERC721A("NFTouring Genesis", "NFTP") { merkleRoot = _merkleRoot; paymentContract = payable(_payments); _setDefaultRoyalty(paymentContract, royaltyFees); _setupRole(MODERATOR_ROLE, msg.sender); _setupRole(WITHDRAWER_ROLE, msg.sender); _setupRole(WITHDRAWER_ROLE, addrEB); _setupRole(WITHDRAWER_ROLE, addrMS); _setupRole(WITHDRAWER_ROLE, addrDC); _safeMint(msg.sender, 100); _safeMint(addrEB, 110); _safeMint(addrMS, 70); _safeMint(addrDC, 20); } //======== MINTING ======== function whitelistMint(uint quantity, bytes32[] calldata proof) external payable { require(uint(saleStatus) == 1, "Wrong sale status"); require(isWhitelisted(msg.sender, proof), "You are not in the whitelist."); require(_numberMinted(msg.sender) + quantity < 3, "Maximum amount of NFT mints reached."); require(totalSupply() + quantity <= whitelistSale + initialMints, "Maximum pre-sale mints reached."); require(msg.value == quantity * price, "Send exact price."); _safeMint(msg.sender, quantity); } function publicMint(uint256 quantity) external payable { require(uint(saleStatus) == 2, "Wrong sale status"); require(_numberMinted(msg.sender) + quantity < 5, "Maximum amount of NFT mints reached."); require(totalSupply() + quantity <= maxSupply, "Maximum sale mints reached."); require(msg.value == quantity * price, "Send exact price."); _safeMint(msg.sender, quantity); } //========= STATUS ========= function nextSaleStatus() external onlyRole(MODERATOR_ROLE) { require(uint(saleStatus)!=2, "Last sale status has been reached"); saleStatus = SaleStatus(uint (saleStatus) + 1); } //======== WHITELIST ======== function setMerkleRoot(bytes32 _merkleRoot) external onlyRole(MODERATOR_ROLE) { merkleRoot = _merkleRoot; } function isWhitelisted(address _account, bytes32[] calldata _proof) internal view returns(bool) { return MerkleProof.verify(_proof, merkleRoot, keccak256(abi.encodePacked(_account))); } //======== PAYMENTS ========= function withdraw() external payable onlyRole(WITHDRAWER_ROLE) { uint contractBalance = address(this).balance; (bool sent1st,) = paymentContract.call{value: contractBalance / 10 * 9}(""); (bool sent2nd,) = payable(addrSD).call{value: contractBalance / 10}(""); require(sent1st && sent2nd, "Failed to send Ether"); } receive() external payable { revert("Only if you mint"); } //====== OVERRIDEN METHODS ====== function tokenURI(uint _tokenId) public view virtual override(ERC721A) returns(string memory) { require(_exists(_tokenId), "Nft has not been minted yet"); return string(abi.encodePacked(baseUri, _toString(_tokenId), ".json")); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, ERC2981, AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } //====== OPENSEA COMPLIANCE ===== function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public payable override onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public payable override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"address","name":"_payments","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","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":"OwnershipNotInitializedForExtraData","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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MODERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAWER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addrDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addrEB","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addrMS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addrSD","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","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":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","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":"nextSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentContract","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","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":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royaltyFees","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","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":"payable","type":"function"},{"inputs":[],"name":"saleStatus","outputs":[{"internalType":"enum NFTouringGenesis.SaleStatus","name":"","type":"uint8"}],"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":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_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":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040526105dc600c5561012c600d556101f4600e55670de0b6b3a7640000600f55610320601060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507334022e74d35414b439e22c153489c4f3e0d293a2601160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073c91629e0459e15911082c78b9a9773887e93f5d0601260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073f1896b2c93e50ff81e610971de80f64594de4e87601360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550734020cd1086a9edaa2b9a61a1138f7e005bd87152601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405180606001604052806040815260200162005a846040913960159081620001d39190620011bb565b50348015620001e157600080fd5b5060405162005ac438038062005ac4833981810160405281019062000207919062001347565b733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280601181526020017f4e46546f7572696e672047656e657369730000000000000000000000000000008152506040518060400160405280600481526020017f4e4654500000000000000000000000000000000000000000000000000000000081525081600290816200029b9190620011bb565b508060039081620002ad9190620011bb565b50620002be6200076d60201b60201c565b600081905550505060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620004bb57801562000381576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620003479291906200139f565b600060405180830381600087803b1580156200036257600080fd5b505af115801562000377573d6000803e3d6000fd5b50505050620004ba565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200043b576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620004019291906200139f565b600060405180830381600087803b1580156200041c57600080fd5b505af115801562000431573d6000803e3d6000fd5b50505050620004b9565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620004849190620013cc565b600060405180830381600087803b1580156200049f57600080fd5b505af1158015620004b4573d6000803e3d6000fd5b505050505b5b5b505081601681905550806010600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620005536010600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16601060009054906101000a90046bffffffffffffffffffffffff166200077260201b60201c565b620005857f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f336200091560201b60201c565b620005b77f10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e4336200091560201b60201c565b6200060b7f10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e4601260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166200091560201b60201c565b6200065f7f10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e4601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166200091560201b60201c565b620006b37f10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e4601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166200091560201b60201c565b620006c63360646200092b60201b60201c565b620006fb601260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16606e6200092b60201b60201c565b62000730601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660466200092b60201b60201c565b62000765601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660146200092b60201b60201c565b505062001692565b600090565b620007826200095160201b60201c565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115620007e3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007da9062001470565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000855576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200084c90620014e2565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600960008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b6200092782826200095b60201b60201c565b5050565b6200094d82826040518060200160405280600081525062000a4d60201b60201c565b5050565b6000612710905090565b6200096d828262000afe60201b60201c565b62000a495760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620009ee62000b6960201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b62000a5f838362000b7160201b60201c565b60008373ffffffffffffffffffffffffffffffffffffffff163b1462000af957600080549050600083820390505b62000aa8600086838060010194508662000d5860201b60201c565b62000adf576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81811062000a8d57816000541462000af657600080fd5b50505b505050565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b6000805490506000820362000bb2576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000bc7600084838562000eb960201b60201c565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555062000c568362000c38600086600062000ebf60201b60201c565b62000c498562000eef60201b60201c565b1762000eff60201b60201c565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811462000cf957808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905062000cbc565b506000820362000d35576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505062000d53600084838562000f2a60201b60201c565b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0262000d8662000f3060201b60201c565b8786866040518563ffffffff1660e01b815260040162000daa9493929190620015af565b6020604051808303816000875af192505050801562000de957506040513d601f19601f8201168201806040525081019062000de6919062001660565b60015b62000e66573d806000811462000e1c576040519150601f19603f3d011682016040523d82523d6000602084013e62000e21565b606091505b50600081510362000e5e576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b50505050565b60008060e883901c905060e862000ede86868462000f3860201b60201c565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b60009392505050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000fc357607f821691505b60208210810362000fd95762000fd862000f7b565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620010437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262001004565b6200104f868362001004565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200109c62001096620010908462001067565b62001071565b62001067565b9050919050565b6000819050919050565b620010b8836200107b565b620010d0620010c782620010a3565b84845462001011565b825550505050565b600090565b620010e7620010d8565b620010f4818484620010ad565b505050565b5b818110156200111c5762001110600082620010dd565b600181019050620010fa565b5050565b601f8211156200116b57620011358162000fdf565b620011408462000ff4565b8101602085101562001150578190505b620011686200115f8562000ff4565b830182620010f9565b50505b505050565b600082821c905092915050565b6000620011906000198460080262001170565b1980831691505092915050565b6000620011ab83836200117d565b9150826002028217905092915050565b620011c68262000f41565b67ffffffffffffffff811115620011e257620011e162000f4c565b5b620011ee825462000faa565b620011fb82828562001120565b600060209050601f8311600181146200123357600084156200121e578287015190505b6200122a85826200119d565b8655506200129a565b601f198416620012438662000fdf565b60005b828110156200126d5784890151825560018201915060208501945060208101905062001246565b868310156200128d578489015162001289601f8916826200117d565b8355505b6001600288020188555050505b505050505050565b600080fd5b6000819050919050565b620012bc81620012a7565b8114620012c857600080fd5b50565b600081519050620012dc81620012b1565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200130f82620012e2565b9050919050565b620013218162001302565b81146200132d57600080fd5b50565b600081519050620013418162001316565b92915050565b60008060408385031215620013615762001360620012a2565b5b60006200137185828601620012cb565b9250506020620013848582860162001330565b9150509250929050565b620013998162001302565b82525050565b6000604082019050620013b660008301856200138e565b620013c560208301846200138e565b9392505050565b6000602082019050620013e360008301846200138e565b92915050565b600082825260208201905092915050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b600062001458602a83620013e9565b91506200146582620013fa565b604082019050919050565b600060208201905081810360008301526200148b8162001449565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b6000620014ca601983620013e9565b9150620014d78262001492565b602082019050919050565b60006020820190508181036000830152620014fd81620014bb565b9050919050565b6200150f8162001067565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156200155157808201518184015260208101905062001534565b60008484015250505050565b6000601f19601f8301169050919050565b60006200157b8262001515565b62001587818562001520565b93506200159981856020860162001531565b620015a4816200155d565b840191505092915050565b6000608082019050620015c660008301876200138e565b620015d560208301866200138e565b620015e4604083018562001504565b8181036060830152620015f881846200156e565b905095945050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6200163a8162001603565b81146200164657600080fd5b50565b6000815190506200165a816200162f565b92915050565b600060208284031215620016795762001678620012a2565b5b6000620016898482850162001649565b91505092915050565b6143e280620016a26000396000f3fe6080604052600436106102555760003560e01c80637cb6475911610139578063a217fddf116100b6578063d2cab0561161007a578063d2cab056146108af578063d547741f146108cb578063d5abeb01146108f4578063e985e9c51461091f578063f1c4035d1461095c578063f9020e331461098757610295565b8063a217fddf146107d7578063a22cb46514610802578063b88d4fde1461082b578063b977665e14610847578063c87b56dd1461087257610295565b806395d89b41116100fd57806395d89b41146107005780639abc83201461072b5780639b5c2812146107565780639c91dd5614610781578063a035b1fe146107ac57610295565b80637cb64759146106195780637e30a6c21461064257806385f438c11461066d5780638d0df0251461069857806391d14854146106c357610295565b80632f2ff15d116101d257806342842e0e1161019657806342842e0e146105165780635e720718146105325780636352211e1461054957806370a0823114610586578063797669c9146105c35780637983e997146105ee57610295565b80632f2ff15d1461046457806331ffd6f11461048d57806336568abe146104b85780633ccfd60b146104e157806341f43434146104eb57610295565b806323b872dd1161021957806323b872dd14610386578063248a9ca3146103a25780632a55205a146103df5780632db115441461041d5780632eb4a7ab1461043957610295565b806301ffc9a71461029a57806306fdde03146102d7578063081812fc14610302578063095ea7b31461033f57806318160ddd1461035b57610295565b36610295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161028c90612f18565b60405180910390fd5b600080fd5b3480156102a657600080fd5b506102c160048036038101906102bc9190612fa4565b6109b2565b6040516102ce9190612fec565b60405180910390f35b3480156102e357600080fd5b506102ec6109c4565b6040516102f99190613086565b60405180910390f35b34801561030e57600080fd5b50610329600480360381019061032491906130de565b610a56565b604051610336919061314c565b60405180910390f35b61035960048036038101906103549190613193565b610ad5565b005b34801561036757600080fd5b50610370610aee565b60405161037d91906131e2565b60405180910390f35b6103a0600480360381019061039b91906131fd565b610b05565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190613286565b610b54565b6040516103d691906132c2565b60405180910390f35b3480156103eb57600080fd5b50610406600480360381019061040191906132dd565b610b74565b60405161041492919061331d565b60405180910390f35b610437600480360381019061043291906130de565b610d5e565b005b34801561044557600080fd5b5061044e610ecb565b60405161045b91906132c2565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613346565b610ed1565b005b34801561049957600080fd5b506104a2610ef2565b6040516104af91906131e2565b60405180910390f35b3480156104c457600080fd5b506104df60048036038101906104da9190613346565b610ef8565b005b6104e9610f7b565b005b3480156104f757600080fd5b50610500611139565b60405161050d91906133e5565b60405180910390f35b610530600480360381019061052b91906131fd565b61114b565b005b34801561053e57600080fd5b5061054761119a565b005b34801561055557600080fd5b50610570600480360381019061056b91906130de565b611294565b60405161057d919061314c565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a89190613400565b6112a6565b6040516105ba91906131e2565b60405180910390f35b3480156105cf57600080fd5b506105d861135e565b6040516105e591906132c2565b60405180910390f35b3480156105fa57600080fd5b50610603611382565b604051610610919061314c565b60405180910390f35b34801561062557600080fd5b50610640600480360381019061063b9190613286565b6113a8565b005b34801561064e57600080fd5b506106576113dd565b6040516106649190613454565b60405180910390f35b34801561067957600080fd5b506106826113fb565b60405161068f91906132c2565b60405180910390f35b3480156106a457600080fd5b506106ad61141f565b6040516106ba919061314c565b60405180910390f35b3480156106cf57600080fd5b506106ea60048036038101906106e59190613346565b611445565b6040516106f79190612fec565b60405180910390f35b34801561070c57600080fd5b506107156114b0565b6040516107229190613086565b60405180910390f35b34801561073757600080fd5b50610740611542565b60405161074d9190613086565b60405180910390f35b34801561076257600080fd5b5061076b6115d0565b604051610778919061314c565b60405180910390f35b34801561078d57600080fd5b506107966115f6565b6040516107a39190613490565b60405180910390f35b3480156107b857600080fd5b506107c161161c565b6040516107ce91906131e2565b60405180910390f35b3480156107e357600080fd5b506107ec611622565b6040516107f991906132c2565b60405180910390f35b34801561080e57600080fd5b50610829600480360381019061082491906134d7565b611629565b005b6108456004803603810190610840919061364c565b611642565b005b34801561085357600080fd5b5061085c611693565b60405161086991906131e2565b60405180910390f35b34801561087e57600080fd5b50610899600480360381019061089491906130de565b611699565b6040516108a69190613086565b60405180910390f35b6108c960048036038101906108c4919061372f565b611715565b005b3480156108d757600080fd5b506108f260048036038101906108ed9190613346565b6118db565b005b34801561090057600080fd5b506109096118fc565b60405161091691906131e2565b60405180910390f35b34801561092b57600080fd5b506109466004803603810190610941919061378f565b611902565b6040516109539190612fec565b60405180910390f35b34801561096857600080fd5b50610971611996565b60405161097e919061314c565b60405180910390f35b34801561099357600080fd5b5061099c6119bc565b6040516109a99190613846565b60405180910390f35b60006109bd826119cf565b9050919050565b6060600280546109d390613890565b80601f01602080910402602001604051908101604052809291908181526020018280546109ff90613890565b8015610a4c5780601f10610a2157610100808354040283529160200191610a4c565b820191906000526020600020905b815481529060010190602001808311610a2f57829003601f168201915b5050505050905090565b6000610a6182611a49565b610a97576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610adf81611aa8565b610ae98383611ba5565b505050565b6000610af8611ce9565b6001546000540303905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b4357610b4233611aa8565b5b610b4e848484611cee565b50505050565b600060086000838152602001908152602001600020600101549050919050565b6000806000600a60008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610d095760096040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610d13612010565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610d3f91906138f0565b610d499190613979565b90508160000151819350935050509250929050565b6002600b60009054906101000a900460ff166002811115610d8257610d816137cf565b5b14610dc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db9906139f6565b60405180910390fd5b600581610dce3361201a565b610dd89190613a16565b10610e18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0f90613abc565b60405180910390fd5b600c5481610e24610aee565b610e2e9190613a16565b1115610e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6690613b28565b60405180910390fd5b600f5481610e7d91906138f0565b3414610ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb590613b94565b60405180910390fd5b610ec83382612071565b50565b60165481565b610eda82610b54565b610ee38161208f565b610eed83836120a3565b505050565b600e5481565b610f00612184565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6490613c26565b60405180910390fd5b610f77828261218c565b5050565b7f10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e4610fa58161208f565b600047905060006010600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166009600a84610ff49190613979565b610ffe91906138f0565b60405161100a90613c77565b60006040518083038185875af1925050503d8060008114611047576040519150601f19603f3d011682016040523d82523d6000602084013e61104c565b606091505b505090506000601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600a846110989190613979565b6040516110a490613c77565b60006040518083038185875af1925050503d80600081146110e1576040519150601f19603f3d011682016040523d82523d6000602084013e6110e6565b606091505b505090508180156110f45750805b611133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112a90613cd8565b60405180910390fd5b50505050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146111895761118833611aa8565b5b61119484848461226e565b50505050565b7f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f6111c48161208f565b6002600b60009054906101000a900460ff1660028111156111e8576111e76137cf565b5b03611228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121f90613d6a565b60405180910390fd5b6001600b60009054906101000a900460ff16600281111561124c5761124b6137cf565b5b6112569190613a16565b6002811115611268576112676137cf565b5b600b60006101000a81548160ff0219169083600281111561128c5761128b6137cf565b5b021790555050565b600061129f8261228e565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361130d576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b7f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f81565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f6113d28161208f565b816016819055505050565b601060009054906101000a90046bffffffffffffffffffffffff1681565b7f10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e481565b601260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600380546114bf90613890565b80601f01602080910402602001604051908101604052809291908181526020018280546114eb90613890565b80156115385780601f1061150d57610100808354040283529160200191611538565b820191906000526020600020905b81548152906001019060200180831161151b57829003601f168201915b5050505050905090565b6015805461154f90613890565b80601f016020809104026020016040519081016040528092919081815260200182805461157b90613890565b80156115c85780601f1061159d576101008083540402835291602001916115c8565b820191906000526020600020905b8154815290600101906020018083116115ab57829003601f168201915b505050505081565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6010600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600f5481565b6000801b81565b8161163381611aa8565b61163d838361235a565b505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146116805761167f33611aa8565b5b61168c85858585612465565b5050505050565b600d5481565b60606116a482611a49565b6116e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116da90613dd6565b60405180910390fd5b60156116ee836124d8565b6040516020016116ff929190613f16565b6040516020818303038152906040529050919050565b6001600b60009054906101000a900460ff166002811115611739576117386137cf565b5b14611779576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611770906139f6565b60405180910390fd5b611784338383612528565b6117c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ba90613f91565b60405180910390fd5b6003836117cf3361201a565b6117d99190613a16565b10611819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181090613abc565b60405180910390fd5b600d54600e546118299190613a16565b83611832610aee565b61183c9190613a16565b111561187d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187490613ffd565b60405180910390fd5b600f548361188b91906138f0565b34146118cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c390613b94565b60405180910390fd5b6118d63384612071565b505050565b6118e482610b54565b6118ed8161208f565b6118f7838361218c565b505050565b600c5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b60009054906101000a900460ff1681565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a425750611a41826125a7565b5b9050919050565b600081611a54611ce9565b11158015611a63575060005482105b8015611aa1575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611ba2576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611b1f92919061401d565b602060405180830381865afa158015611b3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b60919061405b565b611ba157806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b98919061314c565b60405180910390fd5b5b50565b6000611bb082611294565b90508073ffffffffffffffffffffffffffffffffffffffff16611bd1612621565b73ffffffffffffffffffffffffffffffffffffffff1614611c3457611bfd81611bf8612621565b611902565b611c33576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b6000611cf98261228e565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d60576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611d6c84612629565b91509150611d828187611d7d612621565b612650565b611dce57611d9786611d92612621565b611902565b611dcd576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611e34576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e418686866001612694565b8015611e4c57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550611f1a85611ef688888761269a565b7c0200000000000000000000000000000000000000000000000000000000176126c2565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603611fa05760006001850190506000600460008381526020019081526020016000205403611f9e576000548114611f9d578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461200886868660016126ed565b505050505050565b6000612710905090565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b61208b8282604051806020016040528060008152506126f3565b5050565b6120a08161209b612184565b612790565b50565b6120ad8282611445565b6121805760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612125612184565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b6121968282611445565b1561226a5760006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061220f612184565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b61228983838360405180602001604052806000815250611642565b505050565b6000808290508061229d611ce9565b11612323576000548110156123225760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612320575b600081036123165760046000836001900393508381526020019081526020016000205490506122ec565b8092505050612355565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b8060076000612367612621565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612414612621565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516124599190612fec565b60405180910390a35050565b612470848484610b05565b60008373ffffffffffffffffffffffffffffffffffffffff163b146124d25761249b84848484612815565b6124d1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b606060a060405101806040526020810391506000825281835b60011561251357600184039350600a81066030018453600a81049050806124f1575b50828103602084039350808452505050919050565b600061259e838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050506016548660405160200161258391906140d0565b60405160208183030381529060405280519060200120612965565b90509392505050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061261a57506126198261297c565b5b9050919050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86126b18686846129e6565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6126fd83836129ef565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461278b57600080549050600083820390505b61273d6000868380600101945086612815565b612773576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81811061272a57816000541461278857600080fd5b50505b505050565b61279a8282611445565b612811576127a781612baa565b6127b58360001c6020612bd7565b6040516020016127c6929190614183565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128089190613086565b60405180910390fd5b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261283b612621565b8786866040518563ffffffff1660e01b815260040161285d9493929190614212565b6020604051808303816000875af192505050801561289957506040513d601f19601f820116820180604052508101906128969190614273565b60015b612912573d80600081146128c9576040519150601f19603f3d011682016040523d82523d6000602084013e6128ce565b606091505b50600081510361290a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6000826129728584612e13565b1490509392505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60009392505050565b60008054905060008203612a2f576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3c6000848385612694565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612ab383612aa4600086600061269a565b612aad85612e69565b176126c2565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612b5457808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612b19565b5060008203612b8f576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612ba560008483856126ed565b505050565b6060612bd08273ffffffffffffffffffffffffffffffffffffffff16601460ff16612bd7565b9050919050565b606060006002836002612bea91906138f0565b612bf49190613a16565b67ffffffffffffffff811115612c0d57612c0c613521565b5b6040519080825280601f01601f191660200182016040528015612c3f5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612c7757612c766142a0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612cdb57612cda6142a0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612d1b91906138f0565b612d259190613a16565b90505b6001811115612dc5577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612d6757612d666142a0565b5b1a60f81b828281518110612d7e57612d7d6142a0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612dbe906142cf565b9050612d28565b5060008414612e09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e0090614344565b60405180910390fd5b8091505092915050565b60008082905060005b8451811015612e5e57612e4982868381518110612e3c57612e3b6142a0565b5b6020026020010151612e79565b91508080612e5690614364565b915050612e1c565b508091505092915050565b60006001821460e11b9050919050565b6000818310612e9157612e8c8284612ea4565b612e9c565b612e9b8383612ea4565b5b905092915050565b600082600052816020526040600020905092915050565b600082825260208201905092915050565b7f4f6e6c7920696620796f75206d696e7400000000000000000000000000000000600082015250565b6000612f02601083612ebb565b9150612f0d82612ecc565b602082019050919050565b60006020820190508181036000830152612f3181612ef5565b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612f8181612f4c565b8114612f8c57600080fd5b50565b600081359050612f9e81612f78565b92915050565b600060208284031215612fba57612fb9612f42565b5b6000612fc884828501612f8f565b91505092915050565b60008115159050919050565b612fe681612fd1565b82525050565b60006020820190506130016000830184612fdd565b92915050565b600081519050919050565b60005b83811015613030578082015181840152602081019050613015565b60008484015250505050565b6000601f19601f8301169050919050565b600061305882613007565b6130628185612ebb565b9350613072818560208601613012565b61307b8161303c565b840191505092915050565b600060208201905081810360008301526130a0818461304d565b905092915050565b6000819050919050565b6130bb816130a8565b81146130c657600080fd5b50565b6000813590506130d8816130b2565b92915050565b6000602082840312156130f4576130f3612f42565b5b6000613102848285016130c9565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131368261310b565b9050919050565b6131468161312b565b82525050565b6000602082019050613161600083018461313d565b92915050565b6131708161312b565b811461317b57600080fd5b50565b60008135905061318d81613167565b92915050565b600080604083850312156131aa576131a9612f42565b5b60006131b88582860161317e565b92505060206131c9858286016130c9565b9150509250929050565b6131dc816130a8565b82525050565b60006020820190506131f760008301846131d3565b92915050565b60008060006060848603121561321657613215612f42565b5b60006132248682870161317e565b93505060206132358682870161317e565b9250506040613246868287016130c9565b9150509250925092565b6000819050919050565b61326381613250565b811461326e57600080fd5b50565b6000813590506132808161325a565b92915050565b60006020828403121561329c5761329b612f42565b5b60006132aa84828501613271565b91505092915050565b6132bc81613250565b82525050565b60006020820190506132d760008301846132b3565b92915050565b600080604083850312156132f4576132f3612f42565b5b6000613302858286016130c9565b9250506020613313858286016130c9565b9150509250929050565b6000604082019050613332600083018561313d565b61333f60208301846131d3565b9392505050565b6000806040838503121561335d5761335c612f42565b5b600061336b85828601613271565b925050602061337c8582860161317e565b9150509250929050565b6000819050919050565b60006133ab6133a66133a18461310b565b613386565b61310b565b9050919050565b60006133bd82613390565b9050919050565b60006133cf826133b2565b9050919050565b6133df816133c4565b82525050565b60006020820190506133fa60008301846133d6565b92915050565b60006020828403121561341657613415612f42565b5b60006134248482850161317e565b91505092915050565b60006bffffffffffffffffffffffff82169050919050565b61344e8161342d565b82525050565b60006020820190506134696000830184613445565b92915050565b600061347a8261310b565b9050919050565b61348a8161346f565b82525050565b60006020820190506134a56000830184613481565b92915050565b6134b481612fd1565b81146134bf57600080fd5b50565b6000813590506134d1816134ab565b92915050565b600080604083850312156134ee576134ed612f42565b5b60006134fc8582860161317e565b925050602061350d858286016134c2565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6135598261303c565b810181811067ffffffffffffffff8211171561357857613577613521565b5b80604052505050565b600061358b612f38565b90506135978282613550565b919050565b600067ffffffffffffffff8211156135b7576135b6613521565b5b6135c08261303c565b9050602081019050919050565b82818337600083830152505050565b60006135ef6135ea8461359c565b613581565b90508281526020810184848401111561360b5761360a61351c565b5b6136168482856135cd565b509392505050565b600082601f83011261363357613632613517565b5b81356136438482602086016135dc565b91505092915050565b6000806000806080858703121561366657613665612f42565b5b60006136748782880161317e565b94505060206136858782880161317e565b9350506040613696878288016130c9565b925050606085013567ffffffffffffffff8111156136b7576136b6612f47565b5b6136c38782880161361e565b91505092959194509250565b600080fd5b600080fd5b60008083601f8401126136ef576136ee613517565b5b8235905067ffffffffffffffff81111561370c5761370b6136cf565b5b602083019150836020820283011115613728576137276136d4565b5b9250929050565b60008060006040848603121561374857613747612f42565b5b6000613756868287016130c9565b935050602084013567ffffffffffffffff81111561377757613776612f47565b5b613783868287016136d9565b92509250509250925092565b600080604083850312156137a6576137a5612f42565b5b60006137b48582860161317e565b92505060206137c58582860161317e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003811061380f5761380e6137cf565b5b50565b6000819050613820826137fe565b919050565b600061383082613812565b9050919050565b61384081613825565b82525050565b600060208201905061385b6000830184613837565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806138a857607f821691505b6020821081036138bb576138ba613861565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138fb826130a8565b9150613906836130a8565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561393f5761393e6138c1565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613984826130a8565b915061398f836130a8565b92508261399f5761399e61394a565b5b828204905092915050565b7f57726f6e672073616c6520737461747573000000000000000000000000000000600082015250565b60006139e0601183612ebb565b91506139eb826139aa565b602082019050919050565b60006020820190508181036000830152613a0f816139d3565b9050919050565b6000613a21826130a8565b9150613a2c836130a8565b9250828201905080821115613a4457613a436138c1565b5b92915050565b7f4d6178696d756d20616d6f756e74206f66204e4654206d696e7473207265616360008201527f6865642e00000000000000000000000000000000000000000000000000000000602082015250565b6000613aa6602483612ebb565b9150613ab182613a4a565b604082019050919050565b60006020820190508181036000830152613ad581613a99565b9050919050565b7f4d6178696d756d2073616c65206d696e747320726561636865642e0000000000600082015250565b6000613b12601b83612ebb565b9150613b1d82613adc565b602082019050919050565b60006020820190508181036000830152613b4181613b05565b9050919050565b7f53656e642065786163742070726963652e000000000000000000000000000000600082015250565b6000613b7e601183612ebb565b9150613b8982613b48565b602082019050919050565b60006020820190508181036000830152613bad81613b71565b9050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613c10602f83612ebb565b9150613c1b82613bb4565b604082019050919050565b60006020820190508181036000830152613c3f81613c03565b9050919050565b600081905092915050565b50565b6000613c61600083613c46565b9150613c6c82613c51565b600082019050919050565b6000613c8282613c54565b9150819050919050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b6000613cc2601483612ebb565b9150613ccd82613c8c565b602082019050919050565b60006020820190508181036000830152613cf181613cb5565b9050919050565b7f4c6173742073616c652073746174757320686173206265656e2072656163686560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d54602183612ebb565b9150613d5f82613cf8565b604082019050919050565b60006020820190508181036000830152613d8381613d47565b9050919050565b7f4e667420686173206e6f74206265656e206d696e746564207965740000000000600082015250565b6000613dc0601b83612ebb565b9150613dcb82613d8a565b602082019050919050565b60006020820190508181036000830152613def81613db3565b9050919050565b600081905092915050565b60008190508160005260206000209050919050565b60008154613e2381613890565b613e2d8186613df6565b94506001821660008114613e485760018114613e5d57613e90565b60ff1983168652811515820286019350613e90565b613e6685613e01565b60005b83811015613e8857815481890152600182019150602081019050613e69565b838801955050505b50505092915050565b6000613ea482613007565b613eae8185613df6565b9350613ebe818560208601613012565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613f00600583613df6565b9150613f0b82613eca565b600582019050919050565b6000613f228285613e16565b9150613f2e8284613e99565b9150613f3982613ef3565b91508190509392505050565b7f596f7520617265206e6f7420696e207468652077686974656c6973742e000000600082015250565b6000613f7b601d83612ebb565b9150613f8682613f45565b602082019050919050565b60006020820190508181036000830152613faa81613f6e565b9050919050565b7f4d6178696d756d207072652d73616c65206d696e747320726561636865642e00600082015250565b6000613fe7601f83612ebb565b9150613ff282613fb1565b602082019050919050565b6000602082019050818103600083015261401681613fda565b9050919050565b6000604082019050614032600083018561313d565b61403f602083018461313d565b9392505050565b600081519050614055816134ab565b92915050565b60006020828403121561407157614070612f42565b5b600061407f84828501614046565b91505092915050565b60008160601b9050919050565b60006140a082614088565b9050919050565b60006140b282614095565b9050919050565b6140ca6140c58261312b565b6140a7565b82525050565b60006140dc82846140b9565b60148201915081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000614121601783613df6565b915061412c826140eb565b601782019050919050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061416d601183613df6565b915061417882614137565b601182019050919050565b600061418e82614114565b915061419a8285613e99565b91506141a582614160565b91506141b18284613e99565b91508190509392505050565b600081519050919050565b600082825260208201905092915050565b60006141e4826141bd565b6141ee81856141c8565b93506141fe818560208601613012565b6142078161303c565b840191505092915050565b6000608082019050614227600083018761313d565b614234602083018661313d565b61424160408301856131d3565b818103606083015261425381846141d9565b905095945050505050565b60008151905061426d81612f78565b92915050565b60006020828403121561428957614288612f42565b5b60006142978482850161425e565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006142da826130a8565b9150600082036142ed576142ec6138c1565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b600061432e602083612ebb565b9150614339826142f8565b602082019050919050565b6000602082019050818103600083015261435d81614321565b9050919050565b600061436f826130a8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036143a1576143a06138c1565b5b60018201905091905056fea2646970667358221220989ce8219eb9e73f7347aa94c9d4b2cd5491b2ac7a4fe957779bba10c97e0c4e64736f6c6343000810003368747470733a2f2f617277656176652e6e65742f663377324d70333268544750553133666e54764c593834434a636c6e7370425a4a7843674a57562d4373512f47e67801dd6d6c233b84bacbeea3c3886e626ea93b7c9b5765e4c1bcf8dc5b070000000000000000000000006268f463379675479425c1ff708f0ee1fc1c0e2c
Deployed Bytecode
0x6080604052600436106102555760003560e01c80637cb6475911610139578063a217fddf116100b6578063d2cab0561161007a578063d2cab056146108af578063d547741f146108cb578063d5abeb01146108f4578063e985e9c51461091f578063f1c4035d1461095c578063f9020e331461098757610295565b8063a217fddf146107d7578063a22cb46514610802578063b88d4fde1461082b578063b977665e14610847578063c87b56dd1461087257610295565b806395d89b41116100fd57806395d89b41146107005780639abc83201461072b5780639b5c2812146107565780639c91dd5614610781578063a035b1fe146107ac57610295565b80637cb64759146106195780637e30a6c21461064257806385f438c11461066d5780638d0df0251461069857806391d14854146106c357610295565b80632f2ff15d116101d257806342842e0e1161019657806342842e0e146105165780635e720718146105325780636352211e1461054957806370a0823114610586578063797669c9146105c35780637983e997146105ee57610295565b80632f2ff15d1461046457806331ffd6f11461048d57806336568abe146104b85780633ccfd60b146104e157806341f43434146104eb57610295565b806323b872dd1161021957806323b872dd14610386578063248a9ca3146103a25780632a55205a146103df5780632db115441461041d5780632eb4a7ab1461043957610295565b806301ffc9a71461029a57806306fdde03146102d7578063081812fc14610302578063095ea7b31461033f57806318160ddd1461035b57610295565b36610295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161028c90612f18565b60405180910390fd5b600080fd5b3480156102a657600080fd5b506102c160048036038101906102bc9190612fa4565b6109b2565b6040516102ce9190612fec565b60405180910390f35b3480156102e357600080fd5b506102ec6109c4565b6040516102f99190613086565b60405180910390f35b34801561030e57600080fd5b50610329600480360381019061032491906130de565b610a56565b604051610336919061314c565b60405180910390f35b61035960048036038101906103549190613193565b610ad5565b005b34801561036757600080fd5b50610370610aee565b60405161037d91906131e2565b60405180910390f35b6103a0600480360381019061039b91906131fd565b610b05565b005b3480156103ae57600080fd5b506103c960048036038101906103c49190613286565b610b54565b6040516103d691906132c2565b60405180910390f35b3480156103eb57600080fd5b50610406600480360381019061040191906132dd565b610b74565b60405161041492919061331d565b60405180910390f35b610437600480360381019061043291906130de565b610d5e565b005b34801561044557600080fd5b5061044e610ecb565b60405161045b91906132c2565b60405180910390f35b34801561047057600080fd5b5061048b60048036038101906104869190613346565b610ed1565b005b34801561049957600080fd5b506104a2610ef2565b6040516104af91906131e2565b60405180910390f35b3480156104c457600080fd5b506104df60048036038101906104da9190613346565b610ef8565b005b6104e9610f7b565b005b3480156104f757600080fd5b50610500611139565b60405161050d91906133e5565b60405180910390f35b610530600480360381019061052b91906131fd565b61114b565b005b34801561053e57600080fd5b5061054761119a565b005b34801561055557600080fd5b50610570600480360381019061056b91906130de565b611294565b60405161057d919061314c565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a89190613400565b6112a6565b6040516105ba91906131e2565b60405180910390f35b3480156105cf57600080fd5b506105d861135e565b6040516105e591906132c2565b60405180910390f35b3480156105fa57600080fd5b50610603611382565b604051610610919061314c565b60405180910390f35b34801561062557600080fd5b50610640600480360381019061063b9190613286565b6113a8565b005b34801561064e57600080fd5b506106576113dd565b6040516106649190613454565b60405180910390f35b34801561067957600080fd5b506106826113fb565b60405161068f91906132c2565b60405180910390f35b3480156106a457600080fd5b506106ad61141f565b6040516106ba919061314c565b60405180910390f35b3480156106cf57600080fd5b506106ea60048036038101906106e59190613346565b611445565b6040516106f79190612fec565b60405180910390f35b34801561070c57600080fd5b506107156114b0565b6040516107229190613086565b60405180910390f35b34801561073757600080fd5b50610740611542565b60405161074d9190613086565b60405180910390f35b34801561076257600080fd5b5061076b6115d0565b604051610778919061314c565b60405180910390f35b34801561078d57600080fd5b506107966115f6565b6040516107a39190613490565b60405180910390f35b3480156107b857600080fd5b506107c161161c565b6040516107ce91906131e2565b60405180910390f35b3480156107e357600080fd5b506107ec611622565b6040516107f991906132c2565b60405180910390f35b34801561080e57600080fd5b50610829600480360381019061082491906134d7565b611629565b005b6108456004803603810190610840919061364c565b611642565b005b34801561085357600080fd5b5061085c611693565b60405161086991906131e2565b60405180910390f35b34801561087e57600080fd5b50610899600480360381019061089491906130de565b611699565b6040516108a69190613086565b60405180910390f35b6108c960048036038101906108c4919061372f565b611715565b005b3480156108d757600080fd5b506108f260048036038101906108ed9190613346565b6118db565b005b34801561090057600080fd5b506109096118fc565b60405161091691906131e2565b60405180910390f35b34801561092b57600080fd5b506109466004803603810190610941919061378f565b611902565b6040516109539190612fec565b60405180910390f35b34801561096857600080fd5b50610971611996565b60405161097e919061314c565b60405180910390f35b34801561099357600080fd5b5061099c6119bc565b6040516109a99190613846565b60405180910390f35b60006109bd826119cf565b9050919050565b6060600280546109d390613890565b80601f01602080910402602001604051908101604052809291908181526020018280546109ff90613890565b8015610a4c5780601f10610a2157610100808354040283529160200191610a4c565b820191906000526020600020905b815481529060010190602001808311610a2f57829003601f168201915b5050505050905090565b6000610a6182611a49565b610a97576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610adf81611aa8565b610ae98383611ba5565b505050565b6000610af8611ce9565b6001546000540303905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b4357610b4233611aa8565b5b610b4e848484611cee565b50505050565b600060086000838152602001908152602001600020600101549050919050565b6000806000600a60008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610d095760096040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610d13612010565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610d3f91906138f0565b610d499190613979565b90508160000151819350935050509250929050565b6002600b60009054906101000a900460ff166002811115610d8257610d816137cf565b5b14610dc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db9906139f6565b60405180910390fd5b600581610dce3361201a565b610dd89190613a16565b10610e18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0f90613abc565b60405180910390fd5b600c5481610e24610aee565b610e2e9190613a16565b1115610e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6690613b28565b60405180910390fd5b600f5481610e7d91906138f0565b3414610ebe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb590613b94565b60405180910390fd5b610ec83382612071565b50565b60165481565b610eda82610b54565b610ee38161208f565b610eed83836120a3565b505050565b600e5481565b610f00612184565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6490613c26565b60405180910390fd5b610f77828261218c565b5050565b7f10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e4610fa58161208f565b600047905060006010600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166009600a84610ff49190613979565b610ffe91906138f0565b60405161100a90613c77565b60006040518083038185875af1925050503d8060008114611047576040519150601f19603f3d011682016040523d82523d6000602084013e61104c565b606091505b505090506000601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600a846110989190613979565b6040516110a490613c77565b60006040518083038185875af1925050503d80600081146110e1576040519150601f19603f3d011682016040523d82523d6000602084013e6110e6565b606091505b505090508180156110f45750805b611133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112a90613cd8565b60405180910390fd5b50505050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146111895761118833611aa8565b5b61119484848461226e565b50505050565b7f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f6111c48161208f565b6002600b60009054906101000a900460ff1660028111156111e8576111e76137cf565b5b03611228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121f90613d6a565b60405180910390fd5b6001600b60009054906101000a900460ff16600281111561124c5761124b6137cf565b5b6112569190613a16565b6002811115611268576112676137cf565b5b600b60006101000a81548160ff0219169083600281111561128c5761128b6137cf565b5b021790555050565b600061129f8261228e565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361130d576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b7f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f81565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f6113d28161208f565b816016819055505050565b601060009054906101000a90046bffffffffffffffffffffffff1681565b7f10dac8c06a04bec0b551627dad28bc00d6516b0caacd1c7b345fcdb5211334e481565b601260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6060600380546114bf90613890565b80601f01602080910402602001604051908101604052809291908181526020018280546114eb90613890565b80156115385780601f1061150d57610100808354040283529160200191611538565b820191906000526020600020905b81548152906001019060200180831161151b57829003601f168201915b5050505050905090565b6015805461154f90613890565b80601f016020809104026020016040519081016040528092919081815260200182805461157b90613890565b80156115c85780601f1061159d576101008083540402835291602001916115c8565b820191906000526020600020905b8154815290600101906020018083116115ab57829003601f168201915b505050505081565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6010600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600f5481565b6000801b81565b8161163381611aa8565b61163d838361235a565b505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146116805761167f33611aa8565b5b61168c85858585612465565b5050505050565b600d5481565b60606116a482611a49565b6116e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116da90613dd6565b60405180910390fd5b60156116ee836124d8565b6040516020016116ff929190613f16565b6040516020818303038152906040529050919050565b6001600b60009054906101000a900460ff166002811115611739576117386137cf565b5b14611779576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611770906139f6565b60405180910390fd5b611784338383612528565b6117c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ba90613f91565b60405180910390fd5b6003836117cf3361201a565b6117d99190613a16565b10611819576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181090613abc565b60405180910390fd5b600d54600e546118299190613a16565b83611832610aee565b61183c9190613a16565b111561187d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187490613ffd565b60405180910390fd5b600f548361188b91906138f0565b34146118cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c390613b94565b60405180910390fd5b6118d63384612071565b505050565b6118e482610b54565b6118ed8161208f565b6118f7838361218c565b505050565b600c5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b60009054906101000a900460ff1681565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a425750611a41826125a7565b5b9050919050565b600081611a54611ce9565b11158015611a63575060005482105b8015611aa1575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611ba2576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611b1f92919061401d565b602060405180830381865afa158015611b3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b60919061405b565b611ba157806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b98919061314c565b60405180910390fd5b5b50565b6000611bb082611294565b90508073ffffffffffffffffffffffffffffffffffffffff16611bd1612621565b73ffffffffffffffffffffffffffffffffffffffff1614611c3457611bfd81611bf8612621565b611902565b611c33576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b6000611cf98261228e565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d60576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611d6c84612629565b91509150611d828187611d7d612621565b612650565b611dce57611d9786611d92612621565b611902565b611dcd576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611e34576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e418686866001612694565b8015611e4c57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550611f1a85611ef688888761269a565b7c0200000000000000000000000000000000000000000000000000000000176126c2565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603611fa05760006001850190506000600460008381526020019081526020016000205403611f9e576000548114611f9d578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461200886868660016126ed565b505050505050565b6000612710905090565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b61208b8282604051806020016040528060008152506126f3565b5050565b6120a08161209b612184565b612790565b50565b6120ad8282611445565b6121805760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612125612184565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b6121968282611445565b1561226a5760006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061220f612184565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b61228983838360405180602001604052806000815250611642565b505050565b6000808290508061229d611ce9565b11612323576000548110156123225760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612320575b600081036123165760046000836001900393508381526020019081526020016000205490506122ec565b8092505050612355565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b8060076000612367612621565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612414612621565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516124599190612fec565b60405180910390a35050565b612470848484610b05565b60008373ffffffffffffffffffffffffffffffffffffffff163b146124d25761249b84848484612815565b6124d1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b606060a060405101806040526020810391506000825281835b60011561251357600184039350600a81066030018453600a81049050806124f1575b50828103602084039350808452505050919050565b600061259e838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050506016548660405160200161258391906140d0565b60405160208183030381529060405280519060200120612965565b90509392505050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061261a57506126198261297c565b5b9050919050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86126b18686846129e6565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6126fd83836129ef565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461278b57600080549050600083820390505b61273d6000868380600101945086612815565b612773576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81811061272a57816000541461278857600080fd5b50505b505050565b61279a8282611445565b612811576127a781612baa565b6127b58360001c6020612bd7565b6040516020016127c6929190614183565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128089190613086565b60405180910390fd5b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261283b612621565b8786866040518563ffffffff1660e01b815260040161285d9493929190614212565b6020604051808303816000875af192505050801561289957506040513d601f19601f820116820180604052508101906128969190614273565b60015b612912573d80600081146128c9576040519150601f19603f3d011682016040523d82523d6000602084013e6128ce565b606091505b50600081510361290a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6000826129728584612e13565b1490509392505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60009392505050565b60008054905060008203612a2f576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3c6000848385612694565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612ab383612aa4600086600061269a565b612aad85612e69565b176126c2565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612b5457808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612b19565b5060008203612b8f576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612ba560008483856126ed565b505050565b6060612bd08273ffffffffffffffffffffffffffffffffffffffff16601460ff16612bd7565b9050919050565b606060006002836002612bea91906138f0565b612bf49190613a16565b67ffffffffffffffff811115612c0d57612c0c613521565b5b6040519080825280601f01601f191660200182016040528015612c3f5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612c7757612c766142a0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612cdb57612cda6142a0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612d1b91906138f0565b612d259190613a16565b90505b6001811115612dc5577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612d6757612d666142a0565b5b1a60f81b828281518110612d7e57612d7d6142a0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612dbe906142cf565b9050612d28565b5060008414612e09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e0090614344565b60405180910390fd5b8091505092915050565b60008082905060005b8451811015612e5e57612e4982868381518110612e3c57612e3b6142a0565b5b6020026020010151612e79565b91508080612e5690614364565b915050612e1c565b508091505092915050565b60006001821460e11b9050919050565b6000818310612e9157612e8c8284612ea4565b612e9c565b612e9b8383612ea4565b5b905092915050565b600082600052816020526040600020905092915050565b600082825260208201905092915050565b7f4f6e6c7920696620796f75206d696e7400000000000000000000000000000000600082015250565b6000612f02601083612ebb565b9150612f0d82612ecc565b602082019050919050565b60006020820190508181036000830152612f3181612ef5565b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612f8181612f4c565b8114612f8c57600080fd5b50565b600081359050612f9e81612f78565b92915050565b600060208284031215612fba57612fb9612f42565b5b6000612fc884828501612f8f565b91505092915050565b60008115159050919050565b612fe681612fd1565b82525050565b60006020820190506130016000830184612fdd565b92915050565b600081519050919050565b60005b83811015613030578082015181840152602081019050613015565b60008484015250505050565b6000601f19601f8301169050919050565b600061305882613007565b6130628185612ebb565b9350613072818560208601613012565b61307b8161303c565b840191505092915050565b600060208201905081810360008301526130a0818461304d565b905092915050565b6000819050919050565b6130bb816130a8565b81146130c657600080fd5b50565b6000813590506130d8816130b2565b92915050565b6000602082840312156130f4576130f3612f42565b5b6000613102848285016130c9565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006131368261310b565b9050919050565b6131468161312b565b82525050565b6000602082019050613161600083018461313d565b92915050565b6131708161312b565b811461317b57600080fd5b50565b60008135905061318d81613167565b92915050565b600080604083850312156131aa576131a9612f42565b5b60006131b88582860161317e565b92505060206131c9858286016130c9565b9150509250929050565b6131dc816130a8565b82525050565b60006020820190506131f760008301846131d3565b92915050565b60008060006060848603121561321657613215612f42565b5b60006132248682870161317e565b93505060206132358682870161317e565b9250506040613246868287016130c9565b9150509250925092565b6000819050919050565b61326381613250565b811461326e57600080fd5b50565b6000813590506132808161325a565b92915050565b60006020828403121561329c5761329b612f42565b5b60006132aa84828501613271565b91505092915050565b6132bc81613250565b82525050565b60006020820190506132d760008301846132b3565b92915050565b600080604083850312156132f4576132f3612f42565b5b6000613302858286016130c9565b9250506020613313858286016130c9565b9150509250929050565b6000604082019050613332600083018561313d565b61333f60208301846131d3565b9392505050565b6000806040838503121561335d5761335c612f42565b5b600061336b85828601613271565b925050602061337c8582860161317e565b9150509250929050565b6000819050919050565b60006133ab6133a66133a18461310b565b613386565b61310b565b9050919050565b60006133bd82613390565b9050919050565b60006133cf826133b2565b9050919050565b6133df816133c4565b82525050565b60006020820190506133fa60008301846133d6565b92915050565b60006020828403121561341657613415612f42565b5b60006134248482850161317e565b91505092915050565b60006bffffffffffffffffffffffff82169050919050565b61344e8161342d565b82525050565b60006020820190506134696000830184613445565b92915050565b600061347a8261310b565b9050919050565b61348a8161346f565b82525050565b60006020820190506134a56000830184613481565b92915050565b6134b481612fd1565b81146134bf57600080fd5b50565b6000813590506134d1816134ab565b92915050565b600080604083850312156134ee576134ed612f42565b5b60006134fc8582860161317e565b925050602061350d858286016134c2565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6135598261303c565b810181811067ffffffffffffffff8211171561357857613577613521565b5b80604052505050565b600061358b612f38565b90506135978282613550565b919050565b600067ffffffffffffffff8211156135b7576135b6613521565b5b6135c08261303c565b9050602081019050919050565b82818337600083830152505050565b60006135ef6135ea8461359c565b613581565b90508281526020810184848401111561360b5761360a61351c565b5b6136168482856135cd565b509392505050565b600082601f83011261363357613632613517565b5b81356136438482602086016135dc565b91505092915050565b6000806000806080858703121561366657613665612f42565b5b60006136748782880161317e565b94505060206136858782880161317e565b9350506040613696878288016130c9565b925050606085013567ffffffffffffffff8111156136b7576136b6612f47565b5b6136c38782880161361e565b91505092959194509250565b600080fd5b600080fd5b60008083601f8401126136ef576136ee613517565b5b8235905067ffffffffffffffff81111561370c5761370b6136cf565b5b602083019150836020820283011115613728576137276136d4565b5b9250929050565b60008060006040848603121561374857613747612f42565b5b6000613756868287016130c9565b935050602084013567ffffffffffffffff81111561377757613776612f47565b5b613783868287016136d9565b92509250509250925092565b600080604083850312156137a6576137a5612f42565b5b60006137b48582860161317e565b92505060206137c58582860161317e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003811061380f5761380e6137cf565b5b50565b6000819050613820826137fe565b919050565b600061383082613812565b9050919050565b61384081613825565b82525050565b600060208201905061385b6000830184613837565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806138a857607f821691505b6020821081036138bb576138ba613861565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138fb826130a8565b9150613906836130a8565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561393f5761393e6138c1565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613984826130a8565b915061398f836130a8565b92508261399f5761399e61394a565b5b828204905092915050565b7f57726f6e672073616c6520737461747573000000000000000000000000000000600082015250565b60006139e0601183612ebb565b91506139eb826139aa565b602082019050919050565b60006020820190508181036000830152613a0f816139d3565b9050919050565b6000613a21826130a8565b9150613a2c836130a8565b9250828201905080821115613a4457613a436138c1565b5b92915050565b7f4d6178696d756d20616d6f756e74206f66204e4654206d696e7473207265616360008201527f6865642e00000000000000000000000000000000000000000000000000000000602082015250565b6000613aa6602483612ebb565b9150613ab182613a4a565b604082019050919050565b60006020820190508181036000830152613ad581613a99565b9050919050565b7f4d6178696d756d2073616c65206d696e747320726561636865642e0000000000600082015250565b6000613b12601b83612ebb565b9150613b1d82613adc565b602082019050919050565b60006020820190508181036000830152613b4181613b05565b9050919050565b7f53656e642065786163742070726963652e000000000000000000000000000000600082015250565b6000613b7e601183612ebb565b9150613b8982613b48565b602082019050919050565b60006020820190508181036000830152613bad81613b71565b9050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000613c10602f83612ebb565b9150613c1b82613bb4565b604082019050919050565b60006020820190508181036000830152613c3f81613c03565b9050919050565b600081905092915050565b50565b6000613c61600083613c46565b9150613c6c82613c51565b600082019050919050565b6000613c8282613c54565b9150819050919050565b7f4661696c656420746f2073656e64204574686572000000000000000000000000600082015250565b6000613cc2601483612ebb565b9150613ccd82613c8c565b602082019050919050565b60006020820190508181036000830152613cf181613cb5565b9050919050565b7f4c6173742073616c652073746174757320686173206265656e2072656163686560008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d54602183612ebb565b9150613d5f82613cf8565b604082019050919050565b60006020820190508181036000830152613d8381613d47565b9050919050565b7f4e667420686173206e6f74206265656e206d696e746564207965740000000000600082015250565b6000613dc0601b83612ebb565b9150613dcb82613d8a565b602082019050919050565b60006020820190508181036000830152613def81613db3565b9050919050565b600081905092915050565b60008190508160005260206000209050919050565b60008154613e2381613890565b613e2d8186613df6565b94506001821660008114613e485760018114613e5d57613e90565b60ff1983168652811515820286019350613e90565b613e6685613e01565b60005b83811015613e8857815481890152600182019150602081019050613e69565b838801955050505b50505092915050565b6000613ea482613007565b613eae8185613df6565b9350613ebe818560208601613012565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613f00600583613df6565b9150613f0b82613eca565b600582019050919050565b6000613f228285613e16565b9150613f2e8284613e99565b9150613f3982613ef3565b91508190509392505050565b7f596f7520617265206e6f7420696e207468652077686974656c6973742e000000600082015250565b6000613f7b601d83612ebb565b9150613f8682613f45565b602082019050919050565b60006020820190508181036000830152613faa81613f6e565b9050919050565b7f4d6178696d756d207072652d73616c65206d696e747320726561636865642e00600082015250565b6000613fe7601f83612ebb565b9150613ff282613fb1565b602082019050919050565b6000602082019050818103600083015261401681613fda565b9050919050565b6000604082019050614032600083018561313d565b61403f602083018461313d565b9392505050565b600081519050614055816134ab565b92915050565b60006020828403121561407157614070612f42565b5b600061407f84828501614046565b91505092915050565b60008160601b9050919050565b60006140a082614088565b9050919050565b60006140b282614095565b9050919050565b6140ca6140c58261312b565b6140a7565b82525050565b60006140dc82846140b9565b60148201915081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000614121601783613df6565b915061412c826140eb565b601782019050919050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061416d601183613df6565b915061417882614137565b601182019050919050565b600061418e82614114565b915061419a8285613e99565b91506141a582614160565b91506141b18284613e99565b91508190509392505050565b600081519050919050565b600082825260208201905092915050565b60006141e4826141bd565b6141ee81856141c8565b93506141fe818560208601613012565b6142078161303c565b840191505092915050565b6000608082019050614227600083018761313d565b614234602083018661313d565b61424160408301856131d3565b818103606083015261425381846141d9565b905095945050505050565b60008151905061426d81612f78565b92915050565b60006020828403121561428957614288612f42565b5b60006142978482850161425e565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006142da826130a8565b9150600082036142ed576142ec6138c1565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b600061432e602083612ebb565b9150614339826142f8565b602082019050919050565b6000602082019050818103600083015261435d81614321565b9050919050565b600061436f826130a8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036143a1576143a06138c1565b5b60018201905091905056fea2646970667358221220989ce8219eb9e73f7347aa94c9d4b2cd5491b2ac7a4fe957779bba10c97e0c4e64736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
47e67801dd6d6c233b84bacbeea3c3886e626ea93b7c9b5765e4c1bcf8dc5b070000000000000000000000006268f463379675479425c1ff708f0ee1fc1c0e2c
-----Decoded View---------------
Arg [0] : _merkleRoot (bytes32): 0x47e67801dd6d6c233b84bacbeea3c3886e626ea93b7c9b5765e4c1bcf8dc5b07
Arg [1] : _payments (address): 0x6268f463379675479425c1fF708F0eE1fC1C0E2c
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 47e67801dd6d6c233b84bacbeea3c3886e626ea93b7c9b5765e4c1bcf8dc5b07
Arg [1] : 0000000000000000000000006268f463379675479425c1ff708f0ee1fc1c0e2c
Deployed Bytecode Sourcemap
101068:5772:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105280:26;;;;;;;;;;:::i;:::-;;;;;;;;101068:5772;;;;105628:192;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68635:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75126:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106053:165;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64386:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106226:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40091:131;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14061:442;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;103789:426;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;102270:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40532:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101467:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41676:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104878:356;;;:::i;:::-;;46842:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106405:179;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104259:201;;;;;;;;;;;;;:::i;:::-;;70028:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65570:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102341:68;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102014:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104505:121;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101627:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102416:70;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101868:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38564:147;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68811:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102130:90;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101756:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101711:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101551:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37669:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105869:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;106592:245;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101427:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105363:257;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103222:559;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40972:149;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101389:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76075:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101941:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101316:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105628:192;105752:4;105776:36;105800:11;105776:23;:36::i;:::-;105769:43;;105628:192;;;:::o;68635:100::-;68689:13;68722:5;68715:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68635:100;:::o;75126:218::-;75202:7;75227:16;75235:7;75227;:16::i;:::-;75222:64;;75252:34;;;;;;;;;;;;;;75222:64;75306:15;:24;75322:7;75306:24;;;;;;;;;;;:30;;;;;;;;;;;;75299:37;;75126:218;;;:::o;106053:165::-;106157:8;48363:30;48384:8;48363:20;:30::i;:::-;106178:32:::1;106192:8;106202:7;106178:13;:32::i;:::-;106053:165:::0;;;:::o;64386:323::-;64447:7;64675:15;:13;:15::i;:::-;64660:12;;64644:13;;:28;:46;64637:53;;64386:323;:::o;106226:171::-;106335:4;48191:10;48183:18;;:4;:18;;;48179:83;;48218:32;48239:10;48218:20;:32::i;:::-;48179:83;106352:37:::1;106371:4;106377:2;106381:7;106352:18;:37::i;:::-;106226:171:::0;;;;:::o;40091:131::-;40165:7;40192:6;:12;40199:4;40192:12;;;;;;;;;;;:22;;;40185:29;;40091:131;;;:::o;14061:442::-;14158:7;14167;14187:26;14216:17;:27;14234:8;14216:27;;;;;;;;;;;14187:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14288:1;14260:30;;:7;:16;;;:30;;;14256:92;;14317:19;14307:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14256:92;14360:21;14425:17;:15;:17::i;:::-;14384:58;;14398:7;:23;;;14385:36;;:10;:36;;;;:::i;:::-;14384:58;;;;:::i;:::-;14360:82;;14463:7;:16;;;14481:13;14455:40;;;;;;14061:442;;;;;:::o;103789:426::-;103883:1;103868:10;;;;;;;;;;;103863:16;;;;;;;;:::i;:::-;;:21;103855:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;103964:1;103953:8;103925:25;103939:10;103925:13;:25::i;:::-;:36;;;;:::i;:::-;:40;103917:89;;;;;;;;;;;;:::i;:::-;;;;;;;;;104053:9;;104041:8;104025:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:37;;104017:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;104137:5;;104126:8;:16;;;;:::i;:::-;104113:9;:29;104105:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;104176:31;104186:10;104198:8;104176:9;:31::i;:::-;103789:426;:::o;102270:25::-;;;;:::o;40532:147::-;40615:18;40628:4;40615:12;:18::i;:::-;38160:16;38171:4;38160:10;:16::i;:::-;40646:25:::1;40657:4;40663:7;40646:10;:25::i;:::-;40532:147:::0;;;:::o;101467:34::-;;;;:::o;41676:218::-;41783:12;:10;:12::i;:::-;41772:23;;:7;:23;;;41764:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;41860:26;41872:4;41878:7;41860:11;:26::i;:::-;41676:218;;:::o;104878:356::-;102458:28;38160:16;38171:4;38160:10;:16::i;:::-;104952:20:::1;104975:21;104952:44;;105008:12;105025:15;;;;;;;;;;;:20;;105076:1;105071:2;105053:15;:20;;;;:::i;:::-;:24;;;;:::i;:::-;105025:57;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105007:75;;;105094:12;105119:6;;;;;;;;;;;105111:20;;105157:2;105139:15;:20;;;;:::i;:::-;105111:53;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105093:71;;;105183:7;:18;;;;;105194:7;105183:18;105175:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;104941:293;;;104878:356:::0;:::o;46842:143::-;46942:42;46842:143;:::o;106405:179::-;106518:4;48191:10;48183:18;;:4;:18;;;48179:83;;48218:32;48239:10;48218:20;:32::i;:::-;48179:83;106535:41:::1;106558:4;106564:2;106568:7;106535:22;:41::i;:::-;106405:179:::0;;;;:::o;104259:201::-;102382:27;38160:16;38171:4;38160:10;:16::i;:::-;104356:1:::1;104343:10;;;;;;;;;;;104338:16;;;;;;;;:::i;:::-;;:19:::0;104330:65:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;104450:1;104436:10;;;;;;;;;;;104430:17;;;;;;;;:::i;:::-;;:21;;;;:::i;:::-;104419:33;;;;;;;;:::i;:::-;;104406:10;;:46;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;104259:201:::0;:::o;70028:152::-;70100:7;70143:27;70162:7;70143:18;:27::i;:::-;70120:52;;70028:152;;;:::o;65570:233::-;65642:7;65683:1;65666:19;;:5;:19;;;65662:60;;65694:28;;;;;;;;;;;;;;65662:60;59729:13;65740:18;:25;65759:5;65740:25;;;;;;;;;;;;;;;;:55;65733:62;;65570:233;;;:::o;102341:68::-;102382:27;102341:68;:::o;102014:66::-;;;;;;;;;;;;;:::o;104505:121::-;102382:27;38160:16;38171:4;38160:10;:16::i;:::-;104607:11:::1;104594:10;:24;;;;104505:121:::0;;:::o;101627:31::-;;;;;;;;;;;;;:::o;102416:70::-;102458:28;102416:70;:::o;101868:66::-;;;;;;;;;;;;;:::o;38564:147::-;38650:4;38674:6;:12;38681:4;38674:12;;;;;;;;;;;:20;;:29;38695:7;38674:29;;;;;;;;;;;;;;;;;;;;;;;;;38667:36;;38564:147;;;;:::o;68811:104::-;68867:13;68900:7;68893:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68811:104;:::o;102130:90::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;101756:66::-;;;;;;;;;;;;;:::o;101711:38::-;;;;;;;;;;;;;:::o;101551:30::-;;;;:::o;37669:49::-;37714:4;37669:49;;;:::o;105869:176::-;105973:8;48363:30;48384:8;48363:20;:30::i;:::-;105994:43:::1;106018:8;106028;105994:23;:43::i;:::-;105869:176:::0;;;:::o;106592:245::-;106760:4;48191:10;48183:18;;:4;:18;;;48179:83;;48218:32;48239:10;48218:20;:32::i;:::-;48179:83;106782:47:::1;106805:4;106811:2;106815:7;106824:4;106782:22;:47::i;:::-;106592:245:::0;;;;;:::o;101427:33::-;;;;:::o;105363:257::-;105448:13;105482:17;105490:8;105482:7;:17::i;:::-;105474:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;105573:7;105582:19;105592:8;105582:9;:19::i;:::-;105556:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;105542:70;;105363:257;;;:::o;103222:559::-;103342:1;103327:10;;;;;;;;;;;103322:16;;;;;;;;:::i;:::-;;:21;103314:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;103384:32;103398:10;103410:5;;103384:13;:32::i;:::-;103376:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;103508:1;103497:8;103469:25;103483:10;103469:13;:25::i;:::-;:36;;;;:::i;:::-;:40;103461:89;;;;;;;;;;;;:::i;:::-;;;;;;;;;103613:12;;103597:13;;:28;;;;:::i;:::-;103585:8;103569:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:56;;103561:100;;;;;;;;;;;;:::i;:::-;;;;;;;;;103704:5;;103693:8;:16;;;;:::i;:::-;103680:9;:29;103672:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;103742:31;103752:10;103764:8;103742:9;:31::i;:::-;103222:559;;;:::o;40972:149::-;41056:18;41069:4;41056:12;:18::i;:::-;38160:16;38171:4;38160:10;:16::i;:::-;41087:26:::1;41099:4;41105:7;41087:11;:26::i;:::-;40972:149:::0;;;:::o;101389:31::-;;;;:::o;76075:164::-;76172:4;76196:18;:25;76215:5;76196:25;;;;;;;;;;;;;;;:35;76222:8;76196:35;;;;;;;;;;;;;;;;;;;;;;;;;76189:42;;76075:164;;;;:::o;101941:66::-;;;;;;;;;;;;;:::o;101316:28::-;;;;;;;;;;;;;:::o;13791:215::-;13893:4;13932:26;13917:41;;;:11;:41;;;;:81;;;;13962:36;13986:11;13962:23;:36::i;:::-;13917:81;13910:88;;13791:215;;;:::o;76497:282::-;76562:4;76618:7;76599:15;:13;:15::i;:::-;:26;;:66;;;;;76652:13;;76642:7;:23;76599:66;:153;;;;;76751:1;60505:8;76703:17;:26;76721:7;76703:26;;;;;;;;;;;;:44;:49;76599:153;76579:173;;76497:282;;;:::o;48421:419::-;48660:1;46942:42;48612:45;;;:49;48608:225;;;46942:42;48683;;;48734:4;48741:8;48683:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48678:144;;48797:8;48778:28;;;;;;;;;;;:::i;:::-;;;;;;;;48678:144;48608:225;48421:419;:::o;74559:408::-;74648:13;74664:16;74672:7;74664;:16::i;:::-;74648:32;;74720:5;74697:28;;:19;:17;:19::i;:::-;:28;;;74693:175;;74745:44;74762:5;74769:19;:17;:19::i;:::-;74745:16;:44::i;:::-;74740:128;;74817:35;;;;;;;;;;;;;;74740:128;74693:175;74913:2;74880:15;:24;74896:7;74880:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;74951:7;74947:2;74931:28;;74940:5;74931:28;;;;;;;;;;;;74637:330;74559:408;;:::o;63902:92::-;63958:7;63902:92;:::o;78765:2825::-;78907:27;78937;78956:7;78937:18;:27::i;:::-;78907:57;;79022:4;78981:45;;78997:19;78981:45;;;78977:86;;79035:28;;;;;;;;;;;;;;78977:86;79077:27;79106:23;79133:35;79160:7;79133:26;:35::i;:::-;79076:92;;;;79268:68;79293:15;79310:4;79316:19;:17;:19::i;:::-;79268:24;:68::i;:::-;79263:180;;79356:43;79373:4;79379:19;:17;:19::i;:::-;79356:16;:43::i;:::-;79351:92;;79408:35;;;;;;;;;;;;;;79351:92;79263:180;79474:1;79460:16;;:2;:16;;;79456:52;;79485:23;;;;;;;;;;;;;;79456:52;79521:43;79543:4;79549:2;79553:7;79562:1;79521:21;:43::i;:::-;79657:15;79654:160;;;79797:1;79776:19;79769:30;79654:160;80194:18;:24;80213:4;80194:24;;;;;;;;;;;;;;;;80192:26;;;;;;;;;;;;80263:18;:22;80282:2;80263:22;;;;;;;;;;;;;;;;80261:24;;;;;;;;;;;80585:146;80622:2;80671:45;80686:4;80692:2;80696:19;80671:14;:45::i;:::-;60785:8;80643:73;80585:18;:146::i;:::-;80556:17;:26;80574:7;80556:26;;;;;;;;;;;:175;;;;80902:1;60785:8;80851:19;:47;:52;80847:627;;80924:19;80956:1;80946:7;:11;80924:33;;81113:1;81079:17;:30;81097:11;81079:30;;;;;;;;;;;;:35;81075:384;;81217:13;;81202:11;:28;81198:242;;81397:19;81364:17;:30;81382:11;81364:30;;;;;;;;;;;:52;;;;81198:242;81075:384;80905:569;80847:627;81521:7;81517:2;81502:27;;81511:4;81502:27;;;;;;;;;;;;81540:42;81561:4;81567:2;81571:7;81580:1;81540:20;:42::i;:::-;78896:2694;;;78765:2825;;;:::o;14785:97::-;14843:6;14869:5;14862:12;;14785:97;:::o;65885:178::-;65946:7;59729:13;59867:2;65974:18;:25;65993:5;65974:25;;;;;;;;;;;;;;;;:50;;65973:82;65966:89;;65885:178;;;:::o;92637:112::-;92714:27;92724:2;92728:8;92714:27;;;;;;;;;;;;:9;:27::i;:::-;92637:112;;:::o;39015:105::-;39082:30;39093:4;39099:12;:10;:12::i;:::-;39082:10;:30::i;:::-;39015:105;:::o;43273:238::-;43357:22;43365:4;43371:7;43357;:22::i;:::-;43352:152;;43428:4;43396:6;:12;43403:4;43396:12;;;;;;;;;;;:20;;:29;43417:7;43396:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;43479:12;:10;:12::i;:::-;43452:40;;43470:7;43452:40;;43464:4;43452:40;;;;;;;;;;43352:152;43273:238;;:::o;32436:98::-;32489:7;32516:10;32509:17;;32436:98;:::o;43691:239::-;43775:22;43783:4;43789:7;43775;:22::i;:::-;43771:152;;;43846:5;43814:6;:12;43821:4;43814:12;;;;;;;;;;;:20;;:29;43835:7;43814:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;43898:12;:10;:12::i;:::-;43871:40;;43889:7;43871:40;;43883:4;43871:40;;;;;;;;;;43771:152;43691:239;;:::o;81686:193::-;81832:39;81849:4;81855:2;81859:7;81832:39;;;;;;;;;;;;:16;:39::i;:::-;81686:193;;;:::o;71183:1275::-;71250:7;71270:12;71285:7;71270:22;;71353:4;71334:15;:13;:15::i;:::-;:23;71330:1061;;71387:13;;71380:4;:20;71376:1015;;;71425:14;71442:17;:23;71460:4;71442:23;;;;;;;;;;;;71425:40;;71559:1;60505:8;71531:6;:24;:29;71527:845;;72196:113;72213:1;72203:6;:11;72196:113;;72256:17;:25;72274:6;;;;;;;72256:25;;;;;;;;;;;;72247:34;;72196:113;;;72342:6;72335:13;;;;;;71527:845;71402:989;71376:1015;71330:1061;72419:31;;;;;;;;;;;;;;71183:1275;;;;:::o;75684:234::-;75831:8;75779:18;:39;75798:19;:17;:19::i;:::-;75779:39;;;;;;;;;;;;;;;:49;75819:8;75779:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;75891:8;75855:55;;75870:19;:17;:19::i;:::-;75855:55;;;75901:8;75855:55;;;;;;:::i;:::-;;;;;;;;75684:234;;:::o;82477:407::-;82652:31;82665:4;82671:2;82675:7;82652:12;:31::i;:::-;82716:1;82698:2;:14;;;:19;82694:183;;82737:56;82768:4;82774:2;82778:7;82787:5;82737:30;:56::i;:::-;82732:145;;82821:40;;;;;;;;;;;;;;82732:145;82694:183;82477:407;;;;:::o;99012:1745::-;99077:17;99511:4;99504;99498:11;99494:22;99603:1;99597:4;99590:15;99678:4;99675:1;99671:12;99664:19;;99760:1;99755:3;99748:14;99864:3;100103:5;100085:428;100111:1;100085:428;;;100151:1;100146:3;100142:11;100135:18;;100322:2;100316:4;100312:13;100308:2;100304:22;100299:3;100291:36;100416:2;100410:4;100406:13;100398:21;;100483:4;100085:428;100473:25;100085:428;100089:21;100552:3;100547;100543:13;100667:4;100662:3;100658:14;100651:21;;100732:6;100727:3;100720:19;99116:1634;;;99012:1745;;;:::o;104634:199::-;104724:4;104748:77;104767:6;;104748:77;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104775:10;;104814:8;104797:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;104787:37;;;;;;104748:18;:77::i;:::-;104741:84;;104634:199;;;;;:::o;38268:204::-;38353:4;38392:32;38377:47;;;:11;:47;;;;:87;;;;38428:36;38452:11;38428:23;:36::i;:::-;38377:87;38370:94;;38268:204;;;:::o;98805:105::-;98865:7;98892:10;98885:17;;98805:105;:::o;77660:485::-;77762:27;77791:23;77832:38;77873:15;:24;77889:7;77873:24;;;;;;;;;;;77832:65;;78050:18;78027:41;;78107:19;78101:26;78082:45;;78012:126;77660:485;;;:::o;76888:659::-;77037:11;77202:16;77195:5;77191:28;77182:37;;77362:16;77351:9;77347:32;77334:45;;77512:15;77501:9;77498:30;77490:5;77479:9;77476:20;77473:56;77463:66;;76888:659;;;;;:::o;83546:159::-;;;;;:::o;98114:311::-;98249:7;98269:16;60909:3;98295:19;:41;;98269:68;;60909:3;98363:31;98374:4;98380:2;98384:9;98363:10;:31::i;:::-;98355:40;;:62;;98348:69;;;98114:311;;;;;:::o;73006:450::-;73086:14;73254:16;73247:5;73243:28;73234:37;;73431:5;73417:11;73392:23;73388:41;73385:52;73378:5;73375:63;73365:73;;73006:450;;;;:::o;84370:158::-;;;;;:::o;91864:689::-;91995:19;92001:2;92005:8;91995:5;:19::i;:::-;92074:1;92056:2;:14;;;:19;92052:483;;92096:11;92110:13;;92096:27;;92142:13;92164:8;92158:3;:14;92142:30;;92191:233;92222:62;92261:1;92265:2;92269:7;;;;;;92278:5;92222:30;:62::i;:::-;92217:167;;92320:40;;;;;;;;;;;;;;92217:167;92419:3;92411:5;:11;92191:233;;92506:3;92489:13;;:20;92485:34;;92511:8;;;92485:34;92077:458;;92052:483;91864:689;;;:::o;39410:492::-;39499:22;39507:4;39513:7;39499;:22::i;:::-;39494:401;;39687:28;39707:7;39687:19;:28::i;:::-;39788:38;39816:4;39808:13;;39823:2;39788:19;:38::i;:::-;39592:257;;;;;;;;;:::i;:::-;;;;;;;;;;;;;39538:345;;;;;;;;;;;:::i;:::-;;;;;;;;39494:401;39410:492;;:::o;84968:716::-;85131:4;85177:2;85152:45;;;85198:19;:17;:19::i;:::-;85219:4;85225:7;85234:5;85152:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;85148:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85452:1;85435:6;:13;:18;85431:235;;85481:40;;;;;;;;;;;;;;85431:235;85624:6;85618:13;85609:6;85605:2;85601:15;85594:38;85148:529;85321:54;;;85311:64;;;:6;:64;;;;85304:71;;;84968:716;;;;;;:::o;1222:190::-;1347:4;1400;1371:25;1384:5;1391:4;1371:12;:25::i;:::-;:33;1364:40;;1222:190;;;;;:::o;12241:157::-;12326:4;12365:25;12350:40;;;:11;:40;;;;12343:47;;12241:157;;;:::o;97815:147::-;97952:6;97815:147;;;;;:::o;86146:2966::-;86219:20;86242:13;;86219:36;;86282:1;86270:8;:13;86266:44;;86292:18;;;;;;;;;;;;;;86266:44;86323:61;86353:1;86357:2;86361:12;86375:8;86323:21;:61::i;:::-;86867:1;59867:2;86837:1;:26;;86836:32;86824:8;:45;86798:18;:22;86817:2;86798:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;87146:139;87183:2;87237:33;87260:1;87264:2;87268:1;87237:14;:33::i;:::-;87204:30;87225:8;87204:20;:30::i;:::-;:66;87146:18;:139::i;:::-;87112:17;:31;87130:12;87112:31;;;;;;;;;;;:173;;;;87302:16;87333:11;87362:8;87347:12;:23;87333:37;;87883:16;87879:2;87875:25;87863:37;;88255:12;88215:8;88174:1;88112:25;88053:1;87992;87965:335;88626:1;88612:12;88608:20;88566:346;88667:3;88658:7;88655:16;88566:346;;88885:7;88875:8;88872:1;88845:25;88842:1;88839;88834:59;88720:1;88711:7;88707:15;88696:26;;88566:346;;;88570:77;88957:1;88945:8;:13;88941:45;;88967:19;;;;;;;;;;;;;;88941:45;89019:3;89003:13;:19;;;;86572:2462;;89044:60;89073:1;89077:2;89081:12;89095:8;89044:20;:60::i;:::-;86208:2904;86146:2966;;:::o;31599:151::-;31657:13;31690:52;31718:4;31702:22;;29754:2;31690:52;;:11;:52::i;:::-;31683:59;;31599:151;;;:::o;30995:447::-;31070:13;31096:19;31141:1;31132:6;31128:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;31118:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31096:47;;31154:15;:6;31161:1;31154:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;31180;:6;31187:1;31180:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;31211:9;31236:1;31227:6;31223:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;31211:26;;31206:131;31243:1;31239;:5;31206:131;;;31278:8;31295:3;31287:5;:11;31278:21;;;;;;;:::i;:::-;;;;;31266:6;31273:1;31266:9;;;;;;;;:::i;:::-;;;;;:33;;;;;;;;;;;31324:1;31314:11;;;;;31246:3;;;;:::i;:::-;;;31206:131;;;;31364:1;31355:5;:10;31347:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;31427:6;31413:21;;;30995:447;;;;:::o;2089:296::-;2172:7;2192:20;2215:4;2192:27;;2235:9;2230:118;2254:5;:12;2250:1;:16;2230:118;;;2303:33;2313:12;2327:5;2333:1;2327:8;;;;;;;;:::i;:::-;;;;;;;;2303:9;:33::i;:::-;2288:48;;2268:3;;;;;:::i;:::-;;;;2230:118;;;;2365:12;2358:19;;;2089:296;;;;:::o;73558:324::-;73628:14;73861:1;73851:8;73848:15;73822:24;73818:46;73808:56;;73558:324;;;:::o;9129:149::-;9192:7;9223:1;9219;:5;:51;;9250:20;9265:1;9268;9250:14;:20::i;:::-;9219:51;;;9227:20;9242:1;9245;9227:14;:20::i;:::-;9219:51;9212:58;;9129:149;;;;:::o;9286:268::-;9354:13;9461:1;9455:4;9448:15;9490:1;9484:4;9477:15;9531:4;9525;9515:21;9506:30;;9286:268;;;;:::o;7:169:1:-;91:11;125:6;120:3;113:19;165:4;160:3;156:14;141:29;;7:169;;;;:::o;182:166::-;322:18;318:1;310:6;306:14;299:42;182:166;:::o;354:366::-;496:3;517:67;581:2;576:3;517:67;:::i;:::-;510:74;;593:93;682:3;593:93;:::i;:::-;711:2;706:3;702:12;695:19;;354:366;;;:::o;726:419::-;892:4;930:2;919:9;915:18;907:26;;979:9;973:4;969:20;965:1;954:9;950:17;943:47;1007:131;1133:4;1007:131;:::i;:::-;999:139;;726:419;;;:::o;1151:75::-;1184:6;1217:2;1211:9;1201:19;;1151:75;:::o;1232:117::-;1341:1;1338;1331:12;1355:117;1464:1;1461;1454:12;1478:149;1514:7;1554:66;1547:5;1543:78;1532:89;;1478:149;;;:::o;1633:120::-;1705:23;1722:5;1705:23;:::i;:::-;1698:5;1695:34;1685:62;;1743:1;1740;1733:12;1685:62;1633:120;:::o;1759:137::-;1804:5;1842:6;1829:20;1820:29;;1858:32;1884:5;1858:32;:::i;:::-;1759:137;;;;:::o;1902:327::-;1960:6;2009:2;1997:9;1988:7;1984:23;1980:32;1977:119;;;2015:79;;:::i;:::-;1977:119;2135:1;2160:52;2204:7;2195:6;2184:9;2180:22;2160:52;:::i;:::-;2150:62;;2106:116;1902:327;;;;:::o;2235:90::-;2269:7;2312:5;2305:13;2298:21;2287:32;;2235:90;;;:::o;2331:109::-;2412:21;2427:5;2412:21;:::i;:::-;2407:3;2400:34;2331:109;;:::o;2446:210::-;2533:4;2571:2;2560:9;2556:18;2548:26;;2584:65;2646:1;2635:9;2631:17;2622:6;2584:65;:::i;:::-;2446:210;;;;:::o;2662:99::-;2714:6;2748:5;2742:12;2732:22;;2662:99;;;:::o;2767:246::-;2848:1;2858:113;2872:6;2869:1;2866:13;2858:113;;;2957:1;2952:3;2948:11;2942:18;2938:1;2933:3;2929:11;2922:39;2894:2;2891:1;2887:10;2882:15;;2858:113;;;3005:1;2996:6;2991:3;2987:16;2980:27;2829:184;2767:246;;;:::o;3019:102::-;3060:6;3111:2;3107:7;3102:2;3095:5;3091:14;3087:28;3077:38;;3019:102;;;:::o;3127:377::-;3215:3;3243:39;3276:5;3243:39;:::i;:::-;3298:71;3362:6;3357:3;3298:71;:::i;:::-;3291:78;;3378:65;3436:6;3431:3;3424:4;3417:5;3413:16;3378:65;:::i;:::-;3468:29;3490:6;3468:29;:::i;:::-;3463:3;3459:39;3452:46;;3219:285;3127:377;;;;:::o;3510:313::-;3623:4;3661:2;3650:9;3646:18;3638:26;;3710:9;3704:4;3700:20;3696:1;3685:9;3681:17;3674:47;3738:78;3811:4;3802:6;3738:78;:::i;:::-;3730:86;;3510:313;;;;:::o;3829:77::-;3866:7;3895:5;3884:16;;3829:77;;;:::o;3912:122::-;3985:24;4003:5;3985:24;:::i;:::-;3978:5;3975:35;3965:63;;4024:1;4021;4014:12;3965:63;3912:122;:::o;4040:139::-;4086:5;4124:6;4111:20;4102:29;;4140:33;4167:5;4140:33;:::i;:::-;4040:139;;;;:::o;4185:329::-;4244:6;4293:2;4281:9;4272:7;4268:23;4264:32;4261:119;;;4299:79;;:::i;:::-;4261:119;4419:1;4444:53;4489:7;4480:6;4469:9;4465:22;4444:53;:::i;:::-;4434:63;;4390:117;4185:329;;;;:::o;4520:126::-;4557:7;4597:42;4590:5;4586:54;4575:65;;4520:126;;;:::o;4652:96::-;4689:7;4718:24;4736:5;4718:24;:::i;:::-;4707:35;;4652:96;;;:::o;4754:118::-;4841:24;4859:5;4841:24;:::i;:::-;4836:3;4829:37;4754:118;;:::o;4878:222::-;4971:4;5009:2;4998:9;4994:18;4986:26;;5022:71;5090:1;5079:9;5075:17;5066:6;5022:71;:::i;:::-;4878:222;;;;:::o;5106:122::-;5179:24;5197:5;5179:24;:::i;:::-;5172:5;5169:35;5159:63;;5218:1;5215;5208:12;5159:63;5106:122;:::o;5234:139::-;5280:5;5318:6;5305:20;5296:29;;5334:33;5361:5;5334:33;:::i;:::-;5234:139;;;;:::o;5379:474::-;5447:6;5455;5504:2;5492:9;5483:7;5479:23;5475:32;5472:119;;;5510:79;;:::i;:::-;5472:119;5630:1;5655:53;5700:7;5691:6;5680:9;5676:22;5655:53;:::i;:::-;5645:63;;5601:117;5757:2;5783:53;5828:7;5819:6;5808:9;5804:22;5783:53;:::i;:::-;5773:63;;5728:118;5379:474;;;;;:::o;5859:118::-;5946:24;5964:5;5946:24;:::i;:::-;5941:3;5934:37;5859:118;;:::o;5983:222::-;6076:4;6114:2;6103:9;6099:18;6091:26;;6127:71;6195:1;6184:9;6180:17;6171:6;6127:71;:::i;:::-;5983:222;;;;:::o;6211:619::-;6288:6;6296;6304;6353:2;6341:9;6332:7;6328:23;6324:32;6321:119;;;6359:79;;:::i;:::-;6321:119;6479:1;6504:53;6549:7;6540:6;6529:9;6525:22;6504:53;:::i;:::-;6494:63;;6450:117;6606:2;6632:53;6677:7;6668:6;6657:9;6653:22;6632:53;:::i;:::-;6622:63;;6577:118;6734:2;6760:53;6805:7;6796:6;6785:9;6781:22;6760:53;:::i;:::-;6750:63;;6705:118;6211:619;;;;;:::o;6836:77::-;6873:7;6902:5;6891:16;;6836:77;;;:::o;6919:122::-;6992:24;7010:5;6992:24;:::i;:::-;6985:5;6982:35;6972:63;;7031:1;7028;7021:12;6972:63;6919:122;:::o;7047:139::-;7093:5;7131:6;7118:20;7109:29;;7147:33;7174:5;7147:33;:::i;:::-;7047:139;;;;:::o;7192:329::-;7251:6;7300:2;7288:9;7279:7;7275:23;7271:32;7268:119;;;7306:79;;:::i;:::-;7268:119;7426:1;7451:53;7496:7;7487:6;7476:9;7472:22;7451:53;:::i;:::-;7441:63;;7397:117;7192:329;;;;:::o;7527:118::-;7614:24;7632:5;7614:24;:::i;:::-;7609:3;7602:37;7527:118;;:::o;7651:222::-;7744:4;7782:2;7771:9;7767:18;7759:26;;7795:71;7863:1;7852:9;7848:17;7839:6;7795:71;:::i;:::-;7651:222;;;;:::o;7879:474::-;7947:6;7955;8004:2;7992:9;7983:7;7979:23;7975:32;7972:119;;;8010:79;;:::i;:::-;7972:119;8130:1;8155:53;8200:7;8191:6;8180:9;8176:22;8155:53;:::i;:::-;8145:63;;8101:117;8257:2;8283:53;8328:7;8319:6;8308:9;8304:22;8283:53;:::i;:::-;8273:63;;8228:118;7879:474;;;;;:::o;8359:332::-;8480:4;8518:2;8507:9;8503:18;8495:26;;8531:71;8599:1;8588:9;8584:17;8575:6;8531:71;:::i;:::-;8612:72;8680:2;8669:9;8665:18;8656:6;8612:72;:::i;:::-;8359:332;;;;;:::o;8697:474::-;8765:6;8773;8822:2;8810:9;8801:7;8797:23;8793:32;8790:119;;;8828:79;;:::i;:::-;8790:119;8948:1;8973:53;9018:7;9009:6;8998:9;8994:22;8973:53;:::i;:::-;8963:63;;8919:117;9075:2;9101:53;9146:7;9137:6;9126:9;9122:22;9101:53;:::i;:::-;9091:63;;9046:118;8697:474;;;;;:::o;9177:60::-;9205:3;9226:5;9219:12;;9177:60;;;:::o;9243:142::-;9293:9;9326:53;9344:34;9353:24;9371:5;9353:24;:::i;:::-;9344:34;:::i;:::-;9326:53;:::i;:::-;9313:66;;9243:142;;;:::o;9391:126::-;9441:9;9474:37;9505:5;9474:37;:::i;:::-;9461:50;;9391:126;;;:::o;9523:158::-;9605:9;9638:37;9669:5;9638:37;:::i;:::-;9625:50;;9523:158;;;:::o;9687:195::-;9806:69;9869:5;9806:69;:::i;:::-;9801:3;9794:82;9687:195;;:::o;9888:286::-;10013:4;10051:2;10040:9;10036:18;10028:26;;10064:103;10164:1;10153:9;10149:17;10140:6;10064:103;:::i;:::-;9888:286;;;;:::o;10180:329::-;10239:6;10288:2;10276:9;10267:7;10263:23;10259:32;10256:119;;;10294:79;;:::i;:::-;10256:119;10414:1;10439:53;10484:7;10475:6;10464:9;10460:22;10439:53;:::i;:::-;10429:63;;10385:117;10180:329;;;;:::o;10515:109::-;10551:7;10591:26;10584:5;10580:38;10569:49;;10515:109;;;:::o;10630:115::-;10715:23;10732:5;10715:23;:::i;:::-;10710:3;10703:36;10630:115;;:::o;10751:218::-;10842:4;10880:2;10869:9;10865:18;10857:26;;10893:69;10959:1;10948:9;10944:17;10935:6;10893:69;:::i;:::-;10751:218;;;;:::o;10975:104::-;11020:7;11049:24;11067:5;11049:24;:::i;:::-;11038:35;;10975:104;;;:::o;11085:142::-;11188:32;11214:5;11188:32;:::i;:::-;11183:3;11176:45;11085:142;;:::o;11233:254::-;11342:4;11380:2;11369:9;11365:18;11357:26;;11393:87;11477:1;11466:9;11462:17;11453:6;11393:87;:::i;:::-;11233:254;;;;:::o;11493:116::-;11563:21;11578:5;11563:21;:::i;:::-;11556:5;11553:32;11543:60;;11599:1;11596;11589:12;11543:60;11493:116;:::o;11615:133::-;11658:5;11696:6;11683:20;11674:29;;11712:30;11736:5;11712:30;:::i;:::-;11615:133;;;;:::o;11754:468::-;11819:6;11827;11876:2;11864:9;11855:7;11851:23;11847:32;11844:119;;;11882:79;;:::i;:::-;11844:119;12002:1;12027:53;12072:7;12063:6;12052:9;12048:22;12027:53;:::i;:::-;12017:63;;11973:117;12129:2;12155:50;12197:7;12188:6;12177:9;12173:22;12155:50;:::i;:::-;12145:60;;12100:115;11754:468;;;;;:::o;12228:117::-;12337:1;12334;12327:12;12351:117;12460:1;12457;12450:12;12474:180;12522:77;12519:1;12512:88;12619:4;12616:1;12609:15;12643:4;12640:1;12633:15;12660:281;12743:27;12765:4;12743:27;:::i;:::-;12735:6;12731:40;12873:6;12861:10;12858:22;12837:18;12825:10;12822:34;12819:62;12816:88;;;12884:18;;:::i;:::-;12816:88;12924:10;12920:2;12913:22;12703:238;12660:281;;:::o;12947:129::-;12981:6;13008:20;;:::i;:::-;12998:30;;13037:33;13065:4;13057:6;13037:33;:::i;:::-;12947:129;;;:::o;13082:307::-;13143:4;13233:18;13225:6;13222:30;13219:56;;;13255:18;;:::i;:::-;13219:56;13293:29;13315:6;13293:29;:::i;:::-;13285:37;;13377:4;13371;13367:15;13359:23;;13082:307;;;:::o;13395:146::-;13492:6;13487:3;13482;13469:30;13533:1;13524:6;13519:3;13515:16;13508:27;13395:146;;;:::o;13547:423::-;13624:5;13649:65;13665:48;13706:6;13665:48;:::i;:::-;13649:65;:::i;:::-;13640:74;;13737:6;13730:5;13723:21;13775:4;13768:5;13764:16;13813:3;13804:6;13799:3;13795:16;13792:25;13789:112;;;13820:79;;:::i;:::-;13789:112;13910:54;13957:6;13952:3;13947;13910:54;:::i;:::-;13630:340;13547:423;;;;;:::o;13989:338::-;14044:5;14093:3;14086:4;14078:6;14074:17;14070:27;14060:122;;14101:79;;:::i;:::-;14060:122;14218:6;14205:20;14243:78;14317:3;14309:6;14302:4;14294:6;14290:17;14243:78;:::i;:::-;14234:87;;14050:277;13989:338;;;;:::o;14333:943::-;14428:6;14436;14444;14452;14501:3;14489:9;14480:7;14476:23;14472:33;14469:120;;;14508:79;;:::i;:::-;14469:120;14628:1;14653:53;14698:7;14689:6;14678:9;14674:22;14653:53;:::i;:::-;14643:63;;14599:117;14755:2;14781:53;14826:7;14817:6;14806:9;14802:22;14781:53;:::i;:::-;14771:63;;14726:118;14883:2;14909:53;14954:7;14945:6;14934:9;14930:22;14909:53;:::i;:::-;14899:63;;14854:118;15039:2;15028:9;15024:18;15011:32;15070:18;15062:6;15059:30;15056:117;;;15092:79;;:::i;:::-;15056:117;15197:62;15251:7;15242:6;15231:9;15227:22;15197:62;:::i;:::-;15187:72;;14982:287;14333:943;;;;;;;:::o;15282:117::-;15391:1;15388;15381:12;15405:117;15514:1;15511;15504:12;15545:568;15618:8;15628:6;15678:3;15671:4;15663:6;15659:17;15655:27;15645:122;;15686:79;;:::i;:::-;15645:122;15799:6;15786:20;15776:30;;15829:18;15821:6;15818:30;15815:117;;;15851:79;;:::i;:::-;15815:117;15965:4;15957:6;15953:17;15941:29;;16019:3;16011:4;16003:6;15999:17;15989:8;15985:32;15982:41;15979:128;;;16026:79;;:::i;:::-;15979:128;15545:568;;;;;:::o;16119:704::-;16214:6;16222;16230;16279:2;16267:9;16258:7;16254:23;16250:32;16247:119;;;16285:79;;:::i;:::-;16247:119;16405:1;16430:53;16475:7;16466:6;16455:9;16451:22;16430:53;:::i;:::-;16420:63;;16376:117;16560:2;16549:9;16545:18;16532:32;16591:18;16583:6;16580:30;16577:117;;;16613:79;;:::i;:::-;16577:117;16726:80;16798:7;16789:6;16778:9;16774:22;16726:80;:::i;:::-;16708:98;;;;16503:313;16119:704;;;;;:::o;16829:474::-;16897:6;16905;16954:2;16942:9;16933:7;16929:23;16925:32;16922:119;;;16960:79;;:::i;:::-;16922:119;17080:1;17105:53;17150:7;17141:6;17130:9;17126:22;17105:53;:::i;:::-;17095:63;;17051:117;17207:2;17233:53;17278:7;17269:6;17258:9;17254:22;17233:53;:::i;:::-;17223:63;;17178:118;16829:474;;;;;:::o;17309:180::-;17357:77;17354:1;17347:88;17454:4;17451:1;17444:15;17478:4;17475:1;17468:15;17495:120;17583:1;17576:5;17573:12;17563:46;;17589:18;;:::i;:::-;17563:46;17495:120;:::o;17621:141::-;17673:7;17702:5;17691:16;;17708:48;17750:5;17708:48;:::i;:::-;17621:141;;;:::o;17768:::-;17831:9;17864:39;17897:5;17864:39;:::i;:::-;17851:52;;17768:141;;;:::o;17915:157::-;18015:50;18059:5;18015:50;:::i;:::-;18010:3;18003:63;17915:157;;:::o;18078:248::-;18184:4;18222:2;18211:9;18207:18;18199:26;;18235:84;18316:1;18305:9;18301:17;18292:6;18235:84;:::i;:::-;18078:248;;;;:::o;18332:180::-;18380:77;18377:1;18370:88;18477:4;18474:1;18467:15;18501:4;18498:1;18491:15;18518:320;18562:6;18599:1;18593:4;18589:12;18579:22;;18646:1;18640:4;18636:12;18667:18;18657:81;;18723:4;18715:6;18711:17;18701:27;;18657:81;18785:2;18777:6;18774:14;18754:18;18751:38;18748:84;;18804:18;;:::i;:::-;18748:84;18569:269;18518:320;;;:::o;18844:180::-;18892:77;18889:1;18882:88;18989:4;18986:1;18979:15;19013:4;19010:1;19003:15;19030:348;19070:7;19093:20;19111:1;19093:20;:::i;:::-;19088:25;;19127:20;19145:1;19127:20;:::i;:::-;19122:25;;19315:1;19247:66;19243:74;19240:1;19237:81;19232:1;19225:9;19218:17;19214:105;19211:131;;;19322:18;;:::i;:::-;19211:131;19370:1;19367;19363:9;19352:20;;19030:348;;;;:::o;19384:180::-;19432:77;19429:1;19422:88;19529:4;19526:1;19519:15;19553:4;19550:1;19543:15;19570:185;19610:1;19627:20;19645:1;19627:20;:::i;:::-;19622:25;;19661:20;19679:1;19661:20;:::i;:::-;19656:25;;19700:1;19690:35;;19705:18;;:::i;:::-;19690:35;19747:1;19744;19740:9;19735:14;;19570:185;;;;:::o;19761:167::-;19901:19;19897:1;19889:6;19885:14;19878:43;19761:167;:::o;19934:366::-;20076:3;20097:67;20161:2;20156:3;20097:67;:::i;:::-;20090:74;;20173:93;20262:3;20173:93;:::i;:::-;20291:2;20286:3;20282:12;20275:19;;19934:366;;;:::o;20306:419::-;20472:4;20510:2;20499:9;20495:18;20487:26;;20559:9;20553:4;20549:20;20545:1;20534:9;20530:17;20523:47;20587:131;20713:4;20587:131;:::i;:::-;20579:139;;20306:419;;;:::o;20731:191::-;20771:3;20790:20;20808:1;20790:20;:::i;:::-;20785:25;;20824:20;20842:1;20824:20;:::i;:::-;20819:25;;20867:1;20864;20860:9;20853:16;;20888:3;20885:1;20882:10;20879:36;;;20895:18;;:::i;:::-;20879:36;20731:191;;;;:::o;20928:223::-;21068:34;21064:1;21056:6;21052:14;21045:58;21137:6;21132:2;21124:6;21120:15;21113:31;20928:223;:::o;21157:366::-;21299:3;21320:67;21384:2;21379:3;21320:67;:::i;:::-;21313:74;;21396:93;21485:3;21396:93;:::i;:::-;21514:2;21509:3;21505:12;21498:19;;21157:366;;;:::o;21529:419::-;21695:4;21733:2;21722:9;21718:18;21710:26;;21782:9;21776:4;21772:20;21768:1;21757:9;21753:17;21746:47;21810:131;21936:4;21810:131;:::i;:::-;21802:139;;21529:419;;;:::o;21954:177::-;22094:29;22090:1;22082:6;22078:14;22071:53;21954:177;:::o;22137:366::-;22279:3;22300:67;22364:2;22359:3;22300:67;:::i;:::-;22293:74;;22376:93;22465:3;22376:93;:::i;:::-;22494:2;22489:3;22485:12;22478:19;;22137:366;;;:::o;22509:419::-;22675:4;22713:2;22702:9;22698:18;22690:26;;22762:9;22756:4;22752:20;22748:1;22737:9;22733:17;22726:47;22790:131;22916:4;22790:131;:::i;:::-;22782:139;;22509:419;;;:::o;22934:167::-;23074:19;23070:1;23062:6;23058:14;23051:43;22934:167;:::o;23107:366::-;23249:3;23270:67;23334:2;23329:3;23270:67;:::i;:::-;23263:74;;23346:93;23435:3;23346:93;:::i;:::-;23464:2;23459:3;23455:12;23448:19;;23107:366;;;:::o;23479:419::-;23645:4;23683:2;23672:9;23668:18;23660:26;;23732:9;23726:4;23722:20;23718:1;23707:9;23703:17;23696:47;23760:131;23886:4;23760:131;:::i;:::-;23752:139;;23479:419;;;:::o;23904:234::-;24044:34;24040:1;24032:6;24028:14;24021:58;24113:17;24108:2;24100:6;24096:15;24089:42;23904:234;:::o;24144:366::-;24286:3;24307:67;24371:2;24366:3;24307:67;:::i;:::-;24300:74;;24383:93;24472:3;24383:93;:::i;:::-;24501:2;24496:3;24492:12;24485:19;;24144:366;;;:::o;24516:419::-;24682:4;24720:2;24709:9;24705:18;24697:26;;24769:9;24763:4;24759:20;24755:1;24744:9;24740:17;24733:47;24797:131;24923:4;24797:131;:::i;:::-;24789:139;;24516:419;;;:::o;24941:147::-;25042:11;25079:3;25064:18;;24941:147;;;;:::o;25094:114::-;;:::o;25214:398::-;25373:3;25394:83;25475:1;25470:3;25394:83;:::i;:::-;25387:90;;25486:93;25575:3;25486:93;:::i;:::-;25604:1;25599:3;25595:11;25588:18;;25214:398;;;:::o;25618:379::-;25802:3;25824:147;25967:3;25824:147;:::i;:::-;25817:154;;25988:3;25981:10;;25618:379;;;:::o;26003:170::-;26143:22;26139:1;26131:6;26127:14;26120:46;26003:170;:::o;26179:366::-;26321:3;26342:67;26406:2;26401:3;26342:67;:::i;:::-;26335:74;;26418:93;26507:3;26418:93;:::i;:::-;26536:2;26531:3;26527:12;26520:19;;26179:366;;;:::o;26551:419::-;26717:4;26755:2;26744:9;26740:18;26732:26;;26804:9;26798:4;26794:20;26790:1;26779:9;26775:17;26768:47;26832:131;26958:4;26832:131;:::i;:::-;26824:139;;26551:419;;;:::o;26976:220::-;27116:34;27112:1;27104:6;27100:14;27093:58;27185:3;27180:2;27172:6;27168:15;27161:28;26976:220;:::o;27202:366::-;27344:3;27365:67;27429:2;27424:3;27365:67;:::i;:::-;27358:74;;27441:93;27530:3;27441:93;:::i;:::-;27559:2;27554:3;27550:12;27543:19;;27202:366;;;:::o;27574:419::-;27740:4;27778:2;27767:9;27763:18;27755:26;;27827:9;27821:4;27817:20;27813:1;27802:9;27798:17;27791:47;27855:131;27981:4;27855:131;:::i;:::-;27847:139;;27574:419;;;:::o;27999:177::-;28139:29;28135:1;28127:6;28123:14;28116:53;27999:177;:::o;28182:366::-;28324:3;28345:67;28409:2;28404:3;28345:67;:::i;:::-;28338:74;;28421:93;28510:3;28421:93;:::i;:::-;28539:2;28534:3;28530:12;28523:19;;28182:366;;;:::o;28554:419::-;28720:4;28758:2;28747:9;28743:18;28735:26;;28807:9;28801:4;28797:20;28793:1;28782:9;28778:17;28771:47;28835:131;28961:4;28835:131;:::i;:::-;28827:139;;28554:419;;;:::o;28979:148::-;29081:11;29118:3;29103:18;;28979:148;;;;:::o;29133:141::-;29182:4;29205:3;29197:11;;29228:3;29225:1;29218:14;29262:4;29259:1;29249:18;29241:26;;29133:141;;;:::o;29304:874::-;29407:3;29444:5;29438:12;29473:36;29499:9;29473:36;:::i;:::-;29525:89;29607:6;29602:3;29525:89;:::i;:::-;29518:96;;29645:1;29634:9;29630:17;29661:1;29656:166;;;;29836:1;29831:341;;;;29623:549;;29656:166;29740:4;29736:9;29725;29721:25;29716:3;29709:38;29802:6;29795:14;29788:22;29780:6;29776:35;29771:3;29767:45;29760:52;;29656:166;;29831:341;29898:38;29930:5;29898:38;:::i;:::-;29958:1;29972:154;29986:6;29983:1;29980:13;29972:154;;;30060:7;30054:14;30050:1;30045:3;30041:11;30034:35;30110:1;30101:7;30097:15;30086:26;;30008:4;30005:1;30001:12;29996:17;;29972:154;;;30155:6;30150:3;30146:16;30139:23;;29838:334;;29623:549;;29411:767;;29304:874;;;;:::o;30184:390::-;30290:3;30318:39;30351:5;30318:39;:::i;:::-;30373:89;30455:6;30450:3;30373:89;:::i;:::-;30366:96;;30471:65;30529:6;30524:3;30517:4;30510:5;30506:16;30471:65;:::i;:::-;30561:6;30556:3;30552:16;30545:23;;30294:280;30184:390;;;;:::o;30580:155::-;30720:7;30716:1;30708:6;30704:14;30697:31;30580:155;:::o;30741:400::-;30901:3;30922:84;31004:1;30999:3;30922:84;:::i;:::-;30915:91;;31015:93;31104:3;31015:93;:::i;:::-;31133:1;31128:3;31124:11;31117:18;;30741:400;;;:::o;31147:695::-;31425:3;31447:92;31535:3;31526:6;31447:92;:::i;:::-;31440:99;;31556:95;31647:3;31638:6;31556:95;:::i;:::-;31549:102;;31668:148;31812:3;31668:148;:::i;:::-;31661:155;;31833:3;31826:10;;31147:695;;;;;:::o;31848:179::-;31988:31;31984:1;31976:6;31972:14;31965:55;31848:179;:::o;32033:366::-;32175:3;32196:67;32260:2;32255:3;32196:67;:::i;:::-;32189:74;;32272:93;32361:3;32272:93;:::i;:::-;32390:2;32385:3;32381:12;32374:19;;32033:366;;;:::o;32405:419::-;32571:4;32609:2;32598:9;32594:18;32586:26;;32658:9;32652:4;32648:20;32644:1;32633:9;32629:17;32622:47;32686:131;32812:4;32686:131;:::i;:::-;32678:139;;32405:419;;;:::o;32830:181::-;32970:33;32966:1;32958:6;32954:14;32947:57;32830:181;:::o;33017:366::-;33159:3;33180:67;33244:2;33239:3;33180:67;:::i;:::-;33173:74;;33256:93;33345:3;33256:93;:::i;:::-;33374:2;33369:3;33365:12;33358:19;;33017:366;;;:::o;33389:419::-;33555:4;33593:2;33582:9;33578:18;33570:26;;33642:9;33636:4;33632:20;33628:1;33617:9;33613:17;33606:47;33670:131;33796:4;33670:131;:::i;:::-;33662:139;;33389:419;;;:::o;33814:332::-;33935:4;33973:2;33962:9;33958:18;33950:26;;33986:71;34054:1;34043:9;34039:17;34030:6;33986:71;:::i;:::-;34067:72;34135:2;34124:9;34120:18;34111:6;34067:72;:::i;:::-;33814:332;;;;;:::o;34152:137::-;34206:5;34237:6;34231:13;34222:22;;34253:30;34277:5;34253:30;:::i;:::-;34152:137;;;;:::o;34295:345::-;34362:6;34411:2;34399:9;34390:7;34386:23;34382:32;34379:119;;;34417:79;;:::i;:::-;34379:119;34537:1;34562:61;34615:7;34606:6;34595:9;34591:22;34562:61;:::i;:::-;34552:71;;34508:125;34295:345;;;;:::o;34646:94::-;34679:8;34727:5;34723:2;34719:14;34698:35;;34646:94;;;:::o;34746:::-;34785:7;34814:20;34828:5;34814:20;:::i;:::-;34803:31;;34746:94;;;:::o;34846:100::-;34885:7;34914:26;34934:5;34914:26;:::i;:::-;34903:37;;34846:100;;;:::o;34952:157::-;35057:45;35077:24;35095:5;35077:24;:::i;:::-;35057:45;:::i;:::-;35052:3;35045:58;34952:157;;:::o;35115:256::-;35227:3;35242:75;35313:3;35304:6;35242:75;:::i;:::-;35342:2;35337:3;35333:12;35326:19;;35362:3;35355:10;;35115:256;;;;:::o;35377:173::-;35517:25;35513:1;35505:6;35501:14;35494:49;35377:173;:::o;35556:402::-;35716:3;35737:85;35819:2;35814:3;35737:85;:::i;:::-;35730:92;;35831:93;35920:3;35831:93;:::i;:::-;35949:2;35944:3;35940:12;35933:19;;35556:402;;;:::o;35964:167::-;36104:19;36100:1;36092:6;36088:14;36081:43;35964:167;:::o;36137:402::-;36297:3;36318:85;36400:2;36395:3;36318:85;:::i;:::-;36311:92;;36412:93;36501:3;36412:93;:::i;:::-;36530:2;36525:3;36521:12;36514:19;;36137:402;;;:::o;36545:967::-;36927:3;36949:148;37093:3;36949:148;:::i;:::-;36942:155;;37114:95;37205:3;37196:6;37114:95;:::i;:::-;37107:102;;37226:148;37370:3;37226:148;:::i;:::-;37219:155;;37391:95;37482:3;37473:6;37391:95;:::i;:::-;37384:102;;37503:3;37496:10;;36545:967;;;;;:::o;37518:98::-;37569:6;37603:5;37597:12;37587:22;;37518:98;;;:::o;37622:168::-;37705:11;37739:6;37734:3;37727:19;37779:4;37774:3;37770:14;37755:29;;37622:168;;;;:::o;37796:373::-;37882:3;37910:38;37942:5;37910:38;:::i;:::-;37964:70;38027:6;38022:3;37964:70;:::i;:::-;37957:77;;38043:65;38101:6;38096:3;38089:4;38082:5;38078:16;38043:65;:::i;:::-;38133:29;38155:6;38133:29;:::i;:::-;38128:3;38124:39;38117:46;;37886:283;37796:373;;;;:::o;38175:640::-;38370:4;38408:3;38397:9;38393:19;38385:27;;38422:71;38490:1;38479:9;38475:17;38466:6;38422:71;:::i;:::-;38503:72;38571:2;38560:9;38556:18;38547:6;38503:72;:::i;:::-;38585;38653:2;38642:9;38638:18;38629:6;38585:72;:::i;:::-;38704:9;38698:4;38694:20;38689:2;38678:9;38674:18;38667:48;38732:76;38803:4;38794:6;38732:76;:::i;:::-;38724:84;;38175:640;;;;;;;:::o;38821:141::-;38877:5;38908:6;38902:13;38893:22;;38924:32;38950:5;38924:32;:::i;:::-;38821:141;;;;:::o;38968:349::-;39037:6;39086:2;39074:9;39065:7;39061:23;39057:32;39054:119;;;39092:79;;:::i;:::-;39054:119;39212:1;39237:63;39292:7;39283:6;39272:9;39268:22;39237:63;:::i;:::-;39227:73;;39183:127;38968:349;;;;:::o;39323:180::-;39371:77;39368:1;39361:88;39468:4;39465:1;39458:15;39492:4;39489:1;39482:15;39509:171;39548:3;39571:24;39589:5;39571:24;:::i;:::-;39562:33;;39617:4;39610:5;39607:15;39604:41;;39625:18;;:::i;:::-;39604:41;39672:1;39665:5;39661:13;39654:20;;39509:171;;;:::o;39686:182::-;39826:34;39822:1;39814:6;39810:14;39803:58;39686:182;:::o;39874:366::-;40016:3;40037:67;40101:2;40096:3;40037:67;:::i;:::-;40030:74;;40113:93;40202:3;40113:93;:::i;:::-;40231:2;40226:3;40222:12;40215:19;;39874:366;;;:::o;40246:419::-;40412:4;40450:2;40439:9;40435:18;40427:26;;40499:9;40493:4;40489:20;40485:1;40474:9;40470:17;40463:47;40527:131;40653:4;40527:131;:::i;:::-;40519:139;;40246:419;;;:::o;40671:233::-;40710:3;40733:24;40751:5;40733:24;:::i;:::-;40724:33;;40779:66;40772:5;40769:77;40766:103;;40849:18;;:::i;:::-;40766:103;40896:1;40889:5;40885:13;40878:20;;40671:233;;;:::o
Swarm Source
ipfs://989ce8219eb9e73f7347aa94c9d4b2cd5491b2ac7a4fe957779bba10c97e0c4e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.