ERC-721
Overview
Max Total Supply
3,440 WHOOP
Holders
439
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
40 WHOOPLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Whoopsies
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-08-31 */ // SPDX-License-Identifier: MIT /// @title ERC721 Implementation of Whoopsies v2 Collection /// @custom:security-contact [email protected] /// @author Shehroz K. | Captain Unknown (@captainunknown5) // File: lib/Constants.sol pragma solidity ^0.8.13; address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E; address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6; // File: 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: 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: 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: SoladyOwnable.sol pragma solidity ^0.8.4; /// @notice Simple single owner authorization mixin. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol) /// /// @dev Note: /// This implementation does NOT auto-initialize the owner to `msg.sender`. /// You MUST call the `_initializeOwner` in the constructor / initializer. /// /// While the ownable portion follows /// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility, /// the nomenclature for the 2-step ownership handover may be unique to this codebase. abstract contract Ownable { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The caller is not authorized to call the function. error Unauthorized(); /// @dev The `newOwner` cannot be the zero address. error NewOwnerIsZeroAddress(); /// @dev The `pendingOwner` does not have a valid handover request. error NoHandoverRequest(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ownership is transferred from `oldOwner` to `newOwner`. /// This event is intentionally kept the same as OpenZeppelin's Ownable to be /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), /// despite it not being as lightweight as a single argument event. event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); /// @dev An ownership handover to `pendingOwner` has been requested. event OwnershipHandoverRequested(address indexed pendingOwner); /// @dev The ownership handover to `pendingOwner` has been canceled. event OwnershipHandoverCanceled(address indexed pendingOwner); /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`. uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE = 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0; /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE = 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d; /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE = 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The owner slot is given by: `not(_OWNER_SLOT_NOT)`. /// It is intentionally chosen to be a high value /// to avoid collision with lower slots. /// The choice of manual storage layout is to enable compatibility /// with both regular and upgradeable contracts. uint256 private constant _OWNER_SLOT_NOT = 0x8b78c6d8; /// The ownership handover slot of `newOwner` is given by: /// ``` /// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED)) /// let handoverSlot := keccak256(0x00, 0x20) /// ``` /// It stores the expiry timestamp of the two-step ownership handover. uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Initializes the owner directly without authorization guard. /// This function must be called upon initialization, /// regardless of whether the contract is upgradeable or not. /// This is to enable generalization to both regular and upgradeable contracts, /// and to save gas in case the initial owner is not the caller. /// For performance reasons, this function will not check if there /// is an existing owner. function _initializeOwner(address newOwner) internal virtual { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(not(_OWNER_SLOT_NOT), newOwner) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) } } /// @dev Sets the owner directly without authorization guard. function _setOwner(address newOwner) internal virtual { /// @solidity memory-safe-assembly assembly { let ownerSlot := not(_OWNER_SLOT_NOT) // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) // Store the new value. sstore(ownerSlot, newOwner) } } /// @dev Throws if the sender is not the owner. function _checkOwner() internal view virtual { /// @solidity memory-safe-assembly assembly { // If the caller is not the stored owner, revert. if iszero(eq(caller(), sload(not(_OWNER_SLOT_NOT)))) { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } } /// @dev Returns how long a two-step ownership handover is valid for in seconds. /// Override to return a different value if needed. /// Made internal to conserve bytecode. Wrap it in a public function if needed. function _ownershipHandoverValidFor() internal view virtual returns (uint64) { return 48 * 3600; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC UPDATE FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Allows the owner to transfer the ownership to `newOwner`. function transferOwnership(address newOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { if iszero(shl(96, newOwner)) { mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`. revert(0x1c, 0x04) } } _setOwner(newOwner); } /// @dev Allows the owner to renounce their ownership. function renounceOwnership() public payable virtual onlyOwner { _setOwner(address(0)); } /// @dev Request a two-step ownership handover to the caller. /// The request will automatically expire in 48 hours (172800 seconds) by default. function requestOwnershipHandover() public payable virtual { unchecked { uint256 expires = block.timestamp + _ownershipHandoverValidFor(); /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to `expires`. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), expires) // Emit the {OwnershipHandoverRequested} event. log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller()) } } } /// @dev Cancels the two-step ownership handover to the caller, if any. function cancelOwnershipHandover() public payable virtual { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), 0) // Emit the {OwnershipHandoverCanceled} event. log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller()) } } /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`. /// Reverts if there is no existing ownership handover requested by `pendingOwner`. function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) let handoverSlot := keccak256(0x0c, 0x20) // If the handover does not exist, or has expired. if gt(timestamp(), sload(handoverSlot)) { mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`. revert(0x1c, 0x04) } // Set the handover slot to 0. sstore(handoverSlot, 0) } _setOwner(pendingOwner); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC READ FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the owner of the contract. function owner() public view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { result := sload(not(_OWNER_SLOT_NOT)) } } /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`. function ownershipHandoverExpiresAt(address pendingOwner) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Compute the handover slot. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) // Load the handover slot. result := sload(keccak256(0x0c, 0x20)) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MODIFIERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Marks a function as only callable by the owner. modifier onlyOwner() virtual { _checkOwner(); _; } } // File: @openzeppelin/contracts/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.9.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) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 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 256, 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 << 3) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.9.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 `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @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); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // 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/utils/Address.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC165.sol // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC721.sol // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.0; // File: @openzeppelin/contracts/interfaces/IERC4906.sol // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4906.sol) pragma solidity ^0.8.0; /// @title EIP-721 Metadata Update Extension interface IERC4906 is IERC165, IERC721 { /// @dev This event emits when the metadata of a token is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFT. event MetadataUpdate(uint256 _tokenId); /// @dev This event emits when the metadata of a range of tokens is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFTs. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/extensions/ERC721URIStorage.sol) pragma solidity ^0.8.0; /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is IERC4906, ERC721 { using Strings for uint256; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; /** * @dev See {IERC165-supportsInterface} */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) { return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = _baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } return super.tokenURI(tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Emits {MetadataUpdate}. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; emit MetadataUpdate(tokenId); } /** * @dev See {ERC721-_burn}. This override additionally checks to see if a * token-specific URI was set for the token, and if so, it deletes the token URI from * the storage mapping. */ function _burn(uint256 tokenId) internal virtual override { super._burn(tokenId); if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File: WhoopsiesAudited.sol /// @title ERC721 Implementation of Whoopsies v2 Collection pragma solidity ^0.8.9; interface IERC20 { function transfer(address to, uint256 amount) external returns (bool); } // Errors error NotOwner(); error NotActive(); error invalidValue(); error ClaimNotActive(); error TransferFailed(); error ZeroClaimable(); error CoolDownActive(); /// @custom:security-contact [email protected] contract Whoopsies is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable, DefaultOperatorFilterer { address public constant whoopsiesV1 = 0x565AbC3FEaa3bC3820B83620f4BbF16B5c4D47a3; bool public v2ClaimActive = false; bool public doopClaimActive = false; string public baseUri = "ipfs://QmYJGEoa3zRNMVFLsRcgzXNNQ3g2HsQQeipSLFstivW4hB/"; string public constant baseExtension = ".json"; uint256 public immutable initialTime; uint256 public claimPrice; IERC20 public doopToken; mapping (address => uint256) public totalClaimed; mapping (address => uint256) public lastDoopClaimTime; constructor() ERC721("Whoopsies", "WHOOP") { _initializeOwner(msg.sender); initialTime = block.timestamp; } /// @notice Transfers v2 equivalent old collection to the caller /// @param requestedTokenIds TokenID(s) to claim function claimV2NFTs(uint256[] calldata requestedTokenIds) public payable { if (!v2ClaimActive) revert NotActive(); if (requestedTokenIds.length * claimPrice != msg.value) revert invalidValue(); for (uint256 i; i < requestedTokenIds.length;) { if (IERC721(whoopsiesV1).ownerOf(requestedTokenIds[i]) != msg.sender) revert NotOwner(); _safeMint(msg.sender, requestedTokenIds[i]); unchecked { i++; } } } /// @notice Transfers claimable Doop to the caller function claimDoop() public { if (!doopClaimActive) revert ClaimNotActive(); uint256 balance = balanceOf(_msgSender()); if (balance == 0) revert ZeroClaimable(); uint256 claimablePerNFT; uint256 previous = lastDoopClaimTime[msg.sender]; uint256 timestamp = block.timestamp; if (previous != 0) { if (previous + 1 days > timestamp) revert CoolDownActive(); claimablePerNFT = ((timestamp - previous) / 1 days) * 5; } else { claimablePerNFT = ((timestamp - initialTime) / 1 days) * 5; } lastDoopClaimTime[msg.sender] = timestamp; uint256 totalClaimable = claimablePerNFT * balance; unchecked { totalClaimed[msg.sender] += totalClaimable; } if (!doopToken.transfer(msg.sender, totalClaimable * 10 ** 18)) revert TransferFailed(); } /// @notice Retrieves Doop tokens available to claim for the given address /// @param _address The address to query claimable Doop tokens for /// @return Amount of claimable Doop tokens function retrieveClaimableDoop(address _address) public view returns (uint256) { uint256 balance = balanceOf(_msgSender()); uint256 timestamp = block.timestamp; if (balance == 0) return 0; uint256 claimablePerNFT; uint256 pTime = lastDoopClaimTime[_address]; if (pTime != 0) claimablePerNFT = ((timestamp - pTime) / 1 days) * 5; else claimablePerNFT = ((timestamp - initialTime) / 1 days) * 5; uint256 claimable = claimablePerNFT * balance; return claimable * 10 ** 18; } // Utils /// @notice Toggle v2 NFTs claim eligibility state function toggleV2ClaimActive() public onlyOwner { v2ClaimActive = !v2ClaimActive; } /// @notice Toggle Doop Tokens claim eligibility state function toggleDoopClaimActive() public onlyOwner { doopClaimActive = !doopClaimActive; } /// @notice Changes Doop Token address to the given address /// @param _tokenAddress Address to change the Doop token address to function setDoopAddress(address _tokenAddress) public onlyOwner { doopToken = IERC20(_tokenAddress); } /// @notice Changes claim price to the given price /// @param newClaimPrice The new claim price for single claim function setClaimPrice(uint256 newClaimPrice) public onlyOwner { claimPrice = newClaimPrice; } // The following functions are operator filterer overrides. function setApprovalForAll(address operator, bool approved) public override(ERC721, IERC721) onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public override(ERC721, IERC721) onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom(address from, address to, uint256 tokenId) public override(ERC721, IERC721) onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public override(ERC721, IERC721) onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } /// @notice Changes token base URI to the given string /// @param _newBaseURI URI to change the base URI to function setBaseURI(string memory _newBaseURI) public onlyOwner { baseUri = _newBaseURI; } /// @return Current Base URI function _baseURI() internal view override returns (string memory) { return baseUri; } /// @param tokenId TokenID to retrieve URI for /// @return Current URI for the given tokenId function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return string(abi.encodePacked(_baseURI(), Strings.toString(tokenId), baseExtension)); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable, ERC721URIStorage) returns (bool) { return super.supportsInterface(interfaceId); } /// @notice Withdraws given amount of Doop Tokens /// @param amount Amount of Doop token to withdraw function withdrawDoop(uint256 amount) public onlyOwner { doopToken.transfer(msg.sender, amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ClaimNotActive","type":"error"},{"inputs":[],"name":"CoolDownActive","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"NotActive","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroClaimable","type":"error"},{"inputs":[],"name":"invalidValue","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":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claimDoop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"requestedTokenIds","type":"uint256[]"}],"name":"claimV2NFTs","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"doopClaimActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"doopToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"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":"initialTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastDoopClaimTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","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":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"retrieveClaimableDoop","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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newClaimPrice","type":"uint256"}],"name":"setClaimPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"setDoopAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleDoopClaimActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleV2ClaimActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"v2ClaimActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whoopsiesV1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawDoop","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040525f600b5f6101000a81548160ff0219169083151502179055505f600b60016101000a81548160ff02191690831515021790555060405180606001604052806036815260200162004d8e60369139600c9081620000619190620005ba565b503480156200006e575f80fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600981526020017f57686f6f707369657300000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f57484f4f50000000000000000000000000000000000000000000000000000000815250815f9081620001029190620005ba565b508060019081620001149190620005ba565b5050505f6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620002fb578015620001cc576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b815260040162000197929190620006e1565b5f604051808303815f87803b158015620001af575f80fd5b505af1158015620001c2573d5f803e3d5ffd5b50505050620002fa565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000280576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200024b929190620006e1565b5f604051808303815f87803b15801562000263575f80fd5b505af115801562000276573d5f803e3d5ffd5b50505050620002f9565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620002c991906200070c565b5f604051808303815f87803b158015620002e1575f80fd5b505af1158015620002f4573d5f803e3d5ffd5b505050505b5b5b50506200030e336200031c60201b60201c565b426080818152505062000727565b8060601b60601c905080638b78c6d81955805f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a350565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620003d257607f821691505b602082108103620003e857620003e76200038d565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200044c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200040f565b6200045886836200040f565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620004a26200049c620004968462000470565b62000479565b62000470565b9050919050565b5f819050919050565b620004bd8362000482565b620004d5620004cc82620004a9565b8484546200041b565b825550505050565b5f90565b620004eb620004dd565b620004f8818484620004b2565b505050565b5b818110156200051f57620005135f82620004e1565b600181019050620004fe565b5050565b601f8211156200056e576200053881620003ee565b620005438462000400565b8101602085101562000553578190505b6200056b620005628562000400565b830182620004fd565b50505b505050565b5f82821c905092915050565b5f620005905f198460080262000573565b1980831691505092915050565b5f620005aa83836200057f565b9150826002028217905092915050565b620005c58262000356565b67ffffffffffffffff811115620005e157620005e062000360565b5b620005ed8254620003ba565b620005fa82828562000523565b5f60209050601f83116001811462000630575f84156200061b578287015190505b6200062785826200059d565b86555062000696565b601f1984166200064086620003ee565b5f5b82811015620006695784890151825560018201915060208501945060208101905062000642565b8683101562000689578489015162000685601f8916826200057f565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620006c9826200069e565b9050919050565b620006db81620006bd565b82525050565b5f604082019050620006f65f830185620006d0565b620007056020830184620006d0565b9392505050565b5f602082019050620007215f830184620006d0565b92915050565b6080516146406200074e5f395f81816110de015281816115f8015261180b01526146405ff3fe60806040526004361061025b575f3560e01c80636352211e11610143578063c60360f7116100b5578063e985e9c511610079578063e985e9c514610845578063eca30a4114610881578063ef5d9ae8146108bd578063f04e283e146108f9578063f2fde38b14610915578063fee81cf4146109315761025b565b8063c60360f71461074f578063c668286214610779578063c67c74d4146107a3578063c87b56dd146107cd578063e5267d17146108095761025b565b80638da5cb5b116101075780638da5cb5b1461065757806395d89b41146106815780639abc8320146106ab5780639ced0e9b146106d5578063a22cb465146106ff578063b88d4fde146107275761025b565b80636352211e1461059757806370a08231146105d3578063715018a61461060f5780637e082c16146106195780638c1ceda51461062f5761025b565b80632f745c59116101dc57806342842e0e116101a057806342842e0e146104c35780634f6ccce7146104eb57806351f468c01461052757806354d1f13d1461054f57806355f804b3146105595780635e08dff6146105815761025b565b80632f745c59146104015780633745ee951461043d578063381b1e5d14610467578063398280eb1461048357806341f43434146104995761025b565b806315d655c91161022357806315d655c91461035357806317d819d01461037d57806318160ddd146103a557806323b872dd146103cf57806325692962146103f75761025b565b806301ffc9a71461025f57806306fdde031461029b578063081812fc146102c557806308e0415814610301578063095ea7b31461032b575b5f80fd5b34801561026a575f80fd5b506102856004803603810190610280919061312d565b61096d565b6040516102929190613172565b60405180910390f35b3480156102a6575f80fd5b506102af61097e565b6040516102bc9190613215565b60405180910390f35b3480156102d0575f80fd5b506102eb60048036038101906102e69190613268565b610a0d565b6040516102f891906132d2565b60405180910390f35b34801561030c575f80fd5b50610315610a4f565b6040516103229190613346565b60405180910390f35b348015610336575f80fd5b50610351600480360381019061034c9190613389565b610a74565b005b34801561035e575f80fd5b50610367610a8d565b60405161037491906133d6565b60405180910390f35b348015610388575f80fd5b506103a3600480360381019061039e91906133ef565b610a93565b005b3480156103b0575f80fd5b506103b9610ade565b6040516103c691906133d6565b60405180910390f35b3480156103da575f80fd5b506103f560048036038101906103f0919061341a565b610aea565b005b6103ff610b39565b005b34801561040c575f80fd5b5061042760048036038101906104229190613389565b610b8a565b60405161043491906133d6565b60405180910390f35b348015610448575f80fd5b50610451610c2a565b60405161045e91906132d2565b60405180910390f35b610481600480360381019061047c91906134cb565b610c42565b005b34801561048e575f80fd5b50610497610e1b565b005b3480156104a4575f80fd5b506104ad610e4d565b6040516104ba9190613536565b60405180910390f35b3480156104ce575f80fd5b506104e960048036038101906104e4919061341a565b610e5f565b005b3480156104f6575f80fd5b50610511600480360381019061050c9190613268565b610eae565b60405161051e91906133d6565b60405180910390f35b348015610532575f80fd5b5061054d60048036038101906105489190613268565b610f1c565b005b610557610f2e565b005b348015610564575f80fd5b5061057f600480360381019061057a9190613677565b610f67565b005b34801561058c575f80fd5b50610595610f82565b005b3480156105a2575f80fd5b506105bd60048036038101906105b89190613268565b6112a6565b6040516105ca91906132d2565b60405180910390f35b3480156105de575f80fd5b506105f960048036038101906105f491906133ef565b61132a565b60405161060691906133d6565b60405180910390f35b6106176113de565b005b348015610624575f80fd5b5061062d6113f1565b005b34801561063a575f80fd5b5061065560048036038101906106509190613268565b611425565b005b348015610662575f80fd5b5061066b6114cd565b60405161067891906132d2565b60405180910390f35b34801561068c575f80fd5b506106956114da565b6040516106a29190613215565b60405180910390f35b3480156106b6575f80fd5b506106bf61156a565b6040516106cc9190613215565b60405180910390f35b3480156106e0575f80fd5b506106e96115f6565b6040516106f691906133d6565b60405180910390f35b34801561070a575f80fd5b50610725600480360381019061072091906136e8565b61161a565b005b348015610732575f80fd5b5061074d600480360381019061074891906137c4565b611633565b005b34801561075a575f80fd5b50610763611695565b6040516107709190613172565b60405180910390f35b348015610784575f80fd5b5061078d6116a8565b60405161079a9190613215565b60405180910390f35b3480156107ae575f80fd5b506107b76116e1565b6040516107c49190613172565b60405180910390f35b3480156107d8575f80fd5b506107f360048036038101906107ee9190613268565b6116f3565b6040516108009190613215565b60405180910390f35b348015610814575f80fd5b5061082f600480360381019061082a91906133ef565b611764565b60405161083c91906133d6565b60405180910390f35b348015610850575f80fd5b5061086b60048036038101906108669190613844565b61187c565b6040516108789190613172565b60405180910390f35b34801561088c575f80fd5b506108a760048036038101906108a291906133ef565b61190a565b6040516108b491906133d6565b60405180910390f35b3480156108c8575f80fd5b506108e360048036038101906108de91906133ef565b61191f565b6040516108f091906133d6565b60405180910390f35b610913600480360381019061090e91906133ef565b611934565b005b61092f600480360381019061092a91906133ef565b611972565b005b34801561093c575f80fd5b50610957600480360381019061095291906133ef565b61199b565b60405161096491906133d6565b60405180910390f35b5f610977826119b4565b9050919050565b60605f805461098c906138af565b80601f01602080910402602001604051908101604052809291908181526020018280546109b8906138af565b8015610a035780601f106109da57610100808354040283529160200191610a03565b820191905f5260205f20905b8154815290600101906020018083116109e657829003601f168201915b5050505050905090565b5f610a1782611a14565b60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b81610a7e81611a5f565b610a888383611b59565b505050565b600d5481565b610a9b611c6f565b80600e5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f600880549050905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b2857610b2733611a5f565b5b610b33848484611c8b565b50505050565b5f610b42611ceb565b67ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b5f610b948361132a565b8210610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcc9061394f565b60405180910390fd5b60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b73565abc3feaa3bc3820b83620f4bbf16b5c4d47a381565b600b5f9054906101000a900460ff16610c87576040517f80cb55e200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34600d5483839050610c99919061399a565b14610cd0576040517f313223b900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5b82829050811015610e16573373ffffffffffffffffffffffffffffffffffffffff1673565abc3feaa3bc3820b83620f4bbf16b5c4d47a373ffffffffffffffffffffffffffffffffffffffff16636352211e858585818110610d3757610d366139db565b5b905060200201356040518263ffffffff1660e01b8152600401610d5a91906133d6565b602060405180830381865afa158015610d75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d999190613a1c565b73ffffffffffffffffffffffffffffffffffffffff1614610de6576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0933848484818110610dfd57610dfc6139db565b5b90506020020135611cf5565b8080600101915050610cd2565b505050565b610e23611c6f565b600b5f9054906101000a900460ff1615600b5f6101000a81548160ff021916908315150217905550565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e9d57610e9c33611a5f565b5b610ea8848484611d12565b50505050565b5f610eb7610ade565b8210610ef8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eef90613ab7565b60405180910390fd5b60088281548110610f0c57610f0b6139db565b5b905f5260205f2001549050919050565b610f24611c6f565b80600d8190555050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b610f6f611c6f565b80600c9081610f7e9190613c69565b5050565b600b60019054906101000a900460ff16610fc8576040517f24fbaa9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610fd9610fd4611d31565b61132a565b90505f8103611014576040517fbe7538fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8060105f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f4290505f82146110d6578062015180836110719190613d38565b11156110a9576040517f748614c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056201518083836110bb9190613d6b565b6110c59190613dcb565b6110cf919061399a565b925061111f565b6005620151807f0000000000000000000000000000000000000000000000000000000000000000836111089190613d6b565b6111129190613dcb565b61111c919061399a565b92505b8060105f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055505f848461116e919061399a565b905080600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33670de0b6b3a76400008461120c919061399a565b6040518363ffffffff1660e01b8152600401611229929190613dfb565b6020604051808303815f875af1158015611245573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112699190613e36565b61129f576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b5f806112b183611d38565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611321576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131890613eab565b60405180910390fd5b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090613f39565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6113e6611c6f565b6113ef5f611d71565b565b6113f9611c6f565b600b60019054906101000a900460ff1615600b60016101000a81548160ff021916908315150217905550565b61142d611c6f565b600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401611489929190613dfb565b6020604051808303815f875af11580156114a5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114c99190613e36565b5050565b5f638b78c6d81954905090565b6060600180546114e9906138af565b80601f0160208091040260200160405190810160405280929190818152602001828054611515906138af565b80156115605780601f1061153757610100808354040283529160200191611560565b820191905f5260205f20905b81548152906001019060200180831161154357829003601f168201915b5050505050905090565b600c8054611577906138af565b80601f01602080910402602001604051908101604052809291908181526020018280546115a3906138af565b80156115ee5780601f106115c5576101008083540402835291602001916115ee565b820191905f5260205f20905b8154815290600101906020018083116115d157829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000081565b8161162481611a5f565b61162e8383611dae565b505050565b61164461163e611d31565b83611dc4565b611683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167a90613fc7565b60405180910390fd5b61168f84848484611e58565b50505050565b600b60019054906101000a900460ff1681565b6040518060400160405280600581526020017f2e6a736f6e00000000000000000000000000000000000000000000000000000081525081565b600b5f9054906101000a900460ff1681565b60606116fd611eb4565b61170683611f44565b6040518060400160405280600581526020017f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060405160200161174e9392919061401f565b6040516020818303038152906040529050919050565b5f80611776611771611d31565b61132a565b90505f4290505f820361178d575f92505050611877565b5f8060105f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f81146118035760056201518082856117e89190613d6b565b6117f29190613dcb565b6117fc919061399a565b915061184c565b6005620151807f0000000000000000000000000000000000000000000000000000000000000000856118359190613d6b565b61183f9190613dcb565b611849919061399a565b91505b5f8483611859919061399a565b9050670de0b6b3a76400008161186f919061399a565b955050505050505b919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6010602052805f5260405f205f915090505481565b600f602052805f5260405f205f915090505481565b61193c611c6f565b63389a75e1600c52805f526020600c20805442111561196257636f5e88185f526004601cfd5b5f81555061196f81611d71565b50565b61197a611c6f565b8060601b61198f57637448fbae5f526004601cfd5b61199881611d71565b50565b5f63389a75e1600c52815f526020600c20549050919050565b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a0d5750611a0c8261200e565b5b9050919050565b611a1d81612087565b611a5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5390613eab565b60405180910390fd5b50565b5f6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611b56576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611ad592919061404f565b602060405180830381865afa158015611af0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b149190613e36565b611b5557806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b4c91906132d2565b60405180910390fd5b5b50565b5f611b63826112a6565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bca906140e6565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16611bf2611d31565b73ffffffffffffffffffffffffffffffffffffffff161480611c215750611c2081611c1b611d31565b61187c565b5b611c60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5790614174565b60405180910390fd5b611c6a83836120c7565b505050565b638b78c6d819543314611c89576382b429005f526004601cfd5b565b611c9c611c96611d31565b82611dc4565b611cdb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd290613fc7565b60405180910390fd5b611ce683838361217d565b505050565b5f6202a300905090565b611d0e828260405180602001604052805f815250612469565b5050565b611d2c83838360405180602001604052805f815250611633565b505050565b5f33905090565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b638b78c6d8198160601b60601c91508181547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a38181555050565b611dc0611db9611d31565b83836124c3565b5050565b5f80611dcf836112a6565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e115750611e10818561187c565b5b80611e4f57508373ffffffffffffffffffffffffffffffffffffffff16611e3784610a0d565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b611e6384848461217d565b611e6f8484848461262a565b611eae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea590614202565b60405180910390fd5b50505050565b6060600c8054611ec3906138af565b80601f0160208091040260200160405190810160405280929190818152602001828054611eef906138af565b8015611f3a5780601f10611f1157610100808354040283529160200191611f3a565b820191905f5260205f20905b815481529060010190602001808311611f1d57829003601f168201915b5050505050905090565b60605f6001611f52846127ac565b0190505f8167ffffffffffffffff811115611f7057611f6f613553565b5b6040519080825280601f01601f191660200182016040528015611fa25781602001600182028036833780820191505090505b5090505f82602001820190505b600115612003578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611ff857611ff7613d9e565b5b0494505f8503611faf575b819350505050919050565b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612080575061207f826128fd565b5b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff166120a883611d38565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b8160045f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612137836112a6565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b8273ffffffffffffffffffffffffffffffffffffffff1661219d826112a6565b73ffffffffffffffffffffffffffffffffffffffff16146121f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ea90614290565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612261576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122589061431e565b60405180910390fd5b61226e83838360016129de565b8273ffffffffffffffffffffffffffffffffffffffff1661228e826112a6565b73ffffffffffffffffffffffffffffffffffffffff16146122e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122db90614290565b60405180910390fd5b60045f8281526020019081526020015f205f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600160035f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540392505081905550600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461246483838360016129f0565b505050565b61247383836129f6565b61247f5f84848461262a565b6124be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b590614202565b60405180910390fd5b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612531576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252890614386565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161261d9190613172565b60405180910390a3505050565b5f61264a8473ffffffffffffffffffffffffffffffffffffffff16612c09565b1561279f578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612673611d31565b8786866040518563ffffffff1660e01b815260040161269594939291906143f6565b6020604051808303815f875af19250505080156126d057506040513d601f19601f820116820180604052508101906126cd9190614454565b60015b61274f573d805f81146126fe576040519150601f19603f3d011682016040523d82523d5f602084013e612703565b606091505b505f815103612747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161273e90614202565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506127a4565b600190505b949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612808577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816127fe576127fd613d9e565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612845576d04ee2d6d415b85acef8100000000838161283b5761283a613d9e565b5b0492506020810190505b662386f26fc10000831061287457662386f26fc10000838161286a57612869613d9e565b5b0492506010810190505b6305f5e100831061289d576305f5e100838161289357612892613d9e565b5b0492506008810190505b61271083106128c25761271083816128b8576128b7613d9e565b5b0492506004810190505b606483106128e557606483816128db576128da613d9e565b5b0492506002810190505b600a83106128f4576001810190505b80915050919050565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806129c757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806129d757506129d682612c2b565b5b9050919050565b6129ea84848484612c94565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612a64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a5b906144c9565b60405180910390fd5b612a6d81612087565b15612aad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aa490614531565b60405180910390fd5b612aba5f838360016129de565b612ac381612087565b15612b03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612afa90614531565b60405180910390fd5b600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612c055f838360016129f0565b5050565b5f808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612ca084848484612def565b6001811115612ce4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdb906145bf565b60405180910390fd5b5f8290505f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d2957612d2481612df5565b612d68565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612d6757612d668582612e39565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612da957612da481612f8f565b612de8565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612de757612de6848261304f565b5b5b5050505050565b50505050565b60088054905060095f8381526020019081526020015f2081905550600881908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f6001612e458461132a565b612e4f9190613d6b565b90505f60075f8481526020019081526020015f20549050818114612f26575f60065f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205490508060065f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f20819055508160075f8381526020019081526020015f2081905550505b60075f8481526020019081526020015f205f905560065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f905550505050565b5f6001600880549050612fa29190613d6b565b90505f60095f8481526020019081526020015f205490505f60088381548110612fce57612fcd6139db565b5b905f5260205f20015490508060088381548110612fee57612fed6139db565b5b905f5260205f2001819055508160095f8381526020019081526020015f208190555060095f8581526020019081526020015f205f90556008805480613036576130356145dd565b5b600190038181905f5260205f20015f9055905550505050565b5f6130598361132a565b90508160065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060075f8481526020019081526020015f2081905550505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61310c816130d8565b8114613116575f80fd5b50565b5f8135905061312781613103565b92915050565b5f60208284031215613142576131416130d0565b5b5f61314f84828501613119565b91505092915050565b5f8115159050919050565b61316c81613158565b82525050565b5f6020820190506131855f830184613163565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156131c25780820151818401526020810190506131a7565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6131e78261318b565b6131f18185613195565b93506132018185602086016131a5565b61320a816131cd565b840191505092915050565b5f6020820190508181035f83015261322d81846131dd565b905092915050565b5f819050919050565b61324781613235565b8114613251575f80fd5b50565b5f813590506132628161323e565b92915050565b5f6020828403121561327d5761327c6130d0565b5b5f61328a84828501613254565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6132bc82613293565b9050919050565b6132cc816132b2565b82525050565b5f6020820190506132e55f8301846132c3565b92915050565b5f819050919050565b5f61330e61330961330484613293565b6132eb565b613293565b9050919050565b5f61331f826132f4565b9050919050565b5f61333082613315565b9050919050565b61334081613326565b82525050565b5f6020820190506133595f830184613337565b92915050565b613368816132b2565b8114613372575f80fd5b50565b5f813590506133838161335f565b92915050565b5f806040838503121561339f5761339e6130d0565b5b5f6133ac85828601613375565b92505060206133bd85828601613254565b9150509250929050565b6133d081613235565b82525050565b5f6020820190506133e95f8301846133c7565b92915050565b5f60208284031215613404576134036130d0565b5b5f61341184828501613375565b91505092915050565b5f805f60608486031215613431576134306130d0565b5b5f61343e86828701613375565b935050602061344f86828701613375565b925050604061346086828701613254565b9150509250925092565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261348b5761348a61346a565b5b8235905067ffffffffffffffff8111156134a8576134a761346e565b5b6020830191508360208202830111156134c4576134c3613472565b5b9250929050565b5f80602083850312156134e1576134e06130d0565b5b5f83013567ffffffffffffffff8111156134fe576134fd6130d4565b5b61350a85828601613476565b92509250509250929050565b5f61352082613315565b9050919050565b61353081613516565b82525050565b5f6020820190506135495f830184613527565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b613589826131cd565b810181811067ffffffffffffffff821117156135a8576135a7613553565b5b80604052505050565b5f6135ba6130c7565b90506135c68282613580565b919050565b5f67ffffffffffffffff8211156135e5576135e4613553565b5b6135ee826131cd565b9050602081019050919050565b828183375f83830152505050565b5f61361b613616846135cb565b6135b1565b9050828152602081018484840111156136375761363661354f565b5b6136428482856135fb565b509392505050565b5f82601f83011261365e5761365d61346a565b5b813561366e848260208601613609565b91505092915050565b5f6020828403121561368c5761368b6130d0565b5b5f82013567ffffffffffffffff8111156136a9576136a86130d4565b5b6136b58482850161364a565b91505092915050565b6136c781613158565b81146136d1575f80fd5b50565b5f813590506136e2816136be565b92915050565b5f80604083850312156136fe576136fd6130d0565b5b5f61370b85828601613375565b925050602061371c858286016136d4565b9150509250929050565b5f67ffffffffffffffff8211156137405761373f613553565b5b613749826131cd565b9050602081019050919050565b5f61376861376384613726565b6135b1565b9050828152602081018484840111156137845761378361354f565b5b61378f8482856135fb565b509392505050565b5f82601f8301126137ab576137aa61346a565b5b81356137bb848260208601613756565b91505092915050565b5f805f80608085870312156137dc576137db6130d0565b5b5f6137e987828801613375565b94505060206137fa87828801613375565b935050604061380b87828801613254565b925050606085013567ffffffffffffffff81111561382c5761382b6130d4565b5b61383887828801613797565b91505092959194509250565b5f806040838503121561385a576138596130d0565b5b5f61386785828601613375565b925050602061387885828601613375565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806138c657607f821691505b6020821081036138d9576138d8613882565b5b50919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f755f8201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b5f613939602b83613195565b9150613944826138df565b604082019050919050565b5f6020820190508181035f8301526139668161392d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6139a482613235565b91506139af83613235565b92508282026139bd81613235565b915082820484148315176139d4576139d361396d565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050613a168161335f565b92915050565b5f60208284031215613a3157613a306130d0565b5b5f613a3e84828501613a08565b91505092915050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f5f8201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b5f613aa1602c83613195565b9150613aac82613a47565b604082019050919050565b5f6020820190508181035f830152613ace81613a95565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302613b317fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613af6565b613b3b8683613af6565b95508019841693508086168417925050509392505050565b5f613b6d613b68613b6384613235565b6132eb565b613235565b9050919050565b5f819050919050565b613b8683613b53565b613b9a613b9282613b74565b848454613b02565b825550505050565b5f90565b613bae613ba2565b613bb9818484613b7d565b505050565b5b81811015613bdc57613bd15f82613ba6565b600181019050613bbf565b5050565b601f821115613c2157613bf281613ad5565b613bfb84613ae7565b81016020851015613c0a578190505b613c1e613c1685613ae7565b830182613bbe565b50505b505050565b5f82821c905092915050565b5f613c415f1984600802613c26565b1980831691505092915050565b5f613c598383613c32565b9150826002028217905092915050565b613c728261318b565b67ffffffffffffffff811115613c8b57613c8a613553565b5b613c9582546138af565b613ca0828285613be0565b5f60209050601f831160018114613cd1575f8415613cbf578287015190505b613cc98582613c4e565b865550613d30565b601f198416613cdf86613ad5565b5f5b82811015613d0657848901518255600182019150602085019450602081019050613ce1565b86831015613d235784890151613d1f601f891682613c32565b8355505b6001600288020188555050505b505050505050565b5f613d4282613235565b9150613d4d83613235565b9250828201905080821115613d6557613d6461396d565b5b92915050565b5f613d7582613235565b9150613d8083613235565b9250828203905081811115613d9857613d9761396d565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f613dd582613235565b9150613de083613235565b925082613df057613def613d9e565b5b828204905092915050565b5f604082019050613e0e5f8301856132c3565b613e1b60208301846133c7565b9392505050565b5f81519050613e30816136be565b92915050565b5f60208284031215613e4b57613e4a6130d0565b5b5f613e5884828501613e22565b91505092915050565b7f4552433732313a20696e76616c696420746f6b656e20494400000000000000005f82015250565b5f613e95601883613195565b9150613ea082613e61565b602082019050919050565b5f6020820190508181035f830152613ec281613e89565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f7420612076615f8201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b5f613f23602983613195565b9150613f2e82613ec9565b604082019050919050565b5f6020820190508181035f830152613f5081613f17565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e655f8201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b5f613fb1602d83613195565b9150613fbc82613f57565b604082019050919050565b5f6020820190508181035f830152613fde81613fa5565b9050919050565b5f81905092915050565b5f613ff98261318b565b6140038185613fe5565b93506140138185602086016131a5565b80840191505092915050565b5f61402a8286613fef565b91506140368285613fef565b91506140428284613fef565b9150819050949350505050565b5f6040820190506140625f8301856132c3565b61406f60208301846132c3565b9392505050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e655f8201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b5f6140d0602183613195565b91506140db82614076565b604082019050919050565b5f6020820190508181035f8301526140fd816140c4565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f5f8201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b5f61415e603d83613195565b915061416982614104565b604082019050919050565b5f6020820190508181035f83015261418b81614152565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e2045524337323152655f8201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b5f6141ec603283613195565b91506141f782614192565b604082019050919050565b5f6020820190508181035f830152614219816141e0565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f7272656374205f8201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b5f61427a602583613195565b915061428582614220565b604082019050919050565b5f6020820190508181035f8301526142a78161426e565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f614308602483613195565b9150614313826142ae565b604082019050919050565b5f6020820190508181035f830152614335816142fc565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c6572000000000000005f82015250565b5f614370601983613195565b915061437b8261433c565b602082019050919050565b5f6020820190508181035f83015261439d81614364565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6143c8826143a4565b6143d281856143ae565b93506143e28185602086016131a5565b6143eb816131cd565b840191505092915050565b5f6080820190506144095f8301876132c3565b61441660208301866132c3565b61442360408301856133c7565b818103606083015261443581846143be565b905095945050505050565b5f8151905061444e81613103565b92915050565b5f60208284031215614469576144686130d0565b5b5f61447684828501614440565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f20616464726573735f82015250565b5f6144b3602083613195565b91506144be8261447f565b602082019050919050565b5f6020820190508181035f8301526144e0816144a7565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e746564000000005f82015250565b5f61451b601c83613195565b9150614526826144e7565b602082019050919050565b5f6020820190508181035f8301526145488161450f565b9050919050565b7f455243373231456e756d657261626c653a20636f6e73656375746976652074725f8201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b5f6145a9603583613195565b91506145b48261454f565b604082019050919050565b5f6020820190508181035f8301526145d68161459d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220b33bbdf69fe3fc3dffa8908864c177301ae8d1fb98204f8b3567fee043a3db2764736f6c63430008150033697066733a2f2f516d594a47456f61337a524e4d56464c735263677a584e4e5133673248735151656970534c4673746976573468422f
Deployed Bytecode
0x60806040526004361061025b575f3560e01c80636352211e11610143578063c60360f7116100b5578063e985e9c511610079578063e985e9c514610845578063eca30a4114610881578063ef5d9ae8146108bd578063f04e283e146108f9578063f2fde38b14610915578063fee81cf4146109315761025b565b8063c60360f71461074f578063c668286214610779578063c67c74d4146107a3578063c87b56dd146107cd578063e5267d17146108095761025b565b80638da5cb5b116101075780638da5cb5b1461065757806395d89b41146106815780639abc8320146106ab5780639ced0e9b146106d5578063a22cb465146106ff578063b88d4fde146107275761025b565b80636352211e1461059757806370a08231146105d3578063715018a61461060f5780637e082c16146106195780638c1ceda51461062f5761025b565b80632f745c59116101dc57806342842e0e116101a057806342842e0e146104c35780634f6ccce7146104eb57806351f468c01461052757806354d1f13d1461054f57806355f804b3146105595780635e08dff6146105815761025b565b80632f745c59146104015780633745ee951461043d578063381b1e5d14610467578063398280eb1461048357806341f43434146104995761025b565b806315d655c91161022357806315d655c91461035357806317d819d01461037d57806318160ddd146103a557806323b872dd146103cf57806325692962146103f75761025b565b806301ffc9a71461025f57806306fdde031461029b578063081812fc146102c557806308e0415814610301578063095ea7b31461032b575b5f80fd5b34801561026a575f80fd5b506102856004803603810190610280919061312d565b61096d565b6040516102929190613172565b60405180910390f35b3480156102a6575f80fd5b506102af61097e565b6040516102bc9190613215565b60405180910390f35b3480156102d0575f80fd5b506102eb60048036038101906102e69190613268565b610a0d565b6040516102f891906132d2565b60405180910390f35b34801561030c575f80fd5b50610315610a4f565b6040516103229190613346565b60405180910390f35b348015610336575f80fd5b50610351600480360381019061034c9190613389565b610a74565b005b34801561035e575f80fd5b50610367610a8d565b60405161037491906133d6565b60405180910390f35b348015610388575f80fd5b506103a3600480360381019061039e91906133ef565b610a93565b005b3480156103b0575f80fd5b506103b9610ade565b6040516103c691906133d6565b60405180910390f35b3480156103da575f80fd5b506103f560048036038101906103f0919061341a565b610aea565b005b6103ff610b39565b005b34801561040c575f80fd5b5061042760048036038101906104229190613389565b610b8a565b60405161043491906133d6565b60405180910390f35b348015610448575f80fd5b50610451610c2a565b60405161045e91906132d2565b60405180910390f35b610481600480360381019061047c91906134cb565b610c42565b005b34801561048e575f80fd5b50610497610e1b565b005b3480156104a4575f80fd5b506104ad610e4d565b6040516104ba9190613536565b60405180910390f35b3480156104ce575f80fd5b506104e960048036038101906104e4919061341a565b610e5f565b005b3480156104f6575f80fd5b50610511600480360381019061050c9190613268565b610eae565b60405161051e91906133d6565b60405180910390f35b348015610532575f80fd5b5061054d60048036038101906105489190613268565b610f1c565b005b610557610f2e565b005b348015610564575f80fd5b5061057f600480360381019061057a9190613677565b610f67565b005b34801561058c575f80fd5b50610595610f82565b005b3480156105a2575f80fd5b506105bd60048036038101906105b89190613268565b6112a6565b6040516105ca91906132d2565b60405180910390f35b3480156105de575f80fd5b506105f960048036038101906105f491906133ef565b61132a565b60405161060691906133d6565b60405180910390f35b6106176113de565b005b348015610624575f80fd5b5061062d6113f1565b005b34801561063a575f80fd5b5061065560048036038101906106509190613268565b611425565b005b348015610662575f80fd5b5061066b6114cd565b60405161067891906132d2565b60405180910390f35b34801561068c575f80fd5b506106956114da565b6040516106a29190613215565b60405180910390f35b3480156106b6575f80fd5b506106bf61156a565b6040516106cc9190613215565b60405180910390f35b3480156106e0575f80fd5b506106e96115f6565b6040516106f691906133d6565b60405180910390f35b34801561070a575f80fd5b50610725600480360381019061072091906136e8565b61161a565b005b348015610732575f80fd5b5061074d600480360381019061074891906137c4565b611633565b005b34801561075a575f80fd5b50610763611695565b6040516107709190613172565b60405180910390f35b348015610784575f80fd5b5061078d6116a8565b60405161079a9190613215565b60405180910390f35b3480156107ae575f80fd5b506107b76116e1565b6040516107c49190613172565b60405180910390f35b3480156107d8575f80fd5b506107f360048036038101906107ee9190613268565b6116f3565b6040516108009190613215565b60405180910390f35b348015610814575f80fd5b5061082f600480360381019061082a91906133ef565b611764565b60405161083c91906133d6565b60405180910390f35b348015610850575f80fd5b5061086b60048036038101906108669190613844565b61187c565b6040516108789190613172565b60405180910390f35b34801561088c575f80fd5b506108a760048036038101906108a291906133ef565b61190a565b6040516108b491906133d6565b60405180910390f35b3480156108c8575f80fd5b506108e360048036038101906108de91906133ef565b61191f565b6040516108f091906133d6565b60405180910390f35b610913600480360381019061090e91906133ef565b611934565b005b61092f600480360381019061092a91906133ef565b611972565b005b34801561093c575f80fd5b50610957600480360381019061095291906133ef565b61199b565b60405161096491906133d6565b60405180910390f35b5f610977826119b4565b9050919050565b60605f805461098c906138af565b80601f01602080910402602001604051908101604052809291908181526020018280546109b8906138af565b8015610a035780601f106109da57610100808354040283529160200191610a03565b820191905f5260205f20905b8154815290600101906020018083116109e657829003601f168201915b5050505050905090565b5f610a1782611a14565b60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b81610a7e81611a5f565b610a888383611b59565b505050565b600d5481565b610a9b611c6f565b80600e5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f600880549050905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b2857610b2733611a5f565b5b610b33848484611c8b565b50505050565b5f610b42611ceb565b67ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b5f610b948361132a565b8210610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcc9061394f565b60405180910390fd5b60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b73565abc3feaa3bc3820b83620f4bbf16b5c4d47a381565b600b5f9054906101000a900460ff16610c87576040517f80cb55e200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34600d5483839050610c99919061399a565b14610cd0576040517f313223b900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5b82829050811015610e16573373ffffffffffffffffffffffffffffffffffffffff1673565abc3feaa3bc3820b83620f4bbf16b5c4d47a373ffffffffffffffffffffffffffffffffffffffff16636352211e858585818110610d3757610d366139db565b5b905060200201356040518263ffffffff1660e01b8152600401610d5a91906133d6565b602060405180830381865afa158015610d75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d999190613a1c565b73ffffffffffffffffffffffffffffffffffffffff1614610de6576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e0933848484818110610dfd57610dfc6139db565b5b90506020020135611cf5565b8080600101915050610cd2565b505050565b610e23611c6f565b600b5f9054906101000a900460ff1615600b5f6101000a81548160ff021916908315150217905550565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e9d57610e9c33611a5f565b5b610ea8848484611d12565b50505050565b5f610eb7610ade565b8210610ef8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eef90613ab7565b60405180910390fd5b60088281548110610f0c57610f0b6139db565b5b905f5260205f2001549050919050565b610f24611c6f565b80600d8190555050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b610f6f611c6f565b80600c9081610f7e9190613c69565b5050565b600b60019054906101000a900460ff16610fc8576040517f24fbaa9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610fd9610fd4611d31565b61132a565b90505f8103611014576040517fbe7538fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8060105f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f4290505f82146110d6578062015180836110719190613d38565b11156110a9576040517f748614c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056201518083836110bb9190613d6b565b6110c59190613dcb565b6110cf919061399a565b925061111f565b6005620151807f0000000000000000000000000000000000000000000000000000000064f1133b836111089190613d6b565b6111129190613dcb565b61111c919061399a565b92505b8060105f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055505f848461116e919061399a565b905080600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33670de0b6b3a76400008461120c919061399a565b6040518363ffffffff1660e01b8152600401611229929190613dfb565b6020604051808303815f875af1158015611245573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112699190613e36565b61129f576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b5f806112b183611d38565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611321576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131890613eab565b60405180910390fd5b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611399576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139090613f39565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6113e6611c6f565b6113ef5f611d71565b565b6113f9611c6f565b600b60019054906101000a900460ff1615600b60016101000a81548160ff021916908315150217905550565b61142d611c6f565b600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401611489929190613dfb565b6020604051808303815f875af11580156114a5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114c99190613e36565b5050565b5f638b78c6d81954905090565b6060600180546114e9906138af565b80601f0160208091040260200160405190810160405280929190818152602001828054611515906138af565b80156115605780601f1061153757610100808354040283529160200191611560565b820191905f5260205f20905b81548152906001019060200180831161154357829003601f168201915b5050505050905090565b600c8054611577906138af565b80601f01602080910402602001604051908101604052809291908181526020018280546115a3906138af565b80156115ee5780601f106115c5576101008083540402835291602001916115ee565b820191905f5260205f20905b8154815290600101906020018083116115d157829003601f168201915b505050505081565b7f0000000000000000000000000000000000000000000000000000000064f1133b81565b8161162481611a5f565b61162e8383611dae565b505050565b61164461163e611d31565b83611dc4565b611683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167a90613fc7565b60405180910390fd5b61168f84848484611e58565b50505050565b600b60019054906101000a900460ff1681565b6040518060400160405280600581526020017f2e6a736f6e00000000000000000000000000000000000000000000000000000081525081565b600b5f9054906101000a900460ff1681565b60606116fd611eb4565b61170683611f44565b6040518060400160405280600581526020017f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060405160200161174e9392919061401f565b6040516020818303038152906040529050919050565b5f80611776611771611d31565b61132a565b90505f4290505f820361178d575f92505050611877565b5f8060105f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f81146118035760056201518082856117e89190613d6b565b6117f29190613dcb565b6117fc919061399a565b915061184c565b6005620151807f0000000000000000000000000000000000000000000000000000000064f1133b856118359190613d6b565b61183f9190613dcb565b611849919061399a565b91505b5f8483611859919061399a565b9050670de0b6b3a76400008161186f919061399a565b955050505050505b919050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6010602052805f5260405f205f915090505481565b600f602052805f5260405f205f915090505481565b61193c611c6f565b63389a75e1600c52805f526020600c20805442111561196257636f5e88185f526004601cfd5b5f81555061196f81611d71565b50565b61197a611c6f565b8060601b61198f57637448fbae5f526004601cfd5b61199881611d71565b50565b5f63389a75e1600c52815f526020600c20549050919050565b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a0d5750611a0c8261200e565b5b9050919050565b611a1d81612087565b611a5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5390613eab565b60405180910390fd5b50565b5f6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611b56576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611ad592919061404f565b602060405180830381865afa158015611af0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b149190613e36565b611b5557806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b4c91906132d2565b60405180910390fd5b5b50565b5f611b63826112a6565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bca906140e6565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16611bf2611d31565b73ffffffffffffffffffffffffffffffffffffffff161480611c215750611c2081611c1b611d31565b61187c565b5b611c60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5790614174565b60405180910390fd5b611c6a83836120c7565b505050565b638b78c6d819543314611c89576382b429005f526004601cfd5b565b611c9c611c96611d31565b82611dc4565b611cdb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd290613fc7565b60405180910390fd5b611ce683838361217d565b505050565b5f6202a300905090565b611d0e828260405180602001604052805f815250612469565b5050565b611d2c83838360405180602001604052805f815250611633565b505050565b5f33905090565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b638b78c6d8198160601b60601c91508181547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a38181555050565b611dc0611db9611d31565b83836124c3565b5050565b5f80611dcf836112a6565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e115750611e10818561187c565b5b80611e4f57508373ffffffffffffffffffffffffffffffffffffffff16611e3784610a0d565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b611e6384848461217d565b611e6f8484848461262a565b611eae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea590614202565b60405180910390fd5b50505050565b6060600c8054611ec3906138af565b80601f0160208091040260200160405190810160405280929190818152602001828054611eef906138af565b8015611f3a5780601f10611f1157610100808354040283529160200191611f3a565b820191905f5260205f20905b815481529060010190602001808311611f1d57829003601f168201915b5050505050905090565b60605f6001611f52846127ac565b0190505f8167ffffffffffffffff811115611f7057611f6f613553565b5b6040519080825280601f01601f191660200182016040528015611fa25781602001600182028036833780820191505090505b5090505f82602001820190505b600115612003578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611ff857611ff7613d9e565b5b0494505f8503611faf575b819350505050919050565b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612080575061207f826128fd565b5b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff166120a883611d38565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b8160045f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612137836112a6565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b8273ffffffffffffffffffffffffffffffffffffffff1661219d826112a6565b73ffffffffffffffffffffffffffffffffffffffff16146121f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ea90614290565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612261576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122589061431e565b60405180910390fd5b61226e83838360016129de565b8273ffffffffffffffffffffffffffffffffffffffff1661228e826112a6565b73ffffffffffffffffffffffffffffffffffffffff16146122e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122db90614290565b60405180910390fd5b60045f8281526020019081526020015f205f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600160035f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540392505081905550600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461246483838360016129f0565b505050565b61247383836129f6565b61247f5f84848461262a565b6124be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b590614202565b60405180910390fd5b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612531576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252890614386565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161261d9190613172565b60405180910390a3505050565b5f61264a8473ffffffffffffffffffffffffffffffffffffffff16612c09565b1561279f578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612673611d31565b8786866040518563ffffffff1660e01b815260040161269594939291906143f6565b6020604051808303815f875af19250505080156126d057506040513d601f19601f820116820180604052508101906126cd9190614454565b60015b61274f573d805f81146126fe576040519150601f19603f3d011682016040523d82523d5f602084013e612703565b606091505b505f815103612747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161273e90614202565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506127a4565b600190505b949350505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612808577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816127fe576127fd613d9e565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612845576d04ee2d6d415b85acef8100000000838161283b5761283a613d9e565b5b0492506020810190505b662386f26fc10000831061287457662386f26fc10000838161286a57612869613d9e565b5b0492506010810190505b6305f5e100831061289d576305f5e100838161289357612892613d9e565b5b0492506008810190505b61271083106128c25761271083816128b8576128b7613d9e565b5b0492506004810190505b606483106128e557606483816128db576128da613d9e565b5b0492506002810190505b600a83106128f4576001810190505b80915050919050565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806129c757507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806129d757506129d682612c2b565b5b9050919050565b6129ea84848484612c94565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612a64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a5b906144c9565b60405180910390fd5b612a6d81612087565b15612aad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aa490614531565b60405180910390fd5b612aba5f838360016129de565b612ac381612087565b15612b03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612afa90614531565b60405180910390fd5b600160035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508160025f8381526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612c055f838360016129f0565b5050565b5f808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612ca084848484612def565b6001811115612ce4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cdb906145bf565b60405180910390fd5b5f8290505f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612d2957612d2481612df5565b612d68565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612d6757612d668582612e39565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612da957612da481612f8f565b612de8565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612de757612de6848261304f565b5b5b5050505050565b50505050565b60088054905060095f8381526020019081526020015f2081905550600881908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f6001612e458461132a565b612e4f9190613d6b565b90505f60075f8481526020019081526020015f20549050818114612f26575f60065f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205490508060065f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f20819055508160075f8381526020019081526020015f2081905550505b60075f8481526020019081526020015f205f905560065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f905550505050565b5f6001600880549050612fa29190613d6b565b90505f60095f8481526020019081526020015f205490505f60088381548110612fce57612fcd6139db565b5b905f5260205f20015490508060088381548110612fee57612fed6139db565b5b905f5260205f2001819055508160095f8381526020019081526020015f208190555060095f8581526020019081526020015f205f90556008805480613036576130356145dd565b5b600190038181905f5260205f20015f9055905550505050565b5f6130598361132a565b90508160065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060075f8481526020019081526020015f2081905550505050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61310c816130d8565b8114613116575f80fd5b50565b5f8135905061312781613103565b92915050565b5f60208284031215613142576131416130d0565b5b5f61314f84828501613119565b91505092915050565b5f8115159050919050565b61316c81613158565b82525050565b5f6020820190506131855f830184613163565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156131c25780820151818401526020810190506131a7565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6131e78261318b565b6131f18185613195565b93506132018185602086016131a5565b61320a816131cd565b840191505092915050565b5f6020820190508181035f83015261322d81846131dd565b905092915050565b5f819050919050565b61324781613235565b8114613251575f80fd5b50565b5f813590506132628161323e565b92915050565b5f6020828403121561327d5761327c6130d0565b5b5f61328a84828501613254565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6132bc82613293565b9050919050565b6132cc816132b2565b82525050565b5f6020820190506132e55f8301846132c3565b92915050565b5f819050919050565b5f61330e61330961330484613293565b6132eb565b613293565b9050919050565b5f61331f826132f4565b9050919050565b5f61333082613315565b9050919050565b61334081613326565b82525050565b5f6020820190506133595f830184613337565b92915050565b613368816132b2565b8114613372575f80fd5b50565b5f813590506133838161335f565b92915050565b5f806040838503121561339f5761339e6130d0565b5b5f6133ac85828601613375565b92505060206133bd85828601613254565b9150509250929050565b6133d081613235565b82525050565b5f6020820190506133e95f8301846133c7565b92915050565b5f60208284031215613404576134036130d0565b5b5f61341184828501613375565b91505092915050565b5f805f60608486031215613431576134306130d0565b5b5f61343e86828701613375565b935050602061344f86828701613375565b925050604061346086828701613254565b9150509250925092565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261348b5761348a61346a565b5b8235905067ffffffffffffffff8111156134a8576134a761346e565b5b6020830191508360208202830111156134c4576134c3613472565b5b9250929050565b5f80602083850312156134e1576134e06130d0565b5b5f83013567ffffffffffffffff8111156134fe576134fd6130d4565b5b61350a85828601613476565b92509250509250929050565b5f61352082613315565b9050919050565b61353081613516565b82525050565b5f6020820190506135495f830184613527565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b613589826131cd565b810181811067ffffffffffffffff821117156135a8576135a7613553565b5b80604052505050565b5f6135ba6130c7565b90506135c68282613580565b919050565b5f67ffffffffffffffff8211156135e5576135e4613553565b5b6135ee826131cd565b9050602081019050919050565b828183375f83830152505050565b5f61361b613616846135cb565b6135b1565b9050828152602081018484840111156136375761363661354f565b5b6136428482856135fb565b509392505050565b5f82601f83011261365e5761365d61346a565b5b813561366e848260208601613609565b91505092915050565b5f6020828403121561368c5761368b6130d0565b5b5f82013567ffffffffffffffff8111156136a9576136a86130d4565b5b6136b58482850161364a565b91505092915050565b6136c781613158565b81146136d1575f80fd5b50565b5f813590506136e2816136be565b92915050565b5f80604083850312156136fe576136fd6130d0565b5b5f61370b85828601613375565b925050602061371c858286016136d4565b9150509250929050565b5f67ffffffffffffffff8211156137405761373f613553565b5b613749826131cd565b9050602081019050919050565b5f61376861376384613726565b6135b1565b9050828152602081018484840111156137845761378361354f565b5b61378f8482856135fb565b509392505050565b5f82601f8301126137ab576137aa61346a565b5b81356137bb848260208601613756565b91505092915050565b5f805f80608085870312156137dc576137db6130d0565b5b5f6137e987828801613375565b94505060206137fa87828801613375565b935050604061380b87828801613254565b925050606085013567ffffffffffffffff81111561382c5761382b6130d4565b5b61383887828801613797565b91505092959194509250565b5f806040838503121561385a576138596130d0565b5b5f61386785828601613375565b925050602061387885828601613375565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806138c657607f821691505b6020821081036138d9576138d8613882565b5b50919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f755f8201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b5f613939602b83613195565b9150613944826138df565b604082019050919050565b5f6020820190508181035f8301526139668161392d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6139a482613235565b91506139af83613235565b92508282026139bd81613235565b915082820484148315176139d4576139d361396d565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050613a168161335f565b92915050565b5f60208284031215613a3157613a306130d0565b5b5f613a3e84828501613a08565b91505092915050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f5f8201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b5f613aa1602c83613195565b9150613aac82613a47565b604082019050919050565b5f6020820190508181035f830152613ace81613a95565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302613b317fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613af6565b613b3b8683613af6565b95508019841693508086168417925050509392505050565b5f613b6d613b68613b6384613235565b6132eb565b613235565b9050919050565b5f819050919050565b613b8683613b53565b613b9a613b9282613b74565b848454613b02565b825550505050565b5f90565b613bae613ba2565b613bb9818484613b7d565b505050565b5b81811015613bdc57613bd15f82613ba6565b600181019050613bbf565b5050565b601f821115613c2157613bf281613ad5565b613bfb84613ae7565b81016020851015613c0a578190505b613c1e613c1685613ae7565b830182613bbe565b50505b505050565b5f82821c905092915050565b5f613c415f1984600802613c26565b1980831691505092915050565b5f613c598383613c32565b9150826002028217905092915050565b613c728261318b565b67ffffffffffffffff811115613c8b57613c8a613553565b5b613c9582546138af565b613ca0828285613be0565b5f60209050601f831160018114613cd1575f8415613cbf578287015190505b613cc98582613c4e565b865550613d30565b601f198416613cdf86613ad5565b5f5b82811015613d0657848901518255600182019150602085019450602081019050613ce1565b86831015613d235784890151613d1f601f891682613c32565b8355505b6001600288020188555050505b505050505050565b5f613d4282613235565b9150613d4d83613235565b9250828201905080821115613d6557613d6461396d565b5b92915050565b5f613d7582613235565b9150613d8083613235565b9250828203905081811115613d9857613d9761396d565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f613dd582613235565b9150613de083613235565b925082613df057613def613d9e565b5b828204905092915050565b5f604082019050613e0e5f8301856132c3565b613e1b60208301846133c7565b9392505050565b5f81519050613e30816136be565b92915050565b5f60208284031215613e4b57613e4a6130d0565b5b5f613e5884828501613e22565b91505092915050565b7f4552433732313a20696e76616c696420746f6b656e20494400000000000000005f82015250565b5f613e95601883613195565b9150613ea082613e61565b602082019050919050565b5f6020820190508181035f830152613ec281613e89565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f7420612076615f8201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b5f613f23602983613195565b9150613f2e82613ec9565b604082019050919050565b5f6020820190508181035f830152613f5081613f17565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e655f8201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b5f613fb1602d83613195565b9150613fbc82613f57565b604082019050919050565b5f6020820190508181035f830152613fde81613fa5565b9050919050565b5f81905092915050565b5f613ff98261318b565b6140038185613fe5565b93506140138185602086016131a5565b80840191505092915050565b5f61402a8286613fef565b91506140368285613fef565b91506140428284613fef565b9150819050949350505050565b5f6040820190506140625f8301856132c3565b61406f60208301846132c3565b9392505050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e655f8201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b5f6140d0602183613195565b91506140db82614076565b604082019050919050565b5f6020820190508181035f8301526140fd816140c4565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f5f8201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b5f61415e603d83613195565b915061416982614104565b604082019050919050565b5f6020820190508181035f83015261418b81614152565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e2045524337323152655f8201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b5f6141ec603283613195565b91506141f782614192565b604082019050919050565b5f6020820190508181035f830152614219816141e0565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f7272656374205f8201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b5f61427a602583613195565b915061428582614220565b604082019050919050565b5f6020820190508181035f8301526142a78161426e565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f614308602483613195565b9150614313826142ae565b604082019050919050565b5f6020820190508181035f830152614335816142fc565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c6572000000000000005f82015250565b5f614370601983613195565b915061437b8261433c565b602082019050919050565b5f6020820190508181035f83015261439d81614364565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6143c8826143a4565b6143d281856143ae565b93506143e28185602086016131a5565b6143eb816131cd565b840191505092915050565b5f6080820190506144095f8301876132c3565b61441660208301866132c3565b61442360408301856133c7565b818103606083015261443581846143be565b905095945050505050565b5f8151905061444e81613103565b92915050565b5f60208284031215614469576144686130d0565b5b5f61447684828501614440565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f20616464726573735f82015250565b5f6144b3602083613195565b91506144be8261447f565b602082019050919050565b5f6020820190508181035f8301526144e0816144a7565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e746564000000005f82015250565b5f61451b601c83613195565b9150614526826144e7565b602082019050919050565b5f6020820190508181035f8301526145488161450f565b9050919050565b7f455243373231456e756d657261626c653a20636f6e73656375746976652074725f8201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b5f6145a9603583613195565b91506145b48261454f565b604082019050919050565b5f6020820190508181035f8301526145d68161459d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220b33bbdf69fe3fc3dffa8908864c177301ae8d1fb98204f8b3567fee043a3db2764736f6c63430008150033
Deployed Bytecode Sourcemap
88165:6503:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94204:230;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63479:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64991:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88655:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92467:174;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88623:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91834:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82402:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92653:180;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;18670:630;;;:::i;:::-;;82070:256;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88271:80;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89070:510;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91419:97;;;;;;;;;;;;;:::i;:::-;;7863:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92841:188;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82592:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92081:108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19385:466;;;:::i;:::-;;93588:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89644:925;;;;;;;;;;;;;:::i;:::-;;63189:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62920:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18405:102;;;:::i;:::-;;91584:103;;;;;;;;;;;;;:::i;:::-;;94553:112;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;21110:196;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63648:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88440:80;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88580:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92262:193;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66285:279;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88398:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88527:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88358:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93945:251;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90782:559;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65460:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88746:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88691:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20042:724;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17979:358;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;21412:449;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94204:230;94361:4;94390:36;94414:11;94390:23;:36::i;:::-;94383:43;;94204:230;;;:::o;63479:100::-;63533:13;63566:5;63559:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63479:100;:::o;64991:171::-;65067:7;65087:23;65102:7;65087:14;:23::i;:::-;65130:15;:24;65146:7;65130:24;;;;;;;;;;;;;;;;;;;;;65123:31;;64991:171;;;:::o;88655:23::-;;;;;;;;;;;;;:::o;92467:174::-;92580:8;9645:30;9666:8;9645:20;:30::i;:::-;92601:32:::1;92615:8;92625:7;92601:13;:32::i;:::-;92467:174:::0;;;:::o;88623:25::-;;;;:::o;91834:116::-;22258:13;:11;:13::i;:::-;91928::::1;91909:9;;:33;;;;;;;;;;;;;;;;;;91834:116:::0;:::o;82402:113::-;82463:7;82490:10;:17;;;;82483:24;;82402:113;:::o;92653:180::-;92771:4;9379:10;9371:18;;:4;:18;;;9367:83;;9406:32;9427:10;9406:20;:32::i;:::-;9367:83;92788:37:::1;92807:4;92813:2;92817:7;92788:18;:37::i;:::-;92653:180:::0;;;;:::o;18670:630::-;18765:15;18801:28;:26;:28::i;:::-;18783:46;;:15;:46;18765:64;;19001:19;18995:4;18988:33;19052:8;19046:4;19039:22;19109:7;19102:4;19096;19086:21;19079:38;19258:8;19211:45;19208:1;19205;19200:67;18901:381;18670:630::o;82070:256::-;82167:7;82203:23;82220:5;82203:16;:23::i;:::-;82195:5;:31;82187:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;82292:12;:19;82305:5;82292:19;;;;;;;;;;;;;;;:26;82312:5;82292:26;;;;;;;;;;;;82285:33;;82070:256;;;;:::o;88271:80::-;88309:42;88271:80;:::o;89070:510::-;89160:13;;;;;;;;;;;89155:38;;89182:11;;;;;;;;;;;;;;89155:38;89249:9;89235:10;;89208:17;;:24;;:37;;;;:::i;:::-;:50;89204:77;;89267:14;;;;;;;;;;;;;;89204:77;89297:9;89292:281;89312:17;;:24;;89308:1;:28;89292:281;;;89412:10;89358:64;;88309:42;89358:28;;;89387:17;;89405:1;89387:20;;;;;;;:::i;:::-;;;;;;;;89358:50;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:64;;;89354:87;;89431:10;;;;;;;;;;;;;;89354:87;89456:43;89466:10;89478:17;;89496:1;89478:20;;;;;;;:::i;:::-;;;;;;;;89456:9;:43::i;:::-;89543:3;;;;;;;89292:281;;;;89070:510;;:::o;91419:97::-;22258:13;:11;:13::i;:::-;91495::::1;;;;;;;;;;;91494:14;91478:13;;:30;;;;;;;;;;;;;;;;;;91419:97::o:0;7863:143::-;337:42;7863:143;:::o;92841:188::-;92963:4;9379:10;9371:18;;:4;:18;;;9367:83;;9406:32;9427:10;9406:20;:32::i;:::-;9367:83;92980:41:::1;93003:4;93009:2;93013:7;92980:22;:41::i;:::-;92841:188:::0;;;;:::o;82592:233::-;82667:7;82703:30;:28;:30::i;:::-;82695:5;:38;82687:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;82800:10;82811:5;82800:17;;;;;;;;:::i;:::-;;;;;;;;;;82793:24;;82592:233;;;:::o;92081:108::-;22258:13;:11;:13::i;:::-;92168::::1;92155:10;:26;;;;92081:108:::0;:::o;19385:466::-;19591:19;19585:4;19578:33;19638:8;19632:4;19625:22;19691:1;19684:4;19678;19668:21;19661:32;19824:8;19778:44;19775:1;19772;19767:66;19385:466::o;93588:104::-;22258:13;:11;:13::i;:::-;93673:11:::1;93663:7;:21;;;;;;:::i;:::-;;93588:104:::0;:::o;89644:925::-;89688:15;;;;;;;;;;;89683:45;;89712:16;;;;;;;;;;;;;;89683:45;89739:15;89757:23;89767:12;:10;:12::i;:::-;89757:9;:23::i;:::-;89739:41;;89806:1;89795:7;:12;89791:40;;89816:15;;;;;;;;;;;;;;89791:40;89852:23;89886:16;89905:17;:29;89923:10;89905:29;;;;;;;;;;;;;;;;89886:48;;89945:17;89965:15;89945:35;;90009:1;89997:8;:13;89993:265;;90051:9;90042:6;90031:8;:17;;;;:::i;:::-;:29;90027:58;;;90069:16;;;;;;;;;;;;;;90027:58;90154:1;90144:6;90132:8;90120:9;:20;;;;:::i;:::-;90119:31;;;;:::i;:::-;90118:37;;;;:::i;:::-;90100:55;;89993:265;;;90245:1;90235:6;90220:11;90208:9;:23;;;;:::i;:::-;90207:34;;;;:::i;:::-;90206:40;;;;:::i;:::-;90188:58;;89993:265;90302:9;90270:17;:29;90288:10;90270:29;;;;;;;;;;;;;;;:41;;;;90322:22;90365:7;90347:15;:25;;;;:::i;:::-;90322:50;;90436:14;90408:12;:24;90421:10;90408:24;;;;;;;;;;;;;;;;:42;;;;;;;;;;;90479:9;;;;;;;;;;;:18;;;90498:10;90527:8;90510:14;:25;;;;:::i;:::-;90479:57;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90474:87;;90545:16;;;;;;;;;;;;;;90474:87;89672:897;;;;;89644:925::o;63189:223::-;63261:7;63281:13;63297:17;63306:7;63297:8;:17::i;:::-;63281:33;;63350:1;63333:19;;:5;:19;;;63325:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;63399:5;63392:12;;;63189:223;;;:::o;62920:207::-;62992:7;63037:1;63020:19;;:5;:19;;;63012:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;63103:9;:16;63113:5;63103:16;;;;;;;;;;;;;;;;63096:23;;62920:207;;;:::o;18405:102::-;22258:13;:11;:13::i;:::-;18478:21:::1;18496:1;18478:9;:21::i;:::-;18405:102::o:0;91584:103::-;22258:13;:11;:13::i;:::-;91664:15:::1;;;;;;;;;;;91663:16;91645:15;;:34;;;;;;;;;;;;;;;;;;91584:103::o:0;94553:112::-;22258:13;:11;:13::i;:::-;94619:9:::1;;;;;;;;;;;:18;;;94638:10;94650:6;94619:38;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;94553:112:::0;:::o;21110:196::-;21156:14;21271:15;21267:20;21261:27;21251:37;;21110:196;:::o;63648:104::-;63704:13;63737:7;63730:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63648:104;:::o;88440:80::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;88580:36::-;;;:::o;92262:193::-;92383:8;9645:30;9666:8;9645:20;:30::i;:::-;92404:43:::1;92428:8;92438;92404:23;:43::i;:::-;92262:193:::0;;;:::o;66285:279::-;66416:41;66435:12;:10;:12::i;:::-;66449:7;66416:18;:41::i;:::-;66408:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;66518:38;66532:4;66538:2;66542:7;66551:4;66518:13;:38::i;:::-;66285:279;;;;:::o;88398:35::-;;;;;;;;;;;;;:::o;88527:46::-;;;;;;;;;;;;;;;;;;;:::o;88358:33::-;;;;;;;;;;;;;:::o;93945:251::-;94072:13;94134:10;:8;:10::i;:::-;94146:25;94163:7;94146:16;:25::i;:::-;94173:13;;;;;;;;;;;;;;;;;94117:70;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;94103:85;;93945:251;;;:::o;90782:559::-;90852:7;90872:15;90890:23;90900:12;:10;:12::i;:::-;90890:9;:23::i;:::-;90872:41;;90924:17;90944:15;90924:35;;90985:1;90974:7;:12;90970:26;;90995:1;90988:8;;;;;;90970:26;91007:23;91041:13;91057:17;:27;91075:8;91057:27;;;;;;;;;;;;;;;;91041:43;;91108:1;91099:5;:10;91095:142;;91162:1;91152:6;91143:5;91131:9;:17;;;;:::i;:::-;91130:28;;;;:::i;:::-;91129:34;;;;:::i;:::-;91111:52;;91095:142;;;91236:1;91226:6;91211:11;91199:9;:23;;;;:::i;:::-;91198:34;;;;:::i;:::-;91197:40;;;;:::i;:::-;91179:58;;91095:142;91250:17;91288:7;91270:15;:25;;;;:::i;:::-;91250:45;;91325:8;91313:9;:20;;;;:::i;:::-;91306:27;;;;;;;90782:559;;;;:::o;65460:164::-;65557:4;65581:18;:25;65600:5;65581:25;;;;;;;;;;;;;;;:35;65607:8;65581:35;;;;;;;;;;;;;;;;;;;;;;;;;65574:42;;65460:164;;;;:::o;88746:53::-;;;;;;;;;;;;;;;;;:::o;88691:48::-;;;;;;;;;;;;;;;;;:::o;20042:724::-;22258:13;:11;:13::i;:::-;20280:19:::1;20274:4;20267:33;20327:12;20321:4;20314:26;20390:4;20384;20374:21;20498:12;20492:19;20479:11;20476:36;20473:160;;;20545:10;20539:4;20532:24;20613:4;20607;20600:18;20473:160;20712:1;20698:12;20691:23;20196:529;20735:23;20745:12;20735:9;:23::i;:::-;20042:724:::0;:::o;17979:358::-;22258:13;:11;:13::i;:::-;18154:8:::1;18150:2;18146:17;18136:153;;18197:10;18191:4;18184:24;18269:4;18263;18256:18;18136:153;18310:19;18320:8;18310:9;:19::i;:::-;17979:358:::0;:::o;21412:449::-;21535:14;21691:19;21685:4;21678:33;21738:12;21732:4;21725:26;21837:4;21831;21821:21;21815:28;21805:38;;21412:449;;;:::o;78942:207::-;79044:4;79090:10;79083:18;;79068:33;;;:11;:33;;;;:73;;;;79105:36;79129:11;79105:23;:36::i;:::-;79068:73;79061:80;;78942:207;;;:::o;74554:135::-;74636:16;74644:7;74636;:16::i;:::-;74628:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;74554:135;:::o;9788:647::-;10027:1;337:42;9979:45;;;:49;9975:453;;;337:42;10278;;;10329:4;10336:8;10278:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10273:144;;10392:8;10373:28;;;;;;;;;;;:::i;:::-;;;;;;;;10273:144;9975:453;9788:647;:::o;64509:416::-;64590:13;64606:23;64621:7;64606:14;:23::i;:::-;64590:39;;64654:5;64648:11;;:2;:11;;;64640:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;64748:5;64732:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;64757:37;64774:5;64781:12;:10;:12::i;:::-;64757:16;:37::i;:::-;64732:62;64710:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;64896:21;64905:2;64909:7;64896:8;:21::i;:::-;64579:346;64509:416;;:::o;16891:373::-;17111:15;17107:20;17101:27;17091:8;17088:41;17078:168;;17163:10;17157:4;17150:24;17226:4;17220;17213:18;17078:168;16891:373::o;65691:301::-;65852:41;65871:12;:10;:12::i;:::-;65885:7;65852:18;:41::i;:::-;65844:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;65956:28;65966:4;65972:2;65976:7;65956:9;:28::i;:::-;65691:301;;;:::o;17500:112::-;17569:6;17595:9;17588:16;;17500:112;:::o;69160:110::-;69236:26;69246:2;69250:7;69236:26;;;;;;;;;;;;:9;:26::i;:::-;69160:110;;:::o;66063:151::-;66167:39;66184:4;66190:2;66194:7;66167:39;;;;;;;;;;;;:16;:39::i;:::-;66063:151;;;:::o;40297:98::-;40350:7;40377:10;40370:17;;40297:98;:::o;67829:117::-;67895:7;67922;:16;67930:7;67922:16;;;;;;;;;;;;;;;;;;;;;67915:23;;67829:117;;;:::o;16324:506::-;16478:15;16474:20;16577:8;16573:2;16569:17;16565:2;16561:26;16549:38;;16725:8;16713:9;16707:16;16667:38;16664:1;16661;16656:78;16803:8;16792:9;16785:27;16442:381;16324:506;:::o;65234:155::-;65329:52;65348:12;:10;:12::i;:::-;65362:8;65372;65329:18;:52::i;:::-;65234:155;;:::o;68554:264::-;68647:4;68664:13;68680:23;68695:7;68680:14;:23::i;:::-;68664:39;;68733:5;68722:16;;:7;:16;;;:52;;;;68742:32;68759:5;68766:7;68742:16;:32::i;:::-;68722:52;:87;;;;68802:7;68778:31;;:20;68790:7;68778:11;:20::i;:::-;:31;;;68722:87;68714:96;;;68554:264;;;;:::o;67445:270::-;67558:28;67568:4;67574:2;67578:7;67558:9;:28::i;:::-;67605:47;67628:4;67634:2;67638:7;67647:4;67605:22;:47::i;:::-;67597:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;67445:270;;;;:::o;93734:100::-;93786:13;93819:7;93812:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93734:100;:::o;37216:716::-;37272:13;37323:14;37360:1;37340:17;37351:5;37340:10;:17::i;:::-;:21;37323:38;;37376:20;37410:6;37399:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37376:41;;37432:11;37561:6;37557:2;37553:15;37545:6;37541:28;37534:35;;37598:288;37605:4;37598:288;;;37630:5;;;;;;;;37772:8;37767:2;37760:5;37756:14;37751:30;37746:3;37738:44;37828:2;37819:11;;;;;;:::i;:::-;;;;;37862:1;37853:5;:10;37598:288;37849:21;37598:288;37907:6;37900:13;;;;;37216:716;;;:::o;81762:224::-;81864:4;81903:35;81888:50;;;:11;:50;;;;:90;;;;81942:36;81966:11;81942:23;:36::i;:::-;81888:90;81881:97;;81762:224;;;:::o;68259:128::-;68324:4;68377:1;68348:31;;:17;68357:7;68348:8;:17::i;:::-;:31;;;;68341:38;;68259:128;;;:::o;73867:174::-;73969:2;73942:15;:24;73958:7;73942:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;74025:7;74021:2;73987:46;;73996:23;74011:7;73996:14;:23::i;:::-;73987:46;;;;;;;;;;;;73867:174;;:::o;72519:1229::-;72644:4;72617:31;;:23;72632:7;72617:14;:23::i;:::-;:31;;;72609:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;72723:1;72709:16;;:2;:16;;;72701:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;72779:42;72800:4;72806:2;72810:7;72819:1;72779:20;:42::i;:::-;72951:4;72924:31;;:23;72939:7;72924:14;:23::i;:::-;:31;;;72916:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;73069:15;:24;73085:7;73069:24;;;;;;;;;;;;73062:31;;;;;;;;;;;73564:1;73545:9;:15;73555:4;73545:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;73597:1;73580:9;:13;73590:2;73580:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;73639:2;73620:7;:16;73628:7;73620:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;73678:7;73674:2;73659:27;;73668:4;73659:27;;;;;;;;;;;;73699:41;73719:4;73725:2;73729:7;73738:1;73699:19;:41::i;:::-;72519:1229;;;:::o;69497:285::-;69592:18;69598:2;69602:7;69592:5;:18::i;:::-;69643:53;69674:1;69678:2;69682:7;69691:4;69643:22;:53::i;:::-;69621:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;69497:285;;;:::o;74184:281::-;74305:8;74296:17;;:5;:17;;;74288:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;74392:8;74354:18;:25;74373:5;74354:25;;;;;;;;;;;;;;;:35;74380:8;74354:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;74438:8;74416:41;;74431:5;74416:41;;;74448:8;74416:41;;;;;;:::i;:::-;;;;;;;;74184:281;;;:::o;75253:853::-;75407:4;75428:15;:2;:13;;;:15::i;:::-;75424:675;;;75480:2;75464:36;;;75501:12;:10;:12::i;:::-;75515:4;75521:7;75530:4;75464:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;75460:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75722:1;75705:6;:13;:18;75701:328;;75748:60;;;;;;;;;;:::i;:::-;;;;;;;;75701:328;75979:6;75973:13;75964:6;75960:2;75956:15;75949:38;75460:584;75596:41;;;75586:51;;;:6;:51;;;;75579:58;;;;;75424:675;76083:4;76076:11;;75253:853;;;;;;;:::o;34050:948::-;34103:7;34123:14;34140:1;34123:18;;34190:8;34181:5;:17;34177:106;;34228:8;34219:17;;;;;;:::i;:::-;;;;;34265:2;34255:12;;;;34177:106;34310:8;34301:5;:17;34297:106;;34348:8;34339:17;;;;;;:::i;:::-;;;;;34385:2;34375:12;;;;34297:106;34430:8;34421:5;:17;34417:106;;34468:8;34459:17;;;;;;:::i;:::-;;;;;34505:2;34495:12;;;;34417:106;34550:7;34541:5;:16;34537:103;;34587:7;34578:16;;;;;;:::i;:::-;;;;;34623:1;34613:11;;;;34537:103;34667:7;34658:5;:16;34654:103;;34704:7;34695:16;;;;;;:::i;:::-;;;;;34740:1;34730:11;;;;34654:103;34784:7;34775:5;:16;34771:103;;34821:7;34812:16;;;;;;:::i;:::-;;;;;34857:1;34847:11;;;;34771:103;34901:7;34892:5;:16;34888:68;;34939:1;34929:11;;;;34888:68;34984:6;34977:13;;;34050:948;;;:::o;62551:305::-;62653:4;62705:25;62690:40;;;:11;:40;;;;:105;;;;62762:33;62747:48;;;:11;:48;;;;62690:105;:158;;;;62812:36;62836:11;62812:23;:36::i;:::-;62690:158;62670:178;;62551:305;;;:::o;93105:234::-;93275:56;93302:4;93308:2;93312:7;93321:9;93275:26;:56::i;:::-;93105:234;;;;:::o;77676:115::-;;;;;:::o;70118:942::-;70212:1;70198:16;;:2;:16;;;70190:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;70271:16;70279:7;70271;:16::i;:::-;70270:17;70262:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;70333:48;70362:1;70366:2;70370:7;70379:1;70333:20;:48::i;:::-;70480:16;70488:7;70480;:16::i;:::-;70479:17;70471:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;70895:1;70878:9;:13;70888:2;70878:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;70939:2;70920:7;:16;70928:7;70920:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;70984:7;70980:2;70959:33;;70976:1;70959:33;;;;;;;;;;;;71005:47;71033:1;71037:2;71041:7;71050:1;71005:19;:47::i;:::-;70118:942;;:::o;41985:326::-;42045:4;42302:1;42280:7;:19;;;:23;42273:30;;41985:326;;;:::o;53131:157::-;53216:4;53255:25;53240:40;;;:11;:40;;;;53233:47;;53131:157;;;:::o;82899:915::-;83076:61;83103:4;83109:2;83113:12;83127:9;83076:26;:61::i;:::-;83166:1;83154:9;:13;83150:222;;;83297:63;;;;;;;;;;:::i;:::-;;;;;;;;83150:222;83384:15;83402:12;83384:30;;83447:1;83431:18;;:4;:18;;;83427:187;;83466:40;83498:7;83466:31;:40::i;:::-;83427:187;;;83536:2;83528:10;;:4;:10;;;83524:90;;83555:47;83588:4;83594:7;83555:32;:47::i;:::-;83524:90;83427:187;83642:1;83628:16;;:2;:16;;;83624:183;;83661:45;83698:7;83661:36;:45::i;:::-;83624:183;;;83734:4;83728:10;;:2;:10;;;83724:83;;83755:40;83783:2;83787:7;83755:27;:40::i;:::-;83724:83;83624:183;83065:749;82899:915;;;;:::o;76838:116::-;;;;;:::o;84537:164::-;84641:10;:17;;;;84614:15;:24;84630:7;84614:24;;;;;;;;;;;:44;;;;84669:10;84685:7;84669:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84537:164;:::o;85328:988::-;85594:22;85644:1;85619:22;85636:4;85619:16;:22::i;:::-;:26;;;;:::i;:::-;85594:51;;85656:18;85677:17;:26;85695:7;85677:26;;;;;;;;;;;;85656:47;;85824:14;85810:10;:28;85806:328;;85855:19;85877:12;:18;85890:4;85877:18;;;;;;;;;;;;;;;:34;85896:14;85877:34;;;;;;;;;;;;85855:56;;85961:11;85928:12;:18;85941:4;85928:18;;;;;;;;;;;;;;;:30;85947:10;85928:30;;;;;;;;;;;:44;;;;86078:10;86045:17;:30;86063:11;86045:30;;;;;;;;;;;:43;;;;85840:294;85806:328;86230:17;:26;86248:7;86230:26;;;;;;;;;;;86223:33;;;86274:12;:18;86287:4;86274:18;;;;;;;;;;;;;;;:34;86293:14;86274:34;;;;;;;;;;;86267:41;;;85409:907;;85328:988;;:::o;86611:1079::-;86864:22;86909:1;86889:10;:17;;;;:21;;;;:::i;:::-;86864:46;;86921:18;86942:15;:24;86958:7;86942:24;;;;;;;;;;;;86921:45;;87293:19;87315:10;87326:14;87315:26;;;;;;;;:::i;:::-;;;;;;;;;;87293:48;;87379:11;87354:10;87365;87354:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;87490:10;87459:15;:28;87475:11;87459:28;;;;;;;;;;;:41;;;;87631:15;:24;87647:7;87631:24;;;;;;;;;;;87624:31;;;87666:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;86682:1008;;;86611:1079;:::o;84115:221::-;84200:14;84217:20;84234:2;84217:16;:20::i;:::-;84200:37;;84275:7;84248:12;:16;84261:2;84248:16;;;;;;;;;;;;;;;:24;84265:6;84248:24;;;;;;;;;;;:34;;;;84322:6;84293:17;:26;84311:7;84293:26;;;;;;;;;;;:35;;;;84189:147;84115:221;;:::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:60::-;4165:3;4186:5;4179:12;;4137:60;;;:::o;4203:142::-;4253:9;4286:53;4304:34;4313:24;4331:5;4313:24;:::i;:::-;4304:34;:::i;:::-;4286:53;:::i;:::-;4273:66;;4203:142;;;:::o;4351:126::-;4401:9;4434:37;4465:5;4434:37;:::i;:::-;4421:50;;4351:126;;;:::o;4483:141::-;4548:9;4581:37;4612:5;4581:37;:::i;:::-;4568:50;;4483:141;;;:::o;4630:161::-;4732:52;4778:5;4732:52;:::i;:::-;4727:3;4720:65;4630:161;;:::o;4797:252::-;4905:4;4943:2;4932:9;4928:18;4920:26;;4956:86;5039:1;5028:9;5024:17;5015:6;4956:86;:::i;:::-;4797:252;;;;:::o;5055:122::-;5128:24;5146:5;5128:24;:::i;:::-;5121:5;5118:35;5108:63;;5167:1;5164;5157:12;5108:63;5055:122;:::o;5183:139::-;5229:5;5267:6;5254:20;5245:29;;5283:33;5310:5;5283:33;:::i;:::-;5183:139;;;;:::o;5328:474::-;5396:6;5404;5453:2;5441:9;5432:7;5428:23;5424:32;5421:119;;;5459:79;;:::i;:::-;5421:119;5579:1;5604:53;5649:7;5640:6;5629:9;5625:22;5604:53;:::i;:::-;5594:63;;5550:117;5706:2;5732:53;5777:7;5768:6;5757:9;5753:22;5732:53;:::i;:::-;5722:63;;5677:118;5328:474;;;;;:::o;5808:118::-;5895:24;5913:5;5895:24;:::i;:::-;5890:3;5883:37;5808:118;;:::o;5932:222::-;6025:4;6063:2;6052:9;6048:18;6040:26;;6076:71;6144:1;6133:9;6129:17;6120:6;6076:71;:::i;:::-;5932:222;;;;:::o;6160:329::-;6219:6;6268:2;6256:9;6247:7;6243:23;6239:32;6236:119;;;6274:79;;:::i;:::-;6236:119;6394:1;6419:53;6464:7;6455:6;6444:9;6440:22;6419:53;:::i;:::-;6409:63;;6365:117;6160:329;;;;:::o;6495:619::-;6572:6;6580;6588;6637:2;6625:9;6616:7;6612:23;6608:32;6605:119;;;6643:79;;:::i;:::-;6605:119;6763:1;6788:53;6833:7;6824:6;6813:9;6809:22;6788:53;:::i;:::-;6778:63;;6734:117;6890:2;6916:53;6961:7;6952:6;6941:9;6937:22;6916:53;:::i;:::-;6906:63;;6861:118;7018:2;7044:53;7089:7;7080:6;7069:9;7065:22;7044:53;:::i;:::-;7034:63;;6989:118;6495:619;;;;;:::o;7120:117::-;7229:1;7226;7219:12;7243:117;7352:1;7349;7342:12;7366:117;7475:1;7472;7465:12;7506:568;7579:8;7589:6;7639:3;7632:4;7624:6;7620:17;7616:27;7606:122;;7647:79;;:::i;:::-;7606:122;7760:6;7747:20;7737:30;;7790:18;7782:6;7779:30;7776:117;;;7812:79;;:::i;:::-;7776:117;7926:4;7918:6;7914:17;7902:29;;7980:3;7972:4;7964:6;7960:17;7950:8;7946:32;7943:41;7940:128;;;7987:79;;:::i;:::-;7940:128;7506:568;;;;;:::o;8080:559::-;8166:6;8174;8223:2;8211:9;8202:7;8198:23;8194:32;8191:119;;;8229:79;;:::i;:::-;8191:119;8377:1;8366:9;8362:17;8349:31;8407:18;8399:6;8396:30;8393:117;;;8429:79;;:::i;:::-;8393:117;8542:80;8614:7;8605:6;8594:9;8590:22;8542:80;:::i;:::-;8524:98;;;;8320:312;8080:559;;;;;:::o;8645:157::-;8726:9;8759:37;8790:5;8759:37;:::i;:::-;8746:50;;8645:157;;;:::o;8808:193::-;8926:68;8988:5;8926:68;:::i;:::-;8921:3;8914:81;8808:193;;:::o;9007:284::-;9131:4;9169:2;9158:9;9154:18;9146:26;;9182:102;9281:1;9270:9;9266:17;9257:6;9182:102;:::i;:::-;9007:284;;;;:::o;9297:117::-;9406:1;9403;9396:12;9420:180;9468:77;9465:1;9458:88;9565:4;9562:1;9555:15;9589:4;9586:1;9579:15;9606:281;9689:27;9711:4;9689:27;:::i;:::-;9681:6;9677:40;9819:6;9807:10;9804:22;9783:18;9771:10;9768:34;9765:62;9762:88;;;9830:18;;:::i;:::-;9762:88;9870:10;9866:2;9859:22;9649:238;9606:281;;:::o;9893:129::-;9927:6;9954:20;;:::i;:::-;9944:30;;9983:33;10011:4;10003:6;9983:33;:::i;:::-;9893:129;;;:::o;10028:308::-;10090:4;10180:18;10172:6;10169:30;10166:56;;;10202:18;;:::i;:::-;10166:56;10240:29;10262:6;10240:29;:::i;:::-;10232:37;;10324:4;10318;10314:15;10306:23;;10028:308;;;:::o;10342:146::-;10439:6;10434:3;10429;10416:30;10480:1;10471:6;10466:3;10462:16;10455:27;10342:146;;;:::o;10494:425::-;10572:5;10597:66;10613:49;10655:6;10613:49;:::i;:::-;10597:66;:::i;:::-;10588:75;;10686:6;10679:5;10672:21;10724:4;10717:5;10713:16;10762:3;10753:6;10748:3;10744:16;10741:25;10738:112;;;10769:79;;:::i;:::-;10738:112;10859:54;10906:6;10901:3;10896;10859:54;:::i;:::-;10578:341;10494:425;;;;;:::o;10939:340::-;10995:5;11044:3;11037:4;11029:6;11025:17;11021:27;11011:122;;11052:79;;:::i;:::-;11011:122;11169:6;11156:20;11194:79;11269:3;11261:6;11254:4;11246:6;11242:17;11194:79;:::i;:::-;11185:88;;11001:278;10939:340;;;;:::o;11285:509::-;11354:6;11403:2;11391:9;11382:7;11378:23;11374:32;11371:119;;;11409:79;;:::i;:::-;11371:119;11557:1;11546:9;11542:17;11529:31;11587:18;11579:6;11576:30;11573:117;;;11609:79;;:::i;:::-;11573:117;11714:63;11769:7;11760:6;11749:9;11745:22;11714:63;:::i;:::-;11704:73;;11500:287;11285:509;;;;:::o;11800:116::-;11870:21;11885:5;11870:21;:::i;:::-;11863:5;11860:32;11850:60;;11906:1;11903;11896:12;11850:60;11800:116;:::o;11922:133::-;11965:5;12003:6;11990:20;11981:29;;12019:30;12043:5;12019:30;:::i;:::-;11922:133;;;;:::o;12061:468::-;12126:6;12134;12183:2;12171:9;12162:7;12158:23;12154:32;12151:119;;;12189:79;;:::i;:::-;12151:119;12309:1;12334:53;12379:7;12370:6;12359:9;12355:22;12334:53;:::i;:::-;12324:63;;12280:117;12436:2;12462:50;12504:7;12495:6;12484:9;12480:22;12462:50;:::i;:::-;12452:60;;12407:115;12061:468;;;;;:::o;12535:307::-;12596:4;12686:18;12678:6;12675:30;12672:56;;;12708:18;;:::i;:::-;12672:56;12746:29;12768:6;12746:29;:::i;:::-;12738:37;;12830:4;12824;12820:15;12812:23;;12535:307;;;:::o;12848:423::-;12925:5;12950:65;12966:48;13007:6;12966:48;:::i;:::-;12950:65;:::i;:::-;12941:74;;13038:6;13031:5;13024:21;13076:4;13069:5;13065:16;13114:3;13105:6;13100:3;13096:16;13093:25;13090:112;;;13121:79;;:::i;:::-;13090:112;13211:54;13258:6;13253:3;13248;13211:54;:::i;:::-;12931:340;12848:423;;;;;:::o;13290:338::-;13345:5;13394:3;13387:4;13379:6;13375:17;13371:27;13361:122;;13402:79;;:::i;:::-;13361:122;13519:6;13506:20;13544:78;13618:3;13610:6;13603:4;13595:6;13591:17;13544:78;:::i;:::-;13535:87;;13351:277;13290:338;;;;:::o;13634:943::-;13729:6;13737;13745;13753;13802:3;13790:9;13781:7;13777:23;13773:33;13770:120;;;13809:79;;:::i;:::-;13770:120;13929:1;13954:53;13999:7;13990:6;13979:9;13975:22;13954:53;:::i;:::-;13944:63;;13900:117;14056:2;14082:53;14127:7;14118:6;14107:9;14103:22;14082:53;:::i;:::-;14072:63;;14027:118;14184:2;14210:53;14255:7;14246:6;14235:9;14231:22;14210:53;:::i;:::-;14200:63;;14155:118;14340:2;14329:9;14325:18;14312:32;14371:18;14363:6;14360:30;14357:117;;;14393:79;;:::i;:::-;14357:117;14498:62;14552:7;14543:6;14532:9;14528:22;14498:62;:::i;:::-;14488:72;;14283:287;13634:943;;;;;;;:::o;14583:474::-;14651:6;14659;14708:2;14696:9;14687:7;14683:23;14679:32;14676:119;;;14714:79;;:::i;:::-;14676:119;14834:1;14859:53;14904:7;14895:6;14884:9;14880:22;14859:53;:::i;:::-;14849:63;;14805:117;14961:2;14987:53;15032:7;15023:6;15012:9;15008:22;14987:53;:::i;:::-;14977:63;;14932:118;14583:474;;;;;:::o;15063:180::-;15111:77;15108:1;15101:88;15208:4;15205:1;15198:15;15232:4;15229:1;15222:15;15249:320;15293:6;15330:1;15324:4;15320:12;15310:22;;15377:1;15371:4;15367:12;15398:18;15388:81;;15454:4;15446:6;15442:17;15432:27;;15388:81;15516:2;15508:6;15505:14;15485:18;15482:38;15479:84;;15535:18;;:::i;:::-;15479:84;15300:269;15249:320;;;:::o;15575:230::-;15715:34;15711:1;15703:6;15699:14;15692:58;15784:13;15779:2;15771:6;15767:15;15760:38;15575:230;:::o;15811:366::-;15953:3;15974:67;16038:2;16033:3;15974:67;:::i;:::-;15967:74;;16050:93;16139:3;16050:93;:::i;:::-;16168:2;16163:3;16159:12;16152:19;;15811:366;;;:::o;16183:419::-;16349:4;16387:2;16376:9;16372:18;16364:26;;16436:9;16430:4;16426:20;16422:1;16411:9;16407:17;16400:47;16464:131;16590:4;16464:131;:::i;:::-;16456:139;;16183:419;;;:::o;16608:180::-;16656:77;16653:1;16646:88;16753:4;16750:1;16743:15;16777:4;16774:1;16767:15;16794:410;16834:7;16857:20;16875:1;16857:20;:::i;:::-;16852:25;;16891:20;16909:1;16891:20;:::i;:::-;16886:25;;16946:1;16943;16939:9;16968:30;16986:11;16968:30;:::i;:::-;16957:41;;17147:1;17138:7;17134:15;17131:1;17128:22;17108:1;17101:9;17081:83;17058:139;;17177:18;;:::i;:::-;17058:139;16842:362;16794:410;;;;:::o;17210:180::-;17258:77;17255:1;17248:88;17355:4;17352:1;17345:15;17379:4;17376:1;17369:15;17396:143;17453:5;17484:6;17478:13;17469:22;;17500:33;17527:5;17500:33;:::i;:::-;17396:143;;;;:::o;17545:351::-;17615:6;17664:2;17652:9;17643:7;17639:23;17635:32;17632:119;;;17670:79;;:::i;:::-;17632:119;17790:1;17815:64;17871:7;17862:6;17851:9;17847:22;17815:64;:::i;:::-;17805:74;;17761:128;17545:351;;;;:::o;17902:231::-;18042:34;18038:1;18030:6;18026:14;18019:58;18111:14;18106:2;18098:6;18094:15;18087:39;17902:231;:::o;18139:366::-;18281:3;18302:67;18366:2;18361:3;18302:67;:::i;:::-;18295:74;;18378:93;18467:3;18378:93;:::i;:::-;18496:2;18491:3;18487:12;18480:19;;18139:366;;;:::o;18511:419::-;18677:4;18715:2;18704:9;18700:18;18692:26;;18764:9;18758:4;18754:20;18750:1;18739:9;18735:17;18728:47;18792:131;18918:4;18792:131;:::i;:::-;18784:139;;18511:419;;;:::o;18936:141::-;18985:4;19008:3;19000:11;;19031:3;19028:1;19021:14;19065:4;19062:1;19052:18;19044:26;;18936:141;;;:::o;19083:93::-;19120:6;19167:2;19162;19155:5;19151:14;19147:23;19137:33;;19083:93;;;:::o;19182:107::-;19226:8;19276:5;19270:4;19266:16;19245:37;;19182:107;;;;:::o;19295:393::-;19364:6;19414:1;19402:10;19398:18;19437:97;19467:66;19456:9;19437:97;:::i;:::-;19555:39;19585:8;19574:9;19555:39;:::i;:::-;19543:51;;19627:4;19623:9;19616:5;19612:21;19603:30;;19676:4;19666:8;19662:19;19655:5;19652:30;19642:40;;19371:317;;19295:393;;;;;:::o;19694:142::-;19744:9;19777:53;19795:34;19804:24;19822:5;19804:24;:::i;:::-;19795:34;:::i;:::-;19777:53;:::i;:::-;19764:66;;19694:142;;;:::o;19842:75::-;19885:3;19906:5;19899:12;;19842:75;;;:::o;19923:269::-;20033:39;20064:7;20033:39;:::i;:::-;20094:91;20143:41;20167:16;20143:41;:::i;:::-;20135:6;20128:4;20122:11;20094:91;:::i;:::-;20088:4;20081:105;19999:193;19923:269;;;:::o;20198:73::-;20243:3;20198:73;:::o;20277:189::-;20354:32;;:::i;:::-;20395:65;20453:6;20445;20439:4;20395:65;:::i;:::-;20330:136;20277:189;;:::o;20472:186::-;20532:120;20549:3;20542:5;20539:14;20532:120;;;20603:39;20640:1;20633:5;20603:39;:::i;:::-;20576:1;20569:5;20565:13;20556:22;;20532:120;;;20472:186;;:::o;20664:543::-;20765:2;20760:3;20757:11;20754:446;;;20799:38;20831:5;20799:38;:::i;:::-;20883:29;20901:10;20883:29;:::i;:::-;20873:8;20869:44;21066:2;21054:10;21051:18;21048:49;;;21087:8;21072:23;;21048:49;21110:80;21166:22;21184:3;21166:22;:::i;:::-;21156:8;21152:37;21139:11;21110:80;:::i;:::-;20769:431;;20754:446;20664:543;;;:::o;21213:117::-;21267:8;21317:5;21311:4;21307:16;21286:37;;21213:117;;;;:::o;21336:169::-;21380:6;21413:51;21461:1;21457:6;21449:5;21446:1;21442:13;21413:51;:::i;:::-;21409:56;21494:4;21488;21484:15;21474:25;;21387:118;21336:169;;;;:::o;21510:295::-;21586:4;21732:29;21757:3;21751:4;21732:29;:::i;:::-;21724:37;;21794:3;21791:1;21787:11;21781:4;21778:21;21770:29;;21510:295;;;;:::o;21810:1395::-;21927:37;21960:3;21927:37;:::i;:::-;22029:18;22021:6;22018:30;22015:56;;;22051:18;;:::i;:::-;22015:56;22095:38;22127:4;22121:11;22095:38;:::i;:::-;22180:67;22240:6;22232;22226:4;22180:67;:::i;:::-;22274:1;22298:4;22285:17;;22330:2;22322:6;22319:14;22347:1;22342:618;;;;23004:1;23021:6;23018:77;;;23070:9;23065:3;23061:19;23055:26;23046:35;;23018:77;23121:67;23181:6;23174:5;23121:67;:::i;:::-;23115:4;23108:81;22977:222;22312:887;;22342:618;22394:4;22390:9;22382:6;22378:22;22428:37;22460:4;22428:37;:::i;:::-;22487:1;22501:208;22515:7;22512:1;22509:14;22501:208;;;22594:9;22589:3;22585:19;22579:26;22571:6;22564:42;22645:1;22637:6;22633:14;22623:24;;22692:2;22681:9;22677:18;22664:31;;22538:4;22535:1;22531:12;22526:17;;22501:208;;;22737:6;22728:7;22725:19;22722:179;;;22795:9;22790:3;22786:19;22780:26;22838:48;22880:4;22872:6;22868:17;22857:9;22838:48;:::i;:::-;22830:6;22823:64;22745:156;22722:179;22947:1;22943;22935:6;22931:14;22927:22;22921:4;22914:36;22349:611;;;22312:887;;21902:1303;;;21810:1395;;:::o;23211:191::-;23251:3;23270:20;23288:1;23270:20;:::i;:::-;23265:25;;23304:20;23322:1;23304:20;:::i;:::-;23299:25;;23347:1;23344;23340:9;23333:16;;23368:3;23365:1;23362:10;23359:36;;;23375:18;;:::i;:::-;23359:36;23211:191;;;;:::o;23408:194::-;23448:4;23468:20;23486:1;23468:20;:::i;:::-;23463:25;;23502:20;23520:1;23502:20;:::i;:::-;23497:25;;23546:1;23543;23539:9;23531:17;;23570:1;23564:4;23561:11;23558:37;;;23575:18;;:::i;:::-;23558:37;23408:194;;;;:::o;23608:180::-;23656:77;23653:1;23646:88;23753:4;23750:1;23743:15;23777:4;23774:1;23767:15;23794:185;23834:1;23851:20;23869:1;23851:20;:::i;:::-;23846:25;;23885:20;23903:1;23885:20;:::i;:::-;23880:25;;23924:1;23914:35;;23929:18;;:::i;:::-;23914:35;23971:1;23968;23964:9;23959:14;;23794:185;;;;:::o;23985:332::-;24106:4;24144:2;24133:9;24129:18;24121:26;;24157:71;24225:1;24214:9;24210:17;24201:6;24157:71;:::i;:::-;24238:72;24306:2;24295:9;24291:18;24282:6;24238:72;:::i;:::-;23985:332;;;;;:::o;24323:137::-;24377:5;24408:6;24402:13;24393:22;;24424:30;24448:5;24424:30;:::i;:::-;24323:137;;;;:::o;24466:345::-;24533:6;24582:2;24570:9;24561:7;24557:23;24553:32;24550:119;;;24588:79;;:::i;:::-;24550:119;24708:1;24733:61;24786:7;24777:6;24766:9;24762:22;24733:61;:::i;:::-;24723:71;;24679:125;24466:345;;;;:::o;24817:174::-;24957:26;24953:1;24945:6;24941:14;24934:50;24817:174;:::o;24997:366::-;25139:3;25160:67;25224:2;25219:3;25160:67;:::i;:::-;25153:74;;25236:93;25325:3;25236:93;:::i;:::-;25354:2;25349:3;25345:12;25338:19;;24997:366;;;:::o;25369:419::-;25535:4;25573:2;25562:9;25558:18;25550:26;;25622:9;25616:4;25612:20;25608:1;25597:9;25593:17;25586:47;25650:131;25776:4;25650:131;:::i;:::-;25642:139;;25369:419;;;:::o;25794:228::-;25934:34;25930:1;25922:6;25918:14;25911:58;26003:11;25998:2;25990:6;25986:15;25979:36;25794:228;:::o;26028:366::-;26170:3;26191:67;26255:2;26250:3;26191:67;:::i;:::-;26184:74;;26267:93;26356:3;26267:93;:::i;:::-;26385:2;26380:3;26376:12;26369:19;;26028:366;;;:::o;26400:419::-;26566:4;26604:2;26593:9;26589:18;26581:26;;26653:9;26647:4;26643:20;26639:1;26628:9;26624:17;26617:47;26681:131;26807:4;26681:131;:::i;:::-;26673:139;;26400:419;;;:::o;26825:232::-;26965:34;26961:1;26953:6;26949:14;26942:58;27034:15;27029:2;27021:6;27017:15;27010:40;26825:232;:::o;27063:366::-;27205:3;27226:67;27290:2;27285:3;27226:67;:::i;:::-;27219:74;;27302:93;27391:3;27302:93;:::i;:::-;27420:2;27415:3;27411:12;27404:19;;27063:366;;;:::o;27435:419::-;27601:4;27639:2;27628:9;27624:18;27616:26;;27688:9;27682:4;27678:20;27674:1;27663:9;27659:17;27652:47;27716:131;27842:4;27716:131;:::i;:::-;27708:139;;27435:419;;;:::o;27860:148::-;27962:11;27999:3;27984:18;;27860:148;;;;:::o;28014:390::-;28120:3;28148:39;28181:5;28148:39;:::i;:::-;28203:89;28285:6;28280:3;28203:89;:::i;:::-;28196:96;;28301:65;28359:6;28354:3;28347:4;28340:5;28336:16;28301:65;:::i;:::-;28391:6;28386:3;28382:16;28375:23;;28124:280;28014:390;;;;:::o;28410:595::-;28638:3;28660:95;28751:3;28742:6;28660:95;:::i;:::-;28653:102;;28772:95;28863:3;28854:6;28772:95;:::i;:::-;28765:102;;28884:95;28975:3;28966:6;28884:95;:::i;:::-;28877:102;;28996:3;28989:10;;28410:595;;;;;;:::o;29011:332::-;29132:4;29170:2;29159:9;29155:18;29147:26;;29183:71;29251:1;29240:9;29236:17;29227:6;29183:71;:::i;:::-;29264:72;29332:2;29321:9;29317:18;29308:6;29264:72;:::i;:::-;29011:332;;;;;:::o;29349:220::-;29489:34;29485:1;29477:6;29473:14;29466:58;29558:3;29553:2;29545:6;29541:15;29534:28;29349:220;:::o;29575:366::-;29717:3;29738:67;29802:2;29797:3;29738:67;:::i;:::-;29731:74;;29814:93;29903:3;29814:93;:::i;:::-;29932:2;29927:3;29923:12;29916:19;;29575:366;;;:::o;29947:419::-;30113:4;30151:2;30140:9;30136:18;30128:26;;30200:9;30194:4;30190:20;30186:1;30175:9;30171:17;30164:47;30228:131;30354:4;30228:131;:::i;:::-;30220:139;;29947:419;;;:::o;30372:248::-;30512:34;30508:1;30500:6;30496:14;30489:58;30581:31;30576:2;30568:6;30564:15;30557:56;30372:248;:::o;30626:366::-;30768:3;30789:67;30853:2;30848:3;30789:67;:::i;:::-;30782:74;;30865:93;30954:3;30865:93;:::i;:::-;30983:2;30978:3;30974:12;30967:19;;30626:366;;;:::o;30998:419::-;31164:4;31202:2;31191:9;31187:18;31179:26;;31251:9;31245:4;31241:20;31237:1;31226:9;31222:17;31215:47;31279:131;31405:4;31279:131;:::i;:::-;31271:139;;30998:419;;;:::o;31423:237::-;31563:34;31559:1;31551:6;31547:14;31540:58;31632:20;31627:2;31619:6;31615:15;31608:45;31423:237;:::o;31666:366::-;31808:3;31829:67;31893:2;31888:3;31829:67;:::i;:::-;31822:74;;31905:93;31994:3;31905:93;:::i;:::-;32023:2;32018:3;32014:12;32007:19;;31666:366;;;:::o;32038:419::-;32204:4;32242:2;32231:9;32227:18;32219:26;;32291:9;32285:4;32281:20;32277:1;32266:9;32262:17;32255:47;32319:131;32445:4;32319:131;:::i;:::-;32311:139;;32038:419;;;:::o;32463:224::-;32603:34;32599:1;32591:6;32587:14;32580:58;32672:7;32667:2;32659:6;32655:15;32648:32;32463:224;:::o;32693:366::-;32835:3;32856:67;32920:2;32915:3;32856:67;:::i;:::-;32849:74;;32932:93;33021:3;32932:93;:::i;:::-;33050:2;33045:3;33041:12;33034:19;;32693:366;;;:::o;33065:419::-;33231:4;33269:2;33258:9;33254:18;33246:26;;33318:9;33312:4;33308:20;33304:1;33293:9;33289:17;33282:47;33346:131;33472:4;33346:131;:::i;:::-;33338:139;;33065:419;;;:::o;33490:223::-;33630:34;33626:1;33618:6;33614:14;33607:58;33699:6;33694:2;33686:6;33682:15;33675:31;33490:223;:::o;33719:366::-;33861:3;33882:67;33946:2;33941:3;33882:67;:::i;:::-;33875:74;;33958:93;34047:3;33958:93;:::i;:::-;34076:2;34071:3;34067:12;34060:19;;33719:366;;;:::o;34091:419::-;34257:4;34295:2;34284:9;34280:18;34272:26;;34344:9;34338:4;34334:20;34330:1;34319:9;34315:17;34308:47;34372:131;34498:4;34372:131;:::i;:::-;34364:139;;34091:419;;;:::o;34516:175::-;34656:27;34652:1;34644:6;34640:14;34633:51;34516:175;:::o;34697:366::-;34839:3;34860:67;34924:2;34919:3;34860:67;:::i;:::-;34853:74;;34936:93;35025:3;34936:93;:::i;:::-;35054:2;35049:3;35045:12;35038:19;;34697:366;;;:::o;35069:419::-;35235:4;35273:2;35262:9;35258:18;35250:26;;35322:9;35316:4;35312:20;35308:1;35297:9;35293:17;35286:47;35350:131;35476:4;35350:131;:::i;:::-;35342:139;;35069:419;;;:::o;35494:98::-;35545:6;35579:5;35573:12;35563:22;;35494:98;;;:::o;35598:168::-;35681:11;35715:6;35710:3;35703:19;35755:4;35750:3;35746:14;35731:29;;35598:168;;;;:::o;35772:373::-;35858:3;35886:38;35918:5;35886:38;:::i;:::-;35940:70;36003:6;35998:3;35940:70;:::i;:::-;35933:77;;36019:65;36077:6;36072:3;36065:4;36058:5;36054:16;36019:65;:::i;:::-;36109:29;36131:6;36109:29;:::i;:::-;36104:3;36100:39;36093:46;;35862:283;35772:373;;;;:::o;36151:640::-;36346:4;36384:3;36373:9;36369:19;36361:27;;36398:71;36466:1;36455:9;36451:17;36442:6;36398:71;:::i;:::-;36479:72;36547:2;36536:9;36532:18;36523:6;36479:72;:::i;:::-;36561;36629:2;36618:9;36614:18;36605:6;36561:72;:::i;:::-;36680:9;36674:4;36670:20;36665:2;36654:9;36650:18;36643:48;36708:76;36779:4;36770:6;36708:76;:::i;:::-;36700:84;;36151:640;;;;;;;:::o;36797:141::-;36853:5;36884:6;36878:13;36869:22;;36900:32;36926:5;36900:32;:::i;:::-;36797:141;;;;:::o;36944:349::-;37013:6;37062:2;37050:9;37041:7;37037:23;37033:32;37030:119;;;37068:79;;:::i;:::-;37030:119;37188:1;37213:63;37268:7;37259:6;37248:9;37244:22;37213:63;:::i;:::-;37203:73;;37159:127;36944:349;;;;:::o;37299:182::-;37439:34;37435:1;37427:6;37423:14;37416:58;37299:182;:::o;37487:366::-;37629:3;37650:67;37714:2;37709:3;37650:67;:::i;:::-;37643:74;;37726:93;37815:3;37726:93;:::i;:::-;37844:2;37839:3;37835:12;37828:19;;37487:366;;;:::o;37859:419::-;38025:4;38063:2;38052:9;38048:18;38040:26;;38112:9;38106:4;38102:20;38098:1;38087:9;38083:17;38076:47;38140:131;38266:4;38140:131;:::i;:::-;38132:139;;37859:419;;;:::o;38284:178::-;38424:30;38420:1;38412:6;38408:14;38401:54;38284:178;:::o;38468:366::-;38610:3;38631:67;38695:2;38690:3;38631:67;:::i;:::-;38624:74;;38707:93;38796:3;38707:93;:::i;:::-;38825:2;38820:3;38816:12;38809:19;;38468:366;;;:::o;38840:419::-;39006:4;39044:2;39033:9;39029:18;39021:26;;39093:9;39087:4;39083:20;39079:1;39068:9;39064:17;39057:47;39121:131;39247:4;39121:131;:::i;:::-;39113:139;;38840:419;;;:::o;39265:240::-;39405:34;39401:1;39393:6;39389:14;39382:58;39474:23;39469:2;39461:6;39457:15;39450:48;39265:240;:::o;39511:366::-;39653:3;39674:67;39738:2;39733:3;39674:67;:::i;:::-;39667:74;;39750:93;39839:3;39750:93;:::i;:::-;39868:2;39863:3;39859:12;39852:19;;39511:366;;;:::o;39883:419::-;40049:4;40087:2;40076:9;40072:18;40064:26;;40136:9;40130:4;40126:20;40122:1;40111:9;40107:17;40100:47;40164:131;40290:4;40164:131;:::i;:::-;40156:139;;39883:419;;;:::o;40308:180::-;40356:77;40353:1;40346:88;40453:4;40450:1;40443:15;40477:4;40474:1;40467:15
Swarm Source
ipfs://b33bbdf69fe3fc3dffa8908864c177301ae8d1fb98204f8b3567fee043a3db27
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.