ERC-721
Overview
Max Total Supply
5,555 DMPS
Holders
1,894
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 DMPSLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
DeviantsSilverPass
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-02-07 */ // File: operator-filter-registry/src/lib/Constants.sol pragma solidity ^0.8.17; address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E; address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6; // File: operator-filter-registry/src/IOperatorFilterRegistry.sol pragma solidity ^0.8.13; interface IOperatorFilterRegistry { /** * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns * true if supplied registrant address is not registered. */ function isOperatorAllowed(address registrant, address operator) external view returns (bool); /** * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. */ function register(address registrant) external; /** * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. */ function registerAndSubscribe(address registrant, address subscription) external; /** * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another * address without subscribing. */ function registerAndCopyEntries(address registrant, address registrantToCopy) external; /** * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. * Note that this does not remove any filtered addresses or codeHashes. * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. */ function unregister(address addr) external; /** * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. */ function updateOperator(address registrant, address operator, bool filtered) external; /** * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. */ function updateOperators(address registrant, address[] calldata operators, bool filtered) external; /** * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. */ function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; /** * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. */ function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; /** * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous * subscription if present. * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be * used. */ function subscribe(address registrant, address registrantToSubscribe) external; /** * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. */ function unsubscribe(address registrant, bool copyExistingEntries) external; /** * @notice Get the subscription address of a given registrant, if any. */ function subscriptionOf(address addr) external returns (address registrant); /** * @notice Get the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscribers(address registrant) external returns (address[] memory); /** * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscriberAt(address registrant, uint256 index) external returns (address); /** * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. */ function copyEntriesOf(address registrant, address registrantToCopy) external; /** * @notice Returns true if operator is filtered by a given address or its subscription. */ function isOperatorFiltered(address registrant, address operator) external returns (bool); /** * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. */ function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); /** * @notice Returns true if a codeHash is filtered by a given address or its subscription. */ function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); /** * @notice Returns a list of filtered operators for a given address or its subscription. */ function filteredOperators(address addr) external returns (address[] memory); /** * @notice Returns the set of filtered codeHashes for a given address or its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashes(address addr) external returns (bytes32[] memory); /** * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredOperatorAt(address registrant, uint256 index) external returns (address); /** * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); /** * @notice Returns true if an address has registered */ function isRegistered(address addr) external returns (bool); /** * @dev Convenience method to compute the code hash of an arbitrary contract */ function codeHashOf(address addr) external returns (bytes32); } // File: operator-filter-registry/src/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. * Please note that if your token contract does not provide an owner with EIP-173, it must provide * administration methods on the contract itself to interact with the registry otherwise the subscription * will be locked to the options set during construction. */ abstract contract OperatorFilterer { /// @dev Emitted when an operator is not allowed. error OperatorNotAllowed(address operator); IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS); /// @dev The constructor that is called when the contract is being deployed. 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)); } } } } /** * @dev A helper function to check if an operator is allowed. */ 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); } _; } /** * @dev A helper function to check if an operator approval is allowed. */ modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } /** * @dev A helper function to check if an operator is allowed. */ 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) { // under normal circumstances, this function will revert rather than return false, but inheriting contracts // may specify their own OperatorFilterRegistry implementations, which may behave differently if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } } // File: operator-filter-registry/src/DefaultOperatorFilterer.sol pragma solidity ^0.8.13; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. * @dev Please note that if your token contract does not provide an owner with EIP-173, it must provide * administration methods on the contract itself to interact with the registry otherwise the subscription * will be locked to the options set during construction. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { /// @dev The constructor that is called when the contract is being deployed. constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {} } // 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/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: @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/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: 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/DeviantsSilverPass.sol pragma solidity ^0.8.4; /** * @title DeviantsSilverPass * @dev The contract allows users to mint max 2 NFTs per address. * @dev The contract has 2 phases, whitelist sale and public sale. * @dev The contract uses a Merkle proof to validate that an address is whitelisted. * @dev Each phase lasts one day. * @dev Whitelist phase starts on 07.02.2023 at 4 pm UTC, ends in 08.02.2023 at 4 pm UTC. * @dev Public phase starts on 08.02.2023 at 4:01 pm UTC, ends in 09.02.2023 at 4 pm UTC. * @dev The contract also has an owner who have the privilages to set the state of the contract and withdraw erc20 native tokens. */ contract DeviantsSilverPass is ERC721A, Ownable, ReentrancyGuard, DefaultOperatorFilterer { using Strings for uint256; /** * @dev Set max supply for the DeviantsSilverPass collection */ uint256 public constant maxSupply = 5555; /** * @dev Set max amount of NFTs per address */ uint256 public constant maxMintPerWallet = 2; /** * @dev Set cost for second NFT minted during the whitelist sale period */ uint256 public constant priceWhitelistSale = 0.0035 ether; /** * @dev Set cost for second NFT minted during the public sale period */ uint256 public constant pricePublicSale = 0.0035 ether; /** * @dev Set whitelist mint period and public mint period */ uint256 public constant startWLMintTime = 1675785600; uint256 public constant endWLtMintTime = 1675872000; uint256 public constant startPBMintTime = 1675872060; uint256 public constant endPBMintTime = 1675958400; /** * @dev A boolean that indicates whether the mintWhitelistSale function is paused or not. */ bool public pauseWLSale = true; /** * @dev A boolean that indicates whether the mintPublicSale function is paused or not. */ bool public pausePBSale = true; /** * @dev A boolean that indicates whether the contract isindicates is paused or not. */ bool public globalPause = false; /** * @dev The root of the Merkle tree that is used for whitelist check. */ bytes32 public merkleRoot; /** * @dev The account that recive the money from the mints. */ address public payerAccount; /** * @dev Prefix for tokens metadata URIs */ string public baseURI; /** * @dev Sufix for tokens metadata URIs */ string public uriSuffix = '.json'; /** * @dev A mapping that stores the amount of NFTs minted for each address. */ mapping(address => uint256) public addressMintedAmount; /** * @dev Emits an event when an NFT is minted in whitelist sale period. * @param minterAddress The address of the user who executed the mintWhitelistSale. * @param amount The amount of NFTs minted. */ event MintWhitelistSale( address indexed minterAddress, uint256 amount ); /** * @dev Emits an event when an NFT is minted in public sale period. * @param minterAddress The address of the user who executed the mintWhitelistSale. * @param amount The amount of NFTs minted. */ event MintPublicSale( address indexed minterAddress, uint256 amount ); /** * @dev Emits an event when owner mint a batch. * @param owner The addresses who is the contract owner. * @param addresses The addresses array. * @param amount The amount of NFTs minted for each address. */ event MintBatch( address indexed owner, address[] addresses, uint256 amount ); /** * @dev Emits an event when owner mint a batch. * @param owner The addresses who is the contract owner. * @param amount The amount of native tokens withdrawn. */ event Withdraw( address indexed owner, uint256 amount ); /** * @dev Constructor function that sets the initial values for the contract's variables. * @param _merkleRoot The root of the Merkle tree. * @param uri The metadata URI prefix. */ constructor( bytes32 _merkleRoot, string memory uri, address _payerAccount ) ERC721A("Deviants Silver Mint Pass", "DMPS") { merkleRoot = _merkleRoot; baseURI = uri; payerAccount = _payerAccount; } /** * @dev mintWhitelistSale creates NFT tokens for whitelist sale. * @param _mintAmount the amount of NFT tokens to mint. * @param _merkleProof the proof of user's whitelist status. * @notice Throws if: * - whitelistSale closed if the function is called outside of the whitelist sale period or if the contract is paused. * - maxSupply exceeded if the minted amount exceeds the maxSupply. * - mintAmount must be 1 or 2 if the _mintAmount is not 1 or 2. * - Invalid proof if the provided merkle proof is invalid. * - user cannot mint more then 2 NFTs if the user already owns 2 NFTs. * - user must send the exact price if the user already owns 1 NFT and tries to mint 2 NFTs. */ function mintWhitelistSale(uint256 _mintAmount, bytes32[] calldata _merkleProof) external payable nonReentrant{ require(!globalPause,"DMPS: contract is paused"); require((block.timestamp >= startWLMintTime && block.timestamp <= endWLtMintTime) || !pauseWLSale, "DMPS: whitelistSale closed"); require(totalSupply() + _mintAmount <= maxSupply, "DMPS: maxSupply exceeded"); require(_mintAmount == 1 || _mintAmount == 2, "DMPS: mintAmount must be 1 or 2"); bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(msg.sender)))); require(MerkleProof.verify(_merkleProof, merkleRoot, leaf), "DMPS: Invalid proof"); require(_mintAmount + addressMintedAmount[msg.sender] <= 2, "DMPS: user cannot mint more then 2 NFTs" ); if(addressMintedAmount[msg.sender] == 0 && _mintAmount == 1 ){ addressMintedAmount[msg.sender] += _mintAmount; _safeMint(msg.sender,_mintAmount); } else if(addressMintedAmount[msg.sender] == 0 && _mintAmount == 2){ require(msg.value == priceWhitelistSale,"DMPS: user must send the exact price"); addressMintedAmount[msg.sender] += _mintAmount; _safeMint(msg.sender,_mintAmount); } else{ require(msg.value == priceWhitelistSale,"DMPS: user must send the exact price"); addressMintedAmount[msg.sender] += _mintAmount; _safeMint(msg.sender,_mintAmount); } emit MintWhitelistSale(msg.sender, _mintAmount); } /** * @dev Mints NFTs in the public sale period. * @param _mintAmount The number of NFTs to mint (1 or 2). * @notice Throws if: * - public sale period has ended or the contract is paused. * - The maximum supply of NFTs is exceeded. * - The `_mintAmount` is not 1 or 2. * - The user tries to mint more than 2 NFTs. * - The user tries to mint 2 NFTs but does not send the exact price. * - The user tries to mint 1 NFT but sends more than the exact price. */ function mintPublicSale(uint256 _mintAmount) external payable nonReentrant{ require(!globalPause,"DMPS: contract is paused"); require((block.timestamp >= startPBMintTime && block.timestamp <= endPBMintTime) || !pausePBSale ,"DMPS: publicSale closed"); require(totalSupply() + _mintAmount <= maxSupply,"DMPS: maxSupply exceeded"); require(_mintAmount== 1 || _mintAmount == 2, "DMPS: mintAmount must be 1 or 2"); require(_mintAmount + addressMintedAmount[msg.sender] <= 2,"DMPS: user cannot mint more then 2 NFTs" ); if(addressMintedAmount[msg.sender] == 0 && _mintAmount == 1 ){ addressMintedAmount[msg.sender] += _mintAmount; _safeMint(msg.sender,_mintAmount); } else if(addressMintedAmount[msg.sender] == 0 && _mintAmount == 2){ require(msg.value == pricePublicSale,"DMPS: user must send the exact price"); addressMintedAmount[msg.sender] += _mintAmount; _safeMint(msg.sender,_mintAmount); } else{ require(msg.value == pricePublicSale,"DMPS: user must send the exact price"); addressMintedAmount[msg.sender] += _mintAmount; _safeMint(msg.sender,_mintAmount); } emit MintPublicSale(msg.sender, _mintAmount); } /** * @dev Function to mint a batch of NFTs to multiple addresses * @param addresses An array of addresses to mint NFTs to * @param _mintAmounts The amount of NFTs to mint to each address * @notice Only the contract owner can call this function. */ function mintBatch(address[] memory addresses, uint256 _mintAmounts) external onlyOwner{ require(totalSupply() + addresses.length * _mintAmounts <= maxSupply,"DMPS: maxSupply exceeded"); for(uint256 i = 0;i < addresses.length; i++){ _safeMint(addresses[i],_mintAmounts); } emit MintBatch(msg.sender, addresses, _mintAmounts); } /** * @dev Sets the Merkle root on the contract * @param _merkleRoot bytes32: the Merkle root to be set * @notice Only the contract owner can call this function. */ function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner{ merkleRoot = _merkleRoot; } /** * @dev This function sets the base URI of the NFT contract. * @param uri The new base URI of the NFT contract. * @notice Only the contract owner can call this function. */ function setBasedURI(string memory uri) external onlyOwner{ baseURI = uri; } /** * @dev Set the pause state of the contract for the WL Sale, only the contract owner can set the pause state * @param state Boolean state of the pause, true means that the contract is paused, false means that the contract is not paused */ function setPauseWLSale(bool state) external onlyOwner{ pauseWLSale = state; } /** * @dev Set the pause state of the contract for the PB Sale, only the contract owner can set the pause state * @param state Boolean state of the pause, true means that the contract is paused, false means that the contract is not paused */ function setPausePBSale(bool state) external onlyOwner{ pausePBSale = state; } /** * @dev Set the global pause state of the contract, only the contract owner can set the pause state * @param state Boolean state of the pause, true means that the contract is paused, false means that the contract is not paused */ function setGlobalPause(bool state) external onlyOwner{ globalPause = state; } /** * @dev Sets the uriSuffix for the ERC-721 token metadata. * @param _uriSuffix The new uriSuffix to be set. */ function setUriSuffix(string memory _uriSuffix) public onlyOwner { uriSuffix = _uriSuffix; } /** * @dev Sets the payerAccount. * @param _payerAccount The new payerAccount. */ function setPayerAccount(address _payerAccount) public onlyOwner { payerAccount = _payerAccount; } /** * @dev Returns the state of the WhitelistState (true if is open, false if is closed) */ function getWhitelistSaleStatus() public view returns(bool){ if((block.timestamp >= startWLMintTime && block.timestamp <= endWLtMintTime) || !pauseWLSale) { return true; }else{ return false; } } /** * @dev Returns the state of the PauseSale (true if is open, false if is closed) */ function getPauseSaleStatus() public view returns(bool){ if((block.timestamp >= startPBMintTime && block.timestamp <= endPBMintTime) || !pausePBSale) { return true; }else{ return false; } } /** * Transfers the total native coin balance to contract's owner account. * The balance must be > 0 so a zero transfer is avoided. * * Access: Contract Owner */ function withdraw() public nonReentrant { require(msg.sender == owner() || msg.sender == payerAccount, "DMPS: can be called only with the owner or payerAccount"); uint256 balance = address(this).balance; require(balance != 0, "DMPS: contract balance is zero"); sendViaCall(payable(payerAccount), balance); emit Withdraw(msg.sender, balance); } /** * @dev Function to transfer coins (the native cryptocurrency of the platform, i.e.: ETH) * from this contract to the specified address. * * @param _to the address to transfer the coins to * @param _amount amount (in wei) */ function sendViaCall(address payable _to, uint256 _amount) private { (bool sent, ) = _to.call { value: _amount } (""); require(sent, "DMPS: failed to send amount"); } /** * @dev Returns the starting token ID for the token. * @return uint256 The starting token ID for the token. */ function _startTokenId() internal view virtual override returns (uint256) { return 1; } /** * @dev Returns the token URI for the given token ID. Throws if the token ID does not exist * @param _tokenId The token ID to retrieve the URI for * @notice Retrieve the URI for the given token ID * @return The token URI for the given token ID */ function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { require(_exists(_tokenId), 'ERC721Metadata: URI query for nonexistent token'); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, _tokenId.toString(), uriSuffix)) : ''; } /** * @dev Returns the current base URI. * @return The base URI of the contract. */ function _baseURI() internal view virtual override returns (string memory) { return baseURI; } 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":"string","name":"uri","type":"string"},{"internalType":"address","name":"_payerAccount","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":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address[]","name":"addresses","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MintBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minterAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MintPublicSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minterAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MintWhitelistSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressMintedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"endPBMintTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endWLtMintTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseSaleStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistSaleStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalPause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256","name":"_mintAmounts","type":"uint256"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mintPublicSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"mintWhitelistSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pausePBSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseWLSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payerAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricePublicSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceWhitelistSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"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":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBasedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"setGlobalPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"setPausePBSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"setPauseWLSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_payerAccount","type":"address"}],"name":"setPayerAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriSuffix","type":"string"}],"name":"setUriSuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startPBMintTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startWLMintTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriSuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526001600a60006101000a81548160ff0219169083151502179055506001600a60016101000a81548160ff0219169083151502179055506000600a60026101000a81548160ff0219169083151502179055506040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600e90816200009b919062000761565b50348015620000a957600080fd5b50604051620057a3380380620057a38339818101604052810190620000cf919062000a4c565b733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280601981526020017f44657669616e74732053696c766572204d696e742050617373000000000000008152506040518060400160405280600481526020017f444d505300000000000000000000000000000000000000000000000000000000815250816002908162000163919062000761565b50806003908162000175919062000761565b50620001866200041060201b60201c565b6000819055505050620001ae620001a26200041960201b60201c565b6200042160201b60201c565b600160098190555060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620003ab57801562000271576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200023792919062000ad8565b600060405180830381600087803b1580156200025257600080fd5b505af115801562000267573d6000803e3d6000fd5b50505050620003aa565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200032b576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620002f192919062000ad8565b600060405180830381600087803b1580156200030c57600080fd5b505af115801562000321573d6000803e3d6000fd5b50505050620003a9565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b815260040162000374919062000b05565b600060405180830381600087803b1580156200038f57600080fd5b505af1158015620003a4573d6000803e3d6000fd5b505050505b5b5b505082600b8190555081600d9081620003c5919062000761565b5080600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505062000b22565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200056957607f821691505b6020821081036200057f576200057e62000521565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005e97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620005aa565b620005f58683620005aa565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620006426200063c62000636846200060d565b62000617565b6200060d565b9050919050565b6000819050919050565b6200065e8362000621565b620006766200066d8262000649565b848454620005b7565b825550505050565b600090565b6200068d6200067e565b6200069a81848462000653565b505050565b5b81811015620006c257620006b660008262000683565b600181019050620006a0565b5050565b601f8211156200071157620006db8162000585565b620006e6846200059a565b81016020851015620006f6578190505b6200070e62000705856200059a565b8301826200069f565b50505b505050565b600082821c905092915050565b6000620007366000198460080262000716565b1980831691505092915050565b600062000751838362000723565b9150826002028217905092915050565b6200076c82620004e7565b67ffffffffffffffff811115620007885762000787620004f2565b5b62000794825462000550565b620007a1828285620006c6565b600060209050601f831160018114620007d95760008415620007c4578287015190505b620007d0858262000743565b86555062000840565b601f198416620007e98662000585565b60005b828110156200081357848901518255600182019150602085019450602081019050620007ec565b868310156200083357848901516200082f601f89168262000723565b8355505b6001600288020188555050505b505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b62000871816200085c565b81146200087d57600080fd5b50565b600081519050620008918162000866565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b620008bd82620008a1565b810181811067ffffffffffffffff82111715620008df57620008de620004f2565b5b80604052505050565b6000620008f462000848565b9050620009028282620008b2565b919050565b600067ffffffffffffffff821115620009255762000924620004f2565b5b6200093082620008a1565b9050602081019050919050565b60005b838110156200095d57808201518184015260208101905062000940565b60008484015250505050565b6000620009806200097a8462000907565b620008e8565b9050828152602081018484840111156200099f576200099e6200089c565b5b620009ac8482856200093d565b509392505050565b600082601f830112620009cc57620009cb62000897565b5b8151620009de84826020860162000969565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000a1482620009e7565b9050919050565b62000a268162000a07565b811462000a3257600080fd5b50565b60008151905062000a468162000a1b565b92915050565b60008060006060848603121562000a685762000a6762000852565b5b600062000a788682870162000880565b935050602084015167ffffffffffffffff81111562000a9c5762000a9b62000857565b5b62000aaa86828701620009b4565b925050604062000abd8682870162000a35565b9150509250925092565b62000ad28162000a07565b82525050565b600060408201905062000aef600083018562000ac7565b62000afe602083018462000ac7565b9392505050565b600060208201905062000b1c600083018462000ac7565b92915050565b614c718062000b326000396000f3fe6080604052600436106102885760003560e01c80636c0360eb1161015a578063b6afc4dc116100c1578063e985e9c51161007a578063e985e9c51461094a578063ede029fc14610987578063f12d54d8146109b0578063f2702b67146109db578063f2fde38b14610a06578063f9a1deb114610a2f57610288565b8063b6afc4dc14610856578063b88d4fde1461087f578063c1ae1bc71461089b578063c87b56dd146108b7578063cd08c046146108f4578063d5abeb011461091f57610288565b80638da5cb5b116101135780638da5cb5b1461075657806395d89b41146107815780639d80461f146107ac578063a22cb465146107d7578063a548bf7014610800578063b228d9251461082b57610288565b80636c0360eb1461065c57806370a0823114610687578063715018a6146106c45780637cb64759146106db5780637f5502501461070457806389f6fbe61461072d57610288565b80633cd7b152116101fe5780635a5e5d58116101b75780635a5e5d58146105595780635d83744b146105755780636352211e146105a0578063654a13fb146105dd57806369a6b3db146106085780636a99d7991461063157610288565b80633cd7b1521461045457806341f434341461049157806342842e0e146104bc5780634f37888f146104d85780635497e7dc146105035780635503a0e81461052e57610288565b806318160ddd1161025057806318160ddd146103775780631b6e0095146103a257806323b872dd146103cd5780632eb4a7ab146103e95780633970e0ec146104145780633ccfd60b1461043d57610288565b806301ffc9a71461028d57806306fdde03146102ca578063081812fc146102f5578063095ea7b31461033257806316ba10e01461034e575b600080fd5b34801561029957600080fd5b506102b460048036038101906102af9190613411565b610a5a565b6040516102c19190613459565b60405180910390f35b3480156102d657600080fd5b506102df610aec565b6040516102ec9190613504565b60405180910390f35b34801561030157600080fd5b5061031c6004803603810190610317919061355c565b610b7e565b60405161032991906135ca565b60405180910390f35b61034c60048036038101906103479190613611565b610bfd565b005b34801561035a57600080fd5b5061037560048036038101906103709190613786565b610c16565b005b34801561038357600080fd5b5061038c610c31565b60405161039991906137de565b60405180910390f35b3480156103ae57600080fd5b506103b7610c48565b6040516103c49190613459565b60405180910390f35b6103e760048036038101906103e291906137f9565b610c5b565b005b3480156103f557600080fd5b506103fe610caa565b60405161040b9190613865565b60405180910390f35b34801561042057600080fd5b5061043b600480360381019061043691906138ac565b610cb0565b005b34801561044957600080fd5b50610452610cd5565b005b34801561046057600080fd5b5061047b600480360381019061047691906138d9565b610e77565b60405161048891906137de565b60405180910390f35b34801561049d57600080fd5b506104a6610e8f565b6040516104b39190613965565b60405180910390f35b6104d660048036038101906104d191906137f9565b610ea1565b005b3480156104e457600080fd5b506104ed610ef0565b6040516104fa91906135ca565b60405180910390f35b34801561050f57600080fd5b50610518610f16565b60405161052591906137de565b60405180910390f35b34801561053a57600080fd5b50610543610f1e565b6040516105509190613504565b60405180910390f35b610573600480360381019061056e919061355c565b610fac565b005b34801561058157600080fd5b5061058a611465565b6040516105979190613459565b60405180910390f35b3480156105ac57600080fd5b506105c760048036038101906105c2919061355c565b611478565b6040516105d491906135ca565b60405180910390f35b3480156105e957600080fd5b506105f261148a565b6040516105ff91906137de565b60405180910390f35b34801561061457600080fd5b5061062f600480360381019061062a91906138ac565b611495565b005b34801561063d57600080fd5b506106466114ba565b6040516106539190613459565b60405180910390f35b34801561066857600080fd5b50610671611502565b60405161067e9190613504565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a991906138d9565b611590565b6040516106bb91906137de565b60405180910390f35b3480156106d057600080fd5b506106d9611648565b005b3480156106e757600080fd5b5061070260048036038101906106fd91906139ac565b61165c565b005b34801561071057600080fd5b5061072b600480360381019061072691906138d9565b61166e565b005b34801561073957600080fd5b50610754600480360381019061074f91906138ac565b6116ba565b005b34801561076257600080fd5b5061076b6116df565b60405161077891906135ca565b60405180910390f35b34801561078d57600080fd5b50610796611709565b6040516107a39190613504565b60405180910390f35b3480156107b857600080fd5b506107c161179b565b6040516107ce91906137de565b60405180910390f35b3480156107e357600080fd5b506107fe60048036038101906107f991906139d9565b6117a3565b005b34801561080c57600080fd5b506108156117bc565b60405161082291906137de565b60405180910390f35b34801561083757600080fd5b506108406117c4565b60405161084d91906137de565b60405180910390f35b34801561086257600080fd5b5061087d60048036038101906108789190613ae1565b6117c9565b005b61089960048036038101906108949190613bde565b6118cc565b005b6108b560048036038101906108b09190613cbc565b61191d565b005b3480156108c357600080fd5b506108de60048036038101906108d9919061355c565b611eb7565b6040516108eb9190613504565b60405180910390f35b34801561090057600080fd5b50610909611f61565b60405161091691906137de565b60405180910390f35b34801561092b57600080fd5b50610934611f6c565b60405161094191906137de565b60405180910390f35b34801561095657600080fd5b50610971600480360381019061096c9190613d1c565b611f72565b60405161097e9190613459565b60405180910390f35b34801561099357600080fd5b506109ae60048036038101906109a99190613786565b612006565b005b3480156109bc57600080fd5b506109c5612021565b6040516109d29190613459565b60405180910390f35b3480156109e757600080fd5b506109f0612034565b6040516109fd91906137de565b60405180910390f35b348015610a1257600080fd5b50610a2d6004803603810190610a2891906138d9565b61203c565b005b348015610a3b57600080fd5b50610a446120bf565b604051610a519190613459565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610ab557506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ae55750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610afb90613d8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2790613d8b565b8015610b745780601f10610b4957610100808354040283529160200191610b74565b820191906000526020600020905b815481529060010190602001808311610b5757829003601f168201915b5050505050905090565b6000610b8982612107565b610bbf576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610c0781612166565b610c118383612263565b505050565b610c1e6123a7565b80600e9081610c2d9190613f5e565b5050565b6000610c3b612425565b6001546000540303905090565b600a60009054906101000a900460ff1681565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c9957610c9833612166565b5b610ca484848461242e565b50505050565b600b5481565b610cb86123a7565b80600a60016101000a81548160ff02191690831515021790555050565b610cdd612750565b610ce56116df565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610d6b5750600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610daa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da1906140a2565b60405180910390fd5b600047905060008103610df2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de99061410e565b60405180910390fd5b610e1e600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168261279f565b3373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051610e6491906137de565b60405180910390a250610e75612850565b565b600f6020528060005260406000206000915090505481565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610edf57610ede33612166565b5b610eea84848461285a565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6363e5188081565b600e8054610f2b90613d8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5790613d8b565b8015610fa45780601f10610f7957610100808354040283529160200191610fa4565b820191906000526020600020905b815481529060010190602001808311610f8757829003601f168201915b505050505081565b610fb4612750565b600a60029054906101000a900460ff1615611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ffb9061417a565b60405180910390fd5b6363e3c73c421015801561101c57506363e518804211155b806110345750600a60019054906101000a900460ff16155b611073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106a906141e6565b60405180910390fd5b6115b38161107f610c31565b6110899190614235565b11156110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c1906142b5565b60405180910390fd5b60018114806110d95750600281145b611118576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110f90614321565b60405180910390fd5b6002600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826111659190614235565b11156111a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119d906143b3565b60405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156111f55750600181145b1561125f5780600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112499190614235565b9250508190555061125a338261287a565b61140c565b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156112ae5750600281145b1561136157660c6f3b40b6c00034146112fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f390614445565b60405180910390fd5b80600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461134b9190614235565b9250508190555061135c338261287a565b61140b565b660c6f3b40b6c00034146113aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a190614445565b60405180910390fd5b80600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113f99190614235565b9250508190555061140a338261287a565b5b5b3373ffffffffffffffffffffffffffffffffffffffff167fe0e3b14a4f3f053af472cf2a7c31ae0e87fd170dbc7a89466d1c776952bd17378260405161145291906137de565b60405180910390a2611462612850565b50565b600a60019054906101000a900460ff1681565b600061148382612898565b9050919050565b660c6f3b40b6c00081565b61149d6123a7565b80600a60026101000a81548160ff02191690831515021790555050565b60006363e2758042101580156114d457506363e3c7004211155b806114ec5750600a60009054906101000a900460ff16155b156114fa57600190506114ff565b600090505b90565b600d805461150f90613d8b565b80601f016020809104026020016040519081016040528092919081815260200182805461153b90613d8b565b80156115885780601f1061155d57610100808354040283529160200191611588565b820191906000526020600020905b81548152906001019060200180831161156b57829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036115f7576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6116506123a7565b61165a6000612964565b565b6116646123a7565b80600b8190555050565b6116766123a7565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6116c26123a7565b80600a60006101000a81548160ff02191690831515021790555050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606003805461171890613d8b565b80601f016020809104026020016040519081016040528092919081815260200182805461174490613d8b565b80156117915780601f1061176657610100808354040283529160200191611791565b820191906000526020600020905b81548152906001019060200180831161177457829003601f168201915b5050505050905090565b6363e3c73c81565b816117ad81612166565b6117b78383612a2a565b505050565b6363e2758081565b600281565b6117d16123a7565b6115b38183516117e19190614465565b6117e9610c31565b6117f39190614235565b1115611834576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182b906142b5565b60405180910390fd5b60005b825181101561187757611864838281518110611856576118556144a7565b5b60200260200101518361287a565b808061186f906144d6565b915050611837565b503373ffffffffffffffffffffffffffffffffffffffff167fafebc04e277b4161399add90646dd3247f10900e3243c77664bec7480dcfb1ad83836040516118c09291906145dc565b60405180910390a25050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461190a5761190933612166565b5b61191685858585612b35565b5050505050565b611925612750565b600a60029054906101000a900460ff1615611975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196c9061417a565b60405180910390fd5b6363e27580421015801561198d57506363e3c7004211155b806119a55750600a60009054906101000a900460ff16155b6119e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119db90614658565b60405180910390fd5b6115b3836119f0610c31565b6119fa9190614235565b1115611a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a32906142b5565b60405180910390fd5b6001831480611a4a5750600283145b611a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8090614321565b60405180910390fd5b600033604051602001611a9c91906135ca565b60405160208183030381529060405280519060200120604051602001611ac29190614699565b604051602081830303815290604052805190602001209050611b28838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600b5483612ba8565b611b67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b5e90614700565b60405180910390fd5b6002600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611bb49190614235565b1115611bf5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bec906143b3565b60405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054148015611c445750600184145b15611cae5783600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611c989190614235565b92505081905550611ca9338561287a565b611e5b565b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054148015611cfd5750600284145b15611db057660c6f3b40b6c0003414611d4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4290614445565b60405180910390fd5b83600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d9a9190614235565b92505081905550611dab338561287a565b611e5a565b660c6f3b40b6c0003414611df9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df090614445565b60405180910390fd5b83600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e489190614235565b92505081905550611e59338561287a565b5b5b3373ffffffffffffffffffffffffffffffffffffffff167fdaad2e796471df601d12042505b2a806ceb443b41e67b123268a0c7c9e6b065085604051611ea191906137de565b60405180910390a250611eb2612850565b505050565b6060611ec282612107565b611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890614792565b60405180910390fd5b6000611f0b612bbf565b90506000815111611f2b5760405180602001604052806000815250611f59565b80611f3584612c51565b600e604051602001611f4993929190614871565b6040516020818303038152906040525b915050919050565b660c6f3b40b6c00081565b6115b381565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61200e6123a7565b80600d908161201d9190613f5e565b5050565b600a60029054906101000a900460ff1681565b6363e3c70081565b6120446123a7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120aa90614914565b60405180910390fd5b6120bc81612964565b50565b60006363e3c73c42101580156120d957506363e518804211155b806120f15750600a60019054906101000a900460ff16155b156120ff5760019050612104565b600090505b90565b600081612112612425565b11158015612121575060005482105b801561215f575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612260576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016121dd929190614934565b602060405180830381865afa1580156121fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221e9190614972565b61225f57806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161225691906135ca565b60405180910390fd5b5b50565b600061226e82611478565b90508073ffffffffffffffffffffffffffffffffffffffff1661228f612d1f565b73ffffffffffffffffffffffffffffffffffffffff16146122f2576122bb816122b6612d1f565b611f72565b6122f1576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6123af612d27565b73ffffffffffffffffffffffffffffffffffffffff166123cd6116df565b73ffffffffffffffffffffffffffffffffffffffff1614612423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161241a906149eb565b60405180910390fd5b565b60006001905090565b600061243982612898565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146124a0576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806124ac84612d2f565b915091506124c281876124bd612d1f565b612d56565b61250e576124d7866124d2612d1f565b611f72565b61250d576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612574576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125818686866001612d9a565b801561258c57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061265a85612636888887612da0565b7c020000000000000000000000000000000000000000000000000000000017612dc8565b600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036126e057600060018501905060006004600083815260200190815260200160002054036126de5760005481146126dd578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46127488686866001612df3565b505050505050565b600260095403612795576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161278c90614a57565b60405180910390fd5b6002600981905550565b60008273ffffffffffffffffffffffffffffffffffffffff16826040516127c590614aa8565b60006040518083038185875af1925050503d8060008114612802576040519150601f19603f3d011682016040523d82523d6000602084013e612807565b606091505b505090508061284b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284290614b09565b60405180910390fd5b505050565b6001600981905550565b612875838383604051806020016040528060008152506118cc565b505050565b612894828260405180602001604052806000815250612df9565b5050565b600080829050806128a7612425565b1161292d5760005481101561292c5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361292a575b600081036129205760046000836001900393508381526020019081526020016000205490506128f6565b809250505061295f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8060076000612a37612d1f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612ae4612d1f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612b299190613459565b60405180910390a35050565b612b40848484610c5b565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612ba257612b6b84848484612e96565b612ba1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600082612bb58584612fe6565b1490509392505050565b6060600d8054612bce90613d8b565b80601f0160208091040260200160405190810160405280929190818152602001828054612bfa90613d8b565b8015612c475780601f10612c1c57610100808354040283529160200191612c47565b820191906000526020600020905b815481529060010190602001808311612c2a57829003601f168201915b5050505050905090565b606060006001612c608461303c565b01905060008167ffffffffffffffff811115612c7f57612c7e61365b565b5b6040519080825280601f01601f191660200182016040528015612cb15781602001600182028036833780820191505090505b509050600082602001820190505b600115612d14578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612d0857612d07614b29565b5b04945060008503612cbf575b819350505050919050565b600033905090565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612db786868461318f565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b612e038383613198565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612e9157600080549050600083820390505b612e436000868380600101945086612e96565b612e79576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110612e30578160005414612e8e57600080fd5b50505b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612ebc612d1f565b8786866040518563ffffffff1660e01b8152600401612ede9493929190614bad565b6020604051808303816000875af1925050508015612f1a57506040513d601f19601f82011682018060405250810190612f179190614c0e565b60015b612f93573d8060008114612f4a576040519150601f19603f3d011682016040523d82523d6000602084013e612f4f565b606091505b506000815103612f8b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60008082905060005b84518110156130315761301c8286838151811061300f5761300e6144a7565b5b6020026020010151613353565b91508080613029906144d6565b915050612fef565b508091505092915050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061309a577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816130905761308f614b29565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106130d7576d04ee2d6d415b85acef810000000083816130cd576130cc614b29565b5b0492506020810190505b662386f26fc10000831061310657662386f26fc1000083816130fc576130fb614b29565b5b0492506010810190505b6305f5e100831061312f576305f5e100838161312557613124614b29565b5b0492506008810190505b612710831061315457612710838161314a57613149614b29565b5b0492506004810190505b60648310613177576064838161316d5761316c614b29565b5b0492506002810190505b600a8310613186576001810190505b80915050919050565b60009392505050565b600080549050600082036131d8576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131e56000848385612d9a565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061325c8361324d6000866000612da0565b6132568561337e565b17612dc8565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146132fd57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506132c2565b5060008203613338576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061334e6000848385612df3565b505050565b600081831061336b57613366828461338e565b613376565b613375838361338e565b5b905092915050565b60006001821460e11b9050919050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6133ee816133b9565b81146133f957600080fd5b50565b60008135905061340b816133e5565b92915050565b600060208284031215613427576134266133af565b5b6000613435848285016133fc565b91505092915050565b60008115159050919050565b6134538161343e565b82525050565b600060208201905061346e600083018461344a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156134ae578082015181840152602081019050613493565b60008484015250505050565b6000601f19601f8301169050919050565b60006134d682613474565b6134e0818561347f565b93506134f0818560208601613490565b6134f9816134ba565b840191505092915050565b6000602082019050818103600083015261351e81846134cb565b905092915050565b6000819050919050565b61353981613526565b811461354457600080fd5b50565b60008135905061355681613530565b92915050565b600060208284031215613572576135716133af565b5b600061358084828501613547565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006135b482613589565b9050919050565b6135c4816135a9565b82525050565b60006020820190506135df60008301846135bb565b92915050565b6135ee816135a9565b81146135f957600080fd5b50565b60008135905061360b816135e5565b92915050565b60008060408385031215613628576136276133af565b5b6000613636858286016135fc565b925050602061364785828601613547565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613693826134ba565b810181811067ffffffffffffffff821117156136b2576136b161365b565b5b80604052505050565b60006136c56133a5565b90506136d1828261368a565b919050565b600067ffffffffffffffff8211156136f1576136f061365b565b5b6136fa826134ba565b9050602081019050919050565b82818337600083830152505050565b6000613729613724846136d6565b6136bb565b90508281526020810184848401111561374557613744613656565b5b613750848285613707565b509392505050565b600082601f83011261376d5761376c613651565b5b813561377d848260208601613716565b91505092915050565b60006020828403121561379c5761379b6133af565b5b600082013567ffffffffffffffff8111156137ba576137b96133b4565b5b6137c684828501613758565b91505092915050565b6137d881613526565b82525050565b60006020820190506137f360008301846137cf565b92915050565b600080600060608486031215613812576138116133af565b5b6000613820868287016135fc565b9350506020613831868287016135fc565b925050604061384286828701613547565b9150509250925092565b6000819050919050565b61385f8161384c565b82525050565b600060208201905061387a6000830184613856565b92915050565b6138898161343e565b811461389457600080fd5b50565b6000813590506138a681613880565b92915050565b6000602082840312156138c2576138c16133af565b5b60006138d084828501613897565b91505092915050565b6000602082840312156138ef576138ee6133af565b5b60006138fd848285016135fc565b91505092915050565b6000819050919050565b600061392b61392661392184613589565b613906565b613589565b9050919050565b600061393d82613910565b9050919050565b600061394f82613932565b9050919050565b61395f81613944565b82525050565b600060208201905061397a6000830184613956565b92915050565b6139898161384c565b811461399457600080fd5b50565b6000813590506139a681613980565b92915050565b6000602082840312156139c2576139c16133af565b5b60006139d084828501613997565b91505092915050565b600080604083850312156139f0576139ef6133af565b5b60006139fe858286016135fc565b9250506020613a0f85828601613897565b9150509250929050565b600067ffffffffffffffff821115613a3457613a3361365b565b5b602082029050602081019050919050565b600080fd5b6000613a5d613a5884613a19565b6136bb565b90508083825260208201905060208402830185811115613a8057613a7f613a45565b5b835b81811015613aa95780613a9588826135fc565b845260208401935050602081019050613a82565b5050509392505050565b600082601f830112613ac857613ac7613651565b5b8135613ad8848260208601613a4a565b91505092915050565b60008060408385031215613af857613af76133af565b5b600083013567ffffffffffffffff811115613b1657613b156133b4565b5b613b2285828601613ab3565b9250506020613b3385828601613547565b9150509250929050565b600067ffffffffffffffff821115613b5857613b5761365b565b5b613b61826134ba565b9050602081019050919050565b6000613b81613b7c84613b3d565b6136bb565b905082815260208101848484011115613b9d57613b9c613656565b5b613ba8848285613707565b509392505050565b600082601f830112613bc557613bc4613651565b5b8135613bd5848260208601613b6e565b91505092915050565b60008060008060808587031215613bf857613bf76133af565b5b6000613c06878288016135fc565b9450506020613c17878288016135fc565b9350506040613c2887828801613547565b925050606085013567ffffffffffffffff811115613c4957613c486133b4565b5b613c5587828801613bb0565b91505092959194509250565b600080fd5b60008083601f840112613c7c57613c7b613651565b5b8235905067ffffffffffffffff811115613c9957613c98613c61565b5b602083019150836020820283011115613cb557613cb4613a45565b5b9250929050565b600080600060408486031215613cd557613cd46133af565b5b6000613ce386828701613547565b935050602084013567ffffffffffffffff811115613d0457613d036133b4565b5b613d1086828701613c66565b92509250509250925092565b60008060408385031215613d3357613d326133af565b5b6000613d41858286016135fc565b9250506020613d52858286016135fc565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613da357607f821691505b602082108103613db657613db5613d5c565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613e1e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613de1565b613e288683613de1565b95508019841693508086168417925050509392505050565b6000613e5b613e56613e5184613526565b613906565b613526565b9050919050565b6000819050919050565b613e7583613e40565b613e89613e8182613e62565b848454613dee565b825550505050565b600090565b613e9e613e91565b613ea9818484613e6c565b505050565b5b81811015613ecd57613ec2600082613e96565b600181019050613eaf565b5050565b601f821115613f1257613ee381613dbc565b613eec84613dd1565b81016020851015613efb578190505b613f0f613f0785613dd1565b830182613eae565b50505b505050565b600082821c905092915050565b6000613f3560001984600802613f17565b1980831691505092915050565b6000613f4e8383613f24565b9150826002028217905092915050565b613f6782613474565b67ffffffffffffffff811115613f8057613f7f61365b565b5b613f8a8254613d8b565b613f95828285613ed1565b600060209050601f831160018114613fc85760008415613fb6578287015190505b613fc08582613f42565b865550614028565b601f198416613fd686613dbc565b60005b82811015613ffe57848901518255600182019150602085019450602081019050613fd9565b8683101561401b5784890151614017601f891682613f24565b8355505b6001600288020188555050505b505050505050565b7f444d50533a2063616e2062652063616c6c6564206f6e6c79207769746820746860008201527f65206f776e6572206f722070617965724163636f756e74000000000000000000602082015250565b600061408c60378361347f565b915061409782614030565b604082019050919050565b600060208201905081810360008301526140bb8161407f565b9050919050565b7f444d50533a20636f6e74726163742062616c616e6365206973207a65726f0000600082015250565b60006140f8601e8361347f565b9150614103826140c2565b602082019050919050565b60006020820190508181036000830152614127816140eb565b9050919050565b7f444d50533a20636f6e7472616374206973207061757365640000000000000000600082015250565b600061416460188361347f565b915061416f8261412e565b602082019050919050565b6000602082019050818103600083015261419381614157565b9050919050565b7f444d50533a207075626c696353616c6520636c6f736564000000000000000000600082015250565b60006141d060178361347f565b91506141db8261419a565b602082019050919050565b600060208201905081810360008301526141ff816141c3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061424082613526565b915061424b83613526565b925082820190508082111561426357614262614206565b5b92915050565b7f444d50533a206d6178537570706c792065786365656465640000000000000000600082015250565b600061429f60188361347f565b91506142aa82614269565b602082019050919050565b600060208201905081810360008301526142ce81614292565b9050919050565b7f444d50533a206d696e74416d6f756e74206d7573742062652031206f72203200600082015250565b600061430b601f8361347f565b9150614316826142d5565b602082019050919050565b6000602082019050818103600083015261433a816142fe565b9050919050565b7f444d50533a20757365722063616e6e6f74206d696e74206d6f7265207468656e60008201527f2032204e46547300000000000000000000000000000000000000000000000000602082015250565b600061439d60278361347f565b91506143a882614341565b604082019050919050565b600060208201905081810360008301526143cc81614390565b9050919050565b7f444d50533a2075736572206d7573742073656e6420746865206578616374207060008201527f7269636500000000000000000000000000000000000000000000000000000000602082015250565b600061442f60248361347f565b915061443a826143d3565b604082019050919050565b6000602082019050818103600083015261445e81614422565b9050919050565b600061447082613526565b915061447b83613526565b925082820261448981613526565b915082820484148315176144a05761449f614206565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006144e182613526565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361451357614512614206565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614553816135a9565b82525050565b6000614565838361454a565b60208301905092915050565b6000602082019050919050565b60006145898261451e565b6145938185614529565b935061459e8361453a565b8060005b838110156145cf5781516145b68882614559565b97506145c183614571565b9250506001810190506145a2565b5085935050505092915050565b600060408201905081810360008301526145f6818561457e565b905061460560208301846137cf565b9392505050565b7f444d50533a2077686974656c69737453616c6520636c6f736564000000000000600082015250565b6000614642601a8361347f565b915061464d8261460c565b602082019050919050565b6000602082019050818103600083015261467181614635565b9050919050565b6000819050919050565b61469361468e8261384c565b614678565b82525050565b60006146a58284614682565b60208201915081905092915050565b7f444d50533a20496e76616c69642070726f6f6600000000000000000000000000600082015250565b60006146ea60138361347f565b91506146f5826146b4565b602082019050919050565b60006020820190508181036000830152614719816146dd565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b600061477c602f8361347f565b915061478782614720565b604082019050919050565b600060208201905081810360008301526147ab8161476f565b9050919050565b600081905092915050565b60006147c882613474565b6147d281856147b2565b93506147e2818560208601613490565b80840191505092915050565b600081546147fb81613d8b565b61480581866147b2565b94506001821660008114614820576001811461483557614868565b60ff1983168652811515820286019350614868565b61483e85613dbc565b60005b8381101561486057815481890152600182019150602081019050614841565b838801955050505b50505092915050565b600061487d82866147bd565b915061488982856147bd565b915061489582846147ee565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006148fe60268361347f565b9150614909826148a2565b604082019050919050565b6000602082019050818103600083015261492d816148f1565b9050919050565b600060408201905061494960008301856135bb565b61495660208301846135bb565b9392505050565b60008151905061496c81613880565b92915050565b600060208284031215614988576149876133af565b5b60006149968482850161495d565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006149d560208361347f565b91506149e08261499f565b602082019050919050565b60006020820190508181036000830152614a04816149c8565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614a41601f8361347f565b9150614a4c82614a0b565b602082019050919050565b60006020820190508181036000830152614a7081614a34565b9050919050565b600081905092915050565b50565b6000614a92600083614a77565b9150614a9d82614a82565b600082019050919050565b6000614ab382614a85565b9150819050919050565b7f444d50533a206661696c656420746f2073656e6420616d6f756e740000000000600082015250565b6000614af3601b8361347f565b9150614afe82614abd565b602082019050919050565b60006020820190508181036000830152614b2281614ae6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000614b7f82614b58565b614b898185614b63565b9350614b99818560208601613490565b614ba2816134ba565b840191505092915050565b6000608082019050614bc260008301876135bb565b614bcf60208301866135bb565b614bdc60408301856137cf565b8181036060830152614bee8184614b74565b905095945050505050565b600081519050614c08816133e5565b92915050565b600060208284031215614c2457614c236133af565b5b6000614c3284828501614bf9565b9150509291505056fea2646970667358221220b1a4f16b6de2b25b0a5d62895927a093ba6811c3367eddedd42e82e4f54bbc5f64736f6c63430008110033f833f9bb29374b30e2733f881c7dd05b8f925646025029aa523d06456ed3baf700000000000000000000000000000000000000000000000000000000000000600000000000000000000000002acec43e0bb6f7fb37a208fbf8dbe6ec0f6ba72c0000000000000000000000000000000000000000000000000000000000000043697066733a2f2f6261667962656968636c34746d61663673696a69626f7674327734686e637a717a773562646f703470657673636376336e686f73656e6f6c6663752f0000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102885760003560e01c80636c0360eb1161015a578063b6afc4dc116100c1578063e985e9c51161007a578063e985e9c51461094a578063ede029fc14610987578063f12d54d8146109b0578063f2702b67146109db578063f2fde38b14610a06578063f9a1deb114610a2f57610288565b8063b6afc4dc14610856578063b88d4fde1461087f578063c1ae1bc71461089b578063c87b56dd146108b7578063cd08c046146108f4578063d5abeb011461091f57610288565b80638da5cb5b116101135780638da5cb5b1461075657806395d89b41146107815780639d80461f146107ac578063a22cb465146107d7578063a548bf7014610800578063b228d9251461082b57610288565b80636c0360eb1461065c57806370a0823114610687578063715018a6146106c45780637cb64759146106db5780637f5502501461070457806389f6fbe61461072d57610288565b80633cd7b152116101fe5780635a5e5d58116101b75780635a5e5d58146105595780635d83744b146105755780636352211e146105a0578063654a13fb146105dd57806369a6b3db146106085780636a99d7991461063157610288565b80633cd7b1521461045457806341f434341461049157806342842e0e146104bc5780634f37888f146104d85780635497e7dc146105035780635503a0e81461052e57610288565b806318160ddd1161025057806318160ddd146103775780631b6e0095146103a257806323b872dd146103cd5780632eb4a7ab146103e95780633970e0ec146104145780633ccfd60b1461043d57610288565b806301ffc9a71461028d57806306fdde03146102ca578063081812fc146102f5578063095ea7b31461033257806316ba10e01461034e575b600080fd5b34801561029957600080fd5b506102b460048036038101906102af9190613411565b610a5a565b6040516102c19190613459565b60405180910390f35b3480156102d657600080fd5b506102df610aec565b6040516102ec9190613504565b60405180910390f35b34801561030157600080fd5b5061031c6004803603810190610317919061355c565b610b7e565b60405161032991906135ca565b60405180910390f35b61034c60048036038101906103479190613611565b610bfd565b005b34801561035a57600080fd5b5061037560048036038101906103709190613786565b610c16565b005b34801561038357600080fd5b5061038c610c31565b60405161039991906137de565b60405180910390f35b3480156103ae57600080fd5b506103b7610c48565b6040516103c49190613459565b60405180910390f35b6103e760048036038101906103e291906137f9565b610c5b565b005b3480156103f557600080fd5b506103fe610caa565b60405161040b9190613865565b60405180910390f35b34801561042057600080fd5b5061043b600480360381019061043691906138ac565b610cb0565b005b34801561044957600080fd5b50610452610cd5565b005b34801561046057600080fd5b5061047b600480360381019061047691906138d9565b610e77565b60405161048891906137de565b60405180910390f35b34801561049d57600080fd5b506104a6610e8f565b6040516104b39190613965565b60405180910390f35b6104d660048036038101906104d191906137f9565b610ea1565b005b3480156104e457600080fd5b506104ed610ef0565b6040516104fa91906135ca565b60405180910390f35b34801561050f57600080fd5b50610518610f16565b60405161052591906137de565b60405180910390f35b34801561053a57600080fd5b50610543610f1e565b6040516105509190613504565b60405180910390f35b610573600480360381019061056e919061355c565b610fac565b005b34801561058157600080fd5b5061058a611465565b6040516105979190613459565b60405180910390f35b3480156105ac57600080fd5b506105c760048036038101906105c2919061355c565b611478565b6040516105d491906135ca565b60405180910390f35b3480156105e957600080fd5b506105f261148a565b6040516105ff91906137de565b60405180910390f35b34801561061457600080fd5b5061062f600480360381019061062a91906138ac565b611495565b005b34801561063d57600080fd5b506106466114ba565b6040516106539190613459565b60405180910390f35b34801561066857600080fd5b50610671611502565b60405161067e9190613504565b60405180910390f35b34801561069357600080fd5b506106ae60048036038101906106a991906138d9565b611590565b6040516106bb91906137de565b60405180910390f35b3480156106d057600080fd5b506106d9611648565b005b3480156106e757600080fd5b5061070260048036038101906106fd91906139ac565b61165c565b005b34801561071057600080fd5b5061072b600480360381019061072691906138d9565b61166e565b005b34801561073957600080fd5b50610754600480360381019061074f91906138ac565b6116ba565b005b34801561076257600080fd5b5061076b6116df565b60405161077891906135ca565b60405180910390f35b34801561078d57600080fd5b50610796611709565b6040516107a39190613504565b60405180910390f35b3480156107b857600080fd5b506107c161179b565b6040516107ce91906137de565b60405180910390f35b3480156107e357600080fd5b506107fe60048036038101906107f991906139d9565b6117a3565b005b34801561080c57600080fd5b506108156117bc565b60405161082291906137de565b60405180910390f35b34801561083757600080fd5b506108406117c4565b60405161084d91906137de565b60405180910390f35b34801561086257600080fd5b5061087d60048036038101906108789190613ae1565b6117c9565b005b61089960048036038101906108949190613bde565b6118cc565b005b6108b560048036038101906108b09190613cbc565b61191d565b005b3480156108c357600080fd5b506108de60048036038101906108d9919061355c565b611eb7565b6040516108eb9190613504565b60405180910390f35b34801561090057600080fd5b50610909611f61565b60405161091691906137de565b60405180910390f35b34801561092b57600080fd5b50610934611f6c565b60405161094191906137de565b60405180910390f35b34801561095657600080fd5b50610971600480360381019061096c9190613d1c565b611f72565b60405161097e9190613459565b60405180910390f35b34801561099357600080fd5b506109ae60048036038101906109a99190613786565b612006565b005b3480156109bc57600080fd5b506109c5612021565b6040516109d29190613459565b60405180910390f35b3480156109e757600080fd5b506109f0612034565b6040516109fd91906137de565b60405180910390f35b348015610a1257600080fd5b50610a2d6004803603810190610a2891906138d9565b61203c565b005b348015610a3b57600080fd5b50610a446120bf565b604051610a519190613459565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610ab557506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ae55750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610afb90613d8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2790613d8b565b8015610b745780601f10610b4957610100808354040283529160200191610b74565b820191906000526020600020905b815481529060010190602001808311610b5757829003601f168201915b5050505050905090565b6000610b8982612107565b610bbf576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610c0781612166565b610c118383612263565b505050565b610c1e6123a7565b80600e9081610c2d9190613f5e565b5050565b6000610c3b612425565b6001546000540303905090565b600a60009054906101000a900460ff1681565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c9957610c9833612166565b5b610ca484848461242e565b50505050565b600b5481565b610cb86123a7565b80600a60016101000a81548160ff02191690831515021790555050565b610cdd612750565b610ce56116df565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610d6b5750600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610daa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da1906140a2565b60405180910390fd5b600047905060008103610df2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de99061410e565b60405180910390fd5b610e1e600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168261279f565b3373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051610e6491906137de565b60405180910390a250610e75612850565b565b600f6020528060005260406000206000915090505481565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610edf57610ede33612166565b5b610eea84848461285a565b50505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6363e5188081565b600e8054610f2b90613d8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5790613d8b565b8015610fa45780601f10610f7957610100808354040283529160200191610fa4565b820191906000526020600020905b815481529060010190602001808311610f8757829003601f168201915b505050505081565b610fb4612750565b600a60029054906101000a900460ff1615611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ffb9061417a565b60405180910390fd5b6363e3c73c421015801561101c57506363e518804211155b806110345750600a60019054906101000a900460ff16155b611073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106a906141e6565b60405180910390fd5b6115b38161107f610c31565b6110899190614235565b11156110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c1906142b5565b60405180910390fd5b60018114806110d95750600281145b611118576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110f90614321565b60405180910390fd5b6002600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826111659190614235565b11156111a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119d906143b3565b60405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156111f55750600181145b1561125f5780600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112499190614235565b9250508190555061125a338261287a565b61140c565b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480156112ae5750600281145b1561136157660c6f3b40b6c00034146112fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f390614445565b60405180910390fd5b80600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461134b9190614235565b9250508190555061135c338261287a565b61140b565b660c6f3b40b6c00034146113aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a190614445565b60405180910390fd5b80600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113f99190614235565b9250508190555061140a338261287a565b5b5b3373ffffffffffffffffffffffffffffffffffffffff167fe0e3b14a4f3f053af472cf2a7c31ae0e87fd170dbc7a89466d1c776952bd17378260405161145291906137de565b60405180910390a2611462612850565b50565b600a60019054906101000a900460ff1681565b600061148382612898565b9050919050565b660c6f3b40b6c00081565b61149d6123a7565b80600a60026101000a81548160ff02191690831515021790555050565b60006363e2758042101580156114d457506363e3c7004211155b806114ec5750600a60009054906101000a900460ff16155b156114fa57600190506114ff565b600090505b90565b600d805461150f90613d8b565b80601f016020809104026020016040519081016040528092919081815260200182805461153b90613d8b565b80156115885780601f1061155d57610100808354040283529160200191611588565b820191906000526020600020905b81548152906001019060200180831161156b57829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036115f7576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6116506123a7565b61165a6000612964565b565b6116646123a7565b80600b8190555050565b6116766123a7565b80600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6116c26123a7565b80600a60006101000a81548160ff02191690831515021790555050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606003805461171890613d8b565b80601f016020809104026020016040519081016040528092919081815260200182805461174490613d8b565b80156117915780601f1061176657610100808354040283529160200191611791565b820191906000526020600020905b81548152906001019060200180831161177457829003601f168201915b5050505050905090565b6363e3c73c81565b816117ad81612166565b6117b78383612a2a565b505050565b6363e2758081565b600281565b6117d16123a7565b6115b38183516117e19190614465565b6117e9610c31565b6117f39190614235565b1115611834576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182b906142b5565b60405180910390fd5b60005b825181101561187757611864838281518110611856576118556144a7565b5b60200260200101518361287a565b808061186f906144d6565b915050611837565b503373ffffffffffffffffffffffffffffffffffffffff167fafebc04e277b4161399add90646dd3247f10900e3243c77664bec7480dcfb1ad83836040516118c09291906145dc565b60405180910390a25050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461190a5761190933612166565b5b61191685858585612b35565b5050505050565b611925612750565b600a60029054906101000a900460ff1615611975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196c9061417a565b60405180910390fd5b6363e27580421015801561198d57506363e3c7004211155b806119a55750600a60009054906101000a900460ff16155b6119e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119db90614658565b60405180910390fd5b6115b3836119f0610c31565b6119fa9190614235565b1115611a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a32906142b5565b60405180910390fd5b6001831480611a4a5750600283145b611a89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8090614321565b60405180910390fd5b600033604051602001611a9c91906135ca565b60405160208183030381529060405280519060200120604051602001611ac29190614699565b604051602081830303815290604052805190602001209050611b28838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600b5483612ba8565b611b67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b5e90614700565b60405180910390fd5b6002600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611bb49190614235565b1115611bf5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bec906143b3565b60405180910390fd5b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054148015611c445750600184145b15611cae5783600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611c989190614235565b92505081905550611ca9338561287a565b611e5b565b6000600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054148015611cfd5750600284145b15611db057660c6f3b40b6c0003414611d4b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4290614445565b60405180910390fd5b83600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d9a9190614235565b92505081905550611dab338561287a565b611e5a565b660c6f3b40b6c0003414611df9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df090614445565b60405180910390fd5b83600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611e489190614235565b92505081905550611e59338561287a565b5b5b3373ffffffffffffffffffffffffffffffffffffffff167fdaad2e796471df601d12042505b2a806ceb443b41e67b123268a0c7c9e6b065085604051611ea191906137de565b60405180910390a250611eb2612850565b505050565b6060611ec282612107565b611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890614792565b60405180910390fd5b6000611f0b612bbf565b90506000815111611f2b5760405180602001604052806000815250611f59565b80611f3584612c51565b600e604051602001611f4993929190614871565b6040516020818303038152906040525b915050919050565b660c6f3b40b6c00081565b6115b381565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61200e6123a7565b80600d908161201d9190613f5e565b5050565b600a60029054906101000a900460ff1681565b6363e3c70081565b6120446123a7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120aa90614914565b60405180910390fd5b6120bc81612964565b50565b60006363e3c73c42101580156120d957506363e518804211155b806120f15750600a60019054906101000a900460ff16155b156120ff5760019050612104565b600090505b90565b600081612112612425565b11158015612121575060005482105b801561215f575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612260576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016121dd929190614934565b602060405180830381865afa1580156121fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221e9190614972565b61225f57806040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161225691906135ca565b60405180910390fd5b5b50565b600061226e82611478565b90508073ffffffffffffffffffffffffffffffffffffffff1661228f612d1f565b73ffffffffffffffffffffffffffffffffffffffff16146122f2576122bb816122b6612d1f565b611f72565b6122f1576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6123af612d27565b73ffffffffffffffffffffffffffffffffffffffff166123cd6116df565b73ffffffffffffffffffffffffffffffffffffffff1614612423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161241a906149eb565b60405180910390fd5b565b60006001905090565b600061243982612898565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146124a0576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806124ac84612d2f565b915091506124c281876124bd612d1f565b612d56565b61250e576124d7866124d2612d1f565b611f72565b61250d576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612574576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125818686866001612d9a565b801561258c57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061265a85612636888887612da0565b7c020000000000000000000000000000000000000000000000000000000017612dc8565b600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036126e057600060018501905060006004600083815260200190815260200160002054036126de5760005481146126dd578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46127488686866001612df3565b505050505050565b600260095403612795576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161278c90614a57565b60405180910390fd5b6002600981905550565b60008273ffffffffffffffffffffffffffffffffffffffff16826040516127c590614aa8565b60006040518083038185875af1925050503d8060008114612802576040519150601f19603f3d011682016040523d82523d6000602084013e612807565b606091505b505090508061284b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284290614b09565b60405180910390fd5b505050565b6001600981905550565b612875838383604051806020016040528060008152506118cc565b505050565b612894828260405180602001604052806000815250612df9565b5050565b600080829050806128a7612425565b1161292d5760005481101561292c5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361292a575b600081036129205760046000836001900393508381526020019081526020016000205490506128f6565b809250505061295f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8060076000612a37612d1f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612ae4612d1f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612b299190613459565b60405180910390a35050565b612b40848484610c5b565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612ba257612b6b84848484612e96565b612ba1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600082612bb58584612fe6565b1490509392505050565b6060600d8054612bce90613d8b565b80601f0160208091040260200160405190810160405280929190818152602001828054612bfa90613d8b565b8015612c475780601f10612c1c57610100808354040283529160200191612c47565b820191906000526020600020905b815481529060010190602001808311612c2a57829003601f168201915b5050505050905090565b606060006001612c608461303c565b01905060008167ffffffffffffffff811115612c7f57612c7e61365b565b5b6040519080825280601f01601f191660200182016040528015612cb15781602001600182028036833780820191505090505b509050600082602001820190505b600115612d14578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612d0857612d07614b29565b5b04945060008503612cbf575b819350505050919050565b600033905090565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612db786868461318f565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b612e038383613198565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612e9157600080549050600083820390505b612e436000868380600101945086612e96565b612e79576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110612e30578160005414612e8e57600080fd5b50505b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612ebc612d1f565b8786866040518563ffffffff1660e01b8152600401612ede9493929190614bad565b6020604051808303816000875af1925050508015612f1a57506040513d601f19601f82011682018060405250810190612f179190614c0e565b60015b612f93573d8060008114612f4a576040519150601f19603f3d011682016040523d82523d6000602084013e612f4f565b606091505b506000815103612f8b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60008082905060005b84518110156130315761301c8286838151811061300f5761300e6144a7565b5b6020026020010151613353565b91508080613029906144d6565b915050612fef565b508091505092915050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061309a577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816130905761308f614b29565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106130d7576d04ee2d6d415b85acef810000000083816130cd576130cc614b29565b5b0492506020810190505b662386f26fc10000831061310657662386f26fc1000083816130fc576130fb614b29565b5b0492506010810190505b6305f5e100831061312f576305f5e100838161312557613124614b29565b5b0492506008810190505b612710831061315457612710838161314a57613149614b29565b5b0492506004810190505b60648310613177576064838161316d5761316c614b29565b5b0492506002810190505b600a8310613186576001810190505b80915050919050565b60009392505050565b600080549050600082036131d8576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131e56000848385612d9a565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061325c8361324d6000866000612da0565b6132568561337e565b17612dc8565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146132fd57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506132c2565b5060008203613338576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061334e6000848385612df3565b505050565b600081831061336b57613366828461338e565b613376565b613375838361338e565b5b905092915050565b60006001821460e11b9050919050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6133ee816133b9565b81146133f957600080fd5b50565b60008135905061340b816133e5565b92915050565b600060208284031215613427576134266133af565b5b6000613435848285016133fc565b91505092915050565b60008115159050919050565b6134538161343e565b82525050565b600060208201905061346e600083018461344a565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156134ae578082015181840152602081019050613493565b60008484015250505050565b6000601f19601f8301169050919050565b60006134d682613474565b6134e0818561347f565b93506134f0818560208601613490565b6134f9816134ba565b840191505092915050565b6000602082019050818103600083015261351e81846134cb565b905092915050565b6000819050919050565b61353981613526565b811461354457600080fd5b50565b60008135905061355681613530565b92915050565b600060208284031215613572576135716133af565b5b600061358084828501613547565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006135b482613589565b9050919050565b6135c4816135a9565b82525050565b60006020820190506135df60008301846135bb565b92915050565b6135ee816135a9565b81146135f957600080fd5b50565b60008135905061360b816135e5565b92915050565b60008060408385031215613628576136276133af565b5b6000613636858286016135fc565b925050602061364785828601613547565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613693826134ba565b810181811067ffffffffffffffff821117156136b2576136b161365b565b5b80604052505050565b60006136c56133a5565b90506136d1828261368a565b919050565b600067ffffffffffffffff8211156136f1576136f061365b565b5b6136fa826134ba565b9050602081019050919050565b82818337600083830152505050565b6000613729613724846136d6565b6136bb565b90508281526020810184848401111561374557613744613656565b5b613750848285613707565b509392505050565b600082601f83011261376d5761376c613651565b5b813561377d848260208601613716565b91505092915050565b60006020828403121561379c5761379b6133af565b5b600082013567ffffffffffffffff8111156137ba576137b96133b4565b5b6137c684828501613758565b91505092915050565b6137d881613526565b82525050565b60006020820190506137f360008301846137cf565b92915050565b600080600060608486031215613812576138116133af565b5b6000613820868287016135fc565b9350506020613831868287016135fc565b925050604061384286828701613547565b9150509250925092565b6000819050919050565b61385f8161384c565b82525050565b600060208201905061387a6000830184613856565b92915050565b6138898161343e565b811461389457600080fd5b50565b6000813590506138a681613880565b92915050565b6000602082840312156138c2576138c16133af565b5b60006138d084828501613897565b91505092915050565b6000602082840312156138ef576138ee6133af565b5b60006138fd848285016135fc565b91505092915050565b6000819050919050565b600061392b61392661392184613589565b613906565b613589565b9050919050565b600061393d82613910565b9050919050565b600061394f82613932565b9050919050565b61395f81613944565b82525050565b600060208201905061397a6000830184613956565b92915050565b6139898161384c565b811461399457600080fd5b50565b6000813590506139a681613980565b92915050565b6000602082840312156139c2576139c16133af565b5b60006139d084828501613997565b91505092915050565b600080604083850312156139f0576139ef6133af565b5b60006139fe858286016135fc565b9250506020613a0f85828601613897565b9150509250929050565b600067ffffffffffffffff821115613a3457613a3361365b565b5b602082029050602081019050919050565b600080fd5b6000613a5d613a5884613a19565b6136bb565b90508083825260208201905060208402830185811115613a8057613a7f613a45565b5b835b81811015613aa95780613a9588826135fc565b845260208401935050602081019050613a82565b5050509392505050565b600082601f830112613ac857613ac7613651565b5b8135613ad8848260208601613a4a565b91505092915050565b60008060408385031215613af857613af76133af565b5b600083013567ffffffffffffffff811115613b1657613b156133b4565b5b613b2285828601613ab3565b9250506020613b3385828601613547565b9150509250929050565b600067ffffffffffffffff821115613b5857613b5761365b565b5b613b61826134ba565b9050602081019050919050565b6000613b81613b7c84613b3d565b6136bb565b905082815260208101848484011115613b9d57613b9c613656565b5b613ba8848285613707565b509392505050565b600082601f830112613bc557613bc4613651565b5b8135613bd5848260208601613b6e565b91505092915050565b60008060008060808587031215613bf857613bf76133af565b5b6000613c06878288016135fc565b9450506020613c17878288016135fc565b9350506040613c2887828801613547565b925050606085013567ffffffffffffffff811115613c4957613c486133b4565b5b613c5587828801613bb0565b91505092959194509250565b600080fd5b60008083601f840112613c7c57613c7b613651565b5b8235905067ffffffffffffffff811115613c9957613c98613c61565b5b602083019150836020820283011115613cb557613cb4613a45565b5b9250929050565b600080600060408486031215613cd557613cd46133af565b5b6000613ce386828701613547565b935050602084013567ffffffffffffffff811115613d0457613d036133b4565b5b613d1086828701613c66565b92509250509250925092565b60008060408385031215613d3357613d326133af565b5b6000613d41858286016135fc565b9250506020613d52858286016135fc565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613da357607f821691505b602082108103613db657613db5613d5c565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613e1e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613de1565b613e288683613de1565b95508019841693508086168417925050509392505050565b6000613e5b613e56613e5184613526565b613906565b613526565b9050919050565b6000819050919050565b613e7583613e40565b613e89613e8182613e62565b848454613dee565b825550505050565b600090565b613e9e613e91565b613ea9818484613e6c565b505050565b5b81811015613ecd57613ec2600082613e96565b600181019050613eaf565b5050565b601f821115613f1257613ee381613dbc565b613eec84613dd1565b81016020851015613efb578190505b613f0f613f0785613dd1565b830182613eae565b50505b505050565b600082821c905092915050565b6000613f3560001984600802613f17565b1980831691505092915050565b6000613f4e8383613f24565b9150826002028217905092915050565b613f6782613474565b67ffffffffffffffff811115613f8057613f7f61365b565b5b613f8a8254613d8b565b613f95828285613ed1565b600060209050601f831160018114613fc85760008415613fb6578287015190505b613fc08582613f42565b865550614028565b601f198416613fd686613dbc565b60005b82811015613ffe57848901518255600182019150602085019450602081019050613fd9565b8683101561401b5784890151614017601f891682613f24565b8355505b6001600288020188555050505b505050505050565b7f444d50533a2063616e2062652063616c6c6564206f6e6c79207769746820746860008201527f65206f776e6572206f722070617965724163636f756e74000000000000000000602082015250565b600061408c60378361347f565b915061409782614030565b604082019050919050565b600060208201905081810360008301526140bb8161407f565b9050919050565b7f444d50533a20636f6e74726163742062616c616e6365206973207a65726f0000600082015250565b60006140f8601e8361347f565b9150614103826140c2565b602082019050919050565b60006020820190508181036000830152614127816140eb565b9050919050565b7f444d50533a20636f6e7472616374206973207061757365640000000000000000600082015250565b600061416460188361347f565b915061416f8261412e565b602082019050919050565b6000602082019050818103600083015261419381614157565b9050919050565b7f444d50533a207075626c696353616c6520636c6f736564000000000000000000600082015250565b60006141d060178361347f565b91506141db8261419a565b602082019050919050565b600060208201905081810360008301526141ff816141c3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061424082613526565b915061424b83613526565b925082820190508082111561426357614262614206565b5b92915050565b7f444d50533a206d6178537570706c792065786365656465640000000000000000600082015250565b600061429f60188361347f565b91506142aa82614269565b602082019050919050565b600060208201905081810360008301526142ce81614292565b9050919050565b7f444d50533a206d696e74416d6f756e74206d7573742062652031206f72203200600082015250565b600061430b601f8361347f565b9150614316826142d5565b602082019050919050565b6000602082019050818103600083015261433a816142fe565b9050919050565b7f444d50533a20757365722063616e6e6f74206d696e74206d6f7265207468656e60008201527f2032204e46547300000000000000000000000000000000000000000000000000602082015250565b600061439d60278361347f565b91506143a882614341565b604082019050919050565b600060208201905081810360008301526143cc81614390565b9050919050565b7f444d50533a2075736572206d7573742073656e6420746865206578616374207060008201527f7269636500000000000000000000000000000000000000000000000000000000602082015250565b600061442f60248361347f565b915061443a826143d3565b604082019050919050565b6000602082019050818103600083015261445e81614422565b9050919050565b600061447082613526565b915061447b83613526565b925082820261448981613526565b915082820484148315176144a05761449f614206565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006144e182613526565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361451357614512614206565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614553816135a9565b82525050565b6000614565838361454a565b60208301905092915050565b6000602082019050919050565b60006145898261451e565b6145938185614529565b935061459e8361453a565b8060005b838110156145cf5781516145b68882614559565b97506145c183614571565b9250506001810190506145a2565b5085935050505092915050565b600060408201905081810360008301526145f6818561457e565b905061460560208301846137cf565b9392505050565b7f444d50533a2077686974656c69737453616c6520636c6f736564000000000000600082015250565b6000614642601a8361347f565b915061464d8261460c565b602082019050919050565b6000602082019050818103600083015261467181614635565b9050919050565b6000819050919050565b61469361468e8261384c565b614678565b82525050565b60006146a58284614682565b60208201915081905092915050565b7f444d50533a20496e76616c69642070726f6f6600000000000000000000000000600082015250565b60006146ea60138361347f565b91506146f5826146b4565b602082019050919050565b60006020820190508181036000830152614719816146dd565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b600061477c602f8361347f565b915061478782614720565b604082019050919050565b600060208201905081810360008301526147ab8161476f565b9050919050565b600081905092915050565b60006147c882613474565b6147d281856147b2565b93506147e2818560208601613490565b80840191505092915050565b600081546147fb81613d8b565b61480581866147b2565b94506001821660008114614820576001811461483557614868565b60ff1983168652811515820286019350614868565b61483e85613dbc565b60005b8381101561486057815481890152600182019150602081019050614841565b838801955050505b50505092915050565b600061487d82866147bd565b915061488982856147bd565b915061489582846147ee565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006148fe60268361347f565b9150614909826148a2565b604082019050919050565b6000602082019050818103600083015261492d816148f1565b9050919050565b600060408201905061494960008301856135bb565b61495660208301846135bb565b9392505050565b60008151905061496c81613880565b92915050565b600060208284031215614988576149876133af565b5b60006149968482850161495d565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006149d560208361347f565b91506149e08261499f565b602082019050919050565b60006020820190508181036000830152614a04816149c8565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614a41601f8361347f565b9150614a4c82614a0b565b602082019050919050565b60006020820190508181036000830152614a7081614a34565b9050919050565b600081905092915050565b50565b6000614a92600083614a77565b9150614a9d82614a82565b600082019050919050565b6000614ab382614a85565b9150819050919050565b7f444d50533a206661696c656420746f2073656e6420616d6f756e740000000000600082015250565b6000614af3601b8361347f565b9150614afe82614abd565b602082019050919050565b60006020820190508181036000830152614b2281614ae6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000614b7f82614b58565b614b898185614b63565b9350614b99818560208601613490565b614ba2816134ba565b840191505092915050565b6000608082019050614bc260008301876135bb565b614bcf60208301866135bb565b614bdc60408301856137cf565b8181036060830152614bee8184614b74565b905095945050505050565b600081519050614c08816133e5565b92915050565b600060208284031215614c2457614c236133af565b5b6000614c3284828501614bf9565b9150509291505056fea2646970667358221220b1a4f16b6de2b25b0a5d62895927a093ba6811c3367eddedd42e82e4f54bbc5f64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
f833f9bb29374b30e2733f881c7dd05b8f925646025029aa523d06456ed3baf700000000000000000000000000000000000000000000000000000000000000600000000000000000000000002acec43e0bb6f7fb37a208fbf8dbe6ec0f6ba72c0000000000000000000000000000000000000000000000000000000000000043697066733a2f2f6261667962656968636c34746d61663673696a69626f7674327734686e637a717a773562646f703470657673636376336e686f73656e6f6c6663752f0000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _merkleRoot (bytes32): 0xf833f9bb29374b30e2733f881c7dd05b8f925646025029aa523d06456ed3baf7
Arg [1] : uri (string): ipfs://bafybeihcl4tmaf6sijibovt2w4hnczqzw5bdop4pevsccv3nhosenolfcu/
Arg [2] : _payerAccount (address): 0x2ACeC43E0Bb6F7Fb37a208fbf8DBE6eC0F6Ba72C
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : f833f9bb29374b30e2733f881c7dd05b8f925646025029aa523d06456ed3baf7
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [2] : 0000000000000000000000002acec43e0bb6f7fb37a208fbf8dbe6ec0f6ba72c
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000043
Arg [4] : 697066733a2f2f6261667962656968636c34746d61663673696a69626f767432
Arg [5] : 7734686e637a717a773562646f703470657673636376336e686f73656e6f6c66
Arg [6] : 63752f0000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
94527:14921:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60791:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61693:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68184:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108656:165;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;105166:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57444:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95660:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108829:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96092:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104571:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;106439:395;;;;;;;;;;;;;:::i;:::-;;96539:54;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7735:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109008:179;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96207:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95487:50;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96400:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101280:1362;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95810:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63086:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95008:57;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104927:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;105614:252;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96307:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58628:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41570:103;;;;;;;;;;;;;:::i;:::-;;103521:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;105385:112;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104206:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40922:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61869:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95428:52;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108471:177;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95311:52;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94859:44;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102934:385;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109195:246;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99157:1593;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;107837:395;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95167:54;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94743:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69133:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103843:90;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95959:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95370:51;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41828:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;105982:247;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60791:639;60876:4;61215:10;61200:25;;:11;:25;;;;:102;;;;61292:10;61277:25;;:11;:25;;;;61200:102;:179;;;;61369:10;61354:25;;:11;:25;;;;61200:179;61180:199;;60791:639;;;:::o;61693:100::-;61747:13;61780:5;61773:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61693:100;:::o;68184:218::-;68260:7;68285:16;68293:7;68285;:16::i;:::-;68280:64;;68310:34;;;;;;;;;;;;;;68280:64;68364:15;:24;68380:7;68364:24;;;;;;;;;;;:30;;;;;;;;;;;;68357:37;;68184:218;;;:::o;108656:165::-;108760:8;9517:30;9538:8;9517:20;:30::i;:::-;108781:32:::1;108795:8;108805:7;108781:13;:32::i;:::-;108656:165:::0;;;:::o;105166:106::-;40808:13;:11;:13::i;:::-;105254:10:::1;105242:9;:22;;;;;;:::i;:::-;;105166:106:::0;:::o;57444:323::-;57505:7;57733:15;:13;:15::i;:::-;57718:12;;57702:13;;:28;:46;57695:53;;57444:323;:::o;95660:30::-;;;;;;;;;;;;;:::o;108829:171::-;108938:4;9251:10;9243:18;;:4;:18;;;9239:83;;9278:32;9299:10;9278:20;:32::i;:::-;9239:83;108955:37:::1;108974:4;108980:2;108984:7;108955:18;:37::i;:::-;108829:171:::0;;;;:::o;96092:25::-;;;;:::o;104571:92::-;40808:13;:11;:13::i;:::-;104650:5:::1;104636:11;;:19;;;;;;;;;;;;;;;;;;104571:92:::0;:::o;106439:395::-;28632:21;:19;:21::i;:::-;106512:7:::1;:5;:7::i;:::-;106498:21;;:10;:21;;;:51;;;;106537:12;;;;;;;;;;;106523:26;;:10;:26;;;106498:51;106490:119;;;;;;;;;;;;:::i;:::-;;;;;;;;;106620:15;106638:21;106620:39;;106689:1;106678:7;:12:::0;106670:55:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;106736:43;106756:12;;;;;;;;;;;106771:7;106736:11;:43::i;:::-;106806:10;106797:29;;;106818:7;106797:29;;;;;;:::i;:::-;;;;;;;;106479:355;28676:20:::0;:18;:20::i;:::-;106439:395::o;96539:54::-;;;;;;;;;;;;;;;;;:::o;7735:143::-;151:42;7735:143;:::o;109008:179::-;109121:4;9251:10;9243:18;;:4;:18;;;9239:83;;9278:32;9299:10;9278:20;:32::i;:::-;9239:83;109138:41:::1;109161:4;109167:2;109171:7;109138:22;:41::i;:::-;109008:179:::0;;;;:::o;96207:27::-;;;;;;;;;;;;;:::o;95487:50::-;95527:10;95487:50;:::o;96400:33::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;101280:1362::-;28632:21;:19;:21::i;:::-;101374:11:::1;;;;;;;;;;;101373:12;101365:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;95470:10;101433:15;:34;;:70;;;;;95527:10;101471:15;:32;;101433:70;101432:88;;;;101509:11;;;;;;;;;;;101508:12;101432:88;101424:124;;;;;;;;;;;;:::i;:::-;;;;;;;;;94779:4;101583:11;101567:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;101559:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;101668:1;101654:11;:15;:35;;;;101688:1;101673:11;:16;101654:35;101646:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;101797:1;101762:19;:31;101782:10;101762:31;;;;;;;;;;;;;;;;101748:11;:45;;;;:::i;:::-;:50;;101740:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;101893:1;101858:19;:31;101878:10;101858:31;;;;;;;;;;;;;;;;:36;:56;;;;;101913:1;101898:11;:16;101858:56;101855:714;;;101968:11;101933:19;:31;101953:10;101933:31;;;;;;;;;;;;;;;;:46;;;;;;;:::i;:::-;;;;;;;;101994:33;102004:10;102015:11;101994:9;:33::i;:::-;101855:714;;;102092:1;102057:19;:31;102077:10;102057:31;;;;;;;;;;;;;;;;:36;:56;;;;;102112:1;102097:11;:16;102057:56;102054:515;;;95209:12;102137:9;:28;102129:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;102257:11;102222:19;:31;102242:10;102222:31;;;;;;;;;;;;;;;;:46;;;;;;;:::i;:::-;;;;;;;;102283:33;102293:10;102304:11;102283:9;:33::i;:::-;102054:515;;;95209:12;102366:9;:28;102358:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;102498:11;102463:19;:31;102483:10;102463:31;;;;;;;;;;;;;;;;:46;;;;;;;:::i;:::-;;;;;;;;102524:33;102534:10;102545:11;102524:9;:33::i;:::-;102054:515;101855:714;102605:10;102590:39;;;102617:11;102590:39;;;;;;:::i;:::-;;;;;;;;28676:20:::0;:18;:20::i;:::-;101280:1362;:::o;95810:30::-;;;;;;;;;;;;;:::o;63086:152::-;63158:7;63201:27;63220:7;63201:18;:27::i;:::-;63178:52;;63086:152;;;:::o;95008:57::-;95053:12;95008:57;:::o;104927:92::-;40808:13;:11;:13::i;:::-;105006:5:::1;104992:11;;:19;;;;;;;;;;;;;;;;;;104927:92:::0;:::o;105614:252::-;105668:4;95353:10;105688:15;:34;;:71;;;;;95411:10;105726:15;:33;;105688:71;105687:89;;;;105765:11;;;;;;;;;;;105764:12;105687:89;105684:175;;;105800:4;105793:11;;;;105684:175;105842:5;105835:12;;105614:252;;:::o;96307:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58628:233::-;58700:7;58741:1;58724:19;;:5;:19;;;58720:60;;58752:28;;;;;;;;;;;;;;58720:60;52787:13;58798:18;:25;58817:5;58798:25;;;;;;;;;;;;;;;;:55;58791:62;;58628:233;;;:::o;41570:103::-;40808:13;:11;:13::i;:::-;41635:30:::1;41662:1;41635:18;:30::i;:::-;41570:103::o:0;103521:105::-;40808:13;:11;:13::i;:::-;103607:11:::1;103594:10;:24;;;;103521:105:::0;:::o;105385:112::-;40808:13;:11;:13::i;:::-;105476::::1;105461:12;;:28;;;;;;;;;;;;;;;;;;105385:112:::0;:::o;104206:92::-;40808:13;:11;:13::i;:::-;104285:5:::1;104271:11;;:19;;;;;;;;;;;;;;;;;;104206:92:::0;:::o;40922:87::-;40968:7;40995:6;;;;;;;;;;;40988:13;;40922:87;:::o;61869:104::-;61925:13;61958:7;61951:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61869:104;:::o;95428:52::-;95470:10;95428:52;:::o;108471:177::-;108576:8;9517:30;9538:8;9517:20;:30::i;:::-;108597:43:::1;108621:8;108631;108597:23;:43::i;:::-;108471:177:::0;;;:::o;95311:52::-;95353:10;95311:52;:::o;94859:44::-;94902:1;94859:44;:::o;102934:385::-;40808:13;:11;:13::i;:::-;94779:4:::1;103075:12;103056:9;:16;:31;;;;:::i;:::-;103040:13;:11;:13::i;:::-;:47;;;;:::i;:::-;:60;;103032:96;;;;;;;;;;;;:::i;:::-;;;;;;;;;103145:9;103141:107;103163:9;:16;103159:1;:20;103141:107;;;103200:36;103210:9;103220:1;103210:12;;;;;;;;:::i;:::-;;;;;;;;103223;103200:9;:36::i;:::-;103181:3;;;;;:::i;:::-;;;;103141:107;;;;103275:10;103265:46;;;103287:9;103298:12;103265:46;;;;;;;:::i;:::-;;;;;;;;102934:385:::0;;:::o;109195:246::-;109364:4;9251:10;9243:18;;:4;:18;;;9239:83;;9278:32;9299:10;9278:20;:32::i;:::-;9239:83;109386:47:::1;109409:4;109415:2;109419:7;109428:4;109386:22;:47::i;:::-;109195:246:::0;;;;;:::o;99157:1593::-;28632:21;:19;:21::i;:::-;99287:11:::1;;;;;;;;;;;99286:12;99278:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;95353:10;99346:15;:34;;:71;;;;;95411:10;99384:15;:33;;99346:71;99345:89;;;;99423:11;;;;;;;;;;;99422:12;99345:89;99337:128;;;;;;;;;;;;:::i;:::-;;;;;;;;;94779:4;99500:11;99484:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;99476:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;99587:1;99572:11;:16;:36;;;;99607:1;99592:11;:16;99572:36;99564:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;99669:12;99728:10;99717:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;99707:33;;;;;;99694:47;;;;;;;;:::i;:::-;;;;;;;;;;;;;99684:58;;;;;;99669:73;;99761:50;99780:12;;99761:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99794:10;;99806:4;99761:18;:50::i;:::-;99753:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;99903:1;99868:19;:31;99888:10;99868:31;;;;;;;;;;;;;;;;99854:11;:45;;;;:::i;:::-;:50;;99846:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;100008:1;99973:19;:31;99993:10;99973:31;;;;;;;;;;;;;;;;:36;:56;;;;;100028:1;100013:11;:16;99973:56;99970:706;;;100081:11;100046:19;:31;100066:10;100046:31;;;;;;;;;;;;;;;;:46;;;;;;;:::i;:::-;;;;;;;;100107:33;100117:10;100128:11;100107:9;:33::i;:::-;99970:706;;;100205:1;100170:19;:31;100190:10;100170:31;;;;;;;;;;;;;;;;:36;:56;;;;;100225:1;100210:11;:16;100170:56;100167:509;;;95053:12;100250:9;:31;100242:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;100373:11;100338:19;:31;100358:10;100338:31;;;;;;;;;;;;;;;;:46;;;;;;;:::i;:::-;;;;;;;;100399:33;100409:10;100420:11;100399:9;:33::i;:::-;100167:509;;;95053:12;100482:9;:31;100474:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;100605:11;100570:19;:31;100590:10;100570:31;;;;;;;;;;;;;;;;:46;;;;;;;:::i;:::-;;;;;;;;100631:33;100641:10;100652:11;100631:9;:33::i;:::-;100167:509;99970:706;100712:10;100694:42;;;100724:11;100694:42;;;;;;:::i;:::-;;;;;;;;99267:1483;28676:20:::0;:18;:20::i;:::-;99157:1593;;;:::o;107837:395::-;107911:13;107945:17;107953:8;107945:7;:17::i;:::-;107937:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;108027:28;108058:10;:8;:10::i;:::-;108027:41;;108117:1;108092:14;108086:28;:32;:138;;;;;;;;;;;;;;;;;108158:14;108174:19;:8;:17;:19::i;:::-;108195:9;108141:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;108086:138;108079:145;;;107837:395;;;:::o;95167:54::-;95209:12;95167:54;:::o;94743:40::-;94779:4;94743:40;:::o;69133:164::-;69230:4;69254:18;:25;69273:5;69254:25;;;;;;;;;;;;;;;:35;69280:8;69254:35;;;;;;;;;;;;;;;;;;;;;;;;;69247:42;;69133:164;;;;:::o;103843:90::-;40808:13;:11;:13::i;:::-;103922:3:::1;103912:7;:13;;;;;;:::i;:::-;;103843:90:::0;:::o;95959:31::-;;;;;;;;;;;;;:::o;95370:51::-;95411:10;95370:51;:::o;41828:201::-;40808:13;:11;:13::i;:::-;41937:1:::1;41917:22;;:8;:22;;::::0;41909:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;41993:28;42012:8;41993:18;:28::i;:::-;41828:201:::0;:::o;105982:247::-;106032:4;95470:10;106052:15;:34;;:70;;;;;95527:10;106090:15;:32;;106052:70;106051:88;;;;106128:11;;;;;;;;;;;106127:12;106051:88;106048:174;;;106163:4;106156:11;;;;106048:174;106205:5;106198:12;;105982:247;;:::o;69555:282::-;69620:4;69676:7;69657:15;:13;:15::i;:::-;:26;;:66;;;;;69710:13;;69700:7;:23;69657:66;:153;;;;;69809:1;53563:8;69761:17;:26;69779:7;69761:26;;;;;;;;;;;;:44;:49;69657:153;69637:173;;69555:282;;;:::o;9660:647::-;9899:1;151:42;9851:45;;;:49;9847:453;;;151:42;10150;;;10201:4;10208:8;10150:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10145:144;;10264:8;10245:28;;;;;;;;;;;:::i;:::-;;;;;;;;10145:144;9847:453;9660:647;:::o;67617:408::-;67706:13;67722:16;67730:7;67722;:16::i;:::-;67706:32;;67778:5;67755:28;;:19;:17;:19::i;:::-;:28;;;67751:175;;67803:44;67820:5;67827:19;:17;:19::i;:::-;67803:16;:44::i;:::-;67798:128;;67875:35;;;;;;;;;;;;;;67798:128;67751:175;67971:2;67938:15;:24;67954:7;67938:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;68009:7;68005:2;67989:28;;67998:5;67989:28;;;;;;;;;;;;67695:330;67617:408;;:::o;41087:132::-;41162:12;:10;:12::i;:::-;41151:23;;:7;:5;:7::i;:::-;:23;;;41143:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;41087:132::o;107443:101::-;107508:7;107535:1;107528:8;;107443:101;:::o;71823:2825::-;71965:27;71995;72014:7;71995:18;:27::i;:::-;71965:57;;72080:4;72039:45;;72055:19;72039:45;;;72035:86;;72093:28;;;;;;;;;;;;;;72035:86;72135:27;72164:23;72191:35;72218:7;72191:26;:35::i;:::-;72134:92;;;;72326:68;72351:15;72368:4;72374:19;:17;:19::i;:::-;72326:24;:68::i;:::-;72321:180;;72414:43;72431:4;72437:19;:17;:19::i;:::-;72414:16;:43::i;:::-;72409:92;;72466:35;;;;;;;;;;;;;;72409:92;72321:180;72532:1;72518:16;;:2;:16;;;72514:52;;72543:23;;;;;;;;;;;;;;72514:52;72579:43;72601:4;72607:2;72611:7;72620:1;72579:21;:43::i;:::-;72715:15;72712:160;;;72855:1;72834:19;72827:30;72712:160;73252:18;:24;73271:4;73252:24;;;;;;;;;;;;;;;;73250:26;;;;;;;;;;;;73321:18;:22;73340:2;73321:22;;;;;;;;;;;;;;;;73319:24;;;;;;;;;;;73643:146;73680:2;73729:45;73744:4;73750:2;73754:19;73729:14;:45::i;:::-;53843:8;73701:73;73643:18;:146::i;:::-;73614:17;:26;73632:7;73614:26;;;;;;;;;;;:175;;;;73960:1;53843:8;73909:19;:47;:52;73905:627;;73982:19;74014:1;74004:7;:11;73982:33;;74171:1;74137:17;:30;74155:11;74137:30;;;;;;;;;;;;:35;74133:384;;74275:13;;74260:11;:28;74256:242;;74455:19;74422:17;:30;74440:11;74422:30;;;;;;;;;;;:52;;;;74256:242;74133:384;73963:569;73905:627;74579:7;74575:2;74560:27;;74569:4;74560:27;;;;;;;;;;;;74598:42;74619:4;74625:2;74629:7;74638:1;74598:20;:42::i;:::-;71954:2694;;;71823:2825;;;:::o;28712:293::-;28114:1;28846:7;;:19;28838:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;28114:1;28979:7;:18;;;;28712:293::o;107112:189::-;107191:9;107206:3;:8;;107224:7;107206:32;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107190:48;;;107257:4;107249:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;107179:122;107112:189;;:::o;29013:213::-;28070:1;29196:7;:22;;;;29013:213::o;74744:193::-;74890:39;74907:4;74913:2;74917:7;74890:39;;;;;;;;;;;;:16;:39::i;:::-;74744:193;;;:::o;85695:112::-;85772:27;85782:2;85786:8;85772:27;;;;;;;;;;;;:9;:27::i;:::-;85695:112;;:::o;64241:1275::-;64308:7;64328:12;64343:7;64328:22;;64411:4;64392:15;:13;:15::i;:::-;:23;64388:1061;;64445:13;;64438:4;:20;64434:1015;;;64483:14;64500:17;:23;64518:4;64500:23;;;;;;;;;;;;64483:40;;64617:1;53563:8;64589:6;:24;:29;64585:845;;65254:113;65271:1;65261:6;:11;65254:113;;65314:17;:25;65332:6;;;;;;;65314:25;;;;;;;;;;;;65305:34;;65254:113;;;65400:6;65393:13;;;;;;64585:845;64460:989;64434:1015;64388:1061;65477:31;;;;;;;;;;;;;;64241:1275;;;;:::o;42189:191::-;42263:16;42282:6;;;;;;;;;;;42263:25;;42308:8;42299:6;;:17;;;;;;;;;;;;;;;;;;42363:8;42332:40;;42353:8;42332:40;;;;;;;;;;;;42252:128;42189:191;:::o;68742:234::-;68889:8;68837:18;:39;68856:19;:17;:19::i;:::-;68837:39;;;;;;;;;;;;;;;:49;68877:8;68837:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;68949:8;68913:55;;68928:19;:17;:19::i;:::-;68913:55;;;68959:8;68913:55;;;;;;:::i;:::-;;;;;;;;68742:234;;:::o;75535:407::-;75710:31;75723:4;75729:2;75733:7;75710:12;:31::i;:::-;75774:1;75756:2;:14;;;:19;75752:183;;75795:56;75826:4;75832:2;75836:7;75845:5;75795:30;:56::i;:::-;75790:145;;75879:40;;;;;;;;;;;;;;75790:145;75752:183;75535:407;;;;:::o;30455:190::-;30580:4;30633;30604:25;30617:5;30624:4;30604:12;:25::i;:::-;:33;30597:40;;30455:190;;;;;:::o;108355:108::-;108415:13;108448:7;108441:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108355:108;:::o;24393:716::-;24449:13;24500:14;24537:1;24517:17;24528:5;24517:10;:17::i;:::-;:21;24500:38;;24553:20;24587:6;24576:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24553:41;;24609:11;24738:6;24734:2;24730:15;24722:6;24718:28;24711:35;;24775:288;24782:4;24775:288;;;24807:5;;;;;;;;24949:8;24944:2;24937:5;24933:14;24928:30;24923:3;24915:44;25005:2;24996:11;;;;;;:::i;:::-;;;;;25039:1;25030:5;:10;24775:288;25026:21;24775:288;25084:6;25077:13;;;;;24393:716;;;:::o;91863:105::-;91923:7;91950:10;91943:17;;91863:105;:::o;39473:98::-;39526:7;39553:10;39546:17;;39473:98;:::o;70718:485::-;70820:27;70849:23;70890:38;70931:15;:24;70947:7;70931:24;;;;;;;;;;;70890:65;;71108:18;71085:41;;71165:19;71159:26;71140:45;;71070:126;70718:485;;;:::o;69946:659::-;70095:11;70260:16;70253:5;70249:28;70240:37;;70420:16;70409:9;70405:32;70392:45;;70570:15;70559:9;70556:30;70548:5;70537:9;70534:20;70531:56;70521:66;;69946:659;;;;;:::o;76604:159::-;;;;;:::o;91172:311::-;91307:7;91327:16;53967:3;91353:19;:41;;91327:68;;53967:3;91421:31;91432:4;91438:2;91442:9;91421:10;:31::i;:::-;91413:40;;:62;;91406:69;;;91172:311;;;;;:::o;66064:450::-;66144:14;66312:16;66305:5;66301:28;66292:37;;66489:5;66475:11;66450:23;66446:41;66443:52;66436:5;66433:63;66423:73;;66064:450;;;;:::o;77428:158::-;;;;;:::o;84922:689::-;85053:19;85059:2;85063:8;85053:5;:19::i;:::-;85132:1;85114:2;:14;;;:19;85110:483;;85154:11;85168:13;;85154:27;;85200:13;85222:8;85216:3;:14;85200:30;;85249:233;85280:62;85319:1;85323:2;85327:7;;;;;;85336:5;85280:30;:62::i;:::-;85275:167;;85378:40;;;;;;;;;;;;;;85275:167;85477:3;85469:5;:11;85249:233;;85564:3;85547:13;;:20;85543:34;;85569:8;;;85543:34;85135:458;;85110:483;84922:689;;;:::o;78026:716::-;78189:4;78235:2;78210:45;;;78256:19;:17;:19::i;:::-;78277:4;78283:7;78292:5;78210:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;78206:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78510:1;78493:6;:13;:18;78489:235;;78539:40;;;;;;;;;;;;;;78489:235;78682:6;78676:13;78667:6;78663:2;78659:15;78652:38;78206:529;78379:54;;;78369:64;;;:6;:64;;;;78362:71;;;78026:716;;;;;;:::o;31322:296::-;31405:7;31425:20;31448:4;31425:27;;31468:9;31463:118;31487:5;:12;31483:1;:16;31463:118;;;31536:33;31546:12;31560:5;31566:1;31560:8;;;;;;;;:::i;:::-;;;;;;;;31536:9;:33::i;:::-;31521:48;;31501:3;;;;;:::i;:::-;;;;31463:118;;;;31598:12;31591:19;;;31322:296;;;;:::o;21259:922::-;21312:7;21332:14;21349:1;21332:18;;21399:6;21390:5;:15;21386:102;;21435:6;21426:15;;;;;;:::i;:::-;;;;;21470:2;21460:12;;;;21386:102;21515:6;21506:5;:15;21502:102;;21551:6;21542:15;;;;;;:::i;:::-;;;;;21586:2;21576:12;;;;21502:102;21631:6;21622:5;:15;21618:102;;21667:6;21658:15;;;;;;:::i;:::-;;;;;21702:2;21692:12;;;;21618:102;21747:5;21738;:14;21734:99;;21782:5;21773:14;;;;;;:::i;:::-;;;;;21816:1;21806:11;;;;21734:99;21860:5;21851;:14;21847:99;;21895:5;21886:14;;;;;;:::i;:::-;;;;;21929:1;21919:11;;;;21847:99;21973:5;21964;:14;21960:99;;22008:5;21999:14;;;;;;:::i;:::-;;;;;22042:1;22032:11;;;;21960:99;22086:5;22077;:14;22073:66;;22122:1;22112:11;;;;22073:66;22167:6;22160:13;;;21259:922;;;:::o;90873:147::-;91010:6;90873:147;;;;;:::o;79204:2966::-;79277:20;79300:13;;79277:36;;79340:1;79328:8;:13;79324:44;;79350:18;;;;;;;;;;;;;;79324:44;79381:61;79411:1;79415:2;79419:12;79433:8;79381:21;:61::i;:::-;79925:1;52925:2;79895:1;:26;;79894:32;79882:8;:45;79856:18;:22;79875:2;79856:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;80204:139;80241:2;80295:33;80318:1;80322:2;80326:1;80295:14;:33::i;:::-;80262:30;80283:8;80262:20;:30::i;:::-;:66;80204:18;:139::i;:::-;80170:17;:31;80188:12;80170:31;;;;;;;;;;;:173;;;;80360:16;80391:11;80420:8;80405:12;:23;80391:37;;80941:16;80937:2;80933:25;80921:37;;81313:12;81273:8;81232:1;81170:25;81111:1;81050;81023:335;81684:1;81670:12;81666:20;81624:346;81725:3;81716:7;81713:16;81624:346;;81943:7;81933:8;81930:1;81903:25;81900:1;81897;81892:59;81778:1;81769:7;81765:15;81754:26;;81624:346;;;81628:77;82015:1;82003:8;:13;81999:45;;82025:19;;;;;;;;;;;;;;81999:45;82077:3;82061:13;:19;;;;79630:2462;;82102:60;82131:1;82135:2;82139:12;82153:8;82102:20;:60::i;:::-;79266:2904;79204:2966;;:::o;38362:149::-;38425:7;38456:1;38452;:5;:51;;38483:20;38498:1;38501;38483:14;:20::i;:::-;38452:51;;;38460:20;38475:1;38478;38460:14;:20::i;:::-;38452:51;38445:58;;38362:149;;;;:::o;66616:324::-;66686:14;66919:1;66909:8;66906:15;66880:24;66876:46;66866:56;;66616:324;;;:::o;38519:268::-;38587:13;38694:1;38688:4;38681:15;38723:1;38717:4;38710:15;38764:4;38758;38748:21;38739:30;;38519:268;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:117::-;4999:1;4996;4989:12;5013:117;5122:1;5119;5112:12;5136:180;5184:77;5181:1;5174:88;5281:4;5278:1;5271:15;5305:4;5302:1;5295:15;5322:281;5405:27;5427:4;5405:27;:::i;:::-;5397:6;5393:40;5535:6;5523:10;5520:22;5499:18;5487:10;5484:34;5481:62;5478:88;;;5546:18;;:::i;:::-;5478:88;5586:10;5582:2;5575:22;5365:238;5322:281;;:::o;5609:129::-;5643:6;5670:20;;:::i;:::-;5660:30;;5699:33;5727:4;5719:6;5699:33;:::i;:::-;5609:129;;;:::o;5744:308::-;5806:4;5896:18;5888:6;5885:30;5882:56;;;5918:18;;:::i;:::-;5882:56;5956:29;5978:6;5956:29;:::i;:::-;5948:37;;6040:4;6034;6030:15;6022:23;;5744:308;;;:::o;6058:146::-;6155:6;6150:3;6145;6132:30;6196:1;6187:6;6182:3;6178:16;6171:27;6058:146;;;:::o;6210:425::-;6288:5;6313:66;6329:49;6371:6;6329:49;:::i;:::-;6313:66;:::i;:::-;6304:75;;6402:6;6395:5;6388:21;6440:4;6433:5;6429:16;6478:3;6469:6;6464:3;6460:16;6457:25;6454:112;;;6485:79;;:::i;:::-;6454:112;6575:54;6622:6;6617:3;6612;6575:54;:::i;:::-;6294:341;6210:425;;;;;:::o;6655:340::-;6711:5;6760:3;6753:4;6745:6;6741:17;6737:27;6727:122;;6768:79;;:::i;:::-;6727:122;6885:6;6872:20;6910:79;6985:3;6977:6;6970:4;6962:6;6958:17;6910:79;:::i;:::-;6901:88;;6717:278;6655:340;;;;:::o;7001:509::-;7070:6;7119:2;7107:9;7098:7;7094:23;7090:32;7087:119;;;7125:79;;:::i;:::-;7087:119;7273:1;7262:9;7258:17;7245:31;7303:18;7295:6;7292:30;7289:117;;;7325:79;;:::i;:::-;7289:117;7430:63;7485:7;7476:6;7465:9;7461:22;7430:63;:::i;:::-;7420:73;;7216:287;7001:509;;;;:::o;7516:118::-;7603:24;7621:5;7603:24;:::i;:::-;7598:3;7591:37;7516:118;;:::o;7640:222::-;7733:4;7771:2;7760:9;7756:18;7748:26;;7784:71;7852:1;7841:9;7837:17;7828:6;7784:71;:::i;:::-;7640:222;;;;:::o;7868:619::-;7945:6;7953;7961;8010:2;7998:9;7989:7;7985:23;7981:32;7978:119;;;8016:79;;:::i;:::-;7978:119;8136:1;8161:53;8206:7;8197:6;8186:9;8182:22;8161:53;:::i;:::-;8151:63;;8107:117;8263:2;8289:53;8334:7;8325:6;8314:9;8310:22;8289:53;:::i;:::-;8279:63;;8234:118;8391:2;8417:53;8462:7;8453:6;8442:9;8438:22;8417:53;:::i;:::-;8407:63;;8362:118;7868:619;;;;;:::o;8493:77::-;8530:7;8559:5;8548:16;;8493:77;;;:::o;8576:118::-;8663:24;8681:5;8663:24;:::i;:::-;8658:3;8651:37;8576:118;;:::o;8700:222::-;8793:4;8831:2;8820:9;8816:18;8808:26;;8844:71;8912:1;8901:9;8897:17;8888:6;8844:71;:::i;:::-;8700:222;;;;:::o;8928:116::-;8998:21;9013:5;8998:21;:::i;:::-;8991:5;8988:32;8978:60;;9034:1;9031;9024:12;8978:60;8928:116;:::o;9050:133::-;9093:5;9131:6;9118:20;9109:29;;9147:30;9171:5;9147:30;:::i;:::-;9050:133;;;;:::o;9189:323::-;9245:6;9294:2;9282:9;9273:7;9269:23;9265:32;9262:119;;;9300:79;;:::i;:::-;9262:119;9420:1;9445:50;9487:7;9478:6;9467:9;9463:22;9445:50;:::i;:::-;9435:60;;9391:114;9189:323;;;;:::o;9518:329::-;9577:6;9626:2;9614:9;9605:7;9601:23;9597:32;9594:119;;;9632:79;;:::i;:::-;9594:119;9752:1;9777:53;9822:7;9813:6;9802:9;9798:22;9777:53;:::i;:::-;9767:63;;9723:117;9518:329;;;;:::o;9853:60::-;9881:3;9902:5;9895:12;;9853:60;;;:::o;9919:142::-;9969:9;10002:53;10020:34;10029:24;10047:5;10029:24;:::i;:::-;10020:34;:::i;:::-;10002:53;:::i;:::-;9989:66;;9919:142;;;:::o;10067:126::-;10117:9;10150:37;10181:5;10150:37;:::i;:::-;10137:50;;10067:126;;;:::o;10199:157::-;10280:9;10313:37;10344:5;10313:37;:::i;:::-;10300:50;;10199:157;;;:::o;10362:193::-;10480:68;10542:5;10480:68;:::i;:::-;10475:3;10468:81;10362:193;;:::o;10561:284::-;10685:4;10723:2;10712:9;10708:18;10700:26;;10736:102;10835:1;10824:9;10820:17;10811:6;10736:102;:::i;:::-;10561:284;;;;:::o;10851:122::-;10924:24;10942:5;10924:24;:::i;:::-;10917:5;10914:35;10904:63;;10963:1;10960;10953:12;10904:63;10851:122;:::o;10979:139::-;11025:5;11063:6;11050:20;11041:29;;11079:33;11106:5;11079:33;:::i;:::-;10979:139;;;;:::o;11124:329::-;11183:6;11232:2;11220:9;11211:7;11207:23;11203:32;11200:119;;;11238:79;;:::i;:::-;11200:119;11358:1;11383:53;11428:7;11419:6;11408:9;11404:22;11383:53;:::i;:::-;11373:63;;11329:117;11124:329;;;;:::o;11459:468::-;11524:6;11532;11581:2;11569:9;11560:7;11556:23;11552:32;11549:119;;;11587:79;;:::i;:::-;11549:119;11707:1;11732:53;11777:7;11768:6;11757:9;11753:22;11732:53;:::i;:::-;11722:63;;11678:117;11834:2;11860:50;11902:7;11893:6;11882:9;11878:22;11860:50;:::i;:::-;11850:60;;11805:115;11459:468;;;;;:::o;11933:311::-;12010:4;12100:18;12092:6;12089:30;12086:56;;;12122:18;;:::i;:::-;12086:56;12172:4;12164:6;12160:17;12152:25;;12232:4;12226;12222:15;12214:23;;11933:311;;;:::o;12250:117::-;12359:1;12356;12349:12;12390:710;12486:5;12511:81;12527:64;12584:6;12527:64;:::i;:::-;12511:81;:::i;:::-;12502:90;;12612:5;12641:6;12634:5;12627:21;12675:4;12668:5;12664:16;12657:23;;12728:4;12720:6;12716:17;12708:6;12704:30;12757:3;12749:6;12746:15;12743:122;;;12776:79;;:::i;:::-;12743:122;12891:6;12874:220;12908:6;12903:3;12900:15;12874:220;;;12983:3;13012:37;13045:3;13033:10;13012:37;:::i;:::-;13007:3;13000:50;13079:4;13074:3;13070:14;13063:21;;12950:144;12934:4;12929:3;12925:14;12918:21;;12874:220;;;12878:21;12492:608;;12390:710;;;;;:::o;13123:370::-;13194:5;13243:3;13236:4;13228:6;13224:17;13220:27;13210:122;;13251:79;;:::i;:::-;13210:122;13368:6;13355:20;13393:94;13483:3;13475:6;13468:4;13460:6;13456:17;13393:94;:::i;:::-;13384:103;;13200:293;13123:370;;;;:::o;13499:684::-;13592:6;13600;13649:2;13637:9;13628:7;13624:23;13620:32;13617:119;;;13655:79;;:::i;:::-;13617:119;13803:1;13792:9;13788:17;13775:31;13833:18;13825:6;13822:30;13819:117;;;13855:79;;:::i;:::-;13819:117;13960:78;14030:7;14021:6;14010:9;14006:22;13960:78;:::i;:::-;13950:88;;13746:302;14087:2;14113:53;14158:7;14149:6;14138:9;14134:22;14113:53;:::i;:::-;14103:63;;14058:118;13499:684;;;;;:::o;14189:307::-;14250:4;14340:18;14332:6;14329:30;14326:56;;;14362:18;;:::i;:::-;14326:56;14400:29;14422:6;14400:29;:::i;:::-;14392:37;;14484:4;14478;14474:15;14466:23;;14189:307;;;:::o;14502:423::-;14579:5;14604:65;14620:48;14661:6;14620:48;:::i;:::-;14604:65;:::i;:::-;14595:74;;14692:6;14685:5;14678:21;14730:4;14723:5;14719:16;14768:3;14759:6;14754:3;14750:16;14747:25;14744:112;;;14775:79;;:::i;:::-;14744:112;14865:54;14912:6;14907:3;14902;14865:54;:::i;:::-;14585:340;14502:423;;;;;:::o;14944:338::-;14999:5;15048:3;15041:4;15033:6;15029:17;15025:27;15015:122;;15056:79;;:::i;:::-;15015:122;15173:6;15160:20;15198:78;15272:3;15264:6;15257:4;15249:6;15245:17;15198:78;:::i;:::-;15189:87;;15005:277;14944:338;;;;:::o;15288:943::-;15383:6;15391;15399;15407;15456:3;15444:9;15435:7;15431:23;15427:33;15424:120;;;15463:79;;:::i;:::-;15424:120;15583:1;15608:53;15653:7;15644:6;15633:9;15629:22;15608:53;:::i;:::-;15598:63;;15554:117;15710:2;15736:53;15781:7;15772:6;15761:9;15757:22;15736:53;:::i;:::-;15726:63;;15681:118;15838:2;15864:53;15909:7;15900:6;15889:9;15885:22;15864:53;:::i;:::-;15854:63;;15809:118;15994:2;15983:9;15979:18;15966:32;16025:18;16017:6;16014:30;16011:117;;;16047:79;;:::i;:::-;16011:117;16152:62;16206:7;16197:6;16186:9;16182:22;16152:62;:::i;:::-;16142:72;;15937:287;15288:943;;;;;;;:::o;16237:117::-;16346:1;16343;16336:12;16377:568;16450:8;16460:6;16510:3;16503:4;16495:6;16491:17;16487:27;16477:122;;16518:79;;:::i;:::-;16477:122;16631:6;16618:20;16608:30;;16661:18;16653:6;16650:30;16647:117;;;16683:79;;:::i;:::-;16647:117;16797:4;16789:6;16785:17;16773:29;;16851:3;16843:4;16835:6;16831:17;16821:8;16817:32;16814:41;16811:128;;;16858:79;;:::i;:::-;16811:128;16377:568;;;;;:::o;16951:704::-;17046:6;17054;17062;17111:2;17099:9;17090:7;17086:23;17082:32;17079:119;;;17117:79;;:::i;:::-;17079:119;17237:1;17262:53;17307:7;17298:6;17287:9;17283:22;17262:53;:::i;:::-;17252:63;;17208:117;17392:2;17381:9;17377:18;17364:32;17423:18;17415:6;17412:30;17409:117;;;17445:79;;:::i;:::-;17409:117;17558:80;17630:7;17621:6;17610:9;17606:22;17558:80;:::i;:::-;17540:98;;;;17335:313;16951:704;;;;;:::o;17661:474::-;17729:6;17737;17786:2;17774:9;17765:7;17761:23;17757:32;17754:119;;;17792:79;;:::i;:::-;17754:119;17912:1;17937:53;17982:7;17973:6;17962:9;17958:22;17937:53;:::i;:::-;17927:63;;17883:117;18039:2;18065:53;18110:7;18101:6;18090:9;18086:22;18065:53;:::i;:::-;18055:63;;18010:118;17661:474;;;;;:::o;18141:180::-;18189:77;18186:1;18179:88;18286:4;18283:1;18276:15;18310:4;18307:1;18300:15;18327:320;18371:6;18408:1;18402:4;18398:12;18388:22;;18455:1;18449:4;18445:12;18476:18;18466:81;;18532:4;18524:6;18520:17;18510:27;;18466:81;18594:2;18586:6;18583:14;18563:18;18560:38;18557:84;;18613:18;;:::i;:::-;18557:84;18378:269;18327:320;;;:::o;18653:141::-;18702:4;18725:3;18717:11;;18748:3;18745:1;18738:14;18782:4;18779:1;18769:18;18761:26;;18653:141;;;:::o;18800:93::-;18837:6;18884:2;18879;18872:5;18868:14;18864:23;18854:33;;18800:93;;;:::o;18899:107::-;18943:8;18993:5;18987:4;18983:16;18962:37;;18899:107;;;;:::o;19012:393::-;19081:6;19131:1;19119:10;19115:18;19154:97;19184:66;19173:9;19154:97;:::i;:::-;19272:39;19302:8;19291:9;19272:39;:::i;:::-;19260:51;;19344:4;19340:9;19333:5;19329:21;19320:30;;19393:4;19383:8;19379:19;19372:5;19369:30;19359:40;;19088:317;;19012:393;;;;;:::o;19411:142::-;19461:9;19494:53;19512:34;19521:24;19539:5;19521:24;:::i;:::-;19512:34;:::i;:::-;19494:53;:::i;:::-;19481:66;;19411:142;;;:::o;19559:75::-;19602:3;19623:5;19616:12;;19559:75;;;:::o;19640:269::-;19750:39;19781:7;19750:39;:::i;:::-;19811:91;19860:41;19884:16;19860:41;:::i;:::-;19852:6;19845:4;19839:11;19811:91;:::i;:::-;19805:4;19798:105;19716:193;19640:269;;;:::o;19915:73::-;19960:3;19915:73;:::o;19994:189::-;20071:32;;:::i;:::-;20112:65;20170:6;20162;20156:4;20112:65;:::i;:::-;20047:136;19994:189;;:::o;20189:186::-;20249:120;20266:3;20259:5;20256:14;20249:120;;;20320:39;20357:1;20350:5;20320:39;:::i;:::-;20293:1;20286:5;20282:13;20273:22;;20249:120;;;20189:186;;:::o;20381:543::-;20482:2;20477:3;20474:11;20471:446;;;20516:38;20548:5;20516:38;:::i;:::-;20600:29;20618:10;20600:29;:::i;:::-;20590:8;20586:44;20783:2;20771:10;20768:18;20765:49;;;20804:8;20789:23;;20765:49;20827:80;20883:22;20901:3;20883:22;:::i;:::-;20873:8;20869:37;20856:11;20827:80;:::i;:::-;20486:431;;20471:446;20381:543;;;:::o;20930:117::-;20984:8;21034:5;21028:4;21024:16;21003:37;;20930:117;;;;:::o;21053:169::-;21097:6;21130:51;21178:1;21174:6;21166:5;21163:1;21159:13;21130:51;:::i;:::-;21126:56;21211:4;21205;21201:15;21191:25;;21104:118;21053:169;;;;:::o;21227:295::-;21303:4;21449:29;21474:3;21468:4;21449:29;:::i;:::-;21441:37;;21511:3;21508:1;21504:11;21498:4;21495:21;21487:29;;21227:295;;;;:::o;21527:1395::-;21644:37;21677:3;21644:37;:::i;:::-;21746:18;21738:6;21735:30;21732:56;;;21768:18;;:::i;:::-;21732:56;21812:38;21844:4;21838:11;21812:38;:::i;:::-;21897:67;21957:6;21949;21943:4;21897:67;:::i;:::-;21991:1;22015:4;22002:17;;22047:2;22039:6;22036:14;22064:1;22059:618;;;;22721:1;22738:6;22735:77;;;22787:9;22782:3;22778:19;22772:26;22763:35;;22735:77;22838:67;22898:6;22891:5;22838:67;:::i;:::-;22832:4;22825:81;22694:222;22029:887;;22059:618;22111:4;22107:9;22099:6;22095:22;22145:37;22177:4;22145:37;:::i;:::-;22204:1;22218:208;22232:7;22229:1;22226:14;22218:208;;;22311:9;22306:3;22302:19;22296:26;22288:6;22281:42;22362:1;22354:6;22350:14;22340:24;;22409:2;22398:9;22394:18;22381:31;;22255:4;22252:1;22248:12;22243:17;;22218:208;;;22454:6;22445:7;22442:19;22439:179;;;22512:9;22507:3;22503:19;22497:26;22555:48;22597:4;22589:6;22585:17;22574:9;22555:48;:::i;:::-;22547:6;22540:64;22462:156;22439:179;22664:1;22660;22652:6;22648:14;22644:22;22638:4;22631:36;22066:611;;;22029:887;;21619:1303;;;21527:1395;;:::o;22928:242::-;23068:34;23064:1;23056:6;23052:14;23045:58;23137:25;23132:2;23124:6;23120:15;23113:50;22928:242;:::o;23176:366::-;23318:3;23339:67;23403:2;23398:3;23339:67;:::i;:::-;23332:74;;23415:93;23504:3;23415:93;:::i;:::-;23533:2;23528:3;23524:12;23517:19;;23176:366;;;:::o;23548:419::-;23714:4;23752:2;23741:9;23737:18;23729:26;;23801:9;23795:4;23791:20;23787:1;23776:9;23772:17;23765:47;23829:131;23955:4;23829:131;:::i;:::-;23821:139;;23548:419;;;:::o;23973:180::-;24113:32;24109:1;24101:6;24097:14;24090:56;23973:180;:::o;24159:366::-;24301:3;24322:67;24386:2;24381:3;24322:67;:::i;:::-;24315:74;;24398:93;24487:3;24398:93;:::i;:::-;24516:2;24511:3;24507:12;24500:19;;24159:366;;;:::o;24531:419::-;24697:4;24735:2;24724:9;24720:18;24712:26;;24784:9;24778:4;24774:20;24770:1;24759:9;24755:17;24748:47;24812:131;24938:4;24812:131;:::i;:::-;24804:139;;24531:419;;;:::o;24956:174::-;25096:26;25092:1;25084:6;25080:14;25073:50;24956:174;:::o;25136:366::-;25278:3;25299:67;25363:2;25358:3;25299:67;:::i;:::-;25292:74;;25375:93;25464:3;25375:93;:::i;:::-;25493:2;25488:3;25484:12;25477:19;;25136:366;;;:::o;25508:419::-;25674:4;25712:2;25701:9;25697:18;25689:26;;25761:9;25755:4;25751:20;25747:1;25736:9;25732:17;25725:47;25789:131;25915:4;25789:131;:::i;:::-;25781:139;;25508:419;;;:::o;25933:173::-;26073:25;26069:1;26061:6;26057:14;26050:49;25933:173;:::o;26112:366::-;26254:3;26275:67;26339:2;26334:3;26275:67;:::i;:::-;26268:74;;26351:93;26440:3;26351:93;:::i;:::-;26469:2;26464:3;26460:12;26453:19;;26112:366;;;:::o;26484:419::-;26650:4;26688:2;26677:9;26673:18;26665:26;;26737:9;26731:4;26727:20;26723:1;26712:9;26708:17;26701:47;26765:131;26891:4;26765:131;:::i;:::-;26757:139;;26484:419;;;:::o;26909:180::-;26957:77;26954:1;26947:88;27054:4;27051:1;27044:15;27078:4;27075:1;27068:15;27095:191;27135:3;27154:20;27172:1;27154:20;:::i;:::-;27149:25;;27188:20;27206:1;27188:20;:::i;:::-;27183:25;;27231:1;27228;27224:9;27217:16;;27252:3;27249:1;27246:10;27243:36;;;27259:18;;:::i;:::-;27243:36;27095:191;;;;:::o;27292:174::-;27432:26;27428:1;27420:6;27416:14;27409:50;27292:174;:::o;27472:366::-;27614:3;27635:67;27699:2;27694:3;27635:67;:::i;:::-;27628:74;;27711:93;27800:3;27711:93;:::i;:::-;27829:2;27824:3;27820:12;27813:19;;27472:366;;;:::o;27844:419::-;28010:4;28048:2;28037:9;28033:18;28025:26;;28097:9;28091:4;28087:20;28083:1;28072:9;28068:17;28061:47;28125:131;28251:4;28125:131;:::i;:::-;28117:139;;27844:419;;;:::o;28269:181::-;28409:33;28405:1;28397:6;28393:14;28386:57;28269:181;:::o;28456:366::-;28598:3;28619:67;28683:2;28678:3;28619:67;:::i;:::-;28612:74;;28695:93;28784:3;28695:93;:::i;:::-;28813:2;28808:3;28804:12;28797:19;;28456:366;;;:::o;28828:419::-;28994:4;29032:2;29021:9;29017:18;29009:26;;29081:9;29075:4;29071:20;29067:1;29056:9;29052:17;29045:47;29109:131;29235:4;29109:131;:::i;:::-;29101:139;;28828:419;;;:::o;29253:226::-;29393:34;29389:1;29381:6;29377:14;29370:58;29462:9;29457:2;29449:6;29445:15;29438:34;29253:226;:::o;29485:366::-;29627:3;29648:67;29712:2;29707:3;29648:67;:::i;:::-;29641:74;;29724:93;29813:3;29724:93;:::i;:::-;29842:2;29837:3;29833:12;29826:19;;29485:366;;;:::o;29857:419::-;30023:4;30061:2;30050:9;30046:18;30038:26;;30110:9;30104:4;30100:20;30096:1;30085:9;30081:17;30074:47;30138:131;30264:4;30138:131;:::i;:::-;30130:139;;29857:419;;;:::o;30282:223::-;30422:34;30418:1;30410:6;30406:14;30399:58;30491:6;30486:2;30478:6;30474:15;30467:31;30282:223;:::o;30511:366::-;30653:3;30674:67;30738:2;30733:3;30674:67;:::i;:::-;30667:74;;30750:93;30839:3;30750:93;:::i;:::-;30868:2;30863:3;30859:12;30852:19;;30511:366;;;:::o;30883:419::-;31049:4;31087:2;31076:9;31072:18;31064:26;;31136:9;31130:4;31126:20;31122:1;31111:9;31107:17;31100:47;31164:131;31290:4;31164:131;:::i;:::-;31156:139;;30883:419;;;:::o;31308:410::-;31348:7;31371:20;31389:1;31371:20;:::i;:::-;31366:25;;31405:20;31423:1;31405:20;:::i;:::-;31400:25;;31460:1;31457;31453:9;31482:30;31500:11;31482:30;:::i;:::-;31471:41;;31661:1;31652:7;31648:15;31645:1;31642:22;31622:1;31615:9;31595:83;31572:139;;31691:18;;:::i;:::-;31572:139;31356:362;31308:410;;;;:::o;31724:180::-;31772:77;31769:1;31762:88;31869:4;31866:1;31859:15;31893:4;31890:1;31883:15;31910:233;31949:3;31972:24;31990:5;31972:24;:::i;:::-;31963:33;;32018:66;32011:5;32008:77;32005:103;;32088:18;;:::i;:::-;32005:103;32135:1;32128:5;32124:13;32117:20;;31910:233;;;:::o;32149:114::-;32216:6;32250:5;32244:12;32234:22;;32149:114;;;:::o;32269:184::-;32368:11;32402:6;32397:3;32390:19;32442:4;32437:3;32433:14;32418:29;;32269:184;;;;:::o;32459:132::-;32526:4;32549:3;32541:11;;32579:4;32574:3;32570:14;32562:22;;32459:132;;;:::o;32597:108::-;32674:24;32692:5;32674:24;:::i;:::-;32669:3;32662:37;32597:108;;:::o;32711:179::-;32780:10;32801:46;32843:3;32835:6;32801:46;:::i;:::-;32879:4;32874:3;32870:14;32856:28;;32711:179;;;;:::o;32896:113::-;32966:4;32998;32993:3;32989:14;32981:22;;32896:113;;;:::o;33045:732::-;33164:3;33193:54;33241:5;33193:54;:::i;:::-;33263:86;33342:6;33337:3;33263:86;:::i;:::-;33256:93;;33373:56;33423:5;33373:56;:::i;:::-;33452:7;33483:1;33468:284;33493:6;33490:1;33487:13;33468:284;;;33569:6;33563:13;33596:63;33655:3;33640:13;33596:63;:::i;:::-;33589:70;;33682:60;33735:6;33682:60;:::i;:::-;33672:70;;33528:224;33515:1;33512;33508:9;33503:14;;33468:284;;;33472:14;33768:3;33761:10;;33169:608;;;33045:732;;;;:::o;33783:483::-;33954:4;33992:2;33981:9;33977:18;33969:26;;34041:9;34035:4;34031:20;34027:1;34016:9;34012:17;34005:47;34069:108;34172:4;34163:6;34069:108;:::i;:::-;34061:116;;34187:72;34255:2;34244:9;34240:18;34231:6;34187:72;:::i;:::-;33783:483;;;;;:::o;34272:176::-;34412:28;34408:1;34400:6;34396:14;34389:52;34272:176;:::o;34454:366::-;34596:3;34617:67;34681:2;34676:3;34617:67;:::i;:::-;34610:74;;34693:93;34782:3;34693:93;:::i;:::-;34811:2;34806:3;34802:12;34795:19;;34454:366;;;:::o;34826:419::-;34992:4;35030:2;35019:9;35015:18;35007:26;;35079:9;35073:4;35069:20;35065:1;35054:9;35050:17;35043:47;35107:131;35233:4;35107:131;:::i;:::-;35099:139;;34826:419;;;:::o;35251:79::-;35290:7;35319:5;35308:16;;35251:79;;;:::o;35336:157::-;35441:45;35461:24;35479:5;35461:24;:::i;:::-;35441:45;:::i;:::-;35436:3;35429:58;35336:157;;:::o;35499:256::-;35611:3;35626:75;35697:3;35688:6;35626:75;:::i;:::-;35726:2;35721:3;35717:12;35710:19;;35746:3;35739:10;;35499:256;;;;:::o;35761:169::-;35901:21;35897:1;35889:6;35885:14;35878:45;35761:169;:::o;35936:366::-;36078:3;36099:67;36163:2;36158:3;36099:67;:::i;:::-;36092:74;;36175:93;36264:3;36175:93;:::i;:::-;36293:2;36288:3;36284:12;36277:19;;35936:366;;;:::o;36308:419::-;36474:4;36512:2;36501:9;36497:18;36489:26;;36561:9;36555:4;36551:20;36547:1;36536:9;36532:17;36525:47;36589:131;36715:4;36589:131;:::i;:::-;36581:139;;36308:419;;;:::o;36733:234::-;36873:34;36869:1;36861:6;36857:14;36850:58;36942:17;36937:2;36929:6;36925:15;36918:42;36733:234;:::o;36973:366::-;37115:3;37136:67;37200:2;37195:3;37136:67;:::i;:::-;37129:74;;37212:93;37301:3;37212:93;:::i;:::-;37330:2;37325:3;37321:12;37314:19;;36973:366;;;:::o;37345:419::-;37511:4;37549:2;37538:9;37534:18;37526:26;;37598:9;37592:4;37588:20;37584:1;37573:9;37569:17;37562:47;37626:131;37752:4;37626:131;:::i;:::-;37618:139;;37345:419;;;:::o;37770:148::-;37872:11;37909:3;37894:18;;37770:148;;;;:::o;37924:390::-;38030:3;38058:39;38091:5;38058:39;:::i;:::-;38113:89;38195:6;38190:3;38113:89;:::i;:::-;38106:96;;38211:65;38269:6;38264:3;38257:4;38250:5;38246:16;38211:65;:::i;:::-;38301:6;38296:3;38292:16;38285:23;;38034:280;37924:390;;;;:::o;38344:874::-;38447:3;38484:5;38478:12;38513:36;38539:9;38513:36;:::i;:::-;38565:89;38647:6;38642:3;38565:89;:::i;:::-;38558:96;;38685:1;38674:9;38670:17;38701:1;38696:166;;;;38876:1;38871:341;;;;38663:549;;38696:166;38780:4;38776:9;38765;38761:25;38756:3;38749:38;38842:6;38835:14;38828:22;38820:6;38816:35;38811:3;38807:45;38800:52;;38696:166;;38871:341;38938:38;38970:5;38938:38;:::i;:::-;38998:1;39012:154;39026:6;39023:1;39020:13;39012:154;;;39100:7;39094:14;39090:1;39085:3;39081:11;39074:35;39150:1;39141:7;39137:15;39126:26;;39048:4;39045:1;39041:12;39036:17;;39012:154;;;39195:6;39190:3;39186:16;39179:23;;38878:334;;38663:549;;38451:767;;38344:874;;;;:::o;39224:589::-;39449:3;39471:95;39562:3;39553:6;39471:95;:::i;:::-;39464:102;;39583:95;39674:3;39665:6;39583:95;:::i;:::-;39576:102;;39695:92;39783:3;39774:6;39695:92;:::i;:::-;39688:99;;39804:3;39797:10;;39224:589;;;;;;:::o;39819:225::-;39959:34;39955:1;39947:6;39943:14;39936:58;40028:8;40023:2;40015:6;40011:15;40004:33;39819:225;:::o;40050:366::-;40192:3;40213:67;40277:2;40272:3;40213:67;:::i;:::-;40206:74;;40289:93;40378:3;40289:93;:::i;:::-;40407:2;40402:3;40398:12;40391:19;;40050:366;;;:::o;40422:419::-;40588:4;40626:2;40615:9;40611:18;40603:26;;40675:9;40669:4;40665:20;40661:1;40650:9;40646:17;40639:47;40703:131;40829:4;40703:131;:::i;:::-;40695:139;;40422:419;;;:::o;40847:332::-;40968:4;41006:2;40995:9;40991:18;40983:26;;41019:71;41087:1;41076:9;41072:17;41063:6;41019:71;:::i;:::-;41100:72;41168:2;41157:9;41153:18;41144:6;41100:72;:::i;:::-;40847:332;;;;;:::o;41185:137::-;41239:5;41270:6;41264:13;41255:22;;41286:30;41310:5;41286:30;:::i;:::-;41185:137;;;;:::o;41328:345::-;41395:6;41444:2;41432:9;41423:7;41419:23;41415:32;41412:119;;;41450:79;;:::i;:::-;41412:119;41570:1;41595:61;41648:7;41639:6;41628:9;41624:22;41595:61;:::i;:::-;41585:71;;41541:125;41328:345;;;;:::o;41679:182::-;41819:34;41815:1;41807:6;41803:14;41796:58;41679:182;:::o;41867:366::-;42009:3;42030:67;42094:2;42089:3;42030:67;:::i;:::-;42023:74;;42106:93;42195:3;42106:93;:::i;:::-;42224:2;42219:3;42215:12;42208:19;;41867:366;;;:::o;42239:419::-;42405:4;42443:2;42432:9;42428:18;42420:26;;42492:9;42486:4;42482:20;42478:1;42467:9;42463:17;42456:47;42520:131;42646:4;42520:131;:::i;:::-;42512:139;;42239:419;;;:::o;42664:181::-;42804:33;42800:1;42792:6;42788:14;42781:57;42664:181;:::o;42851:366::-;42993:3;43014:67;43078:2;43073:3;43014:67;:::i;:::-;43007:74;;43090:93;43179:3;43090:93;:::i;:::-;43208:2;43203:3;43199:12;43192:19;;42851:366;;;:::o;43223:419::-;43389:4;43427:2;43416:9;43412:18;43404:26;;43476:9;43470:4;43466:20;43462:1;43451:9;43447:17;43440:47;43504:131;43630:4;43504:131;:::i;:::-;43496:139;;43223:419;;;:::o;43648:147::-;43749:11;43786:3;43771:18;;43648:147;;;;:::o;43801:114::-;;:::o;43921:398::-;44080:3;44101:83;44182:1;44177:3;44101:83;:::i;:::-;44094:90;;44193:93;44282:3;44193:93;:::i;:::-;44311:1;44306:3;44302:11;44295:18;;43921:398;;;:::o;44325:379::-;44509:3;44531:147;44674:3;44531:147;:::i;:::-;44524:154;;44695:3;44688:10;;44325:379;;;:::o;44710:177::-;44850:29;44846:1;44838:6;44834:14;44827:53;44710:177;:::o;44893:366::-;45035:3;45056:67;45120:2;45115:3;45056:67;:::i;:::-;45049:74;;45132:93;45221:3;45132:93;:::i;:::-;45250:2;45245:3;45241:12;45234:19;;44893:366;;;:::o;45265:419::-;45431:4;45469:2;45458:9;45454:18;45446:26;;45518:9;45512:4;45508:20;45504:1;45493:9;45489:17;45482:47;45546:131;45672:4;45546:131;:::i;:::-;45538:139;;45265:419;;;:::o;45690:180::-;45738:77;45735:1;45728:88;45835:4;45832:1;45825:15;45859:4;45856:1;45849:15;45876:98;45927:6;45961:5;45955:12;45945:22;;45876:98;;;:::o;45980:168::-;46063:11;46097:6;46092:3;46085:19;46137:4;46132:3;46128:14;46113:29;;45980:168;;;;:::o;46154:373::-;46240:3;46268:38;46300:5;46268:38;:::i;:::-;46322:70;46385:6;46380:3;46322:70;:::i;:::-;46315:77;;46401:65;46459:6;46454:3;46447:4;46440:5;46436:16;46401:65;:::i;:::-;46491:29;46513:6;46491:29;:::i;:::-;46486:3;46482:39;46475:46;;46244:283;46154:373;;;;:::o;46533:640::-;46728:4;46766:3;46755:9;46751:19;46743:27;;46780:71;46848:1;46837:9;46833:17;46824:6;46780:71;:::i;:::-;46861:72;46929:2;46918:9;46914:18;46905:6;46861:72;:::i;:::-;46943;47011:2;47000:9;46996:18;46987:6;46943:72;:::i;:::-;47062:9;47056:4;47052:20;47047:2;47036:9;47032:18;47025:48;47090:76;47161:4;47152:6;47090:76;:::i;:::-;47082:84;;46533:640;;;;;;;:::o;47179:141::-;47235:5;47266:6;47260:13;47251:22;;47282:32;47308:5;47282:32;:::i;:::-;47179:141;;;;:::o;47326:349::-;47395:6;47444:2;47432:9;47423:7;47419:23;47415:32;47412:119;;;47450:79;;:::i;:::-;47412:119;47570:1;47595:63;47650:7;47641:6;47630:9;47626:22;47595:63;:::i;:::-;47585:73;;47541:127;47326:349;;;;:::o
Swarm Source
ipfs://b1a4f16b6de2b25b0a5d62895927a093ba6811c3367eddedd42e82e4f54bbc5f
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.