Overview
TokenID
33
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 0 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Editiens
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-10-12 */ // File: @openzeppelin/contracts/interfaces/IERC5267.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.20; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); } // File: @openzeppelin/contracts/utils/StorageSlot.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } // File: @openzeppelin/contracts/utils/ShortStrings.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol) pragma solidity ^0.8.8; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(_FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } } // File: @openzeppelin/contracts/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @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 v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(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) { uint256 localValue = value; 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] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } 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 bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } } // File: @openzeppelin/contracts/utils/cryptography/EIP712.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. * * _Available since v4.9._ */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } } // File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } // File: @openzeppelin/contracts/utils/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/ERC20/extensions/IERC20Permit.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } } // 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/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/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.20; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); } // File: @openzeppelin/contracts/token/common/ERC2981.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator); /** * @dev The default royalty receiver is invalid. */ error ERC2981InvalidDefaultRoyaltyReceiver(address receiver); /** * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator); /** * @dev The royalty receiver for `tokenId` is invalid. */ error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver); /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidDefaultRoyaltyReceiver(address(0)); } _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0)); } _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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/finance/PaymentSplitter.sol // OpenZeppelin Contracts (last updated v4.8.0) (finance/PaymentSplitter.sol) pragma solidity ^0.8.0; /** * @title PaymentSplitter * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware * that the Ether will be split in this way, since it is handled transparently by the contract. * * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim * an amount proportional to the percentage of total shares they were assigned. The distribution of shares is set at the * time of contract deployment and can't be updated thereafter. * * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release} * function. * * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you * to run tests before sending real value to this contract. */ contract PaymentSplitter is Context { event PayeeAdded(address account, uint256 shares); event PaymentReleased(address to, uint256 amount); event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount); event PaymentReceived(address from, uint256 amount); uint256 private _totalShares; uint256 private _totalReleased; mapping(address => uint256) private _shares; mapping(address => uint256) private _released; address[] private _payees; mapping(IERC20 => uint256) private _erc20TotalReleased; mapping(IERC20 => mapping(address => uint256)) private _erc20Released; /** * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at * the matching position in the `shares` array. * * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no * duplicates in `payees`. */ constructor(address[] memory payees, uint256[] memory shares_) payable { require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch"); require(payees.length > 0, "PaymentSplitter: no payees"); for (uint256 i = 0; i < payees.length; i++) { _addPayee(payees[i], shares_[i]); } } /** * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the * reliability of the events, and not the actual splitting of Ether. * * To learn more about this see the Solidity documentation for * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback * functions]. */ receive() external payable virtual { emit PaymentReceived(_msgSender(), msg.value); } /** * @dev Getter for the total shares held by payees. */ function totalShares() public view returns (uint256) { return _totalShares; } /** * @dev Getter for the total amount of Ether already released. */ function totalReleased() public view returns (uint256) { return _totalReleased; } /** * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20 * contract. */ function totalReleased(IERC20 token) public view returns (uint256) { return _erc20TotalReleased[token]; } /** * @dev Getter for the amount of shares held by an account. */ function shares(address account) public view returns (uint256) { return _shares[account]; } /** * @dev Getter for the amount of Ether already released to a payee. */ function released(address account) public view returns (uint256) { return _released[account]; } /** * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an * IERC20 contract. */ function released(IERC20 token, address account) public view returns (uint256) { return _erc20Released[token][account]; } /** * @dev Getter for the address of the payee number `index`. */ function payee(uint256 index) public view returns (address) { return _payees[index]; } /** * @dev Getter for the amount of payee's releasable Ether. */ function releasable(address account) public view returns (uint256) { uint256 totalReceived = address(this).balance + totalReleased(); return _pendingPayment(account, totalReceived, released(account)); } /** * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an * IERC20 contract. */ function releasable(IERC20 token, address account) public view returns (uint256) { uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token); return _pendingPayment(account, totalReceived, released(token, account)); } /** * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the * total shares and their previous withdrawals. */ function release(address payable account) public virtual { require(_shares[account] > 0, "PaymentSplitter: account has no shares"); uint256 payment = releasable(account); require(payment != 0, "PaymentSplitter: account is not due payment"); // _totalReleased is the sum of all values in _released. // If "_totalReleased += payment" does not overflow, then "_released[account] += payment" cannot overflow. _totalReleased += payment; unchecked { _released[account] += payment; } Address.sendValue(account, payment); emit PaymentReleased(account, payment); } /** * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20 * contract. */ function release(IERC20 token, address account) public virtual { require(_shares[account] > 0, "PaymentSplitter: account has no shares"); uint256 payment = releasable(token, account); require(payment != 0, "PaymentSplitter: account is not due payment"); // _erc20TotalReleased[token] is the sum of all values in _erc20Released[token]. // If "_erc20TotalReleased[token] += payment" does not overflow, then "_erc20Released[token][account] += payment" // cannot overflow. _erc20TotalReleased[token] += payment; unchecked { _erc20Released[token][account] += payment; } SafeERC20.safeTransfer(token, account, payment); emit ERC20PaymentReleased(token, account, payment); } /** * @dev internal logic for computing the pending payment of an `account` given the token historical balances and * already released amounts. */ function _pendingPayment( address account, uint256 totalReceived, uint256 alreadyReleased ) private view returns (uint256) { return (totalReceived * _shares[account]) / _totalShares - alreadyReleased; } /** * @dev Add a new payee to the contract. * @param account The address of the payee to add. * @param shares_ The number of shares owned by the payee. */ function _addPayee(address account, uint256 shares_) private { require(account != address(0), "PaymentSplitter: account is the zero address"); require(shares_ > 0, "PaymentSplitter: shares are 0"); require(_shares[account] == 0, "PaymentSplitter: account already has shares"); _payees.push(account); _shares[account] = shares_; _totalShares = _totalShares + shares_; emit PayeeAdded(account, shares_); } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: .deps/npm/erc721a/contracts/IERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } // File: .deps/npm/erc721a/contracts/ERC721A.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId), ".json")) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } } // File: editiensV2.sol pragma solidity 0.8.21; /* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░▒██░░▓█▓░░░▒█▓░░░░░░░░░░██░░░░██████░░░░▒██░░░░░██▒░░░░██████░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░▒██░░░▒░░░░▓██░░░░░░░░░░▒▒░░▓█▓▒▒▒▒▓██░░▒████░░░██▒░░██▒▒▒▒▒██▓░░░░ ░░░░░▒██████░░░░░░████████░░▓██░▒█████████▒░░░░██░░██▓░░░░░░░░░▒██░██▓░██▒░░██▒░░░░░░░░░░░ ░░░▒██▒▒▒▒░██▓░░██▒░░░░▒██░░▓██░░░▓██░░░░░░░░░░██░░██████▒░░░░░▒██░▓█▓░██▒░░░▒██████░░░░░░ ░░░▒██████░▒▒░░░██▒░░░░▒██░░▓██░░░▓██░░░░░▒▒░░░██░░██▓░░░░░▒▒░░▒██░▓██▒██▒░░▒▒░░░░░▓██░░░░ ░░░░██▒▒▒▒▒██▓░░██▓▒▒▒▒▓██░░▓██░░░▒██▒▒▒▒▒██▒░░██░░▓█▓▒▒▒▒▓██░░▒██░░░████▒░░██▓▒▒▒▒██▓░░░░ ░░░░░▒█████▓░░░░░░██████░░░░▒█▓░░░░░▓█████▒░░░░██░░░░▓█████░░░░▒█▓░░░░░██▒░░░░█████▓░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ */ contract Editiens is ERC721A, ReentrancyGuard, PaymentSplitter, ERC2981, EIP712, Ownable { bool public paused = true; string private constant _name = "Editiens"; string private constant _symbol = "EDITIENS"; string private constant _version = "1"; string public baseURI = "https://editiensnft.s3.amazonaws.com/metadata/"; uint256 public maxSupply = 1000000000; uint256 public cost = 0.0025 ether; address private whitelistSigningKey = 0x9d2f52F34aab44000FaA518cdB833443f2d3B801; bytes32 private whitelistMerkleRoot; mapping(address => uint256) public freeMints; struct EIP712Domain { string name; string version; uint256 chainId; address verifyingContract; address userAddress; } constructor(address[] memory payees, uint256[] memory shares) ERC721A(_name, _symbol) PaymentSplitter(payees, shares) EIP712(_name, _version) payable { _setDefaultRoyalty(address(this), 500); } function mint(bytes calldata signature, bytes32[] calldata merkleProof, uint256 freeQuantity) public payable nonReentrant { require(checkSig(signature), "Mint on Website"); require(totalSupply() + 1 <= maxSupply, "No More Supply"); if (msg.sender != owner()) { require(!paused, "Mint Paused"); } if (isValidMerkleProof(msg.sender, merkleProof, freeQuantity) && freeMints[msg.sender] < freeQuantity) { freeMints[msg.sender] += 1; } else { require(msg.value >= cost, "Pay for Mint"); } _safeMint(msg.sender, 1); } function checkSig(bytes memory signature) public view returns (bool) { bytes32 domain = _domainSeparatorV4(); bytes32 structHash = keccak256(abi.encode( keccak256("Minter(address wallet,uint256 balance)"), msg.sender, balanceOf(msg.sender) )); bytes32 digest = keccak256(abi.encodePacked( "\x19\x01", domain, structHash )); address signer = ECDSA.recover(digest, signature); return (signer == whitelistSigningKey); } function setWhitelistSigningKey(address newSigningKey) public onlyOwner { whitelistSigningKey = newSigningKey; } function isValidMerkleProof(address to, bytes32[] calldata merkleProof, uint256 quantity) public view returns (bool) { bytes32 leaf = keccak256(abi.encodePacked(to, quantity)); return MerkleProof.verify(merkleProof, whitelistMerkleRoot, leaf); } function setWhitelistMerkleRoot(bytes32 merkleRoot) external onlyOwner { require(merkleRoot != bytes32(0), "MerkleRoot is 0"); whitelistMerkleRoot = merkleRoot; } function setCost(uint256 _newCost) external onlyOwner { cost = _newCost; } function setPaused(bool _status) external onlyOwner { paused = _status; } function setBaseURI(string memory _baseTokenURI) external onlyOwner { baseURI = _baseTokenURI; } function _baseURI() internal view virtual override(ERC721A) returns (string memory) { return baseURI; } function setMaxSupply(uint16 newMax) external onlyOwner { require(newMax >= totalSupply(), "Must be more than current supply"); maxSupply = newMax; } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyOwner { _setDefaultRoyalty(receiver, feeNumerator); } function withdraw() public onlyOwner nonReentrant { (bool os, ) = payable(owner()).call{value: address(this).balance}(''); require(os); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"}],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"checkSig","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"freeMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"to","type":"address"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"isValidMerkleProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"freeQuantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseTokenURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"newMax","type":"uint16"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setWhitelistMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSigningKey","type":"address"}],"name":"setWhitelistSigningKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
61016060405260016014806101000a81548160ff0219169083151502179055506040518060600160405280602e81526020016200706f602e91396015908162000049919062000c14565b50633b9aca006016556608e1bc9bf04000601755739d2f52f34aab44000faa518cdb833443f2d3b80160185f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040516200709d3803806200709d8339818101604052810190620000d6919062000fab565b6040518060400160405280600881526020017f4564697469656e730000000000000000000000000000000000000000000000008152506040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525083836040518060400160405280600881526020017f4564697469656e730000000000000000000000000000000000000000000000008152506040518060400160405280600881526020017f4544495449454e530000000000000000000000000000000000000000000000008152508160029081620001c1919062000c14565b508060039081620001d3919062000c14565b50620001e4620003dd60201b60201c565b5f819055505050600160088190555080518251146200023a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200023190620010b2565b60405180910390fd5b5f82511162000280576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002779062001120565b60405180910390fd5b5f5b8251811015620002ee57620002d8838281518110620002a657620002a562001140565b5b6020026020010151838381518110620002c457620002c362001140565b5b6020026020010151620003e160201b60201c565b8080620002e5906200119a565b91505062000282565b505050620003076012836200061060201b90919060201c565b6101208181525050620003256013826200061060201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a08181525050620003646200066560201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250505050620003c1620003b5620006c160201b60201c565b620006c860201b60201c565b620003d5306101f46200078b60201b60201c565b505062001637565b5f90565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000452576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000449906200125a565b60405180910390fd5b5f811162000497576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200048e90620012c8565b60405180910390fd5b5f600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541462000519576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000510906200135c565b60405180910390fd5b600d82908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080600954620005cb91906200137c565b6009819055507f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac828260405162000604929190620013d8565b60405180910390a15050565b5f60208351101562000635576200062d836200093460201b60201c565b90506200065f565b8262000647836200099e60201b60201c565b5f01908162000657919062000c14565b5060ff5f1b90505b92915050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e051610100514630604051602001620006a69594939291906200141d565b60405160208183030381529060405280519060200120905090565b5f33905090565b5f60145f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160145f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f6200079c620009a760201b60201c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff161115620008045781816040517f6f483d09000000000000000000000000000000000000000000000000000000008152600401620007fb929190620014c7565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000877575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016200086e9190620014f2565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060105f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f80829050601f815111156200098357826040517f305a27a90000000000000000000000000000000000000000000000000000000081526004016200097a919062001577565b60405180910390fd5b8051816200099190620015c8565b5f1c175f1b915050919050565b5f819050919050565b5f612710905090565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168062000a2c57607f821691505b60208210810362000a425762000a41620009e7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830262000aa67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000a69565b62000ab2868362000a69565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000afc62000af662000af08462000aca565b62000ad3565b62000aca565b9050919050565b5f819050919050565b62000b178362000adc565b62000b2f62000b268262000b03565b84845462000a75565b825550505050565b5f90565b62000b4562000b37565b62000b5281848462000b0c565b505050565b5b8181101562000b795762000b6d5f8262000b3b565b60018101905062000b58565b5050565b601f82111562000bc85762000b928162000a48565b62000b9d8462000a5a565b8101602085101562000bad578190505b62000bc562000bbc8562000a5a565b83018262000b57565b50505b505050565b5f82821c905092915050565b5f62000bea5f198460080262000bcd565b1980831691505092915050565b5f62000c04838362000bd9565b9150826002028217905092915050565b62000c1f82620009b0565b67ffffffffffffffff81111562000c3b5762000c3a620009ba565b5b62000c47825462000a14565b62000c5482828562000b7d565b5f60209050601f83116001811462000c8a575f841562000c75578287015190505b62000c81858262000bf7565b86555062000cf0565b601f19841662000c9a8662000a48565b5f5b8281101562000cc35784890151825560018201915060208501945060208101905062000c9c565b8683101562000ce3578489015162000cdf601f89168262000bd9565b8355505b6001600288020188555050505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b62000d288262000d0d565b810181811067ffffffffffffffff8211171562000d4a5762000d49620009ba565b5b80604052505050565b5f62000d5e62000cf8565b905062000d6c828262000d1d565b919050565b5f67ffffffffffffffff82111562000d8e5762000d8d620009ba565b5b602082029050602081019050919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f62000dce8262000da3565b9050919050565b62000de08162000dc2565b811462000deb575f80fd5b50565b5f8151905062000dfe8162000dd5565b92915050565b5f62000e1a62000e148462000d71565b62000d53565b9050808382526020820190506020840283018581111562000e405762000e3f62000d9f565b5b835b8181101562000e6d578062000e58888262000dee565b84526020840193505060208101905062000e42565b5050509392505050565b5f82601f83011262000e8e5762000e8d62000d09565b5b815162000ea084826020860162000e04565b91505092915050565b5f67ffffffffffffffff82111562000ec65762000ec5620009ba565b5b602082029050602081019050919050565b62000ee28162000aca565b811462000eed575f80fd5b50565b5f8151905062000f008162000ed7565b92915050565b5f62000f1c62000f168462000ea9565b62000d53565b9050808382526020820190506020840283018581111562000f425762000f4162000d9f565b5b835b8181101562000f6f578062000f5a888262000ef0565b84526020840193505060208101905062000f44565b5050509392505050565b5f82601f83011262000f905762000f8f62000d09565b5b815162000fa284826020860162000f06565b91505092915050565b5f806040838503121562000fc45762000fc362000d01565b5b5f83015167ffffffffffffffff81111562000fe45762000fe362000d05565b5b62000ff28582860162000e77565b925050602083015167ffffffffffffffff81111562001016576200101562000d05565b5b620010248582860162000f79565b9150509250929050565b5f82825260208201905092915050565b7f5061796d656e7453706c69747465723a2070617965657320616e6420736861725f8201527f6573206c656e677468206d69736d617463680000000000000000000000000000602082015250565b5f6200109a6032836200102e565b9150620010a7826200103e565b604082019050919050565b5f6020820190508181035f830152620010cb816200108c565b9050919050565b7f5061796d656e7453706c69747465723a206e6f207061796565730000000000005f82015250565b5f62001108601a836200102e565b91506200111582620010d2565b602082019050919050565b5f6020820190508181035f8301526200113981620010fa565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f620011a68262000aca565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620011db57620011da6200116d565b5b600182019050919050565b7f5061796d656e7453706c69747465723a206163636f756e7420697320746865205f8201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b5f62001242602c836200102e565b91506200124f82620011e6565b604082019050919050565b5f6020820190508181035f830152620012738162001234565b9050919050565b7f5061796d656e7453706c69747465723a207368617265732061726520300000005f82015250565b5f620012b0601d836200102e565b9150620012bd826200127a565b602082019050919050565b5f6020820190508181035f830152620012e181620012a2565b9050919050565b7f5061796d656e7453706c69747465723a206163636f756e7420616c72656164795f8201527f2068617320736861726573000000000000000000000000000000000000000000602082015250565b5f62001344602b836200102e565b91506200135182620012e8565b604082019050919050565b5f6020820190508181035f830152620013758162001336565b9050919050565b5f620013888262000aca565b9150620013958362000aca565b9250828201905080821115620013b057620013af6200116d565b5b92915050565b620013c18162000dc2565b82525050565b620013d28162000aca565b82525050565b5f604082019050620013ed5f830185620013b6565b620013fc6020830184620013c7565b9392505050565b5f819050919050565b620014178162001403565b82525050565b5f60a082019050620014325f8301886200140c565b6200144160208301876200140c565b6200145060408301866200140c565b6200145f6060830185620013c7565b6200146e6080830184620013b6565b9695505050505050565b5f6bffffffffffffffffffffffff82169050919050565b5f620014af620014a9620014a38462001478565b62000ad3565b62000aca565b9050919050565b620014c1816200148f565b82525050565b5f604082019050620014dc5f830185620014b6565b620014eb6020830184620013c7565b9392505050565b5f602082019050620015075f830184620013b6565b92915050565b5f5b838110156200152c5780820151818401526020810190506200150f565b5f8484015250505050565b5f6200154382620009b0565b6200154f81856200102e565b9350620015618185602086016200150d565b6200156c8162000d0d565b840191505092915050565b5f6020820190508181035f83015262001591818462001537565b905092915050565b5f81519050919050565b5f819050602082019050919050565b5f620015bf825162001403565b80915050919050565b5f620015d48262001599565b82620015e084620015a3565b9050620015ed81620015b2565b9250602082101562001630576200162b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080262000a69565b831692505b5050919050565b60805160a05160c05160e0516101005161012051610140516159e6620016895f395f611b8b01525f611b5701525f61323601525f61321501525f612b6c01525f612bc201525f612beb01526159e65ff3fe608060405260043610610280575f3560e01c80636c0360eb1161014e578063a22cb465116100c0578063ce7c2ac211610079578063ce7c2ac2146109dc578063d5abeb0114610a18578063d79779b214610a42578063e33b7de314610a7e578063e985e9c514610aa8578063f2fde38b14610ae4576102c7565b8063a22cb465146108bc578063a3f8eace146108e4578063b88d4fde14610920578063bd32fb661461093c578063c45ac05014610964578063c87b56dd146109a0576102c7565b806384b0196e1161011257806384b0196e146107a45780638b83209b146107d45780638da5cb5b1461081057806395d89b411461083a5780639852595c146108645780639999a040146108a0576102c7565b80636c0360eb146106b05780636c8e7ec5146106da5780636d41d4fb1461071657806370a0823114610752578063715018a61461078e576102c7565b806320510b55116101f257806342842e0e116101ab57806342842e0e146105b657806344a0d68a146105d257806348b75044146105fa57806355f804b3146106225780635c975abb1461064a5780636352211e14610674576102c7565b806320510b55146104b957806323b872dd146104e15780632a55205a146104fd5780633a98ef391461053a5780633ccfd60b14610564578063406072a91461057a576102c7565b8063081812fc11610244578063081812fc146103bd578063095ea7b3146103f957806313faede61461041557806316c38b3c1461043f57806318160ddd146104675780631916558714610491576102c7565b806301b4afbf146102cb57806301ffc9a71461030757806304634d8d1461034357806306421c2f1461036b57806306fdde0314610393576102c7565b366102c7577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be7706102ae610b0c565b346040516102bd929190613a78565b60405180910390a1005b5f80fd5b3480156102d6575f80fd5b506102f160048036038101906102ec9190613b65565b610b13565b6040516102fe9190613bf0565b60405180910390f35b348015610312575f80fd5b5061032d60048036038101906103289190613c5e565b610b98565b60405161033a9190613bf0565b60405180910390f35b34801561034e575f80fd5b5061036960048036038101906103649190613cca565b610ba9565b005b348015610376575f80fd5b50610391600480360381019061038c9190613d3f565b610bbf565b005b34801561039e575f80fd5b506103a7610c23565b6040516103b49190613df4565b60405180910390f35b3480156103c8575f80fd5b506103e360048036038101906103de9190613e14565b610cb3565b6040516103f09190613e3f565b60405180910390f35b610413600480360381019061040e9190613e58565b610d2d565b005b348015610420575f80fd5b50610429610e6c565b6040516104369190613e96565b60405180910390f35b34801561044a575f80fd5b5061046560048036038101906104609190613ed9565b610e72565b005b348015610472575f80fd5b5061047b610e96565b6040516104889190613e96565b60405180910390f35b34801561049c575f80fd5b506104b760048036038101906104b29190613f3f565b610eab565b005b3480156104c4575f80fd5b506104df60048036038101906104da9190613f6a565b611021565b005b6104fb60048036038101906104f69190613f95565b61106c565b005b348015610508575f80fd5b50610523600480360381019061051e9190613fe5565b61137a565b604051610531929190613a78565b60405180910390f35b348015610545575f80fd5b5061054e611556565b60405161055b9190613e96565b60405180910390f35b34801561056f575f80fd5b5061057861155f565b005b348015610585575f80fd5b506105a0600480360381019061059b919061405e565b6115f2565b6040516105ad9190613e96565b60405180910390f35b6105d060048036038101906105cb9190613f95565b611674565b005b3480156105dd575f80fd5b506105f860048036038101906105f39190613e14565b611693565b005b348015610605575f80fd5b50610620600480360381019061061b919061405e565b6116a5565b005b34801561062d575f80fd5b50610648600480360381019061064391906141c4565b6118ab565b005b348015610655575f80fd5b5061065e6118c6565b60405161066b9190613bf0565b60405180910390f35b34801561067f575f80fd5b5061069a60048036038101906106959190613e14565b6118d7565b6040516106a79190613e3f565b60405180910390f35b3480156106bb575f80fd5b506106c46118e8565b6040516106d19190613df4565b60405180910390f35b3480156106e5575f80fd5b5061070060048036038101906106fb91906142a9565b611974565b60405161070d9190613bf0565b60405180910390f35b348015610721575f80fd5b5061073c60048036038101906107379190613f6a565b611a6a565b6040516107499190613e96565b60405180910390f35b34801561075d575f80fd5b5061077860048036038101906107739190613f6a565b611a7f565b6040516107859190613e96565b60405180910390f35b348015610799575f80fd5b506107a2611b34565b005b3480156107af575f80fd5b506107b8611b47565b6040516107cb97969594939291906143f9565b60405180910390f35b3480156107df575f80fd5b506107fa60048036038101906107f59190613e14565b611c44565b6040516108079190613e3f565b60405180910390f35b34801561081b575f80fd5b50610824611c88565b6040516108319190613e3f565b60405180910390f35b348015610845575f80fd5b5061084e611cb0565b60405161085b9190613df4565b60405180910390f35b34801561086f575f80fd5b5061088a60048036038101906108859190613f6a565b611d40565b6040516108979190613e96565b60405180910390f35b6108ba60048036038101906108b591906144d0565b611d86565b005b3480156108c7575f80fd5b506108e260048036038101906108dd9190614561565b61200c565b005b3480156108ef575f80fd5b5061090a60048036038101906109059190613f6a565b612112565b6040516109179190613e96565b60405180910390f35b61093a6004803603810190610935919061459f565b612144565b005b348015610947575f80fd5b50610962600480360381019061095d9190614649565b6121b6565b005b34801561096f575f80fd5b5061098a6004803603810190610985919061405e565b61220c565b6040516109979190613e96565b60405180910390f35b3480156109ab575f80fd5b506109c660048036038101906109c19190613e14565b6122b8565b6040516109d39190613df4565b60405180910390f35b3480156109e7575f80fd5b50610a0260048036038101906109fd9190613f6a565b612353565b604051610a0f9190613e96565b60405180910390f35b348015610a23575f80fd5b50610a2c612399565b604051610a399190613e96565b60405180910390f35b348015610a4d575f80fd5b50610a686004803603810190610a639190614674565b61239f565b604051610a759190613e96565b60405180910390f35b348015610a89575f80fd5b50610a926123e5565b604051610a9f9190613e96565b60405180910390f35b348015610ab3575f80fd5b50610ace6004803603810190610ac9919061469f565b6123ee565b604051610adb9190613bf0565b60405180910390f35b348015610aef575f80fd5b50610b0a6004803603810190610b059190613f6a565b61247c565b005b5f33905090565b5f808583604051602001610b28929190614742565b604051602081830303815290604052805190602001209050610b8d8585808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f82011690508083019250505050505050601954836124fe565b915050949350505050565b5f610ba282612514565b9050919050565b610bb161258d565b610bbb828261260b565b5050565b610bc761258d565b610bcf610e96565b8161ffff161015610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0c906147b7565b60405180910390fd5b8061ffff1660168190555050565b606060028054610c3290614802565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5e90614802565b8015610ca95780601f10610c8057610100808354040283529160200191610ca9565b820191905f5260205f20905b815481529060010190602001808311610c8c57829003601f168201915b5050505050905090565b5f610cbd826127a6565b610cf3576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f610d37826118d7565b90508073ffffffffffffffffffffffffffffffffffffffff16610d58612800565b73ffffffffffffffffffffffffffffffffffffffff1614610dbb57610d8481610d7f612800565b6123ee565b610dba576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b8260065f8481526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60175481565b610e7a61258d565b806014806101000a81548160ff02191690831515021790555050565b5f610e9f612807565b6001545f540303905090565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411610f2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f21906148a2565b60405180910390fd5b5f610f3482612112565b90505f8103610f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6f90614930565b60405180910390fd5b80600a5f828254610f89919061497b565b9250508190555080600c5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550610fe4828261280b565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0568282604051611015929190614a09565b60405180910390a15050565b61102961258d565b8060185f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f611076826128fb565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146110dd576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f806110e8846129be565b915091506110fe81876110f9612800565b6129e1565b61114a576111138661110e612800565b6123ee565b611149576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036111af576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111bc8686866001612a24565b80156111c6575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061128e8561126a888887612a2a565b7c020000000000000000000000000000000000000000000000000000000017612a51565b60045f8681526020019081526020015f20819055505f7c020000000000000000000000000000000000000000000000000000000084160361130a575f6001850190505f60045f8381526020019081526020015f205403611308575f548114611307578360045f8381526020019081526020015f20819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46113728686866001612a7b565b505050505050565b5f805f60115f8681526020019081526020015f206040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff16036115035760106040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b5f61150c612a81565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff16866115389190614a30565b6115429190614a9e565b9050815f0151819350935050509250929050565b5f600954905090565b61156761258d565b61156f612a8a565b5f611578611c88565b73ffffffffffffffffffffffffffffffffffffffff164760405161159b90614afb565b5f6040518083038185875af1925050503d805f81146115d5576040519150601f19603f3d011682016040523d82523d5f602084013e6115da565b606091505b50509050806115e7575f80fd5b506115f0612ad9565b565b5f600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b61168e83838360405180602001604052805f815250612144565b505050565b61169b61258d565b8060178190555050565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411611724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171b906148a2565b60405180910390fd5b5f61172f838361220c565b90505f8103611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176a90614930565b60405180910390fd5b80600e5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546117bf919061497b565b9250508190555080600f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550611856838383612ae3565b8273ffffffffffffffffffffffffffffffffffffffff167f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a838360405161189e929190613a78565b60405180910390a2505050565b6118b361258d565b80601590816118c29190614ca3565b5050565b60148054906101000a900460ff1681565b5f6118e1826128fb565b9050919050565b601580546118f590614802565b80601f016020809104026020016040519081016040528092919081815260200182805461192190614802565b801561196c5780601f106119435761010080835404028352916020019161196c565b820191905f5260205f20905b81548152906001019060200180831161194f57829003601f168201915b505050505081565b5f8061197e612b69565b90505f7ff0b1559ff024fe6a211400bbc1acc6696aa7b9b46e865f1a4e1237c70ff68d15336119ac33611a7f565b6040516020016119be93929190614d72565b6040516020818303038152906040528051906020012090505f82826040516020016119ea929190614e1b565b6040516020818303038152906040528051906020012090505f611a0d8287612c1f565b905060185f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614945050505050919050565b601a602052805f5260405f205f915090505481565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ae5576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611b3c61258d565b611b455f612c44565b565b5f6060805f805f6060611b8460127f0000000000000000000000000000000000000000000000000000000000000000612d0790919063ffffffff16565b611bb860137f0000000000000000000000000000000000000000000000000000000000000000612d0790919063ffffffff16565b46305f801b5f67ffffffffffffffff811115611bd757611bd66140a0565b5b604051908082528060200260200182016040528015611c055781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f600d8281548110611c5957611c58614e51565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f60145f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611cbf90614802565b80601f0160208091040260200160405190810160405280929190818152602001828054611ceb90614802565b8015611d365780601f10611d0d57610100808354040283529160200191611d36565b820191905f5260205f20905b815481529060010190602001808311611d1957829003601f168201915b5050505050905090565b5f600c5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b611d8e612a8a565b611dda85858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050611974565b611e19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1090614ec8565b60405180910390fd5b6016546001611e26610e96565b611e30919061497b565b1115611e71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6890614f30565b60405180910390fd5b611e79611c88565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611efa5760148054906101000a900460ff1615611ef9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef090614f98565b60405180910390fd5b5b611f0633848484610b13565b8015611f4e575080601a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054105b15611fac576001601a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611fa0919061497b565b92505081905550611ff2565b601754341015611ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fe890615000565b60405180910390fd5b5b611ffd336001612db4565b612005612ad9565b5050505050565b8060075f612018612800565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166120c1612800565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516121069190613bf0565b60405180910390a35050565b5f8061211c6123e5565b47612127919061497b565b905061213c838261213786611d40565b612dd1565b915050919050565b61214f84848461106c565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146121b05761217984848484612e3c565b6121af576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6121be61258d565b5f801b8103612202576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121f990615068565b60405180910390fd5b8060198190555050565b5f806122178461239f565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016122509190613e3f565b602060405180830381865afa15801561226b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061228f919061509a565b612299919061497b565b90506122af83826122aa87876115f2565b612dd1565b91505092915050565b60606122c3826127a6565b6122f9576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f612302612f87565b90505f8151036123205760405180602001604052805f81525061234b565b8061232a84613017565b60405160200161233b92919061513f565b6040516020818303038152906040525b915050919050565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60165481565b5f600e5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b5f600a54905090565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b61248461258d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036124f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e9906151dd565b60405180910390fd5b6124fb81612c44565b50565b5f8261250a8584613066565b1490509392505050565b5f7f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806125865750612585826130ba565b5b9050919050565b612595610b0c565b73ffffffffffffffffffffffffffffffffffffffff166125b3611c88565b73ffffffffffffffffffffffffffffffffffffffff1614612609576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260090615245565b60405180910390fd5b565b5f612614612a81565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156126795781816040517f6f483d09000000000000000000000000000000000000000000000000000000008152600401612670929190615293565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126e9575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016126e09190613e3f565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060105f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f816127b0612807565b111580156127be57505f5482105b80156127f957505f7c010000000000000000000000000000000000000000000000000000000060045f8581526020019081526020015f205416145b9050919050565b5f33905090565b5f90565b8047101561284e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284590615304565b60405180910390fd5b5f8273ffffffffffffffffffffffffffffffffffffffff168260405161287390614afb565b5f6040518083038185875af1925050503d805f81146128ad576040519150601f19603f3d011682016040523d82523d5f602084013e6128b2565b606091505b50509050806128f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128ed90615392565b60405180910390fd5b505050565b5f8082905080612909612807565b11612987575f54811015612986575f60045f8381526020019081526020015f205490505f7c0100000000000000000000000000000000000000000000000000000000821603612984575b5f810361297a5760045f836001900393508381526020019081526020015f20549050612953565b80925050506129b9565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e8612a40868684613123565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f612710905090565b600260085403612acf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac6906153fa565b60405180910390fd5b6002600881905550565b6001600881905550565b612b648363a9059cbb60e01b8484604051602401612b02929190613a78565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061312b565b505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015612be457507f000000000000000000000000000000000000000000000000000000000000000046145b15612c11577f00000000000000000000000000000000000000000000000000000000000000009050612c1c565b612c196131f1565b90505b90565b5f805f612c2c8585613286565b91509150612c39816132d2565b819250505092915050565b5f60145f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160145f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606060ff5f1b8314612d2357612d1c83613437565b9050612dae565b818054612d2f90614802565b80601f0160208091040260200160405190810160405280929190818152602001828054612d5b90614802565b8015612da65780601f10612d7d57610100808354040283529160200191612da6565b820191905f5260205f20905b815481529060010190602001808311612d8957829003601f168201915b505050505090505b92915050565b612dcd828260405180602001604052805f8152506134a9565b5050565b5f81600954600b5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205485612e1f9190614a30565b612e299190614a9e565b612e339190615418565b90509392505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612e61612800565b8786866040518563ffffffff1660e01b8152600401612e83949392919061549d565b6020604051808303815f875af1925050508015612ebe57506040513d601f19601f82011682018060405250810190612ebb91906154fb565b60015b612f34573d805f8114612eec576040519150601f19603f3d011682016040523d82523d5f602084013e612ef1565b606091505b505f815103612f2c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606060158054612f9690614802565b80601f0160208091040260200160405190810160405280929190818152602001828054612fc290614802565b801561300d5780601f10612fe45761010080835404028352916020019161300d565b820191905f5260205f20905b815481529060010190602001808311612ff057829003601f168201915b5050505050905090565b606060a060405101806040526020810391505f825281835b60011561305157600184039350600a81066030018453600a810490508061302f575b50828103602084039350808452505050919050565b5f808290505f5b84518110156130af5761309a8286838151811061308d5761308c614e51565b5b6020026020010151613540565b915080806130a790615526565b91505061306d565b508091505092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f9392505050565b5f61318c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661356a9092919063ffffffff16565b90505f815114806131ad5750808060200190518101906131ac9190615581565b5b6131ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131e39061561c565b60405180910390fd5b505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000463060405160200161326b95949392919061563a565b60405160208183030381529060405280519060200120905090565b5f8060418351036132c3575f805f602086015192506040860151915060608601515f1a90506132b787828585613581565b945094505050506132cb565b5f6002915091505b9250929050565b5f60048111156132e5576132e461568b565b5b8160048111156132f8576132f761568b565b5b031561343457600160048111156133125761331161568b565b5b8160048111156133255761332461568b565b5b03613365576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161335c90615702565b60405180910390fd5b600260048111156133795761337861568b565b5b81600481111561338c5761338b61568b565b5b036133cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133c39061576a565b60405180910390fd5b600360048111156133e0576133df61568b565b5b8160048111156133f3576133f261568b565b5b03613433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161342a906157f8565b60405180910390fd5b5b50565b60605f61344383613659565b90505f602067ffffffffffffffff811115613461576134606140a0565b5b6040519080825280601f01601f1916602001820160405280156134935781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b6134b383836136a7565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1461353b575f805490505f83820390505b6134ef5f868380600101945086612e3c565b613525576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106134dd57815f5414613538575f80fd5b50505b505050565b5f818310613557576135528284613850565b613562565b6135618383613850565b5b905092915050565b606061357884845f85613864565b90509392505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0835f1c11156135b9575f600391509150613650565b5f6001878787876040515f81526020016040526040516135dc9493929190615831565b6020604051602081039080840390855afa1580156135fc573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613648575f60019250925050613650565b805f92509250505b94509492505050565b5f8060ff835f1c169050601f81111561369e576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f805490505f82036136e5576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6136f15f848385612a24565b600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550613763836137545f865f612a2a565b61375d8561392d565b17612a51565b60045f8381526020019081526020015f20819055505f80838301905073ffffffffffffffffffffffffffffffffffffffff8516915082825f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4600183015b8181146137fd5780835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a46001810190506137c4565b505f8203613837576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f81905550505061384b5f848385612a7b565b505050565b5f825f528160205260405f20905092915050565b6060824710156138a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138a0906158e4565b60405180910390fd5b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516138d19190615932565b5f6040518083038185875af1925050503d805f811461390b576040519150601f19603f3d011682016040523d82523d5f602084013e613910565b606091505b50915091506139218783838761393c565b92505050949350505050565b5f6001821460e11b9050919050565b6060831561399d575f83510361399557613955856139b0565b613994576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161398b90615992565b60405180910390fd5b5b8290506139a8565b6139a783836139d2565b5b949350505050565b5f808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f825111156139e45781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a189190613df4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613a4a82613a21565b9050919050565b613a5a81613a40565b82525050565b5f819050919050565b613a7281613a60565b82525050565b5f604082019050613a8b5f830185613a51565b613a986020830184613a69565b9392505050565b5f604051905090565b5f80fd5b5f80fd5b613ab981613a40565b8114613ac3575f80fd5b50565b5f81359050613ad481613ab0565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613afb57613afa613ada565b5b8235905067ffffffffffffffff811115613b1857613b17613ade565b5b602083019150836020820283011115613b3457613b33613ae2565b5b9250929050565b613b4481613a60565b8114613b4e575f80fd5b50565b5f81359050613b5f81613b3b565b92915050565b5f805f8060608587031215613b7d57613b7c613aa8565b5b5f613b8a87828801613ac6565b945050602085013567ffffffffffffffff811115613bab57613baa613aac565b5b613bb787828801613ae6565b93509350506040613bca87828801613b51565b91505092959194509250565b5f8115159050919050565b613bea81613bd6565b82525050565b5f602082019050613c035f830184613be1565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613c3d81613c09565b8114613c47575f80fd5b50565b5f81359050613c5881613c34565b92915050565b5f60208284031215613c7357613c72613aa8565b5b5f613c8084828501613c4a565b91505092915050565b5f6bffffffffffffffffffffffff82169050919050565b613ca981613c89565b8114613cb3575f80fd5b50565b5f81359050613cc481613ca0565b92915050565b5f8060408385031215613ce057613cdf613aa8565b5b5f613ced85828601613ac6565b9250506020613cfe85828601613cb6565b9150509250929050565b5f61ffff82169050919050565b613d1e81613d08565b8114613d28575f80fd5b50565b5f81359050613d3981613d15565b92915050565b5f60208284031215613d5457613d53613aa8565b5b5f613d6184828501613d2b565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613da1578082015181840152602081019050613d86565b5f8484015250505050565b5f601f19601f8301169050919050565b5f613dc682613d6a565b613dd08185613d74565b9350613de0818560208601613d84565b613de981613dac565b840191505092915050565b5f6020820190508181035f830152613e0c8184613dbc565b905092915050565b5f60208284031215613e2957613e28613aa8565b5b5f613e3684828501613b51565b91505092915050565b5f602082019050613e525f830184613a51565b92915050565b5f8060408385031215613e6e57613e6d613aa8565b5b5f613e7b85828601613ac6565b9250506020613e8c85828601613b51565b9150509250929050565b5f602082019050613ea95f830184613a69565b92915050565b613eb881613bd6565b8114613ec2575f80fd5b50565b5f81359050613ed381613eaf565b92915050565b5f60208284031215613eee57613eed613aa8565b5b5f613efb84828501613ec5565b91505092915050565b5f613f0e82613a21565b9050919050565b613f1e81613f04565b8114613f28575f80fd5b50565b5f81359050613f3981613f15565b92915050565b5f60208284031215613f5457613f53613aa8565b5b5f613f6184828501613f2b565b91505092915050565b5f60208284031215613f7f57613f7e613aa8565b5b5f613f8c84828501613ac6565b91505092915050565b5f805f60608486031215613fac57613fab613aa8565b5b5f613fb986828701613ac6565b9350506020613fca86828701613ac6565b9250506040613fdb86828701613b51565b9150509250925092565b5f8060408385031215613ffb57613ffa613aa8565b5b5f61400885828601613b51565b925050602061401985828601613b51565b9150509250929050565b5f61402d82613a40565b9050919050565b61403d81614023565b8114614047575f80fd5b50565b5f8135905061405881614034565b92915050565b5f806040838503121561407457614073613aa8565b5b5f6140818582860161404a565b925050602061409285828601613ac6565b9150509250929050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6140d682613dac565b810181811067ffffffffffffffff821117156140f5576140f46140a0565b5b80604052505050565b5f614107613a9f565b905061411382826140cd565b919050565b5f67ffffffffffffffff821115614132576141316140a0565b5b61413b82613dac565b9050602081019050919050565b828183375f83830152505050565b5f61416861416384614118565b6140fe565b9050828152602081018484840111156141845761418361409c565b5b61418f848285614148565b509392505050565b5f82601f8301126141ab576141aa613ada565b5b81356141bb848260208601614156565b91505092915050565b5f602082840312156141d9576141d8613aa8565b5b5f82013567ffffffffffffffff8111156141f6576141f5613aac565b5b61420284828501614197565b91505092915050565b5f67ffffffffffffffff821115614225576142246140a0565b5b61422e82613dac565b9050602081019050919050565b5f61424d6142488461420b565b6140fe565b9050828152602081018484840111156142695761426861409c565b5b614274848285614148565b509392505050565b5f82601f8301126142905761428f613ada565b5b81356142a084826020860161423b565b91505092915050565b5f602082840312156142be576142bd613aa8565b5b5f82013567ffffffffffffffff8111156142db576142da613aac565b5b6142e78482850161427c565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b614324816142f0565b82525050565b5f819050919050565b61433c8161432a565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61437481613a60565b82525050565b5f614385838361436b565b60208301905092915050565b5f602082019050919050565b5f6143a782614342565b6143b1818561434c565b93506143bc8361435c565b805f5b838110156143ec5781516143d3888261437a565b97506143de83614391565b9250506001810190506143bf565b5085935050505092915050565b5f60e08201905061440c5f83018a61431b565b818103602083015261441e8189613dbc565b905081810360408301526144328188613dbc565b90506144416060830187613a69565b61444e6080830186613a51565b61445b60a0830185614333565b81810360c083015261446d818461439d565b905098975050505050505050565b5f8083601f8401126144905761448f613ada565b5b8235905067ffffffffffffffff8111156144ad576144ac613ade565b5b6020830191508360018202830111156144c9576144c8613ae2565b5b9250929050565b5f805f805f606086880312156144e9576144e8613aa8565b5b5f86013567ffffffffffffffff81111561450657614505613aac565b5b6145128882890161447b565b9550955050602086013567ffffffffffffffff81111561453557614534613aac565b5b61454188828901613ae6565b9350935050604061455488828901613b51565b9150509295509295909350565b5f806040838503121561457757614576613aa8565b5b5f61458485828601613ac6565b925050602061459585828601613ec5565b9150509250929050565b5f805f80608085870312156145b7576145b6613aa8565b5b5f6145c487828801613ac6565b94505060206145d587828801613ac6565b93505060406145e687828801613b51565b925050606085013567ffffffffffffffff81111561460757614606613aac565b5b6146138782880161427c565b91505092959194509250565b6146288161432a565b8114614632575f80fd5b50565b5f813590506146438161461f565b92915050565b5f6020828403121561465e5761465d613aa8565b5b5f61466b84828501614635565b91505092915050565b5f6020828403121561468957614688613aa8565b5b5f6146968482850161404a565b91505092915050565b5f80604083850312156146b5576146b4613aa8565b5b5f6146c285828601613ac6565b92505060206146d385828601613ac6565b9150509250929050565b5f8160601b9050919050565b5f6146f3826146dd565b9050919050565b5f614704826146e9565b9050919050565b61471c61471782613a40565b6146fa565b82525050565b5f819050919050565b61473c61473782613a60565b614722565b82525050565b5f61474d828561470b565b60148201915061475d828461472b565b6020820191508190509392505050565b7f4d757374206265206d6f7265207468616e2063757272656e7420737570706c795f82015250565b5f6147a1602083613d74565b91506147ac8261476d565b602082019050919050565b5f6020820190508181035f8301526147ce81614795565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061481957607f821691505b60208210810361482c5761482b6147d5565b5b50919050565b7f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f205f8201527f7368617265730000000000000000000000000000000000000000000000000000602082015250565b5f61488c602683613d74565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f5061796d656e7453706c69747465723a206163636f756e74206973206e6f74205f8201527f647565207061796d656e74000000000000000000000000000000000000000000602082015250565b5f61491a602b83613d74565b9150614925826148c0565b604082019050919050565b5f6020820190508181035f8301526149478161490e565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61498582613a60565b915061499083613a60565b92508282019050808211156149a8576149a761494e565b5b92915050565b5f819050919050565b5f6149d16149cc6149c784613a21565b6149ae565b613a21565b9050919050565b5f6149e2826149b7565b9050919050565b5f6149f3826149d8565b9050919050565b614a03816149e9565b82525050565b5f604082019050614a1c5f8301856149fa565b614a296020830184613a69565b9392505050565b5f614a3a82613a60565b9150614a4583613a60565b9250828202614a5381613a60565b91508282048414831517614a6a57614a6961494e565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f614aa882613a60565b9150614ab383613a60565b925082614ac357614ac2614a71565b5b828204905092915050565b5f81905092915050565b50565b5f614ae65f83614ace565b9150614af182614ad8565b5f82019050919050565b5f614b0582614adb565b9150819050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614b6b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614b30565b614b758683614b30565b95508019841693508086168417925050509392505050565b5f614ba7614ba2614b9d84613a60565b6149ae565b613a60565b9050919050565b5f819050919050565b614bc083614b8d565b614bd4614bcc82614bae565b848454614b3c565b825550505050565b5f90565b614be8614bdc565b614bf3818484614bb7565b505050565b5b81811015614c1657614c0b5f82614be0565b600181019050614bf9565b5050565b601f821115614c5b57614c2c81614b0f565b614c3584614b21565b81016020851015614c44578190505b614c58614c5085614b21565b830182614bf8565b50505b505050565b5f82821c905092915050565b5f614c7b5f1984600802614c60565b1980831691505092915050565b5f614c938383614c6c565b9150826002028217905092915050565b614cac82613d6a565b67ffffffffffffffff811115614cc557614cc46140a0565b5b614ccf8254614802565b614cda828285614c1a565b5f60209050601f831160018114614d0b575f8415614cf9578287015190505b614d038582614c88565b865550614d6a565b601f198416614d1986614b0f565b5f5b82811015614d4057848901518255600182019150602085019450602081019050614d1b565b86831015614d5d5784890151614d59601f891682614c6c565b8355505b6001600288020188555050505b505050505050565b5f606082019050614d855f830186614333565b614d926020830185613a51565b614d9f6040830184613a69565b949350505050565b5f81905092915050565b7f19010000000000000000000000000000000000000000000000000000000000005f82015250565b5f614de5600283614da7565b9150614df082614db1565b600282019050919050565b5f819050919050565b614e15614e108261432a565b614dfb565b82525050565b5f614e2582614dd9565b9150614e318285614e04565b602082019150614e418284614e04565b6020820191508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4d696e74206f6e205765627369746500000000000000000000000000000000005f82015250565b5f614eb2600f83613d74565b9150614ebd82614e7e565b602082019050919050565b5f6020820190508181035f830152614edf81614ea6565b9050919050565b7f4e6f204d6f726520537570706c790000000000000000000000000000000000005f82015250565b5f614f1a600e83613d74565b9150614f2582614ee6565b602082019050919050565b5f6020820190508181035f830152614f4781614f0e565b9050919050565b7f4d696e74205061757365640000000000000000000000000000000000000000005f82015250565b5f614f82600b83613d74565b9150614f8d82614f4e565b602082019050919050565b5f6020820190508181035f830152614faf81614f76565b9050919050565b7f50617920666f72204d696e7400000000000000000000000000000000000000005f82015250565b5f614fea600c83613d74565b9150614ff582614fb6565b602082019050919050565b5f6020820190508181035f83015261501781614fde565b9050919050565b7f4d65726b6c65526f6f74206973203000000000000000000000000000000000005f82015250565b5f615052600f83613d74565b915061505d8261501e565b602082019050919050565b5f6020820190508181035f83015261507f81615046565b9050919050565b5f8151905061509481613b3b565b92915050565b5f602082840312156150af576150ae613aa8565b5b5f6150bc84828501615086565b91505092915050565b5f6150cf82613d6a565b6150d98185614da7565b93506150e9818560208601613d84565b80840191505092915050565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000005f82015250565b5f615129600583614da7565b9150615134826150f5565b600582019050919050565b5f61514a82856150c5565b915061515682846150c5565b91506151618261511d565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6151c7602683613d74565b91506151d28261516d565b604082019050919050565b5f6020820190508181035f8301526151f4816151bb565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f61522f602083613d74565b915061523a826151fb565b602082019050919050565b5f6020820190508181035f83015261525c81615223565b9050919050565b5f61527d61527861527384613c89565b6149ae565b613a60565b9050919050565b61528d81615263565b82525050565b5f6040820190506152a65f830185615284565b6152b36020830184613a69565b9392505050565b7f416464726573733a20696e73756666696369656e742062616c616e63650000005f82015250565b5f6152ee601d83613d74565b91506152f9826152ba565b602082019050919050565b5f6020820190508181035f83015261531b816152e2565b9050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c20725f8201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b5f61537c603a83613d74565b915061538782615322565b604082019050919050565b5f6020820190508181035f8301526153a981615370565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f6153e4601f83613d74565b91506153ef826153b0565b602082019050919050565b5f6020820190508181035f830152615411816153d8565b9050919050565b5f61542282613a60565b915061542d83613a60565b92508282039050818111156154455761544461494e565b5b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f61546f8261544b565b6154798185615455565b9350615489818560208601613d84565b61549281613dac565b840191505092915050565b5f6080820190506154b05f830187613a51565b6154bd6020830186613a51565b6154ca6040830185613a69565b81810360608301526154dc8184615465565b905095945050505050565b5f815190506154f581613c34565b92915050565b5f602082840312156155105761550f613aa8565b5b5f61551d848285016154e7565b91505092915050565b5f61553082613a60565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036155625761556161494e565b5b600182019050919050565b5f8151905061557b81613eaf565b92915050565b5f6020828403121561559657615595613aa8565b5b5f6155a38482850161556d565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e5f8201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b5f615606602a83613d74565b9150615611826155ac565b604082019050919050565b5f6020820190508181035f830152615633816155fa565b9050919050565b5f60a08201905061564d5f830188614333565b61565a6020830187614333565b6156676040830186614333565b6156746060830185613a69565b6156816080830184613a51565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f45434453413a20696e76616c6964207369676e617475726500000000000000005f82015250565b5f6156ec601883613d74565b91506156f7826156b8565b602082019050919050565b5f6020820190508181035f830152615719816156e0565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e677468005f82015250565b5f615754601f83613d74565b915061575f82615720565b602082019050919050565b5f6020820190508181035f83015261578181615748565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c5f8201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b5f6157e2602283613d74565b91506157ed82615788565b604082019050919050565b5f6020820190508181035f83015261580f816157d6565b9050919050565b5f60ff82169050919050565b61582b81615816565b82525050565b5f6080820190506158445f830187614333565b6158516020830186615822565b61585e6040830185614333565b61586b6060830184614333565b95945050505050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f5f8201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b5f6158ce602683613d74565b91506158d982615874565b604082019050919050565b5f6020820190508181035f8301526158fb816158c2565b9050919050565b5f61590c8261544b565b6159168185614ace565b9350615926818560208601613d84565b80840191505092915050565b5f61593d8284615902565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000005f82015250565b5f61597c601d83613d74565b915061598782615948565b602082019050919050565b5f6020820190508181035f8301526159a981615970565b905091905056fea264697066735822122099c8f5f0f169fd2b575caebd56ce7fa194bc905a6429bea85c898f69abd4919164736f6c6343000815003368747470733a2f2f6564697469656e736e66742e73332e616d617a6f6e6177732e636f6d2f6d657461646174612f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000006000000000000000000000000db3e025a4ca9e304728318dce52500bc8f4a69f4000000000000000000000000c09c1e95c2822ac9dd33afd0f36fae1115b6f6e900000000000000000000000050d10e2ac5adb6dc3fe0bd62794f49ac5f9e6a62000000000000000000000000523aad76f08e52c3992b5f0a2be305fdf82166f9000000000000000000000000b832d4b24045690f5fc4476703fe0a35b4861f9300000000000000000000000042b385252781c1c4d36d91300b734520a834d733000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000f
Deployed Bytecode
0x608060405260043610610280575f3560e01c80636c0360eb1161014e578063a22cb465116100c0578063ce7c2ac211610079578063ce7c2ac2146109dc578063d5abeb0114610a18578063d79779b214610a42578063e33b7de314610a7e578063e985e9c514610aa8578063f2fde38b14610ae4576102c7565b8063a22cb465146108bc578063a3f8eace146108e4578063b88d4fde14610920578063bd32fb661461093c578063c45ac05014610964578063c87b56dd146109a0576102c7565b806384b0196e1161011257806384b0196e146107a45780638b83209b146107d45780638da5cb5b1461081057806395d89b411461083a5780639852595c146108645780639999a040146108a0576102c7565b80636c0360eb146106b05780636c8e7ec5146106da5780636d41d4fb1461071657806370a0823114610752578063715018a61461078e576102c7565b806320510b55116101f257806342842e0e116101ab57806342842e0e146105b657806344a0d68a146105d257806348b75044146105fa57806355f804b3146106225780635c975abb1461064a5780636352211e14610674576102c7565b806320510b55146104b957806323b872dd146104e15780632a55205a146104fd5780633a98ef391461053a5780633ccfd60b14610564578063406072a91461057a576102c7565b8063081812fc11610244578063081812fc146103bd578063095ea7b3146103f957806313faede61461041557806316c38b3c1461043f57806318160ddd146104675780631916558714610491576102c7565b806301b4afbf146102cb57806301ffc9a71461030757806304634d8d1461034357806306421c2f1461036b57806306fdde0314610393576102c7565b366102c7577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be7706102ae610b0c565b346040516102bd929190613a78565b60405180910390a1005b5f80fd5b3480156102d6575f80fd5b506102f160048036038101906102ec9190613b65565b610b13565b6040516102fe9190613bf0565b60405180910390f35b348015610312575f80fd5b5061032d60048036038101906103289190613c5e565b610b98565b60405161033a9190613bf0565b60405180910390f35b34801561034e575f80fd5b5061036960048036038101906103649190613cca565b610ba9565b005b348015610376575f80fd5b50610391600480360381019061038c9190613d3f565b610bbf565b005b34801561039e575f80fd5b506103a7610c23565b6040516103b49190613df4565b60405180910390f35b3480156103c8575f80fd5b506103e360048036038101906103de9190613e14565b610cb3565b6040516103f09190613e3f565b60405180910390f35b610413600480360381019061040e9190613e58565b610d2d565b005b348015610420575f80fd5b50610429610e6c565b6040516104369190613e96565b60405180910390f35b34801561044a575f80fd5b5061046560048036038101906104609190613ed9565b610e72565b005b348015610472575f80fd5b5061047b610e96565b6040516104889190613e96565b60405180910390f35b34801561049c575f80fd5b506104b760048036038101906104b29190613f3f565b610eab565b005b3480156104c4575f80fd5b506104df60048036038101906104da9190613f6a565b611021565b005b6104fb60048036038101906104f69190613f95565b61106c565b005b348015610508575f80fd5b50610523600480360381019061051e9190613fe5565b61137a565b604051610531929190613a78565b60405180910390f35b348015610545575f80fd5b5061054e611556565b60405161055b9190613e96565b60405180910390f35b34801561056f575f80fd5b5061057861155f565b005b348015610585575f80fd5b506105a0600480360381019061059b919061405e565b6115f2565b6040516105ad9190613e96565b60405180910390f35b6105d060048036038101906105cb9190613f95565b611674565b005b3480156105dd575f80fd5b506105f860048036038101906105f39190613e14565b611693565b005b348015610605575f80fd5b50610620600480360381019061061b919061405e565b6116a5565b005b34801561062d575f80fd5b50610648600480360381019061064391906141c4565b6118ab565b005b348015610655575f80fd5b5061065e6118c6565b60405161066b9190613bf0565b60405180910390f35b34801561067f575f80fd5b5061069a60048036038101906106959190613e14565b6118d7565b6040516106a79190613e3f565b60405180910390f35b3480156106bb575f80fd5b506106c46118e8565b6040516106d19190613df4565b60405180910390f35b3480156106e5575f80fd5b5061070060048036038101906106fb91906142a9565b611974565b60405161070d9190613bf0565b60405180910390f35b348015610721575f80fd5b5061073c60048036038101906107379190613f6a565b611a6a565b6040516107499190613e96565b60405180910390f35b34801561075d575f80fd5b5061077860048036038101906107739190613f6a565b611a7f565b6040516107859190613e96565b60405180910390f35b348015610799575f80fd5b506107a2611b34565b005b3480156107af575f80fd5b506107b8611b47565b6040516107cb97969594939291906143f9565b60405180910390f35b3480156107df575f80fd5b506107fa60048036038101906107f59190613e14565b611c44565b6040516108079190613e3f565b60405180910390f35b34801561081b575f80fd5b50610824611c88565b6040516108319190613e3f565b60405180910390f35b348015610845575f80fd5b5061084e611cb0565b60405161085b9190613df4565b60405180910390f35b34801561086f575f80fd5b5061088a60048036038101906108859190613f6a565b611d40565b6040516108979190613e96565b60405180910390f35b6108ba60048036038101906108b591906144d0565b611d86565b005b3480156108c7575f80fd5b506108e260048036038101906108dd9190614561565b61200c565b005b3480156108ef575f80fd5b5061090a60048036038101906109059190613f6a565b612112565b6040516109179190613e96565b60405180910390f35b61093a6004803603810190610935919061459f565b612144565b005b348015610947575f80fd5b50610962600480360381019061095d9190614649565b6121b6565b005b34801561096f575f80fd5b5061098a6004803603810190610985919061405e565b61220c565b6040516109979190613e96565b60405180910390f35b3480156109ab575f80fd5b506109c660048036038101906109c19190613e14565b6122b8565b6040516109d39190613df4565b60405180910390f35b3480156109e7575f80fd5b50610a0260048036038101906109fd9190613f6a565b612353565b604051610a0f9190613e96565b60405180910390f35b348015610a23575f80fd5b50610a2c612399565b604051610a399190613e96565b60405180910390f35b348015610a4d575f80fd5b50610a686004803603810190610a639190614674565b61239f565b604051610a759190613e96565b60405180910390f35b348015610a89575f80fd5b50610a926123e5565b604051610a9f9190613e96565b60405180910390f35b348015610ab3575f80fd5b50610ace6004803603810190610ac9919061469f565b6123ee565b604051610adb9190613bf0565b60405180910390f35b348015610aef575f80fd5b50610b0a6004803603810190610b059190613f6a565b61247c565b005b5f33905090565b5f808583604051602001610b28929190614742565b604051602081830303815290604052805190602001209050610b8d8585808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f82011690508083019250505050505050601954836124fe565b915050949350505050565b5f610ba282612514565b9050919050565b610bb161258d565b610bbb828261260b565b5050565b610bc761258d565b610bcf610e96565b8161ffff161015610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0c906147b7565b60405180910390fd5b8061ffff1660168190555050565b606060028054610c3290614802565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5e90614802565b8015610ca95780601f10610c8057610100808354040283529160200191610ca9565b820191905f5260205f20905b815481529060010190602001808311610c8c57829003601f168201915b5050505050905090565b5f610cbd826127a6565b610cf3576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f610d37826118d7565b90508073ffffffffffffffffffffffffffffffffffffffff16610d58612800565b73ffffffffffffffffffffffffffffffffffffffff1614610dbb57610d8481610d7f612800565b6123ee565b610dba576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b8260065f8481526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60175481565b610e7a61258d565b806014806101000a81548160ff02191690831515021790555050565b5f610e9f612807565b6001545f540303905090565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411610f2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f21906148a2565b60405180910390fd5b5f610f3482612112565b90505f8103610f78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6f90614930565b60405180910390fd5b80600a5f828254610f89919061497b565b9250508190555080600c5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550610fe4828261280b565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0568282604051611015929190614a09565b60405180910390a15050565b61102961258d565b8060185f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f611076826128fb565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146110dd576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f806110e8846129be565b915091506110fe81876110f9612800565b6129e1565b61114a576111138661110e612800565b6123ee565b611149576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036111af576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111bc8686866001612a24565b80156111c6575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061128e8561126a888887612a2a565b7c020000000000000000000000000000000000000000000000000000000017612a51565b60045f8681526020019081526020015f20819055505f7c020000000000000000000000000000000000000000000000000000000084160361130a575f6001850190505f60045f8381526020019081526020015f205403611308575f548114611307578360045f8381526020019081526020015f20819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46113728686866001612a7b565b505050505050565b5f805f60115f8681526020019081526020015f206040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505f73ffffffffffffffffffffffffffffffffffffffff16815f015173ffffffffffffffffffffffffffffffffffffffff16036115035760106040518060400160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b5f61150c612a81565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff16866115389190614a30565b6115429190614a9e565b9050815f0151819350935050509250929050565b5f600954905090565b61156761258d565b61156f612a8a565b5f611578611c88565b73ffffffffffffffffffffffffffffffffffffffff164760405161159b90614afb565b5f6040518083038185875af1925050503d805f81146115d5576040519150601f19603f3d011682016040523d82523d5f602084013e6115da565b606091505b50509050806115e7575f80fd5b506115f0612ad9565b565b5f600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b61168e83838360405180602001604052805f815250612144565b505050565b61169b61258d565b8060178190555050565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411611724576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171b906148a2565b60405180910390fd5b5f61172f838361220c565b90505f8103611773576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176a90614930565b60405180910390fd5b80600e5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546117bf919061497b565b9250508190555080600f5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550611856838383612ae3565b8273ffffffffffffffffffffffffffffffffffffffff167f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a838360405161189e929190613a78565b60405180910390a2505050565b6118b361258d565b80601590816118c29190614ca3565b5050565b60148054906101000a900460ff1681565b5f6118e1826128fb565b9050919050565b601580546118f590614802565b80601f016020809104026020016040519081016040528092919081815260200182805461192190614802565b801561196c5780601f106119435761010080835404028352916020019161196c565b820191905f5260205f20905b81548152906001019060200180831161194f57829003601f168201915b505050505081565b5f8061197e612b69565b90505f7ff0b1559ff024fe6a211400bbc1acc6696aa7b9b46e865f1a4e1237c70ff68d15336119ac33611a7f565b6040516020016119be93929190614d72565b6040516020818303038152906040528051906020012090505f82826040516020016119ea929190614e1b565b6040516020818303038152906040528051906020012090505f611a0d8287612c1f565b905060185f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614945050505050919050565b601a602052805f5260405f205f915090505481565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ae5576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611b3c61258d565b611b455f612c44565b565b5f6060805f805f6060611b8460127f4564697469656e73000000000000000000000000000000000000000000000008612d0790919063ffffffff16565b611bb860137f3100000000000000000000000000000000000000000000000000000000000001612d0790919063ffffffff16565b46305f801b5f67ffffffffffffffff811115611bd757611bd66140a0565b5b604051908082528060200260200182016040528015611c055781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f600d8281548110611c5957611c58614e51565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f60145f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611cbf90614802565b80601f0160208091040260200160405190810160405280929190818152602001828054611ceb90614802565b8015611d365780601f10611d0d57610100808354040283529160200191611d36565b820191905f5260205f20905b815481529060010190602001808311611d1957829003601f168201915b5050505050905090565b5f600c5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b611d8e612a8a565b611dda85858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050611974565b611e19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1090614ec8565b60405180910390fd5b6016546001611e26610e96565b611e30919061497b565b1115611e71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6890614f30565b60405180910390fd5b611e79611c88565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611efa5760148054906101000a900460ff1615611ef9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef090614f98565b60405180910390fd5b5b611f0633848484610b13565b8015611f4e575080601a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054105b15611fac576001601a5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254611fa0919061497b565b92505081905550611ff2565b601754341015611ff1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fe890615000565b60405180910390fd5b5b611ffd336001612db4565b612005612ad9565b5050505050565b8060075f612018612800565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166120c1612800565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516121069190613bf0565b60405180910390a35050565b5f8061211c6123e5565b47612127919061497b565b905061213c838261213786611d40565b612dd1565b915050919050565b61214f84848461106c565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146121b05761217984848484612e3c565b6121af576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6121be61258d565b5f801b8103612202576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121f990615068565b60405180910390fd5b8060198190555050565b5f806122178461239f565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016122509190613e3f565b602060405180830381865afa15801561226b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061228f919061509a565b612299919061497b565b90506122af83826122aa87876115f2565b612dd1565b91505092915050565b60606122c3826127a6565b6122f9576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f612302612f87565b90505f8151036123205760405180602001604052805f81525061234b565b8061232a84613017565b60405160200161233b92919061513f565b6040516020818303038152906040525b915050919050565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60165481565b5f600e5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b5f600a54905090565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b61248461258d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036124f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e9906151dd565b60405180910390fd5b6124fb81612c44565b50565b5f8261250a8584613066565b1490509392505050565b5f7f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806125865750612585826130ba565b5b9050919050565b612595610b0c565b73ffffffffffffffffffffffffffffffffffffffff166125b3611c88565b73ffffffffffffffffffffffffffffffffffffffff1614612609576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260090615245565b60405180910390fd5b565b5f612614612a81565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156126795781816040517f6f483d09000000000000000000000000000000000000000000000000000000008152600401612670929190615293565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126e9575f6040517fb6d9900a0000000000000000000000000000000000000000000000000000000081526004016126e09190613e3f565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff1681525060105f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151815f0160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b5f816127b0612807565b111580156127be57505f5482105b80156127f957505f7c010000000000000000000000000000000000000000000000000000000060045f8581526020019081526020015f205416145b9050919050565b5f33905090565b5f90565b8047101561284e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284590615304565b60405180910390fd5b5f8273ffffffffffffffffffffffffffffffffffffffff168260405161287390614afb565b5f6040518083038185875af1925050503d805f81146128ad576040519150601f19603f3d011682016040523d82523d5f602084013e6128b2565b606091505b50509050806128f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128ed90615392565b60405180910390fd5b505050565b5f8082905080612909612807565b11612987575f54811015612986575f60045f8381526020019081526020015f205490505f7c0100000000000000000000000000000000000000000000000000000000821603612984575b5f810361297a5760045f836001900393508381526020019081526020015f20549050612953565b80925050506129b9565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e8612a40868684613123565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b5f612710905090565b600260085403612acf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac6906153fa565b60405180910390fd5b6002600881905550565b6001600881905550565b612b648363a9059cbb60e01b8484604051602401612b02929190613a78565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061312b565b505050565b5f7f000000000000000000000000665c31d41ae01d2cf69498a30fe9e1f29acc324773ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015612be457507f000000000000000000000000000000000000000000000000000000000000000146145b15612c11577f06e588ae0986243b8c48e49fe936c0e64e0756a9a29f78023d96fa710f5234e29050612c1c565b612c196131f1565b90505b90565b5f805f612c2c8585613286565b91509150612c39816132d2565b819250505092915050565b5f60145f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160145f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606060ff5f1b8314612d2357612d1c83613437565b9050612dae565b818054612d2f90614802565b80601f0160208091040260200160405190810160405280929190818152602001828054612d5b90614802565b8015612da65780601f10612d7d57610100808354040283529160200191612da6565b820191905f5260205f20905b815481529060010190602001808311612d8957829003601f168201915b505050505090505b92915050565b612dcd828260405180602001604052805f8152506134a9565b5050565b5f81600954600b5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205485612e1f9190614a30565b612e299190614a9e565b612e339190615418565b90509392505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612e61612800565b8786866040518563ffffffff1660e01b8152600401612e83949392919061549d565b6020604051808303815f875af1925050508015612ebe57506040513d601f19601f82011682018060405250810190612ebb91906154fb565b60015b612f34573d805f8114612eec576040519150601f19603f3d011682016040523d82523d5f602084013e612ef1565b606091505b505f815103612f2c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606060158054612f9690614802565b80601f0160208091040260200160405190810160405280929190818152602001828054612fc290614802565b801561300d5780601f10612fe45761010080835404028352916020019161300d565b820191905f5260205f20905b815481529060010190602001808311612ff057829003601f168201915b5050505050905090565b606060a060405101806040526020810391505f825281835b60011561305157600184039350600a81066030018453600a810490508061302f575b50828103602084039350808452505050919050565b5f808290505f5b84518110156130af5761309a8286838151811061308d5761308c614e51565b5b6020026020010151613540565b915080806130a790615526565b91505061306d565b508091505092915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f9392505050565b5f61318c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661356a9092919063ffffffff16565b90505f815114806131ad5750808060200190518101906131ac9190615581565b5b6131ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131e39061561c565b60405180910390fd5b505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f8a25845f64a645671751233ae78552ec691888101bfbb213f924b141d5a527437fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6463060405160200161326b95949392919061563a565b60405160208183030381529060405280519060200120905090565b5f8060418351036132c3575f805f602086015192506040860151915060608601515f1a90506132b787828585613581565b945094505050506132cb565b5f6002915091505b9250929050565b5f60048111156132e5576132e461568b565b5b8160048111156132f8576132f761568b565b5b031561343457600160048111156133125761331161568b565b5b8160048111156133255761332461568b565b5b03613365576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161335c90615702565b60405180910390fd5b600260048111156133795761337861568b565b5b81600481111561338c5761338b61568b565b5b036133cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133c39061576a565b60405180910390fd5b600360048111156133e0576133df61568b565b5b8160048111156133f3576133f261568b565b5b03613433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161342a906157f8565b60405180910390fd5b5b50565b60605f61344383613659565b90505f602067ffffffffffffffff811115613461576134606140a0565b5b6040519080825280601f01601f1916602001820160405280156134935781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b6134b383836136a7565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1461353b575f805490505f83820390505b6134ef5f868380600101945086612e3c565b613525576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106134dd57815f5414613538575f80fd5b50505b505050565b5f818310613557576135528284613850565b613562565b6135618383613850565b5b905092915050565b606061357884845f85613864565b90509392505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0835f1c11156135b9575f600391509150613650565b5f6001878787876040515f81526020016040526040516135dc9493929190615831565b6020604051602081039080840390855afa1580156135fc573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613648575f60019250925050613650565b805f92509250505b94509492505050565b5f8060ff835f1c169050601f81111561369e576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f805490505f82036136e5576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6136f15f848385612a24565b600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550613763836137545f865f612a2a565b61375d8561392d565b17612a51565b60045f8381526020019081526020015f20819055505f80838301905073ffffffffffffffffffffffffffffffffffffffff8516915082825f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4600183015b8181146137fd5780835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a46001810190506137c4565b505f8203613837576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f81905550505061384b5f848385612a7b565b505050565b5f825f528160205260405f20905092915050565b6060824710156138a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138a0906158e4565b60405180910390fd5b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516138d19190615932565b5f6040518083038185875af1925050503d805f811461390b576040519150601f19603f3d011682016040523d82523d5f602084013e613910565b606091505b50915091506139218783838761393c565b92505050949350505050565b5f6001821460e11b9050919050565b6060831561399d575f83510361399557613955856139b0565b613994576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161398b90615992565b60405180910390fd5b5b8290506139a8565b6139a783836139d2565b5b949350505050565b5f808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5f825111156139e45781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a189190613df4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613a4a82613a21565b9050919050565b613a5a81613a40565b82525050565b5f819050919050565b613a7281613a60565b82525050565b5f604082019050613a8b5f830185613a51565b613a986020830184613a69565b9392505050565b5f604051905090565b5f80fd5b5f80fd5b613ab981613a40565b8114613ac3575f80fd5b50565b5f81359050613ad481613ab0565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613afb57613afa613ada565b5b8235905067ffffffffffffffff811115613b1857613b17613ade565b5b602083019150836020820283011115613b3457613b33613ae2565b5b9250929050565b613b4481613a60565b8114613b4e575f80fd5b50565b5f81359050613b5f81613b3b565b92915050565b5f805f8060608587031215613b7d57613b7c613aa8565b5b5f613b8a87828801613ac6565b945050602085013567ffffffffffffffff811115613bab57613baa613aac565b5b613bb787828801613ae6565b93509350506040613bca87828801613b51565b91505092959194509250565b5f8115159050919050565b613bea81613bd6565b82525050565b5f602082019050613c035f830184613be1565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613c3d81613c09565b8114613c47575f80fd5b50565b5f81359050613c5881613c34565b92915050565b5f60208284031215613c7357613c72613aa8565b5b5f613c8084828501613c4a565b91505092915050565b5f6bffffffffffffffffffffffff82169050919050565b613ca981613c89565b8114613cb3575f80fd5b50565b5f81359050613cc481613ca0565b92915050565b5f8060408385031215613ce057613cdf613aa8565b5b5f613ced85828601613ac6565b9250506020613cfe85828601613cb6565b9150509250929050565b5f61ffff82169050919050565b613d1e81613d08565b8114613d28575f80fd5b50565b5f81359050613d3981613d15565b92915050565b5f60208284031215613d5457613d53613aa8565b5b5f613d6184828501613d2b565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613da1578082015181840152602081019050613d86565b5f8484015250505050565b5f601f19601f8301169050919050565b5f613dc682613d6a565b613dd08185613d74565b9350613de0818560208601613d84565b613de981613dac565b840191505092915050565b5f6020820190508181035f830152613e0c8184613dbc565b905092915050565b5f60208284031215613e2957613e28613aa8565b5b5f613e3684828501613b51565b91505092915050565b5f602082019050613e525f830184613a51565b92915050565b5f8060408385031215613e6e57613e6d613aa8565b5b5f613e7b85828601613ac6565b9250506020613e8c85828601613b51565b9150509250929050565b5f602082019050613ea95f830184613a69565b92915050565b613eb881613bd6565b8114613ec2575f80fd5b50565b5f81359050613ed381613eaf565b92915050565b5f60208284031215613eee57613eed613aa8565b5b5f613efb84828501613ec5565b91505092915050565b5f613f0e82613a21565b9050919050565b613f1e81613f04565b8114613f28575f80fd5b50565b5f81359050613f3981613f15565b92915050565b5f60208284031215613f5457613f53613aa8565b5b5f613f6184828501613f2b565b91505092915050565b5f60208284031215613f7f57613f7e613aa8565b5b5f613f8c84828501613ac6565b91505092915050565b5f805f60608486031215613fac57613fab613aa8565b5b5f613fb986828701613ac6565b9350506020613fca86828701613ac6565b9250506040613fdb86828701613b51565b9150509250925092565b5f8060408385031215613ffb57613ffa613aa8565b5b5f61400885828601613b51565b925050602061401985828601613b51565b9150509250929050565b5f61402d82613a40565b9050919050565b61403d81614023565b8114614047575f80fd5b50565b5f8135905061405881614034565b92915050565b5f806040838503121561407457614073613aa8565b5b5f6140818582860161404a565b925050602061409285828601613ac6565b9150509250929050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6140d682613dac565b810181811067ffffffffffffffff821117156140f5576140f46140a0565b5b80604052505050565b5f614107613a9f565b905061411382826140cd565b919050565b5f67ffffffffffffffff821115614132576141316140a0565b5b61413b82613dac565b9050602081019050919050565b828183375f83830152505050565b5f61416861416384614118565b6140fe565b9050828152602081018484840111156141845761418361409c565b5b61418f848285614148565b509392505050565b5f82601f8301126141ab576141aa613ada565b5b81356141bb848260208601614156565b91505092915050565b5f602082840312156141d9576141d8613aa8565b5b5f82013567ffffffffffffffff8111156141f6576141f5613aac565b5b61420284828501614197565b91505092915050565b5f67ffffffffffffffff821115614225576142246140a0565b5b61422e82613dac565b9050602081019050919050565b5f61424d6142488461420b565b6140fe565b9050828152602081018484840111156142695761426861409c565b5b614274848285614148565b509392505050565b5f82601f8301126142905761428f613ada565b5b81356142a084826020860161423b565b91505092915050565b5f602082840312156142be576142bd613aa8565b5b5f82013567ffffffffffffffff8111156142db576142da613aac565b5b6142e78482850161427c565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b614324816142f0565b82525050565b5f819050919050565b61433c8161432a565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61437481613a60565b82525050565b5f614385838361436b565b60208301905092915050565b5f602082019050919050565b5f6143a782614342565b6143b1818561434c565b93506143bc8361435c565b805f5b838110156143ec5781516143d3888261437a565b97506143de83614391565b9250506001810190506143bf565b5085935050505092915050565b5f60e08201905061440c5f83018a61431b565b818103602083015261441e8189613dbc565b905081810360408301526144328188613dbc565b90506144416060830187613a69565b61444e6080830186613a51565b61445b60a0830185614333565b81810360c083015261446d818461439d565b905098975050505050505050565b5f8083601f8401126144905761448f613ada565b5b8235905067ffffffffffffffff8111156144ad576144ac613ade565b5b6020830191508360018202830111156144c9576144c8613ae2565b5b9250929050565b5f805f805f606086880312156144e9576144e8613aa8565b5b5f86013567ffffffffffffffff81111561450657614505613aac565b5b6145128882890161447b565b9550955050602086013567ffffffffffffffff81111561453557614534613aac565b5b61454188828901613ae6565b9350935050604061455488828901613b51565b9150509295509295909350565b5f806040838503121561457757614576613aa8565b5b5f61458485828601613ac6565b925050602061459585828601613ec5565b9150509250929050565b5f805f80608085870312156145b7576145b6613aa8565b5b5f6145c487828801613ac6565b94505060206145d587828801613ac6565b93505060406145e687828801613b51565b925050606085013567ffffffffffffffff81111561460757614606613aac565b5b6146138782880161427c565b91505092959194509250565b6146288161432a565b8114614632575f80fd5b50565b5f813590506146438161461f565b92915050565b5f6020828403121561465e5761465d613aa8565b5b5f61466b84828501614635565b91505092915050565b5f6020828403121561468957614688613aa8565b5b5f6146968482850161404a565b91505092915050565b5f80604083850312156146b5576146b4613aa8565b5b5f6146c285828601613ac6565b92505060206146d385828601613ac6565b9150509250929050565b5f8160601b9050919050565b5f6146f3826146dd565b9050919050565b5f614704826146e9565b9050919050565b61471c61471782613a40565b6146fa565b82525050565b5f819050919050565b61473c61473782613a60565b614722565b82525050565b5f61474d828561470b565b60148201915061475d828461472b565b6020820191508190509392505050565b7f4d757374206265206d6f7265207468616e2063757272656e7420737570706c795f82015250565b5f6147a1602083613d74565b91506147ac8261476d565b602082019050919050565b5f6020820190508181035f8301526147ce81614795565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061481957607f821691505b60208210810361482c5761482b6147d5565b5b50919050565b7f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f205f8201527f7368617265730000000000000000000000000000000000000000000000000000602082015250565b5f61488c602683613d74565b915061489782614832565b604082019050919050565b5f6020820190508181035f8301526148b981614880565b9050919050565b7f5061796d656e7453706c69747465723a206163636f756e74206973206e6f74205f8201527f647565207061796d656e74000000000000000000000000000000000000000000602082015250565b5f61491a602b83613d74565b9150614925826148c0565b604082019050919050565b5f6020820190508181035f8301526149478161490e565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61498582613a60565b915061499083613a60565b92508282019050808211156149a8576149a761494e565b5b92915050565b5f819050919050565b5f6149d16149cc6149c784613a21565b6149ae565b613a21565b9050919050565b5f6149e2826149b7565b9050919050565b5f6149f3826149d8565b9050919050565b614a03816149e9565b82525050565b5f604082019050614a1c5f8301856149fa565b614a296020830184613a69565b9392505050565b5f614a3a82613a60565b9150614a4583613a60565b9250828202614a5381613a60565b91508282048414831517614a6a57614a6961494e565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f614aa882613a60565b9150614ab383613a60565b925082614ac357614ac2614a71565b5b828204905092915050565b5f81905092915050565b50565b5f614ae65f83614ace565b9150614af182614ad8565b5f82019050919050565b5f614b0582614adb565b9150819050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614b6b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614b30565b614b758683614b30565b95508019841693508086168417925050509392505050565b5f614ba7614ba2614b9d84613a60565b6149ae565b613a60565b9050919050565b5f819050919050565b614bc083614b8d565b614bd4614bcc82614bae565b848454614b3c565b825550505050565b5f90565b614be8614bdc565b614bf3818484614bb7565b505050565b5b81811015614c1657614c0b5f82614be0565b600181019050614bf9565b5050565b601f821115614c5b57614c2c81614b0f565b614c3584614b21565b81016020851015614c44578190505b614c58614c5085614b21565b830182614bf8565b50505b505050565b5f82821c905092915050565b5f614c7b5f1984600802614c60565b1980831691505092915050565b5f614c938383614c6c565b9150826002028217905092915050565b614cac82613d6a565b67ffffffffffffffff811115614cc557614cc46140a0565b5b614ccf8254614802565b614cda828285614c1a565b5f60209050601f831160018114614d0b575f8415614cf9578287015190505b614d038582614c88565b865550614d6a565b601f198416614d1986614b0f565b5f5b82811015614d4057848901518255600182019150602085019450602081019050614d1b565b86831015614d5d5784890151614d59601f891682614c6c565b8355505b6001600288020188555050505b505050505050565b5f606082019050614d855f830186614333565b614d926020830185613a51565b614d9f6040830184613a69565b949350505050565b5f81905092915050565b7f19010000000000000000000000000000000000000000000000000000000000005f82015250565b5f614de5600283614da7565b9150614df082614db1565b600282019050919050565b5f819050919050565b614e15614e108261432a565b614dfb565b82525050565b5f614e2582614dd9565b9150614e318285614e04565b602082019150614e418284614e04565b6020820191508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4d696e74206f6e205765627369746500000000000000000000000000000000005f82015250565b5f614eb2600f83613d74565b9150614ebd82614e7e565b602082019050919050565b5f6020820190508181035f830152614edf81614ea6565b9050919050565b7f4e6f204d6f726520537570706c790000000000000000000000000000000000005f82015250565b5f614f1a600e83613d74565b9150614f2582614ee6565b602082019050919050565b5f6020820190508181035f830152614f4781614f0e565b9050919050565b7f4d696e74205061757365640000000000000000000000000000000000000000005f82015250565b5f614f82600b83613d74565b9150614f8d82614f4e565b602082019050919050565b5f6020820190508181035f830152614faf81614f76565b9050919050565b7f50617920666f72204d696e7400000000000000000000000000000000000000005f82015250565b5f614fea600c83613d74565b9150614ff582614fb6565b602082019050919050565b5f6020820190508181035f83015261501781614fde565b9050919050565b7f4d65726b6c65526f6f74206973203000000000000000000000000000000000005f82015250565b5f615052600f83613d74565b915061505d8261501e565b602082019050919050565b5f6020820190508181035f83015261507f81615046565b9050919050565b5f8151905061509481613b3b565b92915050565b5f602082840312156150af576150ae613aa8565b5b5f6150bc84828501615086565b91505092915050565b5f6150cf82613d6a565b6150d98185614da7565b93506150e9818560208601613d84565b80840191505092915050565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000005f82015250565b5f615129600583614da7565b9150615134826150f5565b600582019050919050565b5f61514a82856150c5565b915061515682846150c5565b91506151618261511d565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6151c7602683613d74565b91506151d28261516d565b604082019050919050565b5f6020820190508181035f8301526151f4816151bb565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f61522f602083613d74565b915061523a826151fb565b602082019050919050565b5f6020820190508181035f83015261525c81615223565b9050919050565b5f61527d61527861527384613c89565b6149ae565b613a60565b9050919050565b61528d81615263565b82525050565b5f6040820190506152a65f830185615284565b6152b36020830184613a69565b9392505050565b7f416464726573733a20696e73756666696369656e742062616c616e63650000005f82015250565b5f6152ee601d83613d74565b91506152f9826152ba565b602082019050919050565b5f6020820190508181035f83015261531b816152e2565b9050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c20725f8201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b5f61537c603a83613d74565b915061538782615322565b604082019050919050565b5f6020820190508181035f8301526153a981615370565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f6153e4601f83613d74565b91506153ef826153b0565b602082019050919050565b5f6020820190508181035f830152615411816153d8565b9050919050565b5f61542282613a60565b915061542d83613a60565b92508282039050818111156154455761544461494e565b5b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f61546f8261544b565b6154798185615455565b9350615489818560208601613d84565b61549281613dac565b840191505092915050565b5f6080820190506154b05f830187613a51565b6154bd6020830186613a51565b6154ca6040830185613a69565b81810360608301526154dc8184615465565b905095945050505050565b5f815190506154f581613c34565b92915050565b5f602082840312156155105761550f613aa8565b5b5f61551d848285016154e7565b91505092915050565b5f61553082613a60565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036155625761556161494e565b5b600182019050919050565b5f8151905061557b81613eaf565b92915050565b5f6020828403121561559657615595613aa8565b5b5f6155a38482850161556d565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e5f8201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b5f615606602a83613d74565b9150615611826155ac565b604082019050919050565b5f6020820190508181035f830152615633816155fa565b9050919050565b5f60a08201905061564d5f830188614333565b61565a6020830187614333565b6156676040830186614333565b6156746060830185613a69565b6156816080830184613a51565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f45434453413a20696e76616c6964207369676e617475726500000000000000005f82015250565b5f6156ec601883613d74565b91506156f7826156b8565b602082019050919050565b5f6020820190508181035f830152615719816156e0565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e677468005f82015250565b5f615754601f83613d74565b915061575f82615720565b602082019050919050565b5f6020820190508181035f83015261578181615748565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c5f8201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b5f6157e2602283613d74565b91506157ed82615788565b604082019050919050565b5f6020820190508181035f83015261580f816157d6565b9050919050565b5f60ff82169050919050565b61582b81615816565b82525050565b5f6080820190506158445f830187614333565b6158516020830186615822565b61585e6040830185614333565b61586b6060830184614333565b95945050505050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f5f8201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b5f6158ce602683613d74565b91506158d982615874565b604082019050919050565b5f6020820190508181035f8301526158fb816158c2565b9050919050565b5f61590c8261544b565b6159168185614ace565b9350615926818560208601613d84565b80840191505092915050565b5f61593d8284615902565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000005f82015250565b5f61597c601d83613d74565b915061598782615948565b602082019050919050565b5f6020820190508181035f8301526159a981615970565b905091905056fea264697066735822122099c8f5f0f169fd2b575caebd56ce7fa194bc905a6429bea85c898f69abd4919164736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000006000000000000000000000000db3e025a4ca9e304728318dce52500bc8f4a69f4000000000000000000000000c09c1e95c2822ac9dd33afd0f36fae1115b6f6e900000000000000000000000050d10e2ac5adb6dc3fe0bd62794f49ac5f9e6a62000000000000000000000000523aad76f08e52c3992b5f0a2be305fdf82166f9000000000000000000000000b832d4b24045690f5fc4476703fe0a35b4861f9300000000000000000000000042b385252781c1c4d36d91300b734520a834d733000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000f
-----Decoded View---------------
Arg [0] : payees (address[]): 0xdB3E025A4Ca9e304728318dce52500Bc8F4a69F4,0xc09C1e95C2822aC9dd33afd0F36FaE1115b6f6E9,0x50D10E2aC5ADB6Dc3fE0bD62794f49AC5F9E6a62,0x523AAD76f08e52C3992b5f0A2BE305fdf82166F9,0xb832d4B24045690f5fC4476703fe0A35B4861F93,0x42B385252781C1c4d36D91300b734520A834D733
Arg [1] : shares (uint256[]): 35,20,10,10,10,15
-----Encoded View---------------
16 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [3] : 000000000000000000000000db3e025a4ca9e304728318dce52500bc8f4a69f4
Arg [4] : 000000000000000000000000c09c1e95c2822ac9dd33afd0f36fae1115b6f6e9
Arg [5] : 00000000000000000000000050d10e2ac5adb6dc3fe0bd62794f49ac5f9e6a62
Arg [6] : 000000000000000000000000523aad76f08e52c3992b5f0a2be305fdf82166f9
Arg [7] : 000000000000000000000000b832d4b24045690f5fc4476703fe0a35b4861f93
Arg [8] : 00000000000000000000000042b385252781c1c4d36d91300b734520a834d733
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000023
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [12] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [13] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [14] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [15] : 000000000000000000000000000000000000000000000000000000000000000f
Deployed Bytecode Sourcemap
153212:3939:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91175:40;91191:12;:10;:12::i;:::-;91205:9;91175:40;;;;;;;:::i;:::-;;;;;;;;153212:3939;;;;;155572:268;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;156655:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;156834:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;156475:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118544:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125044:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124477:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;153608:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;156137:87;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;114295:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93696:671;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;155438:126;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;128683:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80827:429;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;91306:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;156988:160;;;;;;;;;;;;;:::i;:::-;;92435:135;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;131604:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;156041:88;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94635:792;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;156232:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;153308:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119946:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;153485:72;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;154862:568;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;153778:44;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115479:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98401:103;;;;;;;;;;;;;:::i;:::-;;41540:657;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;92661:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97760:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118720:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92157:109;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;154221:633;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;125602:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;92851:225;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;132395:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;155848:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93236:260;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118930:327;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91953:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;153564:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91743:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91491:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125993:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98659:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87596:98;87649:7;87676:10;87669:17;;87596:98;:::o;155572:268::-;155683:4;155700:12;155742:2;155746:8;155725:30;;;;;;;;;:::i;:::-;;;;;;;;;;;;;155715:41;;;;;;155700:56;;155774:58;155793:11;;155774:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;155806:19;;155827:4;155774:18;:58::i;:::-;155767:65;;;155572:268;;;;;;:::o;156655:171::-;156758:4;156782:36;156806:11;156782:23;:36::i;:::-;156775:43;;156655:171;;;:::o;156834:146::-;97646:13;:11;:13::i;:::-;156930:42:::1;156949:8;156959:12;156930:18;:42::i;:::-;156834:146:::0;;:::o;156475:172::-;97646:13;:11;:13::i;:::-;156560::::1;:11;:13::i;:::-;156550:6;:23;;;;156542:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;156633:6;156621:18;;:9;:18;;;;156475:172:::0;:::o;118544:100::-;118598:13;118631:5;118624:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;118544:100;:::o;125044:218::-;125120:7;125145:16;125153:7;125145;:16::i;:::-;125140:64;;125170:34;;;;;;;;;;;;;;125140:64;125224:15;:24;125240:7;125224:24;;;;;;;;;;;:30;;;;;;;;;;;;125217:37;;125044:218;;;:::o;124477:408::-;124566:13;124582:16;124590:7;124582;:16::i;:::-;124566:32;;124638:5;124615:28;;:19;:17;:19::i;:::-;:28;;;124611:175;;124663:44;124680:5;124687:19;:17;:19::i;:::-;124663:16;:44::i;:::-;124658:128;;124735:35;;;;;;;;;;;;;;124658:128;124611:175;124831:2;124798:15;:24;124814:7;124798:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;124869:7;124865:2;124849:28;;124858:5;124849:28;;;;;;;;;;;;124555:330;124477:408;;:::o;153608:34::-;;;;:::o;156137:87::-;97646:13;:11;:13::i;:::-;156209:7:::1;156200:6;::::0;:16:::1;;;;;;;;;;;;;;;;;;156137:87:::0;:::o;114295:323::-;114356:7;114584:15;:13;:15::i;:::-;114569:12;;114553:13;;:28;:46;114546:53;;114295:323;:::o;93696:671::-;93791:1;93772:7;:16;93780:7;93772:16;;;;;;;;;;;;;;;;:20;93764:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;93848:15;93866:19;93877:7;93866:10;:19::i;:::-;93848:37;;93917:1;93906:7;:12;93898:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;94179:7;94161:14;;:25;;;;;;;:::i;:::-;;;;;;;;94244:7;94222:9;:18;94232:7;94222:18;;;;;;;;;;;;;;;;:29;;;;;;;;;;;94275:35;94293:7;94302;94275:17;:35::i;:::-;94326:33;94342:7;94351;94326:33;;;;;;;:::i;:::-;;;;;;;;93753:614;93696:671;:::o;155438:126::-;97646:13;:11;:13::i;:::-;155543::::1;155521:19;;:35;;;;;;;;;;;;;;;;;;155438:126:::0;:::o;128683:2825::-;128825:27;128855;128874:7;128855:18;:27::i;:::-;128825:57;;128940:4;128899:45;;128915:19;128899:45;;;128895:86;;128953:28;;;;;;;;;;;;;;128895:86;128995:27;129024:23;129051:35;129078:7;129051:26;:35::i;:::-;128994:92;;;;129186:68;129211:15;129228:4;129234:19;:17;:19::i;:::-;129186:24;:68::i;:::-;129181:180;;129274:43;129291:4;129297:19;:17;:19::i;:::-;129274:16;:43::i;:::-;129269:92;;129326:35;;;;;;;;;;;;;;129269:92;129181:180;129392:1;129378:16;;:2;:16;;;129374:52;;129403:23;;;;;;;;;;;;;;129374:52;129439:43;129461:4;129467:2;129471:7;129480:1;129439:21;:43::i;:::-;129575:15;129572:160;;;129715:1;129694:19;129687:30;129572:160;130112:18;:24;130131:4;130112:24;;;;;;;;;;;;;;;;130110:26;;;;;;;;;;;;130181:18;:22;130200:2;130181:22;;;;;;;;;;;;;;;;130179:24;;;;;;;;;;;130503:146;130540:2;130589:45;130604:4;130610:2;130614:19;130589:14;:45::i;:::-;110694:8;130561:73;130503:18;:146::i;:::-;130474:17;:26;130492:7;130474:26;;;;;;;;;;;:175;;;;130820:1;110694:8;130769:19;:47;:52;130765:627;;130842:19;130874:1;130864:7;:11;130842:33;;131031:1;130997:17;:30;131015:11;130997:30;;;;;;;;;;;;:35;130993:384;;131135:13;;131120:11;:28;131116:242;;131315:19;131282:17;:30;131300:11;131282:30;;;;;;;;;;;:52;;;;131116:242;130993:384;130823:569;130765:627;131439:7;131435:2;131420:27;;131429:4;131420:27;;;;;;;;;;;;131458:42;131479:4;131485:2;131489:7;131498:1;131458:20;:42::i;:::-;128814:2694;;;128683:2825;;;:::o;80827:429::-;80913:7;80922;80942:26;80971:17;:26;80989:7;80971:26;;;;;;;;;;;80942:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81042:1;81014:30;;:7;:16;;;:30;;;81010:92;;81071:19;81061:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81010:92;81114:21;81178:17;:15;:17::i;:::-;81138:57;;81151:7;:23;;;81139:35;;:9;:35;;;;:::i;:::-;81138:57;;;;:::i;:::-;81114:81;;81216:7;:16;;;81234:13;81208:40;;;;;;80827:429;;;;;:::o;91306:91::-;91350:7;91377:12;;91370:19;;91306:91;:::o;156988:160::-;97646:13;:11;:13::i;:::-;86006:21:::1;:19;:21::i;:::-;157050:7:::2;157071;:5;:7::i;:::-;157063:21;;157092;157063:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;157049:69;;;157137:2;157129:11;;;::::0;::::2;;157038:110;86050:20:::1;:18;:20::i;:::-;156988:160::o:0;92435:135::-;92505:7;92532:14;:21;92547:5;92532:21;;;;;;;;;;;;;;;:30;92554:7;92532:30;;;;;;;;;;;;;;;;92525:37;;92435:135;;;;:::o;131604:193::-;131750:39;131767:4;131773:2;131777:7;131750:39;;;;;;;;;;;;:16;:39::i;:::-;131604:193;;;:::o;156041:88::-;97646:13;:11;:13::i;:::-;156113:8:::1;156106:4;:15;;;;156041:88:::0;:::o;94635:792::-;94736:1;94717:7;:16;94725:7;94717:16;;;;;;;;;;;;;;;;:20;94709:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;94793:15;94811:26;94822:5;94829:7;94811:10;:26::i;:::-;94793:44;;94869:1;94858:7;:12;94850:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95203:7;95173:19;:26;95193:5;95173:26;;;;;;;;;;;;;;;;:37;;;;;;;:::i;:::-;;;;;;;;95280:7;95246:14;:21;95261:5;95246:21;;;;;;;;;;;;;;;:30;95268:7;95246:30;;;;;;;;;;;;;;;;:41;;;;;;;;;;;95311:47;95334:5;95341:7;95350;95311:22;:47::i;:::-;95395:5;95374:45;;;95402:7;95411;95374:45;;;;;;;:::i;:::-;;;;;;;;94698:729;94635:792;;:::o;156232:110::-;97646:13;:11;:13::i;:::-;156321::::1;156311:7;:23;;;;;;:::i;:::-;;156232:110:::0;:::o;153308:25::-;;;;;;;;;;;;:::o;119946:152::-;120018:7;120061:27;120080:7;120061:18;:27::i;:::-;120038:52;;119946:152;;;:::o;153485:72::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;154862:568::-;154925:4;154942:14;154959:20;:18;:20::i;:::-;154942:37;;154992:18;155048:51;155114:10;155139:21;155149:10;155139:9;:21::i;:::-;155023:148;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;155013:159;;;;;;154992:180;;155185:14;155268:6;155289:10;155212:98;;;;;;;;;:::i;:::-;;;;;;;;;;;;;155202:109;;;;;;155185:126;;155324:14;155341:32;155355:6;155363:9;155341:13;:32::i;:::-;155324:49;;155402:19;;;;;;;;;;;155392:29;;:6;:29;;;155384:38;;;;;;154862:568;;;:::o;153778:44::-;;;;;;;;;;;;;;;;;:::o;115479:233::-;115551:7;115592:1;115575:19;;:5;:19;;;115571:60;;115603:28;;;;;;;;;;;;;;115571:60;109638:13;115649:18;:25;115668:5;115649:25;;;;;;;;;;;;;;;;:55;115642:62;;115479:233;;;:::o;98401:103::-;97646:13;:11;:13::i;:::-;98466:30:::1;98493:1;98466:18;:30::i;:::-;98401:103::o:0;41540:657::-;41661:13;41689:18;41722:21;41758:15;41788:25;41828:12;41855:27;41963:41;41990:13;41963:5;:26;;:41;;;;:::i;:::-;42019:47;42049:16;42019:8;:29;;:47;;;;:::i;:::-;42081:13;42117:4;42145:1;42137:10;;42176:1;42162:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41910:279;;;;;;;;;;;;;;;;;;;;;41540:657;;;;;;;:::o;92661:100::-;92712:7;92739;92747:5;92739:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;92732:21;;92661:100;;;:::o;97760:87::-;97806:7;97833:6;;;;;;;;;;;97826:13;;97760:87;:::o;118720:104::-;118776:13;118809:7;118802:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;118720:104;:::o;92157:109::-;92213:7;92240:9;:18;92250:7;92240:18;;;;;;;;;;;;;;;;92233:25;;92157:109;;;:::o;154221:633::-;86006:21;:19;:21::i;:::-;154362:19:::1;154371:9;;154362:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:8;:19::i;:::-;154354:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;154441:9;;154436:1;154420:13;:11;:13::i;:::-;:17;;;;:::i;:::-;:30;;154412:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;154500:7;:5;:7::i;:::-;154486:21;;:10;:21;;;154482:85;;154533:6;::::0;::::1;;;;;;;;154532:7;154524:31;;;;;;;;;;;;:::i;:::-;;;;;;;;;154482:85;154583:57;154602:10;154614:11;;154627:12;154583:18;:57::i;:::-;:97;;;;;154668:12;154644:9;:21;154654:10;154644:21;;;;;;;;;;;;;;;;:36;154583:97;154579:231;;;154722:1;154697:9;:21;154707:10;154697:21;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;154579:231;;;154777:4;;154764:9;:17;;154756:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;154579:231;154822:24;154832:10;154844:1;154822:9;:24::i;:::-;86050:20:::0;:18;:20::i;:::-;154221:633;;;;;:::o;125602:234::-;125749:8;125697:18;:39;125716:19;:17;:19::i;:::-;125697:39;;;;;;;;;;;;;;;:49;125737:8;125697:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;125809:8;125773:55;;125788:19;:17;:19::i;:::-;125773:55;;;125819:8;125773:55;;;;;;:::i;:::-;;;;;;;;125602:234;;:::o;92851:225::-;92909:7;92929:21;92977:15;:13;:15::i;:::-;92953:21;:39;;;;:::i;:::-;92929:63;;93010:58;93026:7;93035:13;93050:17;93059:7;93050:8;:17::i;:::-;93010:15;:58::i;:::-;93003:65;;;92851:225;;;:::o;132395:407::-;132570:31;132583:4;132589:2;132593:7;132570:12;:31::i;:::-;132634:1;132616:2;:14;;;:19;132612:183;;132655:56;132686:4;132692:2;132696:7;132705:5;132655:30;:56::i;:::-;132650:145;;132739:40;;;;;;;;;;;;;;132650:145;132612:183;132395:407;;;;:::o;155848:185::-;97646:13;:11;:13::i;:::-;155960:1:::1;155952:10:::0;::::1;155938;:24:::0;155930:52:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;156015:10;155993:19;:32;;;;155848:185:::0;:::o;93236:260::-;93308:7;93328:21;93385:20;93399:5;93385:13;:20::i;:::-;93352:5;:15;;;93376:4;93352:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;93328:77;;93423:65;93439:7;93448:13;93463:24;93472:5;93479:7;93463:8;:24::i;:::-;93423:15;:65::i;:::-;93416:72;;;93236:260;;;;:::o;118930:327::-;119003:13;119034:16;119042:7;119034;:16::i;:::-;119029:59;;119059:29;;;;;;;;;;;;;;119029:59;119101:21;119125:10;:8;:10::i;:::-;119101:34;;119178:1;119159:7;119153:21;:26;:96;;;;;;;;;;;;;;;;;119206:7;119215:18;119225:7;119215:9;:18::i;:::-;119189:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;119153:96;119146:103;;;118930:327;;;:::o;91953:105::-;92007:7;92034;:16;92042:7;92034:16;;;;;;;;;;;;;;;;92027:23;;91953:105;;;:::o;153564:37::-;;;;:::o;91743:119::-;91801:7;91828:19;:26;91848:5;91828:26;;;;;;;;;;;;;;;;91821:33;;91743:119;;;:::o;91491:95::-;91537:7;91564:14;;91557:21;;91491:95;:::o;125993:164::-;126090:4;126114:18;:25;126133:5;126114:25;;;;;;;;;;;;;;;:35;126140:8;126114:35;;;;;;;;;;;;;;;;;;;;;;;;;126107:42;;125993:164;;;;:::o;98659:201::-;97646:13;:11;:13::i;:::-;98768:1:::1;98748:22;;:8;:22;;::::0;98740:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;98824:28;98843:8;98824:18;:28::i;:::-;98659:201:::0;:::o;43540:156::-;43631:4;43684;43655:25;43668:5;43675:4;43655:12;:25::i;:::-;:33;43648:40;;43540:156;;;;;:::o;80557:215::-;80659:4;80698:26;80683:41;;;:11;:41;;;;:81;;;;80728:36;80752:11;80728:23;:36::i;:::-;80683:81;80676:88;;80557:215;;;:::o;97925:132::-;98000:12;:10;:12::i;:::-;97989:23;;:7;:5;:7::i;:::-;:23;;;97981:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97925:132::o;81906:518::-;82001:19;82023:17;:15;:17::i;:::-;82001:39;;;;82070:11;82055:12;:26;;;82051:176;;;82189:12;82203:11;82160:55;;;;;;;;;;;;:::i;:::-;;;;;;;;82051:176;82261:1;82241:22;;:8;:22;;;82237:110;;82332:1;82287:48;;;;;;;;;;;:::i;:::-;;;;;;;;82237:110;82381:35;;;;;;;;82393:8;82381:35;;;;;;82403:12;82381:35;;;;;82359:19;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81990:434;81906:518;;:::o;126415:282::-;126480:4;126536:7;126517:15;:13;:15::i;:::-;:26;;:66;;;;;126570:13;;126560:7;:23;126517:66;:153;;;;;126669:1;110414:8;126621:17;:26;126639:7;126621:26;;;;;;;;;;;;:44;:49;126517:153;126497:173;;126415:282;;;:::o;148723:105::-;148783:7;148810:10;148803:17;;148723:105;:::o;113811:92::-;113867:7;113811:92;:::o;54971:317::-;55086:6;55061:21;:31;;55053:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;55140:12;55158:9;:14;;55180:6;55158:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55139:52;;;55210:7;55202:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;55042:246;54971:317;;:::o;121101:1275::-;121168:7;121188:12;121203:7;121188:22;;121271:4;121252:15;:13;:15::i;:::-;:23;121248:1061;;121305:13;;121298:4;:20;121294:1015;;;121343:14;121360:17;:23;121378:4;121360:23;;;;;;;;;;;;121343:40;;121477:1;110414:8;121449:6;:24;:29;121445:845;;122114:113;122131:1;122121:6;:11;122114:113;;122174:17;:25;122192:6;;;;;;;122174:25;;;;;;;;;;;;122165:34;;122114:113;;;122260:6;122253:13;;;;;;121445:845;121320:989;121294:1015;121248:1061;122337:31;;;;;;;;;;;;;;121101:1275;;;;:::o;127578:485::-;127680:27;127709:23;127750:38;127791:15;:24;127807:7;127791:24;;;;;;;;;;;127750:65;;127968:18;127945:41;;128025:19;128019:26;128000:45;;127930:126;127578:485;;;:::o;126806:659::-;126955:11;127120:16;127113:5;127109:28;127100:37;;127280:16;127269:9;127265:32;127252:45;;127430:15;127419:9;127416:30;127408:5;127397:9;127394:20;127391:56;127381:66;;126806:659;;;;;:::o;133464:159::-;;;;;:::o;148032:311::-;148167:7;148187:16;110818:3;148213:19;:41;;148187:68;;110818:3;148281:31;148292:4;148298:2;148302:9;148281:10;:31::i;:::-;148273:40;;:62;;148266:69;;;148032:311;;;;;:::o;122924:450::-;123004:14;123172:16;123165:5;123161:28;123152:37;;123349:5;123335:11;123310:23;123306:41;123303:52;123296:5;123293:63;123283:73;;122924:450;;;;:::o;134288:158::-;;;;;:::o;81538:97::-;81596:6;81622:5;81615:12;;81538:97;:::o;86086:293::-;85488:1;86220:7;;:19;86212:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;85488:1;86353:7;:18;;;;86086:293::o;86387:213::-;85444:1;86570:7;:22;;;;86387:213::o;69558:177::-;69641:86;69661:5;69691:23;;;69716:2;69720:5;69668:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69641:19;:86::i;:::-;69558:177;;;:::o;40178:268::-;40231:7;40272:11;40255:28;;40263:4;40255:28;;;:63;;;;;40304:14;40287:13;:31;40255:63;40251:188;;;40342:22;40335:29;;;;40251:188;40404:23;:21;:23::i;:::-;40397:30;;40178:268;;:::o;30857:231::-;30935:7;30956:17;30975:18;30997:27;31008:4;31014:9;30997:10;:27::i;:::-;30955:69;;;;31035:18;31047:5;31035:11;:18::i;:::-;31071:9;31064:16;;;;30857:231;;;;:::o;99020:191::-;99094:16;99113:6;;;;;;;;;;;99094:25;;99139:8;99130:6;;:17;;;;;;;;;;;;;;;;;;99194:8;99163:40;;99184:8;99163:40;;;;;;;;;;;;99083:128;99020:191;:::o;8537:274::-;8631:13;6482:66;8690:18;;8680:5;8661:47;8657:147;;8732:15;8741:5;8732:8;:15::i;:::-;8725:22;;;;8657:147;8787:5;8780:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8537:274;;;;;:::o;142555:112::-;142632:27;142642:2;142646:8;142632:27;;;;;;;;;;;;:9;:27::i;:::-;142555:112;;:::o;95605:248::-;95751:7;95830:15;95815:12;;95795:7;:16;95803:7;95795:16;;;;;;;;;;;;;;;;95779:13;:32;;;;:::i;:::-;95778:49;;;;:::i;:::-;:67;;;;:::i;:::-;95771:74;;95605:248;;;;;:::o;134886:716::-;135049:4;135095:2;135070:45;;;135116:19;:17;:19::i;:::-;135137:4;135143:7;135152:5;135070:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;135066:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;135370:1;135353:6;:13;:18;135349:235;;135399:40;;;;;;;;;;;;;;135349:235;135542:6;135536:13;135527:6;135523:2;135519:15;135512:38;135066:529;135239:54;;;135229:64;;;:6;:64;;;;135222:71;;;134886:716;;;;;;:::o;156350:117::-;156419:13;156452:7;156445:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;156350:117;:::o;148930:1745::-;148995:17;149429:4;149422;149416:11;149412:22;149521:1;149515:4;149508:15;149596:4;149593:1;149589:12;149582:19;;149678:1;149673:3;149666:14;149782:3;150021:5;150003:428;150029:1;150003:428;;;150069:1;150064:3;150060:11;150053:18;;150240:2;150234:4;150230:13;150226:2;150222:22;150217:3;150209:36;150334:2;150328:4;150324:13;150316:21;;150401:4;150003:428;150391:25;150003:428;150007:21;150470:3;150465;150461:13;150585:4;150580:3;150576:14;150569:21;;150650:6;150645:3;150638:19;149034:1634;;;148930:1745;;;:::o;44259:296::-;44342:7;44362:20;44385:4;44362:27;;44405:9;44400:118;44424:5;:12;44420:1;:16;44400:118;;;44473:33;44483:12;44497:5;44503:1;44497:8;;;;;;;;:::i;:::-;;;;;;;;44473:9;:33::i;:::-;44458:48;;44438:3;;;;;:::i;:::-;;;;44400:118;;;;44535:12;44528:19;;;44259:296;;;;:::o;77455:157::-;77540:4;77579:25;77564:40;;;:11;:40;;;;77557:47;;77455:157;;;:::o;147733:147::-;147870:6;147733:147;;;;;:::o;73904:649::-;74328:23;74354:69;74382:4;74354:69;;;;;;;;;;;;;;;;;74362:5;74354:27;;;;:69;;;;;:::i;:::-;74328:95;;74463:1;74442:10;:17;:22;:56;;;;74479:10;74468:30;;;;;;;;;;;;:::i;:::-;74442:56;74434:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;73974:579;73904:649;;:::o;40454:182::-;40509:7;38370:95;40569:11;40582:14;40598:13;40621:4;40546:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;40536:92;;;;;;40529:99;;40454:182;:::o;29308:747::-;29389:7;29398:12;29447:2;29427:9;:16;:22;29423:625;;29466:9;29490;29514:7;29771:4;29760:9;29756:20;29750:27;29745:32;;29821:4;29810:9;29806:20;29800:27;29795:32;;29879:4;29868:9;29864:20;29858:27;29855:1;29850:36;29845:41;;29922:25;29933:4;29939:1;29942;29945;29922:10;:25::i;:::-;29915:32;;;;;;;;;29423:625;29996:1;30000:35;29980:56;;;;29308:747;;;;;;:::o;27701:521::-;27779:20;27770:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;27766:449;27816:7;27766:449;27877:29;27868:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;27864:351;;27923:34;;;;;;;;;;:::i;:::-;;;;;;;;27864:351;27988:35;27979:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;27975:240;;28040:41;;;;;;;;;;:::i;:::-;;;;;;;;27975:240;28112:30;28103:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;28099:116;;28159:44;;;;;;;;;;:::i;:::-;;;;;;;;28099:116;27701:521;;:::o;7191:415::-;7250:13;7276:11;7290:16;7301:4;7290:10;:16::i;:::-;7276:30;;7396:17;7427:2;7416:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7396:34;;7521:3;7516;7509:16;7562:4;7555;7550:3;7546:14;7539:28;7595:3;7588:10;;;;7191:415;;;:::o;141782:689::-;141913:19;141919:2;141923:8;141913:5;:19::i;:::-;141992:1;141974:2;:14;;;:19;141970:483;;142014:11;142028:13;;142014:27;;142060:13;142082:8;142076:3;:14;142060:30;;142109:233;142140:62;142179:1;142183:2;142187:7;;;;;;142196:5;142140:30;:62::i;:::-;142135:167;;142238:40;;;;;;;;;;;;;;142135:167;142337:3;142329:5;:11;142109:233;;142424:3;142407:13;;:20;142403:34;;142429:8;;;142403:34;141995:458;;141970:483;141782:689;;;:::o;51689:149::-;51752:7;51783:1;51779;:5;:51;;51810:20;51825:1;51828;51810:14;:20::i;:::-;51779:51;;;51787:20;51802:1;51805;51787:14;:20::i;:::-;51779:51;51772:58;;51689:149;;;;:::o;56467:229::-;56604:12;56636:52;56658:6;56666:4;56672:1;56675:12;56636:21;:52::i;:::-;56629:59;;56467:229;;;;;:::o;32241:1477::-;32329:7;32338:12;33263:66;33258:1;33250:10;;:79;33246:163;;;33362:1;33366:30;33346:51;;;;;;33246:163;33506:14;33523:24;33533:4;33539:1;33542;33545;33523:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33506:41;;33580:1;33562:20;;:6;:20;;;33558:103;;33615:1;33619:29;33599:50;;;;;;;33558:103;33681:6;33689:20;33673:37;;;;;32241:1477;;;;;;;;:::o;7683:251::-;7744:7;7764:14;7817:4;7808;7781:33;;:40;7764:57;;7845:2;7836:6;:11;7832:71;;;7871:20;;;;;;;;;;;;;;7832:71;7920:6;7913:13;;;7683:251;;;:::o;136064:2966::-;136137:20;136160:13;;136137:36;;136200:1;136188:8;:13;136184:44;;136210:18;;;;;;;;;;;;;;136184:44;136241:61;136271:1;136275:2;136279:12;136293:8;136241:21;:61::i;:::-;136785:1;109776:2;136755:1;:26;;136754:32;136742:8;:45;136716:18;:22;136735:2;136716:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;137064:139;137101:2;137155:33;137178:1;137182:2;137186:1;137155:14;:33::i;:::-;137122:30;137143:8;137122:20;:30::i;:::-;:66;137064:18;:139::i;:::-;137030:17;:31;137048:12;137030:31;;;;;;;;;;;:173;;;;137220:16;137251:11;137280:8;137265:12;:23;137251:37;;137801:16;137797:2;137793:25;137781:37;;138173:12;138133:8;138092:1;138030:25;137971:1;137910;137883:335;138544:1;138530:12;138526:20;138484:346;138585:3;138576:7;138573:16;138484:346;;138803:7;138793:8;138790:1;138763:25;138760:1;138757;138752:59;138638:1;138629:7;138625:15;138614:26;;138484:346;;;138488:77;138875:1;138863:8;:13;138859:45;;138885:19;;;;;;;;;;;;;;138859:45;138937:3;138921:13;:19;;;;136490:2462;;138962:60;138991:1;138995:2;138999:12;139013:8;138962:20;:60::i;:::-;136126:2904;136064:2966;;:::o;51963:268::-;52031:13;52138:1;52132:4;52125:15;52167:1;52161:4;52154:15;52208:4;52202;52192:21;52183:30;;51963:268;;;;:::o;57553:455::-;57723:12;57781:5;57756:21;:30;;57748:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;57841:12;57855:23;57882:6;:11;;57901:5;57908:4;57882:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57840:73;;;;57931:69;57958:6;57966:7;57975:10;57987:12;57931:26;:69::i;:::-;57924:76;;;;57553:455;;;;;;:::o;123476:324::-;123546:14;123779:1;123769:8;123766:15;123740:24;123736:46;123726:56;;123476:324;;;:::o;60126:644::-;60311:12;60340:7;60336:427;;;60389:1;60368:10;:17;:22;60364:290;;60586:18;60597:6;60586:10;:18::i;:::-;60578:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;60364:290;60675:10;60668:17;;;;60336:427;60718:33;60726:10;60738:12;60718:7;:33::i;:::-;60126:644;;;;;;;:::o;53712:326::-;53772:4;54029:1;54007:7;:19;;;:23;54000:30;;53712:326;;;:::o;61312:552::-;61493:1;61473:10;:17;:21;61469:388;;;61705:10;61699:17;61762:15;61749:10;61745:2;61741:19;61734:44;61469:388;61832:12;61825:20;;;;;;;;;;;:::i;:::-;;;;;;;;7:126:1;44:7;84:42;77:5;73:54;62:65;;7:126;;;:::o;139:96::-;176:7;205:24;223:5;205:24;:::i;:::-;194:35;;139:96;;;:::o;241:118::-;328:24;346:5;328:24;:::i;:::-;323:3;316:37;241:118;;:::o;365:77::-;402:7;431:5;420:16;;365:77;;;:::o;448:118::-;535:24;553:5;535:24;:::i;:::-;530:3;523:37;448:118;;:::o;572:332::-;693:4;731:2;720:9;716:18;708:26;;744:71;812:1;801:9;797:17;788:6;744:71;:::i;:::-;825:72;893:2;882:9;878:18;869:6;825:72;:::i;:::-;572:332;;;;;:::o;910:75::-;943:6;976:2;970:9;960:19;;910:75;:::o;991:117::-;1100:1;1097;1090:12;1114:117;1223:1;1220;1213:12;1237:122;1310:24;1328:5;1310:24;:::i;:::-;1303:5;1300:35;1290:63;;1349:1;1346;1339:12;1290:63;1237:122;:::o;1365:139::-;1411:5;1449:6;1436:20;1427:29;;1465:33;1492:5;1465:33;:::i;:::-;1365:139;;;;:::o;1510:117::-;1619:1;1616;1609:12;1633:117;1742:1;1739;1732:12;1756:117;1865:1;1862;1855:12;1896:568;1969:8;1979:6;2029:3;2022:4;2014:6;2010:17;2006:27;1996:122;;2037:79;;:::i;:::-;1996:122;2150:6;2137:20;2127:30;;2180:18;2172:6;2169:30;2166:117;;;2202:79;;:::i;:::-;2166:117;2316:4;2308:6;2304:17;2292:29;;2370:3;2362:4;2354:6;2350:17;2340:8;2336:32;2333:41;2330:128;;;2377:79;;:::i;:::-;2330:128;1896:568;;;;;:::o;2470:122::-;2543:24;2561:5;2543:24;:::i;:::-;2536:5;2533:35;2523:63;;2582:1;2579;2572:12;2523:63;2470:122;:::o;2598:139::-;2644:5;2682:6;2669:20;2660:29;;2698:33;2725:5;2698:33;:::i;:::-;2598:139;;;;:::o;2743:849::-;2847:6;2855;2863;2871;2920:2;2908:9;2899:7;2895:23;2891:32;2888:119;;;2926:79;;:::i;:::-;2888:119;3046:1;3071:53;3116:7;3107:6;3096:9;3092:22;3071:53;:::i;:::-;3061:63;;3017:117;3201:2;3190:9;3186:18;3173:32;3232:18;3224:6;3221:30;3218:117;;;3254:79;;:::i;:::-;3218:117;3367:80;3439:7;3430:6;3419:9;3415:22;3367:80;:::i;:::-;3349:98;;;;3144:313;3496:2;3522:53;3567:7;3558:6;3547:9;3543:22;3522:53;:::i;:::-;3512:63;;3467:118;2743:849;;;;;;;:::o;3598:90::-;3632:7;3675:5;3668:13;3661:21;3650:32;;3598:90;;;:::o;3694:109::-;3775:21;3790:5;3775:21;:::i;:::-;3770:3;3763:34;3694:109;;:::o;3809:210::-;3896:4;3934:2;3923:9;3919:18;3911:26;;3947:65;4009:1;3998:9;3994:17;3985:6;3947:65;:::i;:::-;3809:210;;;;:::o;4025:149::-;4061:7;4101:66;4094:5;4090:78;4079:89;;4025:149;;;:::o;4180:120::-;4252:23;4269:5;4252:23;:::i;:::-;4245:5;4242:34;4232:62;;4290:1;4287;4280:12;4232:62;4180:120;:::o;4306:137::-;4351:5;4389:6;4376:20;4367:29;;4405:32;4431:5;4405:32;:::i;:::-;4306:137;;;;:::o;4449:327::-;4507:6;4556:2;4544:9;4535:7;4531:23;4527:32;4524:119;;;4562:79;;:::i;:::-;4524:119;4682:1;4707:52;4751:7;4742:6;4731:9;4727:22;4707:52;:::i;:::-;4697:62;;4653:116;4449:327;;;;:::o;4782:109::-;4818:7;4858:26;4851:5;4847:38;4836:49;;4782:109;;;:::o;4897:120::-;4969:23;4986:5;4969:23;:::i;:::-;4962:5;4959:34;4949:62;;5007:1;5004;4997:12;4949:62;4897:120;:::o;5023:137::-;5068:5;5106:6;5093:20;5084:29;;5122:32;5148:5;5122:32;:::i;:::-;5023:137;;;;:::o;5166:472::-;5233:6;5241;5290:2;5278:9;5269:7;5265:23;5261:32;5258:119;;;5296:79;;:::i;:::-;5258:119;5416:1;5441:53;5486:7;5477:6;5466:9;5462:22;5441:53;:::i;:::-;5431:63;;5387:117;5543:2;5569:52;5613:7;5604:6;5593:9;5589:22;5569:52;:::i;:::-;5559:62;;5514:117;5166:472;;;;;:::o;5644:89::-;5680:7;5720:6;5713:5;5709:18;5698:29;;5644:89;;;:::o;5739:120::-;5811:23;5828:5;5811:23;:::i;:::-;5804:5;5801:34;5791:62;;5849:1;5846;5839:12;5791:62;5739:120;:::o;5865:137::-;5910:5;5948:6;5935:20;5926:29;;5964:32;5990:5;5964:32;:::i;:::-;5865:137;;;;:::o;6008:327::-;6066:6;6115:2;6103:9;6094:7;6090:23;6086:32;6083:119;;;6121:79;;:::i;:::-;6083:119;6241:1;6266:52;6310:7;6301:6;6290:9;6286:22;6266:52;:::i;:::-;6256:62;;6212:116;6008:327;;;;:::o;6341:99::-;6393:6;6427:5;6421:12;6411:22;;6341:99;;;:::o;6446:169::-;6530:11;6564:6;6559:3;6552:19;6604:4;6599:3;6595:14;6580:29;;6446:169;;;;:::o;6621:246::-;6702:1;6712:113;6726:6;6723:1;6720:13;6712:113;;;6811:1;6806:3;6802:11;6796:18;6792:1;6787:3;6783:11;6776:39;6748:2;6745:1;6741:10;6736:15;;6712:113;;;6859:1;6850:6;6845:3;6841:16;6834:27;6683:184;6621:246;;;:::o;6873:102::-;6914:6;6965:2;6961:7;6956:2;6949:5;6945:14;6941:28;6931:38;;6873:102;;;:::o;6981:377::-;7069:3;7097:39;7130:5;7097:39;:::i;:::-;7152:71;7216:6;7211:3;7152:71;:::i;:::-;7145:78;;7232:65;7290:6;7285:3;7278:4;7271:5;7267:16;7232:65;:::i;:::-;7322:29;7344:6;7322:29;:::i;:::-;7317:3;7313:39;7306:46;;7073:285;6981:377;;;;:::o;7364:313::-;7477:4;7515:2;7504:9;7500:18;7492:26;;7564:9;7558:4;7554:20;7550:1;7539:9;7535:17;7528:47;7592:78;7665:4;7656:6;7592:78;:::i;:::-;7584:86;;7364:313;;;;:::o;7683:329::-;7742:6;7791:2;7779:9;7770:7;7766:23;7762:32;7759:119;;;7797:79;;:::i;:::-;7759:119;7917:1;7942:53;7987:7;7978:6;7967:9;7963:22;7942:53;:::i;:::-;7932:63;;7888:117;7683:329;;;;:::o;8018:222::-;8111:4;8149:2;8138:9;8134:18;8126:26;;8162:71;8230:1;8219:9;8215:17;8206:6;8162:71;:::i;:::-;8018:222;;;;:::o;8246:474::-;8314:6;8322;8371:2;8359:9;8350:7;8346:23;8342:32;8339:119;;;8377:79;;:::i;:::-;8339:119;8497:1;8522:53;8567:7;8558:6;8547:9;8543:22;8522:53;:::i;:::-;8512:63;;8468:117;8624:2;8650:53;8695:7;8686:6;8675:9;8671:22;8650:53;:::i;:::-;8640:63;;8595:118;8246:474;;;;;:::o;8726:222::-;8819:4;8857:2;8846:9;8842:18;8834:26;;8870:71;8938:1;8927:9;8923:17;8914:6;8870:71;:::i;:::-;8726:222;;;;:::o;8954:116::-;9024:21;9039:5;9024:21;:::i;:::-;9017:5;9014:32;9004:60;;9060:1;9057;9050:12;9004:60;8954:116;:::o;9076:133::-;9119:5;9157:6;9144:20;9135:29;;9173:30;9197:5;9173:30;:::i;:::-;9076:133;;;;:::o;9215:323::-;9271:6;9320:2;9308:9;9299:7;9295:23;9291:32;9288:119;;;9326:79;;:::i;:::-;9288:119;9446:1;9471:50;9513:7;9504:6;9493:9;9489:22;9471:50;:::i;:::-;9461:60;;9417:114;9215:323;;;;:::o;9544:104::-;9589:7;9618:24;9636:5;9618:24;:::i;:::-;9607:35;;9544:104;;;:::o;9654:138::-;9735:32;9761:5;9735:32;:::i;:::-;9728:5;9725:43;9715:71;;9782:1;9779;9772:12;9715:71;9654:138;:::o;9798:155::-;9852:5;9890:6;9877:20;9868:29;;9906:41;9941:5;9906:41;:::i;:::-;9798:155;;;;:::o;9959:345::-;10026:6;10075:2;10063:9;10054:7;10050:23;10046:32;10043:119;;;10081:79;;:::i;:::-;10043:119;10201:1;10226:61;10279:7;10270:6;10259:9;10255:22;10226:61;:::i;:::-;10216:71;;10172:125;9959:345;;;;:::o;10310:329::-;10369:6;10418:2;10406:9;10397:7;10393:23;10389:32;10386:119;;;10424:79;;:::i;:::-;10386:119;10544:1;10569:53;10614:7;10605:6;10594:9;10590:22;10569:53;:::i;:::-;10559:63;;10515:117;10310:329;;;;:::o;10645:619::-;10722:6;10730;10738;10787:2;10775:9;10766:7;10762:23;10758:32;10755:119;;;10793:79;;:::i;:::-;10755:119;10913:1;10938:53;10983:7;10974:6;10963:9;10959:22;10938:53;:::i;:::-;10928:63;;10884:117;11040:2;11066:53;11111:7;11102:6;11091:9;11087:22;11066:53;:::i;:::-;11056:63;;11011:118;11168:2;11194:53;11239:7;11230:6;11219:9;11215:22;11194:53;:::i;:::-;11184:63;;11139:118;10645:619;;;;;:::o;11270:474::-;11338:6;11346;11395:2;11383:9;11374:7;11370:23;11366:32;11363:119;;;11401:79;;:::i;:::-;11363:119;11521:1;11546:53;11591:7;11582:6;11571:9;11567:22;11546:53;:::i;:::-;11536:63;;11492:117;11648:2;11674:53;11719:7;11710:6;11699:9;11695:22;11674:53;:::i;:::-;11664:63;;11619:118;11270:474;;;;;:::o;11750:111::-;11802:7;11831:24;11849:5;11831:24;:::i;:::-;11820:35;;11750:111;;;:::o;11867:152::-;11955:39;11988:5;11955:39;:::i;:::-;11948:5;11945:50;11935:78;;12009:1;12006;11999:12;11935:78;11867:152;:::o;12025:169::-;12086:5;12124:6;12111:20;12102:29;;12140:48;12182:5;12140:48;:::i;:::-;12025:169;;;;:::o;12200:504::-;12283:6;12291;12340:2;12328:9;12319:7;12315:23;12311:32;12308:119;;;12346:79;;:::i;:::-;12308:119;12466:1;12491:68;12551:7;12542:6;12531:9;12527:22;12491:68;:::i;:::-;12481:78;;12437:132;12608:2;12634:53;12679:7;12670:6;12659:9;12655:22;12634:53;:::i;:::-;12624:63;;12579:118;12200:504;;;;;:::o;12710:117::-;12819:1;12816;12809:12;12833:180;12881:77;12878:1;12871:88;12978:4;12975:1;12968:15;13002:4;12999:1;12992:15;13019:281;13102:27;13124:4;13102:27;:::i;:::-;13094:6;13090:40;13232:6;13220:10;13217:22;13196:18;13184:10;13181:34;13178:62;13175:88;;;13243:18;;:::i;:::-;13175:88;13283:10;13279:2;13272:22;13062:238;13019:281;;:::o;13306:129::-;13340:6;13367:20;;:::i;:::-;13357:30;;13396:33;13424:4;13416:6;13396:33;:::i;:::-;13306:129;;;:::o;13441:308::-;13503:4;13593:18;13585:6;13582:30;13579:56;;;13615:18;;:::i;:::-;13579:56;13653:29;13675:6;13653:29;:::i;:::-;13645:37;;13737:4;13731;13727:15;13719:23;;13441:308;;;:::o;13755:146::-;13852:6;13847:3;13842;13829:30;13893:1;13884:6;13879:3;13875:16;13868:27;13755:146;;;:::o;13907:425::-;13985:5;14010:66;14026:49;14068:6;14026:49;:::i;:::-;14010:66;:::i;:::-;14001:75;;14099:6;14092:5;14085:21;14137:4;14130:5;14126:16;14175:3;14166:6;14161:3;14157:16;14154:25;14151:112;;;14182:79;;:::i;:::-;14151:112;14272:54;14319:6;14314:3;14309;14272:54;:::i;:::-;13991:341;13907:425;;;;;:::o;14352:340::-;14408:5;14457:3;14450:4;14442:6;14438:17;14434:27;14424:122;;14465:79;;:::i;:::-;14424:122;14582:6;14569:20;14607:79;14682:3;14674:6;14667:4;14659:6;14655:17;14607:79;:::i;:::-;14598:88;;14414:278;14352:340;;;;:::o;14698:509::-;14767:6;14816:2;14804:9;14795:7;14791:23;14787:32;14784:119;;;14822:79;;:::i;:::-;14784:119;14970:1;14959:9;14955:17;14942:31;15000:18;14992:6;14989:30;14986:117;;;15022:79;;:::i;:::-;14986:117;15127:63;15182:7;15173:6;15162:9;15158:22;15127:63;:::i;:::-;15117:73;;14913:287;14698:509;;;;:::o;15213:307::-;15274:4;15364:18;15356:6;15353:30;15350:56;;;15386:18;;:::i;:::-;15350:56;15424:29;15446:6;15424:29;:::i;:::-;15416:37;;15508:4;15502;15498:15;15490:23;;15213:307;;;:::o;15526:423::-;15603:5;15628:65;15644:48;15685:6;15644:48;:::i;:::-;15628:65;:::i;:::-;15619:74;;15716:6;15709:5;15702:21;15754:4;15747:5;15743:16;15792:3;15783:6;15778:3;15774:16;15771:25;15768:112;;;15799:79;;:::i;:::-;15768:112;15889:54;15936:6;15931:3;15926;15889:54;:::i;:::-;15609:340;15526:423;;;;;:::o;15968:338::-;16023:5;16072:3;16065:4;16057:6;16053:17;16049:27;16039:122;;16080:79;;:::i;:::-;16039:122;16197:6;16184:20;16222:78;16296:3;16288:6;16281:4;16273:6;16269:17;16222:78;:::i;:::-;16213:87;;16029:277;15968:338;;;;:::o;16312:507::-;16380:6;16429:2;16417:9;16408:7;16404:23;16400:32;16397:119;;;16435:79;;:::i;:::-;16397:119;16583:1;16572:9;16568:17;16555:31;16613:18;16605:6;16602:30;16599:117;;;16635:79;;:::i;:::-;16599:117;16740:62;16794:7;16785:6;16774:9;16770:22;16740:62;:::i;:::-;16730:72;;16526:286;16312:507;;;;:::o;16825:149::-;16861:7;16901:66;16894:5;16890:78;16879:89;;16825:149;;;:::o;16980:115::-;17065:23;17082:5;17065:23;:::i;:::-;17060:3;17053:36;16980:115;;:::o;17101:77::-;17138:7;17167:5;17156:16;;17101:77;;;:::o;17184:118::-;17271:24;17289:5;17271:24;:::i;:::-;17266:3;17259:37;17184:118;;:::o;17308:114::-;17375:6;17409:5;17403:12;17393:22;;17308:114;;;:::o;17428:184::-;17527:11;17561:6;17556:3;17549:19;17601:4;17596:3;17592:14;17577:29;;17428:184;;;;:::o;17618:132::-;17685:4;17708:3;17700:11;;17738:4;17733:3;17729:14;17721:22;;17618:132;;;:::o;17756:108::-;17833:24;17851:5;17833:24;:::i;:::-;17828:3;17821:37;17756:108;;:::o;17870:179::-;17939:10;17960:46;18002:3;17994:6;17960:46;:::i;:::-;18038:4;18033:3;18029:14;18015:28;;17870:179;;;;:::o;18055:113::-;18125:4;18157;18152:3;18148:14;18140:22;;18055:113;;;:::o;18204:732::-;18323:3;18352:54;18400:5;18352:54;:::i;:::-;18422:86;18501:6;18496:3;18422:86;:::i;:::-;18415:93;;18532:56;18582:5;18532:56;:::i;:::-;18611:7;18642:1;18627:284;18652:6;18649:1;18646:13;18627:284;;;18728:6;18722:13;18755:63;18814:3;18799:13;18755:63;:::i;:::-;18748:70;;18841:60;18894:6;18841:60;:::i;:::-;18831:70;;18687:224;18674:1;18671;18667:9;18662:14;;18627:284;;;18631:14;18927:3;18920:10;;18328:608;;;18204:732;;;;:::o;18942:1215::-;19291:4;19329:3;19318:9;19314:19;19306:27;;19343:69;19409:1;19398:9;19394:17;19385:6;19343:69;:::i;:::-;19459:9;19453:4;19449:20;19444:2;19433:9;19429:18;19422:48;19487:78;19560:4;19551:6;19487:78;:::i;:::-;19479:86;;19612:9;19606:4;19602:20;19597:2;19586:9;19582:18;19575:48;19640:78;19713:4;19704:6;19640:78;:::i;:::-;19632:86;;19728:72;19796:2;19785:9;19781:18;19772:6;19728:72;:::i;:::-;19810:73;19878:3;19867:9;19863:19;19854:6;19810:73;:::i;:::-;19893;19961:3;19950:9;19946:19;19937:6;19893:73;:::i;:::-;20014:9;20008:4;20004:20;19998:3;19987:9;19983:19;19976:49;20042:108;20145:4;20136:6;20042:108;:::i;:::-;20034:116;;18942:1215;;;;;;;;;;:::o;20176:552::-;20233:8;20243:6;20293:3;20286:4;20278:6;20274:17;20270:27;20260:122;;20301:79;;:::i;:::-;20260:122;20414:6;20401:20;20391:30;;20444:18;20436:6;20433:30;20430:117;;;20466:79;;:::i;:::-;20430:117;20580:4;20572:6;20568:17;20556:29;;20634:3;20626:4;20618:6;20614:17;20604:8;20600:32;20597:41;20594:128;;;20641:79;;:::i;:::-;20594:128;20176:552;;;;;:::o;20734:1047::-;20849:6;20857;20865;20873;20881;20930:2;20918:9;20909:7;20905:23;20901:32;20898:119;;;20936:79;;:::i;:::-;20898:119;21084:1;21073:9;21069:17;21056:31;21114:18;21106:6;21103:30;21100:117;;;21136:79;;:::i;:::-;21100:117;21249:64;21305:7;21296:6;21285:9;21281:22;21249:64;:::i;:::-;21231:82;;;;21027:296;21390:2;21379:9;21375:18;21362:32;21421:18;21413:6;21410:30;21407:117;;;21443:79;;:::i;:::-;21407:117;21556:80;21628:7;21619:6;21608:9;21604:22;21556:80;:::i;:::-;21538:98;;;;21333:313;21685:2;21711:53;21756:7;21747:6;21736:9;21732:22;21711:53;:::i;:::-;21701:63;;21656:118;20734:1047;;;;;;;;:::o;21787:468::-;21852:6;21860;21909:2;21897:9;21888:7;21884:23;21880:32;21877:119;;;21915:79;;:::i;:::-;21877:119;22035:1;22060:53;22105:7;22096:6;22085:9;22081:22;22060:53;:::i;:::-;22050:63;;22006:117;22162:2;22188:50;22230:7;22221:6;22210:9;22206:22;22188:50;:::i;:::-;22178:60;;22133:115;21787:468;;;;;:::o;22261:943::-;22356:6;22364;22372;22380;22429:3;22417:9;22408:7;22404:23;22400:33;22397:120;;;22436:79;;:::i;:::-;22397:120;22556:1;22581:53;22626:7;22617:6;22606:9;22602:22;22581:53;:::i;:::-;22571:63;;22527:117;22683:2;22709:53;22754:7;22745:6;22734:9;22730:22;22709:53;:::i;:::-;22699:63;;22654:118;22811:2;22837:53;22882:7;22873:6;22862:9;22858:22;22837:53;:::i;:::-;22827:63;;22782:118;22967:2;22956:9;22952:18;22939:32;22998:18;22990:6;22987:30;22984:117;;;23020:79;;:::i;:::-;22984:117;23125:62;23179:7;23170:6;23159:9;23155:22;23125:62;:::i;:::-;23115:72;;22910:287;22261:943;;;;;;;:::o;23210:122::-;23283:24;23301:5;23283:24;:::i;:::-;23276:5;23273:35;23263:63;;23322:1;23319;23312:12;23263:63;23210:122;:::o;23338:139::-;23384:5;23422:6;23409:20;23400:29;;23438:33;23465:5;23438:33;:::i;:::-;23338:139;;;;:::o;23483:329::-;23542:6;23591:2;23579:9;23570:7;23566:23;23562:32;23559:119;;;23597:79;;:::i;:::-;23559:119;23717:1;23742:53;23787:7;23778:6;23767:9;23763:22;23742:53;:::i;:::-;23732:63;;23688:117;23483:329;;;;:::o;23818:359::-;23892:6;23941:2;23929:9;23920:7;23916:23;23912:32;23909:119;;;23947:79;;:::i;:::-;23909:119;24067:1;24092:68;24152:7;24143:6;24132:9;24128:22;24092:68;:::i;:::-;24082:78;;24038:132;23818:359;;;;:::o;24183:474::-;24251:6;24259;24308:2;24296:9;24287:7;24283:23;24279:32;24276:119;;;24314:79;;:::i;:::-;24276:119;24434:1;24459:53;24504:7;24495:6;24484:9;24480:22;24459:53;:::i;:::-;24449:63;;24405:117;24561:2;24587:53;24632:7;24623:6;24612:9;24608:22;24587:53;:::i;:::-;24577:63;;24532:118;24183:474;;;;;:::o;24663:94::-;24696:8;24744:5;24740:2;24736:14;24715:35;;24663:94;;;:::o;24763:::-;24802:7;24831:20;24845:5;24831:20;:::i;:::-;24820:31;;24763:94;;;:::o;24863:100::-;24902:7;24931:26;24951:5;24931:26;:::i;:::-;24920:37;;24863:100;;;:::o;24969:157::-;25074:45;25094:24;25112:5;25094:24;:::i;:::-;25074:45;:::i;:::-;25069:3;25062:58;24969:157;;:::o;25132:79::-;25171:7;25200:5;25189:16;;25132:79;;;:::o;25217:157::-;25322:45;25342:24;25360:5;25342:24;:::i;:::-;25322:45;:::i;:::-;25317:3;25310:58;25217:157;;:::o;25380:397::-;25520:3;25535:75;25606:3;25597:6;25535:75;:::i;:::-;25635:2;25630:3;25626:12;25619:19;;25648:75;25719:3;25710:6;25648:75;:::i;:::-;25748:2;25743:3;25739:12;25732:19;;25768:3;25761:10;;25380:397;;;;;:::o;25783:182::-;25923:34;25919:1;25911:6;25907:14;25900:58;25783:182;:::o;25971:366::-;26113:3;26134:67;26198:2;26193:3;26134:67;:::i;:::-;26127:74;;26210:93;26299:3;26210:93;:::i;:::-;26328:2;26323:3;26319:12;26312:19;;25971:366;;;:::o;26343:419::-;26509:4;26547:2;26536:9;26532:18;26524:26;;26596:9;26590:4;26586:20;26582:1;26571:9;26567:17;26560:47;26624:131;26750:4;26624:131;:::i;:::-;26616:139;;26343:419;;;:::o;26768:180::-;26816:77;26813:1;26806:88;26913:4;26910:1;26903:15;26937:4;26934:1;26927:15;26954:320;26998:6;27035:1;27029:4;27025:12;27015:22;;27082:1;27076:4;27072:12;27103:18;27093:81;;27159:4;27151:6;27147:17;27137:27;;27093:81;27221:2;27213:6;27210:14;27190:18;27187:38;27184:84;;27240:18;;:::i;:::-;27184:84;27005:269;26954:320;;;:::o;27280:225::-;27420:34;27416:1;27408:6;27404:14;27397:58;27489:8;27484:2;27476:6;27472:15;27465:33;27280:225;:::o;27511:366::-;27653:3;27674:67;27738:2;27733:3;27674:67;:::i;:::-;27667:74;;27750:93;27839:3;27750:93;:::i;:::-;27868:2;27863:3;27859:12;27852:19;;27511:366;;;:::o;27883:419::-;28049:4;28087:2;28076:9;28072:18;28064:26;;28136:9;28130:4;28126:20;28122:1;28111:9;28107:17;28100:47;28164:131;28290:4;28164:131;:::i;:::-;28156:139;;27883:419;;;:::o;28308:230::-;28448:34;28444:1;28436:6;28432:14;28425:58;28517:13;28512:2;28504:6;28500:15;28493:38;28308:230;:::o;28544:366::-;28686:3;28707:67;28771:2;28766:3;28707:67;:::i;:::-;28700:74;;28783:93;28872:3;28783:93;:::i;:::-;28901:2;28896:3;28892:12;28885:19;;28544:366;;;:::o;28916:419::-;29082:4;29120:2;29109:9;29105:18;29097:26;;29169:9;29163:4;29159:20;29155:1;29144:9;29140:17;29133:47;29197:131;29323:4;29197:131;:::i;:::-;29189:139;;28916:419;;;:::o;29341:180::-;29389:77;29386:1;29379:88;29486:4;29483:1;29476:15;29510:4;29507:1;29500:15;29527:191;29567:3;29586:20;29604:1;29586:20;:::i;:::-;29581:25;;29620:20;29638:1;29620:20;:::i;:::-;29615:25;;29663:1;29660;29656:9;29649:16;;29684:3;29681:1;29678:10;29675:36;;;29691:18;;:::i;:::-;29675:36;29527:191;;;;:::o;29724:60::-;29752:3;29773:5;29766:12;;29724:60;;;:::o;29790:142::-;29840:9;29873:53;29891:34;29900:24;29918:5;29900:24;:::i;:::-;29891:34;:::i;:::-;29873:53;:::i;:::-;29860:66;;29790:142;;;:::o;29938:126::-;29988:9;30021:37;30052:5;30021:37;:::i;:::-;30008:50;;29938:126;;;:::o;30070:134::-;30128:9;30161:37;30192:5;30161:37;:::i;:::-;30148:50;;30070:134;;;:::o;30210:147::-;30305:45;30344:5;30305:45;:::i;:::-;30300:3;30293:58;30210:147;;:::o;30363:348::-;30492:4;30530:2;30519:9;30515:18;30507:26;;30543:79;30619:1;30608:9;30604:17;30595:6;30543:79;:::i;:::-;30632:72;30700:2;30689:9;30685:18;30676:6;30632:72;:::i;:::-;30363:348;;;;;:::o;30717:410::-;30757:7;30780:20;30798:1;30780:20;:::i;:::-;30775:25;;30814:20;30832:1;30814:20;:::i;:::-;30809:25;;30869:1;30866;30862:9;30891:30;30909:11;30891:30;:::i;:::-;30880:41;;31070:1;31061:7;31057:15;31054:1;31051:22;31031:1;31024:9;31004:83;30981:139;;31100:18;;:::i;:::-;30981:139;30765:362;30717:410;;;;:::o;31133:180::-;31181:77;31178:1;31171:88;31278:4;31275:1;31268:15;31302:4;31299:1;31292:15;31319:185;31359:1;31376:20;31394:1;31376:20;:::i;:::-;31371:25;;31410:20;31428:1;31410:20;:::i;:::-;31405:25;;31449:1;31439:35;;31454:18;;:::i;:::-;31439:35;31496:1;31493;31489:9;31484:14;;31319:185;;;;:::o;31510:147::-;31611:11;31648:3;31633:18;;31510:147;;;;:::o;31663:114::-;;:::o;31783:398::-;31942:3;31963:83;32044:1;32039:3;31963:83;:::i;:::-;31956:90;;32055:93;32144:3;32055:93;:::i;:::-;32173:1;32168:3;32164:11;32157:18;;31783:398;;;:::o;32187:379::-;32371:3;32393:147;32536:3;32393:147;:::i;:::-;32386:154;;32557:3;32550:10;;32187:379;;;:::o;32572:141::-;32621:4;32644:3;32636:11;;32667:3;32664:1;32657:14;32701:4;32698:1;32688:18;32680:26;;32572:141;;;:::o;32719:93::-;32756:6;32803:2;32798;32791:5;32787:14;32783:23;32773:33;;32719:93;;;:::o;32818:107::-;32862:8;32912:5;32906:4;32902:16;32881:37;;32818:107;;;;:::o;32931:393::-;33000:6;33050:1;33038:10;33034:18;33073:97;33103:66;33092:9;33073:97;:::i;:::-;33191:39;33221:8;33210:9;33191:39;:::i;:::-;33179:51;;33263:4;33259:9;33252:5;33248:21;33239:30;;33312:4;33302:8;33298:19;33291:5;33288:30;33278:40;;33007:317;;32931:393;;;;;:::o;33330:142::-;33380:9;33413:53;33431:34;33440:24;33458:5;33440:24;:::i;:::-;33431:34;:::i;:::-;33413:53;:::i;:::-;33400:66;;33330:142;;;:::o;33478:75::-;33521:3;33542:5;33535:12;;33478:75;;;:::o;33559:269::-;33669:39;33700:7;33669:39;:::i;:::-;33730:91;33779:41;33803:16;33779:41;:::i;:::-;33771:6;33764:4;33758:11;33730:91;:::i;:::-;33724:4;33717:105;33635:193;33559:269;;;:::o;33834:73::-;33879:3;33834:73;:::o;33913:189::-;33990:32;;:::i;:::-;34031:65;34089:6;34081;34075:4;34031:65;:::i;:::-;33966:136;33913:189;;:::o;34108:186::-;34168:120;34185:3;34178:5;34175:14;34168:120;;;34239:39;34276:1;34269:5;34239:39;:::i;:::-;34212:1;34205:5;34201:13;34192:22;;34168:120;;;34108:186;;:::o;34300:543::-;34401:2;34396:3;34393:11;34390:446;;;34435:38;34467:5;34435:38;:::i;:::-;34519:29;34537:10;34519:29;:::i;:::-;34509:8;34505:44;34702:2;34690:10;34687:18;34684:49;;;34723:8;34708:23;;34684:49;34746:80;34802:22;34820:3;34802:22;:::i;:::-;34792:8;34788:37;34775:11;34746:80;:::i;:::-;34405:431;;34390:446;34300:543;;;:::o;34849:117::-;34903:8;34953:5;34947:4;34943:16;34922:37;;34849:117;;;;:::o;34972:169::-;35016:6;35049:51;35097:1;35093:6;35085:5;35082:1;35078:13;35049:51;:::i;:::-;35045:56;35130:4;35124;35120:15;35110:25;;35023:118;34972:169;;;;:::o;35146:295::-;35222:4;35368:29;35393:3;35387:4;35368:29;:::i;:::-;35360:37;;35430:3;35427:1;35423:11;35417:4;35414:21;35406:29;;35146:295;;;;:::o;35446:1395::-;35563:37;35596:3;35563:37;:::i;:::-;35665:18;35657:6;35654:30;35651:56;;;35687:18;;:::i;:::-;35651:56;35731:38;35763:4;35757:11;35731:38;:::i;:::-;35816:67;35876:6;35868;35862:4;35816:67;:::i;:::-;35910:1;35934:4;35921:17;;35966:2;35958:6;35955:14;35983:1;35978:618;;;;36640:1;36657:6;36654:77;;;36706:9;36701:3;36697:19;36691:26;36682:35;;36654:77;36757:67;36817:6;36810:5;36757:67;:::i;:::-;36751:4;36744:81;36613:222;35948:887;;35978:618;36030:4;36026:9;36018:6;36014:22;36064:37;36096:4;36064:37;:::i;:::-;36123:1;36137:208;36151:7;36148:1;36145:14;36137:208;;;36230:9;36225:3;36221:19;36215:26;36207:6;36200:42;36281:1;36273:6;36269:14;36259:24;;36328:2;36317:9;36313:18;36300:31;;36174:4;36171:1;36167:12;36162:17;;36137:208;;;36373:6;36364:7;36361:19;36358:179;;;36431:9;36426:3;36422:19;36416:26;36474:48;36516:4;36508:6;36504:17;36493:9;36474:48;:::i;:::-;36466:6;36459:64;36381:156;36358:179;36583:1;36579;36571:6;36567:14;36563:22;36557:4;36550:36;35985:611;;;35948:887;;35538:1303;;;35446:1395;;:::o;36847:442::-;36996:4;37034:2;37023:9;37019:18;37011:26;;37047:71;37115:1;37104:9;37100:17;37091:6;37047:71;:::i;:::-;37128:72;37196:2;37185:9;37181:18;37172:6;37128:72;:::i;:::-;37210;37278:2;37267:9;37263:18;37254:6;37210:72;:::i;:::-;36847:442;;;;;;:::o;37295:148::-;37397:11;37434:3;37419:18;;37295:148;;;;:::o;37449:214::-;37589:66;37585:1;37577:6;37573:14;37566:90;37449:214;:::o;37669:400::-;37829:3;37850:84;37932:1;37927:3;37850:84;:::i;:::-;37843:91;;37943:93;38032:3;37943:93;:::i;:::-;38061:1;38056:3;38052:11;38045:18;;37669:400;;;:::o;38075:79::-;38114:7;38143:5;38132:16;;38075:79;;;:::o;38160:157::-;38265:45;38285:24;38303:5;38285:24;:::i;:::-;38265:45;:::i;:::-;38260:3;38253:58;38160:157;;:::o;38323:663::-;38564:3;38586:148;38730:3;38586:148;:::i;:::-;38579:155;;38744:75;38815:3;38806:6;38744:75;:::i;:::-;38844:2;38839:3;38835:12;38828:19;;38857:75;38928:3;38919:6;38857:75;:::i;:::-;38957:2;38952:3;38948:12;38941:19;;38977:3;38970:10;;38323:663;;;;;:::o;38992:180::-;39040:77;39037:1;39030:88;39137:4;39134:1;39127:15;39161:4;39158:1;39151:15;39178:165;39318:17;39314:1;39306:6;39302:14;39295:41;39178:165;:::o;39349:366::-;39491:3;39512:67;39576:2;39571:3;39512:67;:::i;:::-;39505:74;;39588:93;39677:3;39588:93;:::i;:::-;39706:2;39701:3;39697:12;39690:19;;39349:366;;;:::o;39721:419::-;39887:4;39925:2;39914:9;39910:18;39902:26;;39974:9;39968:4;39964:20;39960:1;39949:9;39945:17;39938:47;40002:131;40128:4;40002:131;:::i;:::-;39994:139;;39721:419;;;:::o;40146:164::-;40286:16;40282:1;40274:6;40270:14;40263:40;40146:164;:::o;40316:366::-;40458:3;40479:67;40543:2;40538:3;40479:67;:::i;:::-;40472:74;;40555:93;40644:3;40555:93;:::i;:::-;40673:2;40668:3;40664:12;40657:19;;40316:366;;;:::o;40688:419::-;40854:4;40892:2;40881:9;40877:18;40869:26;;40941:9;40935:4;40931:20;40927:1;40916:9;40912:17;40905:47;40969:131;41095:4;40969:131;:::i;:::-;40961:139;;40688:419;;;:::o;41113:161::-;41253:13;41249:1;41241:6;41237:14;41230:37;41113:161;:::o;41280:366::-;41422:3;41443:67;41507:2;41502:3;41443:67;:::i;:::-;41436:74;;41519:93;41608:3;41519:93;:::i;:::-;41637:2;41632:3;41628:12;41621:19;;41280:366;;;:::o;41652:419::-;41818:4;41856:2;41845:9;41841:18;41833:26;;41905:9;41899:4;41895:20;41891:1;41880:9;41876:17;41869:47;41933:131;42059:4;41933:131;:::i;:::-;41925:139;;41652:419;;;:::o;42077:162::-;42217:14;42213:1;42205:6;42201:14;42194:38;42077:162;:::o;42245:366::-;42387:3;42408:67;42472:2;42467:3;42408:67;:::i;:::-;42401:74;;42484:93;42573:3;42484:93;:::i;:::-;42602:2;42597:3;42593:12;42586:19;;42245:366;;;:::o;42617:419::-;42783:4;42821:2;42810:9;42806:18;42798:26;;42870:9;42864:4;42860:20;42856:1;42845:9;42841:17;42834:47;42898:131;43024:4;42898:131;:::i;:::-;42890:139;;42617:419;;;:::o;43042:165::-;43182:17;43178:1;43170:6;43166:14;43159:41;43042:165;:::o;43213:366::-;43355:3;43376:67;43440:2;43435:3;43376:67;:::i;:::-;43369:74;;43452:93;43541:3;43452:93;:::i;:::-;43570:2;43565:3;43561:12;43554:19;;43213:366;;;:::o;43585:419::-;43751:4;43789:2;43778:9;43774:18;43766:26;;43838:9;43832:4;43828:20;43824:1;43813:9;43809:17;43802:47;43866:131;43992:4;43866:131;:::i;:::-;43858:139;;43585:419;;;:::o;44010:143::-;44067:5;44098:6;44092:13;44083:22;;44114:33;44141:5;44114:33;:::i;:::-;44010:143;;;;:::o;44159:351::-;44229:6;44278:2;44266:9;44257:7;44253:23;44249:32;44246:119;;;44284:79;;:::i;:::-;44246:119;44404:1;44429:64;44485:7;44476:6;44465:9;44461:22;44429:64;:::i;:::-;44419:74;;44375:128;44159:351;;;;:::o;44516:390::-;44622:3;44650:39;44683:5;44650:39;:::i;:::-;44705:89;44787:6;44782:3;44705:89;:::i;:::-;44698:96;;44803:65;44861:6;44856:3;44849:4;44842:5;44838:16;44803:65;:::i;:::-;44893:6;44888:3;44884:16;44877:23;;44626:280;44516:390;;;;:::o;44912:155::-;45052:7;45048:1;45040:6;45036:14;45029:31;44912:155;:::o;45073:400::-;45233:3;45254:84;45336:1;45331:3;45254:84;:::i;:::-;45247:91;;45347:93;45436:3;45347:93;:::i;:::-;45465:1;45460:3;45456:11;45449:18;;45073:400;;;:::o;45479:701::-;45760:3;45782:95;45873:3;45864:6;45782:95;:::i;:::-;45775:102;;45894:95;45985:3;45976:6;45894:95;:::i;:::-;45887:102;;46006:148;46150:3;46006:148;:::i;:::-;45999:155;;46171:3;46164:10;;45479:701;;;;;:::o;46186:225::-;46326:34;46322:1;46314:6;46310:14;46303:58;46395:8;46390:2;46382:6;46378:15;46371:33;46186:225;:::o;46417:366::-;46559:3;46580:67;46644:2;46639:3;46580:67;:::i;:::-;46573:74;;46656:93;46745:3;46656:93;:::i;:::-;46774:2;46769:3;46765:12;46758:19;;46417:366;;;:::o;46789:419::-;46955:4;46993:2;46982:9;46978:18;46970:26;;47042:9;47036:4;47032:20;47028:1;47017:9;47013:17;47006:47;47070:131;47196:4;47070:131;:::i;:::-;47062:139;;46789:419;;;:::o;47214:182::-;47354:34;47350:1;47342:6;47338:14;47331:58;47214:182;:::o;47402:366::-;47544:3;47565:67;47629:2;47624:3;47565:67;:::i;:::-;47558:74;;47641:93;47730:3;47641:93;:::i;:::-;47759:2;47754:3;47750:12;47743:19;;47402:366;;;:::o;47774:419::-;47940:4;47978:2;47967:9;47963:18;47955:26;;48027:9;48021:4;48017:20;48013:1;48002:9;47998:17;47991:47;48055:131;48181:4;48055:131;:::i;:::-;48047:139;;47774:419;;;:::o;48199:140::-;48248:9;48281:52;48299:33;48308:23;48325:5;48308:23;:::i;:::-;48299:33;:::i;:::-;48281:52;:::i;:::-;48268:65;;48199:140;;;:::o;48345:129::-;48431:36;48461:5;48431:36;:::i;:::-;48426:3;48419:49;48345:129;;:::o;48480:330::-;48600:4;48638:2;48627:9;48623:18;48615:26;;48651:70;48718:1;48707:9;48703:17;48694:6;48651:70;:::i;:::-;48731:72;48799:2;48788:9;48784:18;48775:6;48731:72;:::i;:::-;48480:330;;;;;:::o;48816:179::-;48956:31;48952:1;48944:6;48940:14;48933:55;48816:179;:::o;49001:366::-;49143:3;49164:67;49228:2;49223:3;49164:67;:::i;:::-;49157:74;;49240:93;49329:3;49240:93;:::i;:::-;49358:2;49353:3;49349:12;49342:19;;49001:366;;;:::o;49373:419::-;49539:4;49577:2;49566:9;49562:18;49554:26;;49626:9;49620:4;49616:20;49612:1;49601:9;49597:17;49590:47;49654:131;49780:4;49654:131;:::i;:::-;49646:139;;49373:419;;;:::o;49798:245::-;49938:34;49934:1;49926:6;49922:14;49915:58;50007:28;50002:2;49994:6;49990:15;49983:53;49798:245;:::o;50049:366::-;50191:3;50212:67;50276:2;50271:3;50212:67;:::i;:::-;50205:74;;50288:93;50377:3;50288:93;:::i;:::-;50406:2;50401:3;50397:12;50390:19;;50049:366;;;:::o;50421:419::-;50587:4;50625:2;50614:9;50610:18;50602:26;;50674:9;50668:4;50664:20;50660:1;50649:9;50645:17;50638:47;50702:131;50828:4;50702:131;:::i;:::-;50694:139;;50421:419;;;:::o;50846:181::-;50986:33;50982:1;50974:6;50970:14;50963:57;50846:181;:::o;51033:366::-;51175:3;51196:67;51260:2;51255:3;51196:67;:::i;:::-;51189:74;;51272:93;51361:3;51272:93;:::i;:::-;51390:2;51385:3;51381:12;51374:19;;51033:366;;;:::o;51405:419::-;51571:4;51609:2;51598:9;51594:18;51586:26;;51658:9;51652:4;51648:20;51644:1;51633:9;51629:17;51622:47;51686:131;51812:4;51686:131;:::i;:::-;51678:139;;51405:419;;;:::o;51830:194::-;51870:4;51890:20;51908:1;51890:20;:::i;:::-;51885:25;;51924:20;51942:1;51924:20;:::i;:::-;51919:25;;51968:1;51965;51961:9;51953:17;;51992:1;51986:4;51983:11;51980:37;;;51997:18;;:::i;:::-;51980:37;51830:194;;;;:::o;52030:98::-;52081:6;52115:5;52109:12;52099:22;;52030:98;;;:::o;52134:168::-;52217:11;52251:6;52246:3;52239:19;52291:4;52286:3;52282:14;52267:29;;52134:168;;;;:::o;52308:373::-;52394:3;52422:38;52454:5;52422:38;:::i;:::-;52476:70;52539:6;52534:3;52476:70;:::i;:::-;52469:77;;52555:65;52613:6;52608:3;52601:4;52594:5;52590:16;52555:65;:::i;:::-;52645:29;52667:6;52645:29;:::i;:::-;52640:3;52636:39;52629:46;;52398:283;52308:373;;;;:::o;52687:640::-;52882:4;52920:3;52909:9;52905:19;52897:27;;52934:71;53002:1;52991:9;52987:17;52978:6;52934:71;:::i;:::-;53015:72;53083:2;53072:9;53068:18;53059:6;53015:72;:::i;:::-;53097;53165:2;53154:9;53150:18;53141:6;53097:72;:::i;:::-;53216:9;53210:4;53206:20;53201:2;53190:9;53186:18;53179:48;53244:76;53315:4;53306:6;53244:76;:::i;:::-;53236:84;;52687:640;;;;;;;:::o;53333:141::-;53389:5;53420:6;53414:13;53405:22;;53436:32;53462:5;53436:32;:::i;:::-;53333:141;;;;:::o;53480:349::-;53549:6;53598:2;53586:9;53577:7;53573:23;53569:32;53566:119;;;53604:79;;:::i;:::-;53566:119;53724:1;53749:63;53804:7;53795:6;53784:9;53780:22;53749:63;:::i;:::-;53739:73;;53695:127;53480:349;;;;:::o;53835:233::-;53874:3;53897:24;53915:5;53897:24;:::i;:::-;53888:33;;53943:66;53936:5;53933:77;53930:103;;54013:18;;:::i;:::-;53930:103;54060:1;54053:5;54049:13;54042:20;;53835:233;;;:::o;54074:137::-;54128:5;54159:6;54153:13;54144:22;;54175:30;54199:5;54175:30;:::i;:::-;54074:137;;;;:::o;54217:345::-;54284:6;54333:2;54321:9;54312:7;54308:23;54304:32;54301:119;;;54339:79;;:::i;:::-;54301:119;54459:1;54484:61;54537:7;54528:6;54517:9;54513:22;54484:61;:::i;:::-;54474:71;;54430:125;54217:345;;;;:::o;54568:229::-;54708:34;54704:1;54696:6;54692:14;54685:58;54777:12;54772:2;54764:6;54760:15;54753:37;54568:229;:::o;54803:366::-;54945:3;54966:67;55030:2;55025:3;54966:67;:::i;:::-;54959:74;;55042:93;55131:3;55042:93;:::i;:::-;55160:2;55155:3;55151:12;55144:19;;54803:366;;;:::o;55175:419::-;55341:4;55379:2;55368:9;55364:18;55356:26;;55428:9;55422:4;55418:20;55414:1;55403:9;55399:17;55392:47;55456:131;55582:4;55456:131;:::i;:::-;55448:139;;55175:419;;;:::o;55600:664::-;55805:4;55843:3;55832:9;55828:19;55820:27;;55857:71;55925:1;55914:9;55910:17;55901:6;55857:71;:::i;:::-;55938:72;56006:2;55995:9;55991:18;55982:6;55938:72;:::i;:::-;56020;56088:2;56077:9;56073:18;56064:6;56020:72;:::i;:::-;56102;56170:2;56159:9;56155:18;56146:6;56102:72;:::i;:::-;56184:73;56252:3;56241:9;56237:19;56228:6;56184:73;:::i;:::-;55600:664;;;;;;;;:::o;56270:180::-;56318:77;56315:1;56308:88;56415:4;56412:1;56405:15;56439:4;56436:1;56429:15;56456:174;56596:26;56592:1;56584:6;56580:14;56573:50;56456:174;:::o;56636:366::-;56778:3;56799:67;56863:2;56858:3;56799:67;:::i;:::-;56792:74;;56875:93;56964:3;56875:93;:::i;:::-;56993:2;56988:3;56984:12;56977:19;;56636:366;;;:::o;57008:419::-;57174:4;57212:2;57201:9;57197:18;57189:26;;57261:9;57255:4;57251:20;57247:1;57236:9;57232:17;57225:47;57289:131;57415:4;57289:131;:::i;:::-;57281:139;;57008:419;;;:::o;57433:181::-;57573:33;57569:1;57561:6;57557:14;57550:57;57433:181;:::o;57620:366::-;57762:3;57783:67;57847:2;57842:3;57783:67;:::i;:::-;57776:74;;57859:93;57948:3;57859:93;:::i;:::-;57977:2;57972:3;57968:12;57961:19;;57620:366;;;:::o;57992:419::-;58158:4;58196:2;58185:9;58181:18;58173:26;;58245:9;58239:4;58235:20;58231:1;58220:9;58216:17;58209:47;58273:131;58399:4;58273:131;:::i;:::-;58265:139;;57992:419;;;:::o;58417:221::-;58557:34;58553:1;58545:6;58541:14;58534:58;58626:4;58621:2;58613:6;58609:15;58602:29;58417:221;:::o;58644:366::-;58786:3;58807:67;58871:2;58866:3;58807:67;:::i;:::-;58800:74;;58883:93;58972:3;58883:93;:::i;:::-;59001:2;58996:3;58992:12;58985:19;;58644:366;;;:::o;59016:419::-;59182:4;59220:2;59209:9;59205:18;59197:26;;59269:9;59263:4;59259:20;59255:1;59244:9;59240:17;59233:47;59297:131;59423:4;59297:131;:::i;:::-;59289:139;;59016:419;;;:::o;59441:86::-;59476:7;59516:4;59509:5;59505:16;59494:27;;59441:86;;;:::o;59533:112::-;59616:22;59632:5;59616:22;:::i;:::-;59611:3;59604:35;59533:112;;:::o;59651:545::-;59824:4;59862:3;59851:9;59847:19;59839:27;;59876:71;59944:1;59933:9;59929:17;59920:6;59876:71;:::i;:::-;59957:68;60021:2;60010:9;60006:18;59997:6;59957:68;:::i;:::-;60035:72;60103:2;60092:9;60088:18;60079:6;60035:72;:::i;:::-;60117;60185:2;60174:9;60170:18;60161:6;60117:72;:::i;:::-;59651:545;;;;;;;:::o;60202:225::-;60342:34;60338:1;60330:6;60326:14;60319:58;60411:8;60406:2;60398:6;60394:15;60387:33;60202:225;:::o;60433:366::-;60575:3;60596:67;60660:2;60655:3;60596:67;:::i;:::-;60589:74;;60672:93;60761:3;60672:93;:::i;:::-;60790:2;60785:3;60781:12;60774:19;;60433:366;;;:::o;60805:419::-;60971:4;61009:2;60998:9;60994:18;60986:26;;61058:9;61052:4;61048:20;61044:1;61033:9;61029:17;61022:47;61086:131;61212:4;61086:131;:::i;:::-;61078:139;;60805:419;;;:::o;61230:386::-;61334:3;61362:38;61394:5;61362:38;:::i;:::-;61416:88;61497:6;61492:3;61416:88;:::i;:::-;61409:95;;61513:65;61571:6;61566:3;61559:4;61552:5;61548:16;61513:65;:::i;:::-;61603:6;61598:3;61594:16;61587:23;;61338:278;61230:386;;;;:::o;61622:271::-;61752:3;61774:93;61863:3;61854:6;61774:93;:::i;:::-;61767:100;;61884:3;61877:10;;61622:271;;;;:::o;61899:179::-;62039:31;62035:1;62027:6;62023:14;62016:55;61899:179;:::o;62084:366::-;62226:3;62247:67;62311:2;62306:3;62247:67;:::i;:::-;62240:74;;62323:93;62412:3;62323:93;:::i;:::-;62441:2;62436:3;62432:12;62425:19;;62084:366;;;:::o;62456:419::-;62622:4;62660:2;62649:9;62645:18;62637:26;;62709:9;62703:4;62699:20;62695:1;62684:9;62680:17;62673:47;62737:131;62863:4;62737:131;:::i;:::-;62729:139;;62456:419;;;:::o
Swarm Source
ipfs://99c8f5f0f169fd2b575caebd56ce7fa194bc905a6429bea85c898f69abd49191
Loading...
Loading
Loading...
Loading
[ 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.