ERC-20
Overview
Max Total Supply
0 SudoGovernor
Holders
0
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:
SudoGovernor
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-01-30 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.9; // OpenZeppelin Contracts (last updated v4.8.0) (governance/Governor.sol) // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @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); } /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } /** * @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) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @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) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol) /** * @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]. * * _Available since v3.4._ */ abstract contract EIP712 { /* solhint-disable var-name-mixedcase */ // 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 _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; address private immutable _CACHED_THIS; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @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) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _CACHED_THIS = address(this); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, 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); } } // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) /** * @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; } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } } // OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol) /** * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that * the existing queue contents are left in storage. * * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be * used in storage, and not in memory. * ``` * DoubleEndedQueue.Bytes32Deque queue; * ``` * * _Available since v4.6._ */ library DoubleEndedQueue { /** * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty. */ error Empty(); /** * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds. */ error OutOfBounds(); /** * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely * assume that these 128-bit indices will not overflow, and use unchecked arithmetic. * * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and * lead to unexpected behavior. * * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at * data[end - 1]. */ struct Bytes32Deque { int128 _begin; int128 _end; mapping(int128 => bytes32) _data; } /** * @dev Inserts an item at the end of the queue. */ function pushBack(Bytes32Deque storage deque, bytes32 value) internal { int128 backIndex = deque._end; deque._data[backIndex] = value; unchecked { deque._end = backIndex + 1; } } /** * @dev Removes the item at the end of the queue and returns it. * * Reverts with `Empty` if the queue is empty. */ function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 backIndex; unchecked { backIndex = deque._end - 1; } value = deque._data[backIndex]; delete deque._data[backIndex]; deque._end = backIndex; } /** * @dev Inserts an item at the beginning of the queue. */ function pushFront(Bytes32Deque storage deque, bytes32 value) internal { int128 frontIndex; unchecked { frontIndex = deque._begin - 1; } deque._data[frontIndex] = value; deque._begin = frontIndex; } /** * @dev Removes the item at the beginning of the queue and returns it. * * Reverts with `Empty` if the queue is empty. */ function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 frontIndex = deque._begin; value = deque._data[frontIndex]; delete deque._data[frontIndex]; unchecked { deque._begin = frontIndex + 1; } } /** * @dev Returns the item at the beginning of the queue. * * Reverts with `Empty` if the queue is empty. */ function front(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 frontIndex = deque._begin; return deque._data[frontIndex]; } /** * @dev Returns the item at the end of the queue. * * Reverts with `Empty` if the queue is empty. */ function back(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 backIndex; unchecked { backIndex = deque._end - 1; } return deque._data[backIndex]; } /** * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at * `length(deque) - 1`. * * Reverts with `OutOfBounds` if the index is out of bounds. */ function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) { // int256(deque._begin) is a safe upcast int128 idx = SafeCast.toInt128(int256(deque._begin) + SafeCast.toInt256(index)); if (idx >= deque._end) revert OutOfBounds(); return deque._data[idx]; } /** * @dev Resets the queue back to being empty. * * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses * out on potential gas refunds. */ function clear(Bytes32Deque storage deque) internal { deque._begin = 0; deque._end = 0; } /** * @dev Returns the number of items in the queue. */ function length(Bytes32Deque storage deque) internal view returns (uint256) { // The interface preserves the invariant that begin <= end so we assume this will not overflow. // We also assume there are at most int256.max items in the queue. unchecked { return uint256(int256(deque._end) - int256(deque._begin)); } } /** * @dev Returns true if the queue is empty. */ function empty(Bytes32Deque storage deque) internal view returns (bool) { return deque._end <= deque._begin; } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) /** * @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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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); } } } // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @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; } } // OpenZeppelin Contracts v4.4.1 (utils/Timers.sol) /** * @dev Tooling for timepoints, timers and delays */ library Timers { struct Timestamp { uint64 _deadline; } function getDeadline(Timestamp memory timer) internal pure returns (uint64) { return timer._deadline; } function setDeadline(Timestamp storage timer, uint64 timestamp) internal { timer._deadline = timestamp; } function reset(Timestamp storage timer) internal { timer._deadline = 0; } function isUnset(Timestamp memory timer) internal pure returns (bool) { return timer._deadline == 0; } function isStarted(Timestamp memory timer) internal pure returns (bool) { return timer._deadline > 0; } function isPending(Timestamp memory timer) internal view returns (bool) { return timer._deadline > block.timestamp; } function isExpired(Timestamp memory timer) internal view returns (bool) { return isStarted(timer) && timer._deadline <= block.timestamp; } struct BlockNumber { uint64 _deadline; } function getDeadline(BlockNumber memory timer) internal pure returns (uint64) { return timer._deadline; } function setDeadline(BlockNumber storage timer, uint64 timestamp) internal { timer._deadline = timestamp; } function reset(BlockNumber storage timer) internal { timer._deadline = 0; } function isUnset(BlockNumber memory timer) internal pure returns (bool) { return timer._deadline == 0; } function isStarted(BlockNumber memory timer) internal pure returns (bool) { return timer._deadline > 0; } function isPending(BlockNumber memory timer) internal view returns (bool) { return timer._deadline > block.number; } function isExpired(BlockNumber memory timer) internal view returns (bool) { return isStarted(timer) && timer._deadline <= block.number; } } // OpenZeppelin Contracts (last updated v4.8.0) (governance/IGovernor.sol) /** * @dev Interface of the {Governor} core. * * _Available since v4.3._ */ abstract contract IGovernor is IERC165 { enum ProposalState { Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, Executed } /** * @dev Emitted when a proposal is created. */ event ProposalCreated( uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 startBlock, uint256 endBlock, string description ); /** * @dev Emitted when a proposal is canceled. */ event ProposalCanceled(uint256 proposalId); /** * @dev Emitted when a proposal is executed. */ event ProposalExecuted(uint256 proposalId); /** * @dev Emitted when a vote is cast without params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. */ event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); /** * @dev Emitted when a vote is cast with params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. * `params` are additional encoded parameters. Their intepepretation also depends on the voting module used. */ event VoteCastWithParams( address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params ); /** * @notice module:core * @dev Name of the governor instance (used in building the ERC712 domain separator). */ function name() public view virtual returns (string memory); /** * @notice module:core * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1" */ function version() public view virtual returns (string memory); /** * @notice module:voting * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`. * * There are 2 standard keys: `support` and `quorum`. * * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`. * - `quorum=bravo` means that only For votes are counted towards quorum. * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum. * * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique * name that describes the behavior. For example: * * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain. * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote. * * NOTE: The string can be decoded by the standard * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`] * JavaScript class. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public pure virtual returns (string memory); /** * @notice module:core * @dev Hashing function used to (re)build the proposal id from the proposal details.. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public pure virtual returns (uint256); /** * @notice module:core * @dev Current state of a proposal, following Compound's convention */ function state(uint256 proposalId) public view virtual returns (ProposalState); /** * @notice module:core * @dev Block number used to retrieve user's votes and quorum. As per Compound's Comp and OpenZeppelin's * ERC20Votes, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the * beginning of the following block. */ function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256); /** * @notice module:core * @dev Block number at which votes close. Votes close at the end of this block, so it is possible to cast a vote * during this block. */ function proposalDeadline(uint256 proposalId) public view virtual returns (uint256); /** * @notice module:user-config * @dev Delay, in number of block, between the proposal is created and the vote starts. This can be increassed to * leave time for users to buy voting power, or delegate it, before the voting of a proposal starts. */ function votingDelay() public view virtual returns (uint256); /** * @notice module:user-config * @dev Delay, in number of blocks, between the vote start and vote ends. * * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting * duration compared to the voting delay. */ function votingPeriod() public view virtual returns (uint256); /** * @notice module:user-config * @dev Minimum number of cast voted required for a proposal to be successful. * * Note: The `blockNumber` parameter corresponds to the snapshot used for counting vote. This allows to scale the * quorum depending on values such as the totalSupply of a token at this block (see {ERC20Votes}). */ function quorum(uint256 blockNumber) public view virtual returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `blockNumber`. * * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or * multiple), {ERC20Votes} tokens. */ function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `blockNumber` given additional encoded parameters. */ function getVotesWithParams( address account, uint256 blockNumber, bytes memory params ) public view virtual returns (uint256); /** * @notice module:voting * @dev Returns whether `account` has cast a vote on `proposalId`. */ function hasVoted(uint256 proposalId, address account) public view virtual returns (bool); /** * @dev Create a new proposal. Vote start {IGovernor-votingDelay} blocks after the proposal is created and ends * {IGovernor-votingPeriod} blocks after the voting starts. * * Emits a {ProposalCreated} event. */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual returns (uint256 proposalId); /** * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the * deadline to be reached. * * Emits a {ProposalExecuted} event. * * Note: some module can modify the requirements for execution, for example by adding an additional timelock. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public payable virtual returns (uint256 proposalId); /** * @dev Cast a vote * * Emits a {VoteCast} event. */ function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason * * Emits a {VoteCast} event. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) public virtual returns (uint256 balance); /** * @dev Cast a vote using the user's cryptographic signature. * * Emits a {VoteCast} event. */ function castVoteBySig( uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s ) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature. * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual returns (uint256 balance); } /** * @dev Core of the governance system, designed to be extended though various modules. * * This contract is abstract and requires several function to be implemented in various modules: * * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} * - A voting module must implement {_getVotes} * - Additionanly, the {votingPeriod} must also be implemented * * _Available since v4.3._ */ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver { using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; using SafeCast for uint256; using Timers for Timers.BlockNumber; bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); struct ProposalCore { Timers.BlockNumber voteStart; Timers.BlockNumber voteEnd; bool executed; bool canceled; } string private _name; mapping(uint256 => ProposalCore) private _proposals; // This queue keeps track of the governor operating on itself. Calls to functions protected by the // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. DoubleEndedQueue.Bytes32Deque private _governanceCall; /** * @dev Restricts a function so it can only be executed through governance proposals. For example, governance * parameter setters in {GovernorSettings} are protected using this modifier. * * The governance executing address may be different from the Governor's own address, for example it could be a * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, * for example, additional timelock proposers are not able to change governance parameters without going through the * governance protocol (since v4.6). */ modifier onlyGovernance() { require(_msgSender() == _executor(), "Governor: onlyGovernance"); if (_executor() != address(this)) { bytes32 msgDataHash = keccak256(_msgData()); // loop until popping the expected operation - throw if deque is empty (operation not authorized) while (_governanceCall.popFront() != msgDataHash) {} } _; } /** * @dev Sets the value for {name} and {version} */ constructor(string memory name_) EIP712(name_, version()) { _name = name_; } /** * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) */ receive() external payable virtual { require(_executor() == address(this)); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { // In addition to the current interfaceId, also support previous version of the interfaceId that did not // include the castVoteWithReasonAndParams() function as standard return interfaceId == (type(IGovernor).interfaceId ^ this.castVoteWithReasonAndParams.selector ^ this.castVoteWithReasonAndParamsBySig.selector ^ this.getVotesWithParams.selector) || interfaceId == type(IGovernor).interfaceId || interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IGovernor-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IGovernor-version}. */ function version() public view virtual override returns (string memory) { return "1"; } /** * @dev See {IGovernor-hashProposal}. * * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in * advance, before the proposal is submitted. * * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the * same proposal (with same operation and same description) will have the same id if submitted on multiple governors * across multiple networks. This also means that in order to execute the same operation twice (on the same * governor) the proposer will have to change the description in order to avoid proposal id conflicts. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public pure virtual override returns (uint256) { return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); } /** * @dev See {IGovernor-state}. */ function state(uint256 proposalId) public view virtual override returns (ProposalState) { ProposalCore storage proposal = _proposals[proposalId]; if (proposal.executed) { return ProposalState.Executed; } if (proposal.canceled) { return ProposalState.Canceled; } uint256 snapshot = proposalSnapshot(proposalId); if (snapshot == 0) { revert("Governor: unknown proposal id"); } if (snapshot >= block.number) { return ProposalState.Pending; } uint256 deadline = proposalDeadline(proposalId); if (deadline >= block.number) { return ProposalState.Active; } if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { return ProposalState.Succeeded; } else { return ProposalState.Defeated; } } /** * @dev See {IGovernor-proposalSnapshot}. */ function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { return _proposals[proposalId].voteStart.getDeadline(); } /** * @dev See {IGovernor-proposalDeadline}. */ function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { return _proposals[proposalId].voteEnd.getDeadline(); } /** * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. */ function proposalThreshold() public view virtual returns (uint256) { return 0; } /** * @dev Amount of votes already cast passes the threshold limit. */ function _quorumReached(uint256 proposalId) internal view virtual returns (bool); /** * @dev Is the proposal successful or not. */ function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); /** * @dev Get the voting weight of `account` at a specific `blockNumber`, for a vote as described by `params`. */ function _getVotes( address account, uint256 blockNumber, bytes memory params ) internal view virtual returns (uint256); /** * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. * * Note: Support is generic and can represent various things depending on the voting system used. */ function _countVote( uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory params ) internal virtual; /** * @dev Default additional encoded parameters used by castVote methods that don't include them * * Note: Should be overridden by specific implementations to use an appropriate value, the * meaning of the additional params, in the context of that implementation */ function _defaultParams() internal view virtual returns (bytes memory) { return ""; } /** * @dev See {IGovernor-propose}. */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual override returns (uint256) { require( getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold" ); uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); ProposalCore storage proposal = _proposals[proposalId]; require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); uint64 snapshot = block.number.toUint64() + votingDelay().toUint64(); uint64 deadline = snapshot + votingPeriod().toUint64(); proposal.voteStart.setDeadline(snapshot); proposal.voteEnd.setDeadline(deadline); emit ProposalCreated( proposalId, _msgSender(), targets, values, new string[](targets.length), calldatas, snapshot, deadline, description ); return proposalId; } /** * @dev See {IGovernor-execute}. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public payable virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); ProposalState status = state(proposalId); require( status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful" ); _proposals[proposalId].executed = true; emit ProposalExecuted(proposalId); _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); _execute(proposalId, targets, values, calldatas, descriptionHash); _afterExecute(proposalId, targets, values, calldatas, descriptionHash); return proposalId; } /** * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism */ function _execute( uint256, /* proposalId */ address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { string memory errorMessage = "Governor: call reverted without message"; for (uint256 i = 0; i < targets.length; ++i) { (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); Address.verifyCallResult(success, returndata, errorMessage); } } /** * @dev Hook before execution is triggered. */ function _beforeExecute( uint256, /* proposalId */ address[] memory targets, uint256[] memory, /* values */ bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { for (uint256 i = 0; i < targets.length; ++i) { if (targets[i] == address(this)) { _governanceCall.pushBack(keccak256(calldatas[i])); } } } } /** * @dev Hook after execution is triggered. */ function _afterExecute( uint256, /* proposalId */ address[] memory, /* targets */ uint256[] memory, /* values */ bytes[] memory, /* calldatas */ bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { if (!_governanceCall.empty()) { _governanceCall.clear(); } } } /** * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as * canceled to allow distinguishing it from executed proposals. * * Emits a {IGovernor-ProposalCanceled} event. */ function _cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal virtual returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); ProposalState status = state(proposalId); require( status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed, "Governor: proposal not active" ); _proposals[proposalId].canceled = true; emit ProposalCanceled(proposalId); return proposalId; } /** * @dev See {IGovernor-getVotes}. */ function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { return _getVotes(account, blockNumber, _defaultParams()); } /** * @dev See {IGovernor-getVotesWithParams}. */ function getVotesWithParams( address account, uint256 blockNumber, bytes memory params ) public view virtual override returns (uint256) { return _getVotes(account, blockNumber, params); } /** * @dev See {IGovernor-castVote}. */ function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReason}. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason); } /** * @dev See {IGovernor-castVoteWithReasonAndParams}. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason, params); } /** * @dev See {IGovernor-castVoteBySig}. */ function castVoteBySig( uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { address voter = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), v, r, s ); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { address voter = ECDSA.recover( _hashTypedDataV4( keccak256( abi.encode( EXTENDED_BALLOT_TYPEHASH, proposalId, support, keccak256(bytes(reason)), keccak256(params) ) ) ), v, r, s ); return _castVote(proposalId, voter, support, reason, params); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). * * Emits a {IGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint8 support, string memory reason ) internal virtual returns (uint256) { return _castVote(proposalId, account, support, reason, _defaultParams()); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. * * Emits a {IGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params ) internal virtual returns (uint256) { ProposalCore storage proposal = _proposals[proposalId]; require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); uint256 weight = _getVotes(account, proposal.voteStart.getDeadline(), params); _countVote(proposalId, account, support, weight, params); if (params.length == 0) { emit VoteCast(account, proposalId, support, weight, reason); } else { emit VoteCastWithParams(account, proposalId, support, weight, reason, params); } return weight; } /** * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor * is some contract other than the governor itself, like when using a timelock, this function can be invoked * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ function relay( address target, uint256 value, bytes calldata data ) external payable virtual onlyGovernance { (bool success, bytes memory returndata) = target.call{value: value}(data); Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); } /** * @dev Address through which the governor executes action. Will be overloaded by module that execute actions * through another contract such as a timelock. */ function _executor() internal view virtual returns (address) { return address(this); } /** * @dev See {IERC721Receiver-onERC721Received}. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155Received}. */ function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155BatchReceived}. */ function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } } // OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorSettings.sol) /** * @dev Extension of {Governor} for settings updatable through governance. * * _Available since v4.4._ */ abstract contract GovernorSettings is Governor { uint256 private _votingDelay; uint256 private _votingPeriod; uint256 private _proposalThreshold; event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay); event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod); event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold); /** * @dev Initialize the governance parameters. */ constructor( uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold ) { _setVotingDelay(initialVotingDelay); _setVotingPeriod(initialVotingPeriod); _setProposalThreshold(initialProposalThreshold); } /** * @dev See {IGovernor-votingDelay}. */ function votingDelay() public view virtual override returns (uint256) { return _votingDelay; } /** * @dev See {IGovernor-votingPeriod}. */ function votingPeriod() public view virtual override returns (uint256) { return _votingPeriod; } /** * @dev See {Governor-proposalThreshold}. */ function proposalThreshold() public view virtual override returns (uint256) { return _proposalThreshold; } /** * @dev Update the voting delay. This operation can only be performed through a governance proposal. * * Emits a {VotingDelaySet} event. */ function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance { _setVotingDelay(newVotingDelay); } /** * @dev Update the voting period. This operation can only be performed through a governance proposal. * * Emits a {VotingPeriodSet} event. */ function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance { _setVotingPeriod(newVotingPeriod); } /** * @dev Update the proposal threshold. This operation can only be performed through a governance proposal. * * Emits a {ProposalThresholdSet} event. */ function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance { _setProposalThreshold(newProposalThreshold); } /** * @dev Internal setter for the voting delay. * * Emits a {VotingDelaySet} event. */ function _setVotingDelay(uint256 newVotingDelay) internal virtual { emit VotingDelaySet(_votingDelay, newVotingDelay); _votingDelay = newVotingDelay; } /** * @dev Internal setter for the voting period. * * Emits a {VotingPeriodSet} event. */ function _setVotingPeriod(uint256 newVotingPeriod) internal virtual { // voting period must be at least one block long require(newVotingPeriod > 0, "GovernorSettings: voting period too low"); emit VotingPeriodSet(_votingPeriod, newVotingPeriod); _votingPeriod = newVotingPeriod; } /** * @dev Internal setter for the proposal threshold. * * Emits a {ProposalThresholdSet} event. */ function _setProposalThreshold(uint256 newProposalThreshold) internal virtual { emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold); _proposalThreshold = newProposalThreshold; } } // OpenZeppelin Contracts (last updated v4.8.0) (governance/extensions/GovernorCountingSimple.sol) /** * @dev Extension of {Governor} for simple, 3 options, vote counting. * * _Available since v4.3._ */ abstract contract GovernorCountingSimple is Governor { /** * @dev Supported vote types. Matches Governor Bravo ordering. */ enum VoteType { Against, For, Abstain } struct ProposalVote { uint256 againstVotes; uint256 forVotes; uint256 abstainVotes; mapping(address => bool) hasVoted; } mapping(uint256 => ProposalVote) private _proposalVotes; /** * @dev See {IGovernor-COUNTING_MODE}. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public pure virtual override returns (string memory) { return "support=bravo&quorum=for,abstain"; } /** * @dev See {IGovernor-hasVoted}. */ function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { return _proposalVotes[proposalId].hasVoted[account]; } /** * @dev Accessor to the internal vote counts. */ function proposalVotes(uint256 proposalId) public view virtual returns ( uint256 againstVotes, uint256 forVotes, uint256 abstainVotes ) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes); } /** * @dev See {Governor-_quorumReached}. */ function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return quorum(proposalSnapshot(proposalId)) <= proposalVote.forVotes + proposalVote.abstainVotes; } /** * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. */ function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return proposalVote.forVotes > proposalVote.againstVotes; } /** * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo). */ function _countVote( uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory // params ) internal virtual override { ProposalVote storage proposalVote = _proposalVotes[proposalId]; require(!proposalVote.hasVoted[account], "GovernorVotingSimple: vote already cast"); proposalVote.hasVoted[account] = true; if (support == uint8(VoteType.Against)) { proposalVote.againstVotes += weight; } else if (support == uint8(VoteType.For)) { proposalVote.forVotes += weight; } else if (support == uint8(VoteType.Abstain)) { proposalVote.abstainVotes += weight; } else { revert("GovernorVotingSimple: invalid value for enum VoteType"); } } } // OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorVotesComp.sol) // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20VotesComp.sol) // OpenZeppelin Contracts (last updated v4.8.1) (token/ERC20/extensions/ERC20Votes.sol) // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol) // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) /** * @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. */ 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]. */ 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); } // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) /** * @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); } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } /** * @dev Implementation 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. * * _Available since v3.4._ */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { using Counters for Counters.Counter; mapping(address => Counters.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private constant _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. * However, to ensure consistency with the upgradeable transpiler, we will continue * to reserve a slot. * @custom:oz-renamed-from _PERMIT_TYPEHASH */ // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ constructor(string memory name) EIP712(name, "1") {} /** * @dev See {IERC20Permit-permit}. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } } // OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). */ function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); /** * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 blockNumber) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; } /** * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's, * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1. * * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module. * * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting * power can be queried through the public accessors {getVotes} and {getPastVotes}. * * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. * * _Available since v4.2._ */ abstract contract ERC20Votes is IVotes, ERC20Permit { struct Checkpoint { uint32 fromBlock; uint224 votes; } bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); mapping(address => address) private _delegates; mapping(address => Checkpoint[]) private _checkpoints; Checkpoint[] private _totalSupplyCheckpoints; /** * @dev Get the `pos`-th checkpoint for `account`. */ function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) { return _checkpoints[account][pos]; } /** * @dev Get number of checkpoints for `account`. */ function numCheckpoints(address account) public view virtual returns (uint32) { return SafeCast.toUint32(_checkpoints[account].length); } /** * @dev Get the address `account` is currently delegating to. */ function delegates(address account) public view virtual override returns (address) { return _delegates[account]; } /** * @dev Gets the current votes balance for `account` */ function getVotes(address account) public view virtual override returns (uint256) { uint256 pos = _checkpoints[account].length; return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes; } /** * @dev Retrieve the number of votes for `account` at the end of `blockNumber`. * * Requirements: * * - `blockNumber` must have been already mined */ function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { require(blockNumber < block.number, "ERC20Votes: block not yet mined"); return _checkpointsLookup(_checkpoints[account], blockNumber); } /** * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. * It is but NOT the sum of all the delegated votes! * * Requirements: * * - `blockNumber` must have been already mined */ function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { require(blockNumber < block.number, "ERC20Votes: block not yet mined"); return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber); } /** * @dev Lookup a value in a list of (sorted) checkpoints. */ function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) { // We run a binary search to look for the earliest checkpoint taken after `blockNumber`. // // Initially we check if the block is recent to narrow the search range. // During the loop, the index of the wanted checkpoint remains in the range [low-1, high). // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant. // - If the middle checkpoint is after `blockNumber`, we look in [low, mid) // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high) // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not // out of bounds (in which case we're looking too far in the past and the result is 0). // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out // the same. uint256 length = ckpts.length; uint256 low = 0; uint256 high = length; if (length > 5) { uint256 mid = length - Math.sqrt(length); if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) { high = mid; } else { low = mid + 1; } } while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) { high = mid; } else { low = mid + 1; } } return high == 0 ? 0 : _unsafeAccess(ckpts, high - 1).votes; } /** * @dev Delegate votes from the sender to `delegatee`. */ function delegate(address delegatee) public virtual override { _delegate(_msgSender(), delegatee); } /** * @dev Delegates votes from signer to `delegatee` */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= expiry, "ERC20Votes: signature expired"); address signer = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s ); require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce"); _delegate(signer, delegatee); } /** * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1). */ function _maxSupply() internal view virtual returns (uint224) { return type(uint224).max; } /** * @dev Snapshots the totalSupply after it has been increased. */ function _mint(address account, uint256 amount) internal virtual override { super._mint(account, amount); require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes"); _writeCheckpoint(_totalSupplyCheckpoints, _add, amount); } /** * @dev Snapshots the totalSupply after it has been decreased. */ function _burn(address account, uint256 amount) internal virtual override { super._burn(account, amount); _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount); } /** * @dev Move voting power when tokens are transferred. * * Emits a {IVotes-DelegateVotesChanged} event. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._afterTokenTransfer(from, to, amount); _moveVotingPower(delegates(from), delegates(to), amount); } /** * @dev Change delegation for `delegator` to `delegatee`. * * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. */ function _delegate(address delegator, address delegatee) internal virtual { address currentDelegate = delegates(delegator); uint256 delegatorBalance = balanceOf(delegator); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveVotingPower(currentDelegate, delegatee, delegatorBalance); } function _moveVotingPower( address src, address dst, uint256 amount ) private { if (src != dst && amount > 0) { if (src != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); emit DelegateVotesChanged(src, oldWeight, newWeight); } if (dst != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount); emit DelegateVotesChanged(dst, oldWeight, newWeight); } } } function _writeCheckpoint( Checkpoint[] storage ckpts, function(uint256, uint256) view returns (uint256) op, uint256 delta ) private returns (uint256 oldWeight, uint256 newWeight) { uint256 pos = ckpts.length; Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1); oldWeight = oldCkpt.votes; newWeight = op(oldWeight, delta); if (pos > 0 && oldCkpt.fromBlock == block.number) { _unsafeAccess(ckpts, pos - 1).votes = SafeCast.toUint224(newWeight); } else { ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)})); } } function _add(uint256 a, uint256 b) private pure returns (uint256) { return a + b; } function _subtract(uint256 a, uint256 b) private pure returns (uint256) { return a - b; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess(Checkpoint[] storage ckpts, uint256 pos) private pure returns (Checkpoint storage result) { assembly { mstore(0, ckpts.slot) result.slot := add(keccak256(0, 0x20), pos) } } } /** * @dev Extension of ERC20 to support Compound's voting and delegation. This version exactly matches Compound's * interface, with the drawback of only supporting supply up to (2^96^ - 1). * * NOTE: You should use this contract if you need exact compatibility with COMP (for example in order to use your token * with Governor Alpha or Bravo) and if you are sure the supply cap of 2^96^ is enough for you. Otherwise, use the * {ERC20Votes} variant of this module. * * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting * power can be queried through the public accessors {getCurrentVotes} and {getPriorVotes}. * * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. * * _Available since v4.2._ */ abstract contract ERC20VotesComp is ERC20Votes { /** * @dev Comp version of the {getVotes} accessor, with `uint96` return type. */ function getCurrentVotes(address account) external view virtual returns (uint96) { return SafeCast.toUint96(getVotes(account)); } /** * @dev Comp version of the {getPastVotes} accessor, with `uint96` return type. */ function getPriorVotes(address account, uint256 blockNumber) external view virtual returns (uint96) { return SafeCast.toUint96(getPastVotes(account, blockNumber)); } /** * @dev Maximum token supply. Reduced to `type(uint96).max` (2^96^ - 1) to fit COMP interface. */ function _maxSupply() internal view virtual override returns (uint224) { return type(uint96).max; } } /** * @dev Extension of {Governor} for voting weight extraction from a Comp token. * * _Available since v4.3._ */ abstract contract GovernorVotesComp is Governor { ERC20VotesComp public immutable token; constructor(ERC20VotesComp token_) { token = token_; } /** * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). */ function _getVotes( address account, uint256 blockNumber, bytes memory /*params*/ ) internal view virtual override returns (uint256) { return token.getPriorVotes(account, blockNumber); } } contract SudoGovernor is Governor, GovernorSettings, GovernorCountingSimple, GovernorVotesComp { constructor(ERC20VotesComp _token) Governor("SudoGovernor") GovernorSettings(14400 /* 2 days */, 21600 /* 3 days */, 300000e18) GovernorVotesComp(_token) {} function quorum(uint256) public pure override returns (uint256) { return 2400000e18; } // The following functions are overrides required by Solidity. function votingDelay() public view override(IGovernor, GovernorSettings) returns (uint256) { return super.votingDelay(); } function votingPeriod() public view override(IGovernor, GovernorSettings) returns (uint256) { return super.votingPeriod(); } function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { return super.proposalThreshold(); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ERC20VotesComp","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Empty","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldProposalThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newProposalThreshold","type":"uint256"}],"name":"ProposalThresholdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"VoteCastWithParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"VotingDelaySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"VotingPeriodSet","type":"event"},{"inputs":[],"name":"BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COUNTING_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"EXTENDED_BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"}],"name":"castVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castVoteWithReason","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"castVoteWithReasonAndParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteWithReasonAndParamsBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"execute","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"getVotesWithParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"hasVoted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"hashProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalVotes","outputs":[{"internalType":"uint256","name":"againstVotes","type":"uint256"},{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"abstainVotes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"string","name":"description","type":"string"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"quorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"relay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newProposalThreshold","type":"uint256"}],"name":"setProposalThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"setVotingDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"setVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"state","outputs":[{"internalType":"enum IGovernor.ProposalState","name":"","type":"uint8"}],"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":"token","outputs":[{"internalType":"contract ERC20VotesComp","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101606040523480156200001257600080fd5b5060405162005861380380620058618339818101604052810190620000389190620003db565b80613840615460693f870857a3e0e38000006040518060400160405280600c81526020017f5375646f476f7665726e6f7200000000000000000000000000000000000000008152508062000091620001c960201b60201c565b60008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508260e081815250508161010081815250504660a08181525050620000fa8184846200020660201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250508061012081815250505050505050806000908162000154919062000687565b505062000167836200024260201b60201c565b62000178826200028960201b60201c565b62000189816200031660201b60201c565b5050508073ffffffffffffffffffffffffffffffffffffffff166101408173ffffffffffffffffffffffffffffffffffffffff16815250505050620008de565b60606040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250905090565b6000838383463060405160200162000223959493929190620007ab565b6040516020818303038152906040528051906020012090509392505050565b7fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93600454826040516200027792919062000808565b60405180910390a18060048190555050565b60008111620002cf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002c690620008bc565b60405180910390fd5b7f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828600554826040516200030492919062000808565b60405180910390a18060058190555050565b7fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461600654826040516200034b92919062000808565b60405180910390a18060068190555050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200038f8262000362565b9050919050565b6000620003a38262000382565b9050919050565b620003b58162000396565b8114620003c157600080fd5b50565b600081519050620003d581620003aa565b92915050565b600060208284031215620003f457620003f36200035d565b5b60006200040484828501620003c4565b91505092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200048f57607f821691505b602082108103620004a557620004a462000447565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200050f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620004d0565b6200051b8683620004d0565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000568620005626200055c8462000533565b6200053d565b62000533565b9050919050565b6000819050919050565b620005848362000547565b6200059c62000593826200056f565b848454620004dd565b825550505050565b600090565b620005b3620005a4565b620005c081848462000579565b505050565b5b81811015620005e857620005dc600082620005a9565b600181019050620005c6565b5050565b601f82111562000637576200060181620004ab565b6200060c84620004c0565b810160208510156200061c578190505b620006346200062b85620004c0565b830182620005c5565b50505b505050565b600082821c905092915050565b60006200065c600019846008026200063c565b1980831691505092915050565b600062000677838362000649565b9150826002028217905092915050565b62000692826200040d565b67ffffffffffffffff811115620006ae57620006ad62000418565b5b620006ba825462000476565b620006c7828285620005ec565b600060209050601f831160018114620006ff5760008415620006ea578287015190505b620006f6858262000669565b86555062000766565b601f1984166200070f86620004ab565b60005b82811015620007395784890151825560018201915060208501945060208101905062000712565b8683101562000759578489015162000755601f89168262000649565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b62000783816200076e565b82525050565b620007948162000533565b82525050565b620007a58162000382565b82525050565b600060a082019050620007c2600083018862000778565b620007d1602083018762000778565b620007e0604083018662000778565b620007ef606083018562000789565b620007fe60808301846200079a565b9695505050505050565b60006040820190506200081f600083018562000789565b6200082e602083018462000789565b9392505050565b600082825260208201905092915050565b7f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f642060008201527f746f6f206c6f7700000000000000000000000000000000000000000000000000602082015250565b6000620008a460278362000835565b9150620008b18262000846565b604082019050919050565b60006020820190508181036000830152620008d78162000895565b9050919050565b60805160a05160c05160e051610100516101205161014051614f216200094060003960008181611a8801526121f00152600061245f015260006124a101526000612480015260006123b50152600061240b015260006124340152614f216000f3fe6080604052600436106101f25760003560e01c806370b0f6601161010d578063c59057e4116100a0578063eb9019d41161006f578063eb9019d414610805578063ece40cc114610842578063f23a6e611461086b578063f8ce560a146108a8578063fc0c546a146108e557610238565b8063c59057e414610749578063dd4e2ba514610786578063deaaa7cc146107b1578063ea0217cf146107dc57610238565b8063b58131b0116100dc578063b58131b014610688578063bc197c81146106b3578063c01f9e37146106f0578063c28bc2fa1461072d57610238565b806370b0f660146105a85780637b3c71d3146105d15780637d5e81e21461060e5780639a802a6d1461064b57610238565b80633932abb111610185578063544ffc9c11610154578063544ffc9c146104c457806354fd4d5014610503578063567813881461052e5780635f398a141461056b57610238565b80633932abb1146103e25780633bccf4fd1461040d5780633e4f49e61461044a578063438596321461048757610238565b8063150b7a02116101c1578063150b7a021461030d5780632656227d1461034a5780632d63f6931461037a5780632fe3e261146103b757610238565b806301ffc9a71461023d57806302a251a31461027a57806303420181146102a557806306fdde03146102e257610238565b36610238573073ffffffffffffffffffffffffffffffffffffffff16610216610910565b73ffffffffffffffffffffffffffffffffffffffff161461023657600080fd5b005b600080fd5b34801561024957600080fd5b50610264600480360381019061025f9190612b72565b610918565b6040516102719190612bba565b60405180910390f35b34801561028657600080fd5b5061028f610a7d565b60405161029c9190612bee565b60405180910390f35b3480156102b157600080fd5b506102cc60048036038101906102c79190612e4a565b610a8c565b6040516102d99190612bee565b60405180910390f35b3480156102ee57600080fd5b506102f7610b71565b6040516103049190612fa7565b60405180910390f35b34801561031957600080fd5b50610334600480360381019061032f9190613027565b610c03565b60405161034191906130b9565b60405180910390f35b610364600480360381019061035f919061333b565b610c17565b6040516103719190612bee565b60405180910390f35b34801561038657600080fd5b506103a1600480360381019061039c91906133f6565b610d64565b6040516103ae9190612bee565b60405180910390f35b3480156103c357600080fd5b506103cc610dd2565b6040516103d99190613432565b60405180910390f35b3480156103ee57600080fd5b506103f7610df6565b6040516104049190612bee565b60405180910390f35b34801561041957600080fd5b50610434600480360381019061042f919061344d565b610e05565b6040516104419190612bee565b60405180910390f35b34801561045657600080fd5b50610471600480360381019061046c91906133f6565b610e8f565b60405161047e919061353f565b60405180910390f35b34801561049357600080fd5b506104ae60048036038101906104a9919061355a565b610fa3565b6040516104bb9190612bba565b60405180910390f35b3480156104d057600080fd5b506104eb60048036038101906104e691906133f6565b61100e565b6040516104fa9392919061359a565b60405180910390f35b34801561050f57600080fd5b50610518611046565b6040516105259190612fa7565b60405180910390f35b34801561053a57600080fd5b50610555600480360381019061055091906135d1565b611083565b6040516105629190612bee565b60405180910390f35b34801561057757600080fd5b50610592600480360381019061058d9190613611565b6110b4565b60405161059f9190612bee565b60405180910390f35b3480156105b457600080fd5b506105cf60048036038101906105ca91906133f6565b61111e565b005b3480156105dd57600080fd5b506105f860048036038101906105f391906136b5565b611215565b6040516106059190612bee565b60405180910390f35b34801561061a57600080fd5b50610635600480360381019061063091906137ca565b61127d565b6040516106429190612bee565b60405180910390f35b34801561065757600080fd5b50610672600480360381019061066d91906138a1565b611584565b60405161067f9190612bee565b60405180910390f35b34801561069457600080fd5b5061069d61159a565b6040516106aa9190612bee565b60405180910390f35b3480156106bf57600080fd5b506106da60048036038101906106d59190613910565b6115a9565b6040516106e791906130b9565b60405180910390f35b3480156106fc57600080fd5b50610717600480360381019061071291906133f6565b6115be565b6040516107249190612bee565b60405180910390f35b61074760048036038101906107429190613a35565b61162c565b005b34801561075557600080fd5b50610770600480360381019061076b919061333b565b6117b5565b60405161077d9190612bee565b60405180910390f35b34801561079257600080fd5b5061079b6117f1565b6040516107a89190612fa7565b60405180910390f35b3480156107bd57600080fd5b506107c661182e565b6040516107d39190613432565b60405180910390f35b3480156107e857600080fd5b5061080360048036038101906107fe91906133f6565b611852565b005b34801561081157600080fd5b5061082c60048036038101906108279190613aa9565b611949565b6040516108399190612bee565b60405180910390f35b34801561084e57600080fd5b50610869600480360381019061086491906133f6565b611965565b005b34801561087757600080fd5b50610892600480360381019061088d9190613ae9565b611a5c565b60405161089f91906130b9565b60405180910390f35b3480156108b457600080fd5b506108cf60048036038101906108ca91906133f6565b611a71565b6040516108dc9190612bee565b60405180910390f35b3480156108f157600080fd5b506108fa611a86565b6040516109079190613bdf565b60405180910390f35b600030905090565b6000639a802a6d60e01b630342018160e01b635f398a1460e01b7f79dd796f000000000000000000000000000000000000000000000000000000001818187bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109fe57507f79dd796f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a6657507f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a765750610a7582611aaa565b5b9050919050565b6000610a87611b14565b905090565b600080610b0f610b077fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af888c8c8c8c604051610ac8929190613c2a565b60405180910390208b80519060200120604051602001610aec959493929190613c52565b60405160208183030381529060405280519060200120611b1e565b868686611b38565b9050610b628a828b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508a611b63565b91505098975050505050505050565b606060008054610b8090613cd4565b80601f0160208091040260200160405190810160405280929190818152602001828054610bac90613cd4565b8015610bf95780601f10610bce57610100808354040283529160200191610bf9565b820191906000526020600020905b815481529060010190602001808311610bdc57829003601f168201915b5050505050905090565b600063150b7a0260e01b9050949350505050565b600080610c26868686866117b5565b90506000610c3382610e8f565b905060046007811115610c4957610c486134c8565b5b816007811115610c5c57610c5b6134c8565b5b1480610c8c575060056007811115610c7757610c766134c8565b5b816007811115610c8a57610c896134c8565b5b145b610ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc290613d77565b60405180910390fd5b600180600084815260200190815260200160002060020160006101000a81548160ff0219169083151502179055507f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f82604051610d289190612bee565b60405180910390a1610d3d8288888888611d1f565b610d4a8288888888611e02565b610d578288888888611f11565b8192505050949350505050565b6000610dc1600160008481526020019081526020016000206000016040518060200160405290816000820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050611f6c565b67ffffffffffffffff169050919050565b7fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af8881565b6000610e00611f7a565b905090565b600080610e66610e5e7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f8989604051602001610e4393929190613d97565b60405160208183030381529060405280519060200120611b1e565b868686611b38565b9050610e8387828860405180602001604052806000815250611f84565b91505095945050505050565b6000806001600084815260200190815260200160002090508060020160009054906101000a900460ff1615610ec8576007915050610f9e565b8060020160019054906101000a900460ff1615610ee9576002915050610f9e565b6000610ef484610d64565b905060008103610f39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3090613e1a565b60405180910390fd5b438110610f4b57600092505050610f9e565b6000610f56856115be565b9050438110610f6b5760019350505050610f9e565b610f7485611fa4565b8015610f855750610f8485611feb565b5b15610f965760049350505050610f9e565b600393505050505b919050565b60006007600084815260200190815260200160002060030160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600080600080600760008681526020019081526020016000209050806000015481600101548260020154935093509350509193909250565b60606040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250905090565b60008061108e612016565b90506110ab84828560405180602001604052806000815250611f84565b91505092915050565b6000806110bf612016565b905061111287828888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087611b63565b91505095945050505050565b611126610910565b73ffffffffffffffffffffffffffffffffffffffff16611144612016565b73ffffffffffffffffffffffffffffffffffffffff161461119a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119190613e86565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff166111b9610910565b73ffffffffffffffffffffffffffffffffffffffff16146112095760006111de61201e565b6040516111ec929190613c2a565b604051809103902090505b80611202600261202b565b036111f757505b61121281612107565b50565b600080611220612016565b905061127286828787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611f84565b915050949350505050565b600061128761159a565b6112a4611292612016565b60014361129f9190613ed5565b611949565b10156112e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112dc90613f7b565b60405180910390fd5b60006112fa86868686805190602001206117b5565b90508451865114611340576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113379061400d565b60405180910390fd5b8351865114611384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137b9061400d565b60405180910390fd5b60008651116113c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bf90614079565b60405180910390fd5b6000600160008381526020019081526020016000209050611428816000016040518060200160405290816000820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff168152505061214c565b611467576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145e9061410b565b60405180910390fd5b6000611479611474610df6565b612166565b61148243612166565b61148c919061413f565b905060006114a061149b610a7d565b612166565b826114ab919061413f565b90506114c382846000016121bd90919063ffffffff16565b6114d981846001016121bd90919063ffffffff16565b7f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e084611503612016565b8b8b8d5167ffffffffffffffff8111156115205761151f612ce9565b5b60405190808252806020026020018201604052801561155357816020015b606081526020019060019003908161153e5790505b508c88888e60405161156d9998979695949392919061455a565b60405180910390a183945050505050949350505050565b60006115918484846121ec565b90509392505050565b60006115a46122a1565b905090565b600063bc197c8160e01b905095945050505050565b600061161b600160008481526020019081526020016000206001016040518060200160405290816000820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050611f6c565b67ffffffffffffffff169050919050565b611634610910565b73ffffffffffffffffffffffffffffffffffffffff16611652612016565b73ffffffffffffffffffffffffffffffffffffffff16146116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169f90613e86565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff166116c7610910565b73ffffffffffffffffffffffffffffffffffffffff16146117175760006116ec61201e565b6040516116fa929190613c2a565b604051809103902090505b80611710600261202b565b0361170557505b6000808573ffffffffffffffffffffffffffffffffffffffff16858585604051611742929190613c2a565b60006040518083038185875af1925050503d806000811461177f576040519150601f19603f3d011682016040523d82523d6000602084013e611784565b606091505b50915091506117ac8282604051806060016040528060288152602001614e9d602891396122ab565b50505050505050565b6000848484846040516020016117ce949392919061460a565b6040516020818303038152906040528051906020012060001c9050949350505050565b60606040518060400160405280602081526020017f737570706f72743d627261766f2671756f72756d3d666f722c6162737461696e815250905090565b7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b61185a610910565b73ffffffffffffffffffffffffffffffffffffffff16611878612016565b73ffffffffffffffffffffffffffffffffffffffff16146118ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c590613e86565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff166118ed610910565b73ffffffffffffffffffffffffffffffffffffffff161461193d57600061191261201e565b604051611920929190613c2a565b604051809103902090505b80611936600261202b565b0361192b57505b611946816122cd565b50565b600061195d8383611958612355565b6121ec565b905092915050565b61196d610910565b73ffffffffffffffffffffffffffffffffffffffff1661198b612016565b73ffffffffffffffffffffffffffffffffffffffff16146119e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d890613e86565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16611a00610910565b73ffffffffffffffffffffffffffffffffffffffff1614611a50576000611a2561201e565b604051611a33929190613c2a565b604051809103902090505b80611a49600261202b565b03611a3e57505b611a598161236c565b50565b600063f23a6e6160e01b905095945050505050565b60006a01fc3842bd1f071c0000009050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000600554905090565b6000611b31611b2b6123b1565b836124cb565b9050919050565b6000806000611b49878787876124fe565b91509150611b56816125e0565b8192505050949350505050565b60008060016000888152602001908152602001600020905060016007811115611b8f57611b8e6134c8565b5b611b9888610e8f565b6007811115611baa57611ba96134c8565b5b14611bea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be1906146d6565b60405180910390fd5b6000611c4987611c39846000016040518060200160405290816000820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050611f6c565b67ffffffffffffffff16866121ec565b9050611c588888888488612746565b6000845103611cba578673ffffffffffffffffffffffffffffffffffffffff167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda489888489604051611cad94939291906146f6565b60405180910390a2611d11565b8673ffffffffffffffffffffffffffffffffffffffff167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb87128988848989604051611d0895949392919061478c565b60405180910390a25b809250505095945050505050565b3073ffffffffffffffffffffffffffffffffffffffff16611d3e610910565b73ffffffffffffffffffffffffffffffffffffffff1614611dfb5760005b8451811015611df9573073ffffffffffffffffffffffffffffffffffffffff16858281518110611d8f57611d8e6147ed565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611de857611de7838281518110611dc857611dc76147ed565b5b602002602001015180519060200120600261294a90919063ffffffff16565b5b80611df29061481c565b9050611d5c565b505b5050505050565b6000604051806060016040528060278152602001614ec560279139905060005b8551811015611f0857600080878381518110611e4157611e406147ed565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16878481518110611e7257611e716147ed565b5b6020026020010151878581518110611e8d57611e8c6147ed565b5b6020026020010151604051611ea29190614895565b60006040518083038185875af1925050503d8060008114611edf576040519150601f19603f3d011682016040523d82523d6000602084013e611ee4565b606091505b5091509150611ef48282866122ab565b50505080611f019061481c565b9050611e22565b50505050505050565b3073ffffffffffffffffffffffffffffffffffffffff16611f30610910565b73ffffffffffffffffffffffffffffffffffffffff1614611f6557611f5560026129c6565b611f6457611f6360026129fb565b5b5b5050505050565b600081600001519050919050565b6000600454905090565b6000611f9a85858585611f95612355565b611b63565b9050949350505050565b60008060076000848152602001908152602001600020905080600201548160010154611fd091906148ac565b611fe1611fdc85610d64565b611a71565b1115915050919050565b6000806007600084815260200190815260200160002090508060000154816001015411915050919050565b600033905090565b3660008036915091509091565b6000612036826129c6565b1561206d576040517f3db2a12a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008260000160009054906101000a9004600f0b905082600101600082600f0b600f0b815260200190815260200160002054915082600101600082600f0b600f0b815260200190815260200160002060009055600181018360000160006101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff16021790555050919050565b7fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a936004548260405161213a9291906148e0565b60405180910390a18060048190555050565b600080826000015167ffffffffffffffff16149050919050565b600067ffffffffffffffff80168211156121b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ac9061497b565b60405180910390fd5b819050919050565b808260000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663782d6fe185856040518363ffffffff1660e01b815260040161224992919061499b565b602060405180830381865afa158015612266573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228a9190614a08565b6bffffffffffffffffffffffff1690509392505050565b6000600654905090565b606083156122bb578290506122c6565b6122c58383612a7c565b5b9392505050565b60008111612310576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230790614aa7565b60405180910390fd5b7f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828600554826040516123439291906148e0565b60405180910390a18060058190555050565b606060405180602001604052806000815250905090565b7fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc054616006548260405161239f9291906148e0565b60405180910390a18060068190555050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561242d57507f000000000000000000000000000000000000000000000000000000000000000046145b1561245a577f000000000000000000000000000000000000000000000000000000000000000090506124c8565b6124c57f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612acc565b90505b90565b600082826040516020016124e0929190614b3f565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c11156125395760006003915091506125d7565b60006001878787876040516000815260200160405260405161255e9493929190614b76565b6020604051602081039080840390855afa158015612580573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036125ce576000600192509250506125d7565b80600092509250505b94509492505050565b600060048111156125f4576125f36134c8565b5b816004811115612607576126066134c8565b5b03156127435760016004811115612621576126206134c8565b5b816004811115612634576126336134c8565b5b03612674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161266b90614c07565b60405180910390fd5b60026004811115612688576126876134c8565b5b81600481111561269b5761269a6134c8565b5b036126db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d290614c73565b60405180910390fd5b600360048111156126ef576126ee6134c8565b5b816004811115612702576127016134c8565b5b03612742576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161273990614d05565b60405180910390fd5b5b50565b60006007600087815260200190815260200160002090508060030160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156127ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127e390614d97565b60405180910390fd5b60018160030160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506000600281111561285a576128596134c8565b5b60ff168460ff1603612886578281600001600082825461287a91906148ac565b92505081905550612942565b6001600281111561289a576128996134c8565b5b60ff168460ff16036128c657828160010160008282546128ba91906148ac565b92505081905550612941565b6002808111156128d9576128d86134c8565b5b60ff168460ff160361290557828160020160008282546128f991906148ac565b92505081905550612940565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161293790614e29565b60405180910390fd5b5b5b505050505050565b60008260000160109054906101000a9004600f0b90508183600101600083600f0b600f0b815260200190815260200160002081905550600181018360000160106101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff160217905550505050565b60008160000160009054906101000a9004600f0b600f0b8260000160109054906101000a9004600f0b600f0b13159050919050565b60008160000160006101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff16021790555060008160000160106101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff16021790555050565b600082511115612a8f5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac39190612fa7565b60405180910390fd5b60008383834630604051602001612ae7959493929190614e49565b6040516020818303038152906040528051906020012090509392505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b4f81612b1a565b8114612b5a57600080fd5b50565b600081359050612b6c81612b46565b92915050565b600060208284031215612b8857612b87612b10565b5b6000612b9684828501612b5d565b91505092915050565b60008115159050919050565b612bb481612b9f565b82525050565b6000602082019050612bcf6000830184612bab565b92915050565b6000819050919050565b612be881612bd5565b82525050565b6000602082019050612c036000830184612bdf565b92915050565b612c1281612bd5565b8114612c1d57600080fd5b50565b600081359050612c2f81612c09565b92915050565b600060ff82169050919050565b612c4b81612c35565b8114612c5657600080fd5b50565b600081359050612c6881612c42565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612c9357612c92612c6e565b5b8235905067ffffffffffffffff811115612cb057612caf612c73565b5b602083019150836001820283011115612ccc57612ccb612c78565b5b9250929050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612d2182612cd8565b810181811067ffffffffffffffff82111715612d4057612d3f612ce9565b5b80604052505050565b6000612d53612b06565b9050612d5f8282612d18565b919050565b600067ffffffffffffffff821115612d7f57612d7e612ce9565b5b612d8882612cd8565b9050602081019050919050565b82818337600083830152505050565b6000612db7612db284612d64565b612d49565b905082815260208101848484011115612dd357612dd2612cd3565b5b612dde848285612d95565b509392505050565b600082601f830112612dfb57612dfa612c6e565b5b8135612e0b848260208601612da4565b91505092915050565b6000819050919050565b612e2781612e14565b8114612e3257600080fd5b50565b600081359050612e4481612e1e565b92915050565b60008060008060008060008060e0898b031215612e6a57612e69612b10565b5b6000612e788b828c01612c20565b9850506020612e898b828c01612c59565b975050604089013567ffffffffffffffff811115612eaa57612ea9612b15565b5b612eb68b828c01612c7d565b9650965050606089013567ffffffffffffffff811115612ed957612ed8612b15565b5b612ee58b828c01612de6565b9450506080612ef68b828c01612c59565b93505060a0612f078b828c01612e35565b92505060c0612f188b828c01612e35565b9150509295985092959890939650565b600081519050919050565b600082825260208201905092915050565b60005b83811015612f62578082015181840152602081019050612f47565b60008484015250505050565b6000612f7982612f28565b612f838185612f33565b9350612f93818560208601612f44565b612f9c81612cd8565b840191505092915050565b60006020820190508181036000830152612fc18184612f6e565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ff482612fc9565b9050919050565b61300481612fe9565b811461300f57600080fd5b50565b60008135905061302181612ffb565b92915050565b6000806000806080858703121561304157613040612b10565b5b600061304f87828801613012565b945050602061306087828801613012565b935050604061307187828801612c20565b925050606085013567ffffffffffffffff81111561309257613091612b15565b5b61309e87828801612de6565b91505092959194509250565b6130b381612b1a565b82525050565b60006020820190506130ce60008301846130aa565b92915050565b600067ffffffffffffffff8211156130ef576130ee612ce9565b5b602082029050602081019050919050565b600061311361310e846130d4565b612d49565b9050808382526020820190506020840283018581111561313657613135612c78565b5b835b8181101561315f578061314b8882613012565b845260208401935050602081019050613138565b5050509392505050565b600082601f83011261317e5761317d612c6e565b5b813561318e848260208601613100565b91505092915050565b600067ffffffffffffffff8211156131b2576131b1612ce9565b5b602082029050602081019050919050565b60006131d66131d184613197565b612d49565b905080838252602082019050602084028301858111156131f9576131f8612c78565b5b835b81811015613222578061320e8882612c20565b8452602084019350506020810190506131fb565b5050509392505050565b600082601f83011261324157613240612c6e565b5b81356132518482602086016131c3565b91505092915050565b600067ffffffffffffffff82111561327557613274612ce9565b5b602082029050602081019050919050565b60006132996132948461325a565b612d49565b905080838252602082019050602084028301858111156132bc576132bb612c78565b5b835b8181101561330357803567ffffffffffffffff8111156132e1576132e0612c6e565b5b8086016132ee8982612de6565b855260208501945050506020810190506132be565b5050509392505050565b600082601f83011261332257613321612c6e565b5b8135613332848260208601613286565b91505092915050565b6000806000806080858703121561335557613354612b10565b5b600085013567ffffffffffffffff81111561337357613372612b15565b5b61337f87828801613169565b945050602085013567ffffffffffffffff8111156133a05761339f612b15565b5b6133ac8782880161322c565b935050604085013567ffffffffffffffff8111156133cd576133cc612b15565b5b6133d98782880161330d565b92505060606133ea87828801612e35565b91505092959194509250565b60006020828403121561340c5761340b612b10565b5b600061341a84828501612c20565b91505092915050565b61342c81612e14565b82525050565b60006020820190506134476000830184613423565b92915050565b600080600080600060a0868803121561346957613468612b10565b5b600061347788828901612c20565b955050602061348888828901612c59565b945050604061349988828901612c59565b93505060606134aa88828901612e35565b92505060806134bb88828901612e35565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60088110613508576135076134c8565b5b50565b6000819050613519826134f7565b919050565b60006135298261350b565b9050919050565b6135398161351e565b82525050565b60006020820190506135546000830184613530565b92915050565b6000806040838503121561357157613570612b10565b5b600061357f85828601612c20565b925050602061359085828601613012565b9150509250929050565b60006060820190506135af6000830186612bdf565b6135bc6020830185612bdf565b6135c96040830184612bdf565b949350505050565b600080604083850312156135e8576135e7612b10565b5b60006135f685828601612c20565b925050602061360785828601612c59565b9150509250929050565b60008060008060006080868803121561362d5761362c612b10565b5b600061363b88828901612c20565b955050602061364c88828901612c59565b945050604086013567ffffffffffffffff81111561366d5761366c612b15565b5b61367988828901612c7d565b9350935050606086013567ffffffffffffffff81111561369c5761369b612b15565b5b6136a888828901612de6565b9150509295509295909350565b600080600080606085870312156136cf576136ce612b10565b5b60006136dd87828801612c20565b94505060206136ee87828801612c59565b935050604085013567ffffffffffffffff81111561370f5761370e612b15565b5b61371b87828801612c7d565b925092505092959194509250565b600067ffffffffffffffff82111561374457613743612ce9565b5b61374d82612cd8565b9050602081019050919050565b600061376d61376884613729565b612d49565b90508281526020810184848401111561378957613788612cd3565b5b613794848285612d95565b509392505050565b600082601f8301126137b1576137b0612c6e565b5b81356137c184826020860161375a565b91505092915050565b600080600080608085870312156137e4576137e3612b10565b5b600085013567ffffffffffffffff81111561380257613801612b15565b5b61380e87828801613169565b945050602085013567ffffffffffffffff81111561382f5761382e612b15565b5b61383b8782880161322c565b935050604085013567ffffffffffffffff81111561385c5761385b612b15565b5b6138688782880161330d565b925050606085013567ffffffffffffffff81111561388957613888612b15565b5b6138958782880161379c565b91505092959194509250565b6000806000606084860312156138ba576138b9612b10565b5b60006138c886828701613012565b93505060206138d986828701612c20565b925050604084013567ffffffffffffffff8111156138fa576138f9612b15565b5b61390686828701612de6565b9150509250925092565b600080600080600060a0868803121561392c5761392b612b10565b5b600061393a88828901613012565b955050602061394b88828901613012565b945050604086013567ffffffffffffffff81111561396c5761396b612b15565b5b6139788882890161322c565b935050606086013567ffffffffffffffff81111561399957613998612b15565b5b6139a58882890161322c565b925050608086013567ffffffffffffffff8111156139c6576139c5612b15565b5b6139d288828901612de6565b9150509295509295909350565b60008083601f8401126139f5576139f4612c6e565b5b8235905067ffffffffffffffff811115613a1257613a11612c73565b5b602083019150836001820283011115613a2e57613a2d612c78565b5b9250929050565b60008060008060608587031215613a4f57613a4e612b10565b5b6000613a5d87828801613012565b9450506020613a6e87828801612c20565b935050604085013567ffffffffffffffff811115613a8f57613a8e612b15565b5b613a9b878288016139df565b925092505092959194509250565b60008060408385031215613ac057613abf612b10565b5b6000613ace85828601613012565b9250506020613adf85828601612c20565b9150509250929050565b600080600080600060a08688031215613b0557613b04612b10565b5b6000613b1388828901613012565b9550506020613b2488828901613012565b9450506040613b3588828901612c20565b9350506060613b4688828901612c20565b925050608086013567ffffffffffffffff811115613b6757613b66612b15565b5b613b7388828901612de6565b9150509295509295909350565b6000819050919050565b6000613ba5613ba0613b9b84612fc9565b613b80565b612fc9565b9050919050565b6000613bb782613b8a565b9050919050565b6000613bc982613bac565b9050919050565b613bd981613bbe565b82525050565b6000602082019050613bf46000830184613bd0565b92915050565b600081905092915050565b6000613c118385613bfa565b9350613c1e838584612d95565b82840190509392505050565b6000613c37828486613c05565b91508190509392505050565b613c4c81612c35565b82525050565b600060a082019050613c676000830188613423565b613c746020830187612bdf565b613c816040830186613c43565b613c8e6060830185613423565b613c9b6080830184613423565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613cec57607f821691505b602082108103613cff57613cfe613ca5565b5b50919050565b7f476f7665726e6f723a2070726f706f73616c206e6f742073756363657373667560008201527f6c00000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d61602183612f33565b9150613d6c82613d05565b604082019050919050565b60006020820190508181036000830152613d9081613d54565b9050919050565b6000606082019050613dac6000830186613423565b613db96020830185612bdf565b613dc66040830184613c43565b949350505050565b7f476f7665726e6f723a20756e6b6e6f776e2070726f706f73616c206964000000600082015250565b6000613e04601d83612f33565b9150613e0f82613dce565b602082019050919050565b60006020820190508181036000830152613e3381613df7565b9050919050565b7f476f7665726e6f723a206f6e6c79476f7665726e616e63650000000000000000600082015250565b6000613e70601883612f33565b9150613e7b82613e3a565b602082019050919050565b60006020820190508181036000830152613e9f81613e63565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613ee082612bd5565b9150613eeb83612bd5565b9250828203905081811115613f0357613f02613ea6565b5b92915050565b7f476f7665726e6f723a2070726f706f73657220766f7465732062656c6f77207060008201527f726f706f73616c207468726573686f6c64000000000000000000000000000000602082015250565b6000613f65603183612f33565b9150613f7082613f09565b604082019050919050565b60006020820190508181036000830152613f9481613f58565b9050919050565b7f476f7665726e6f723a20696e76616c69642070726f706f73616c206c656e677460008201527f6800000000000000000000000000000000000000000000000000000000000000602082015250565b6000613ff7602183612f33565b915061400282613f9b565b604082019050919050565b6000602082019050818103600083015261402681613fea565b9050919050565b7f476f7665726e6f723a20656d7074792070726f706f73616c0000000000000000600082015250565b6000614063601883612f33565b915061406e8261402d565b602082019050919050565b6000602082019050818103600083015261409281614056565b9050919050565b7f476f7665726e6f723a2070726f706f73616c20616c726561647920657869737460008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006140f5602183612f33565b915061410082614099565b604082019050919050565b60006020820190508181036000830152614124816140e8565b9050919050565b600067ffffffffffffffff82169050919050565b600061414a8261412b565b91506141558361412b565b9250828201905067ffffffffffffffff81111561417557614174613ea6565b5b92915050565b61418481612fe9565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6141bf81612fe9565b82525050565b60006141d183836141b6565b60208301905092915050565b6000602082019050919050565b60006141f58261418a565b6141ff8185614195565b935061420a836141a6565b8060005b8381101561423b57815161422288826141c5565b975061422d836141dd565b92505060018101905061420e565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61427d81612bd5565b82525050565b600061428f8383614274565b60208301905092915050565b6000602082019050919050565b60006142b382614248565b6142bd8185614253565b93506142c883614264565b8060005b838110156142f95781516142e08882614283565b97506142eb8361429b565b9250506001810190506142cc565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061434e82612f28565b6143588185614332565b9350614368818560208601612f44565b61437181612cd8565b840191505092915050565b60006143888383614343565b905092915050565b6000602082019050919050565b60006143a882614306565b6143b28185614311565b9350836020820285016143c485614322565b8060005b8581101561440057848403895281516143e1858261437c565b94506143ec83614390565b925060208a019950506001810190506143c8565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60006144658261443e565b61446f8185614449565b935061447f818560208601612f44565b61448881612cd8565b840191505092915050565b600061449f838361445a565b905092915050565b6000602082019050919050565b60006144bf82614412565b6144c9818561441d565b9350836020820285016144db8561442e565b8060005b8581101561451757848403895281516144f88582614493565b9450614503836144a7565b925060208a019950506001810190506144df565b50829750879550505050505092915050565b600061454461453f61453a8461412b565b613b80565b612bd5565b9050919050565b61455481614529565b82525050565b600061012082019050614570600083018c612bdf565b61457d602083018b61417b565b818103604083015261458f818a6141ea565b905081810360608301526145a381896142a8565b905081810360808301526145b7818861439d565b905081810360a08301526145cb81876144b4565b90506145da60c083018661454b565b6145e760e083018561454b565b8181036101008301526145fa8184612f6e565b90509a9950505050505050505050565b6000608082019050818103600083015261462481876141ea565b9050818103602083015261463881866142a8565b9050818103604083015261464c81856144b4565b905061465b6060830184613423565b95945050505050565b7f476f7665726e6f723a20766f7465206e6f742063757272656e746c792061637460008201527f6976650000000000000000000000000000000000000000000000000000000000602082015250565b60006146c0602383612f33565b91506146cb82614664565b604082019050919050565b600060208201905081810360008301526146ef816146b3565b9050919050565b600060808201905061470b6000830187612bdf565b6147186020830186613c43565b6147256040830185612bdf565b81810360608301526147378184612f6e565b905095945050505050565b600082825260208201905092915050565b600061475e8261443e565b6147688185614742565b9350614778818560208601612f44565b61478181612cd8565b840191505092915050565b600060a0820190506147a16000830188612bdf565b6147ae6020830187613c43565b6147bb6040830186612bdf565b81810360608301526147cd8185612f6e565b905081810360808301526147e18184614753565b90509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061482782612bd5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361485957614858613ea6565b5b600182019050919050565b600061486f8261443e565b6148798185613bfa565b9350614889818560208601612f44565b80840191505092915050565b60006148a18284614864565b915081905092915050565b60006148b782612bd5565b91506148c283612bd5565b92508282019050808211156148da576148d9613ea6565b5b92915050565b60006040820190506148f56000830185612bdf565b6149026020830184612bdf565b9392505050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203660008201527f3420626974730000000000000000000000000000000000000000000000000000602082015250565b6000614965602683612f33565b915061497082614909565b604082019050919050565b6000602082019050818103600083015261499481614958565b9050919050565b60006040820190506149b0600083018561417b565b6149bd6020830184612bdf565b9392505050565b60006bffffffffffffffffffffffff82169050919050565b6149e5816149c4565b81146149f057600080fd5b50565b600081519050614a02816149dc565b92915050565b600060208284031215614a1e57614a1d612b10565b5b6000614a2c848285016149f3565b91505092915050565b7f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f642060008201527f746f6f206c6f7700000000000000000000000000000000000000000000000000602082015250565b6000614a91602783612f33565b9150614a9c82614a35565b604082019050919050565b60006020820190508181036000830152614ac081614a84565b9050919050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000614b08600283614ac7565b9150614b1382614ad2565b600282019050919050565b6000819050919050565b614b39614b3482612e14565b614b1e565b82525050565b6000614b4a82614afb565b9150614b568285614b28565b602082019150614b668284614b28565b6020820191508190509392505050565b6000608082019050614b8b6000830187613423565b614b986020830186613c43565b614ba56040830185613423565b614bb26060830184613423565b95945050505050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000614bf1601883612f33565b9150614bfc82614bbb565b602082019050919050565b60006020820190508181036000830152614c2081614be4565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614c5d601f83612f33565b9150614c6882614c27565b602082019050919050565b60006020820190508181036000830152614c8c81614c50565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614cef602283612f33565b9150614cfa82614c93565b604082019050919050565b60006020820190508181036000830152614d1e81614ce2565b9050919050565b7f476f7665726e6f72566f74696e6753696d706c653a20766f746520616c72656160008201527f6479206361737400000000000000000000000000000000000000000000000000602082015250565b6000614d81602783612f33565b9150614d8c82614d25565b604082019050919050565b60006020820190508181036000830152614db081614d74565b9050919050565b7f476f7665726e6f72566f74696e6753696d706c653a20696e76616c696420766160008201527f6c756520666f7220656e756d20566f7465547970650000000000000000000000602082015250565b6000614e13603583612f33565b9150614e1e82614db7565b604082019050919050565b60006020820190508181036000830152614e4281614e06565b9050919050565b600060a082019050614e5e6000830188613423565b614e6b6020830187613423565b614e786040830186613423565b614e856060830185612bdf565b614e92608083018461417b565b969550505050505056fe476f7665726e6f723a2072656c617920726576657274656420776974686f7574206d657373616765476f7665726e6f723a2063616c6c20726576657274656420776974686f7574206d657373616765a264697066735822122007d0065dfa1b0b6d01e855d84d3bda7886cec984eb729e8e1da32f15f3ffd0d564736f6c634300081100330000000000000000000000003446dd70b2d52a6bf4a5a192d9b0a161295ab7f9
Deployed Bytecode
0x6080604052600436106101f25760003560e01c806370b0f6601161010d578063c59057e4116100a0578063eb9019d41161006f578063eb9019d414610805578063ece40cc114610842578063f23a6e611461086b578063f8ce560a146108a8578063fc0c546a146108e557610238565b8063c59057e414610749578063dd4e2ba514610786578063deaaa7cc146107b1578063ea0217cf146107dc57610238565b8063b58131b0116100dc578063b58131b014610688578063bc197c81146106b3578063c01f9e37146106f0578063c28bc2fa1461072d57610238565b806370b0f660146105a85780637b3c71d3146105d15780637d5e81e21461060e5780639a802a6d1461064b57610238565b80633932abb111610185578063544ffc9c11610154578063544ffc9c146104c457806354fd4d5014610503578063567813881461052e5780635f398a141461056b57610238565b80633932abb1146103e25780633bccf4fd1461040d5780633e4f49e61461044a578063438596321461048757610238565b8063150b7a02116101c1578063150b7a021461030d5780632656227d1461034a5780632d63f6931461037a5780632fe3e261146103b757610238565b806301ffc9a71461023d57806302a251a31461027a57806303420181146102a557806306fdde03146102e257610238565b36610238573073ffffffffffffffffffffffffffffffffffffffff16610216610910565b73ffffffffffffffffffffffffffffffffffffffff161461023657600080fd5b005b600080fd5b34801561024957600080fd5b50610264600480360381019061025f9190612b72565b610918565b6040516102719190612bba565b60405180910390f35b34801561028657600080fd5b5061028f610a7d565b60405161029c9190612bee565b60405180910390f35b3480156102b157600080fd5b506102cc60048036038101906102c79190612e4a565b610a8c565b6040516102d99190612bee565b60405180910390f35b3480156102ee57600080fd5b506102f7610b71565b6040516103049190612fa7565b60405180910390f35b34801561031957600080fd5b50610334600480360381019061032f9190613027565b610c03565b60405161034191906130b9565b60405180910390f35b610364600480360381019061035f919061333b565b610c17565b6040516103719190612bee565b60405180910390f35b34801561038657600080fd5b506103a1600480360381019061039c91906133f6565b610d64565b6040516103ae9190612bee565b60405180910390f35b3480156103c357600080fd5b506103cc610dd2565b6040516103d99190613432565b60405180910390f35b3480156103ee57600080fd5b506103f7610df6565b6040516104049190612bee565b60405180910390f35b34801561041957600080fd5b50610434600480360381019061042f919061344d565b610e05565b6040516104419190612bee565b60405180910390f35b34801561045657600080fd5b50610471600480360381019061046c91906133f6565b610e8f565b60405161047e919061353f565b60405180910390f35b34801561049357600080fd5b506104ae60048036038101906104a9919061355a565b610fa3565b6040516104bb9190612bba565b60405180910390f35b3480156104d057600080fd5b506104eb60048036038101906104e691906133f6565b61100e565b6040516104fa9392919061359a565b60405180910390f35b34801561050f57600080fd5b50610518611046565b6040516105259190612fa7565b60405180910390f35b34801561053a57600080fd5b50610555600480360381019061055091906135d1565b611083565b6040516105629190612bee565b60405180910390f35b34801561057757600080fd5b50610592600480360381019061058d9190613611565b6110b4565b60405161059f9190612bee565b60405180910390f35b3480156105b457600080fd5b506105cf60048036038101906105ca91906133f6565b61111e565b005b3480156105dd57600080fd5b506105f860048036038101906105f391906136b5565b611215565b6040516106059190612bee565b60405180910390f35b34801561061a57600080fd5b50610635600480360381019061063091906137ca565b61127d565b6040516106429190612bee565b60405180910390f35b34801561065757600080fd5b50610672600480360381019061066d91906138a1565b611584565b60405161067f9190612bee565b60405180910390f35b34801561069457600080fd5b5061069d61159a565b6040516106aa9190612bee565b60405180910390f35b3480156106bf57600080fd5b506106da60048036038101906106d59190613910565b6115a9565b6040516106e791906130b9565b60405180910390f35b3480156106fc57600080fd5b50610717600480360381019061071291906133f6565b6115be565b6040516107249190612bee565b60405180910390f35b61074760048036038101906107429190613a35565b61162c565b005b34801561075557600080fd5b50610770600480360381019061076b919061333b565b6117b5565b60405161077d9190612bee565b60405180910390f35b34801561079257600080fd5b5061079b6117f1565b6040516107a89190612fa7565b60405180910390f35b3480156107bd57600080fd5b506107c661182e565b6040516107d39190613432565b60405180910390f35b3480156107e857600080fd5b5061080360048036038101906107fe91906133f6565b611852565b005b34801561081157600080fd5b5061082c60048036038101906108279190613aa9565b611949565b6040516108399190612bee565b60405180910390f35b34801561084e57600080fd5b50610869600480360381019061086491906133f6565b611965565b005b34801561087757600080fd5b50610892600480360381019061088d9190613ae9565b611a5c565b60405161089f91906130b9565b60405180910390f35b3480156108b457600080fd5b506108cf60048036038101906108ca91906133f6565b611a71565b6040516108dc9190612bee565b60405180910390f35b3480156108f157600080fd5b506108fa611a86565b6040516109079190613bdf565b60405180910390f35b600030905090565b6000639a802a6d60e01b630342018160e01b635f398a1460e01b7f79dd796f000000000000000000000000000000000000000000000000000000001818187bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109fe57507f79dd796f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a6657507f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a765750610a7582611aaa565b5b9050919050565b6000610a87611b14565b905090565b600080610b0f610b077fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af888c8c8c8c604051610ac8929190613c2a565b60405180910390208b80519060200120604051602001610aec959493929190613c52565b60405160208183030381529060405280519060200120611b1e565b868686611b38565b9050610b628a828b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508a611b63565b91505098975050505050505050565b606060008054610b8090613cd4565b80601f0160208091040260200160405190810160405280929190818152602001828054610bac90613cd4565b8015610bf95780601f10610bce57610100808354040283529160200191610bf9565b820191906000526020600020905b815481529060010190602001808311610bdc57829003601f168201915b5050505050905090565b600063150b7a0260e01b9050949350505050565b600080610c26868686866117b5565b90506000610c3382610e8f565b905060046007811115610c4957610c486134c8565b5b816007811115610c5c57610c5b6134c8565b5b1480610c8c575060056007811115610c7757610c766134c8565b5b816007811115610c8a57610c896134c8565b5b145b610ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc290613d77565b60405180910390fd5b600180600084815260200190815260200160002060020160006101000a81548160ff0219169083151502179055507f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f82604051610d289190612bee565b60405180910390a1610d3d8288888888611d1f565b610d4a8288888888611e02565b610d578288888888611f11565b8192505050949350505050565b6000610dc1600160008481526020019081526020016000206000016040518060200160405290816000820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050611f6c565b67ffffffffffffffff169050919050565b7fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af8881565b6000610e00611f7a565b905090565b600080610e66610e5e7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f8989604051602001610e4393929190613d97565b60405160208183030381529060405280519060200120611b1e565b868686611b38565b9050610e8387828860405180602001604052806000815250611f84565b91505095945050505050565b6000806001600084815260200190815260200160002090508060020160009054906101000a900460ff1615610ec8576007915050610f9e565b8060020160019054906101000a900460ff1615610ee9576002915050610f9e565b6000610ef484610d64565b905060008103610f39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3090613e1a565b60405180910390fd5b438110610f4b57600092505050610f9e565b6000610f56856115be565b9050438110610f6b5760019350505050610f9e565b610f7485611fa4565b8015610f855750610f8485611feb565b5b15610f965760049350505050610f9e565b600393505050505b919050565b60006007600084815260200190815260200160002060030160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600080600080600760008681526020019081526020016000209050806000015481600101548260020154935093509350509193909250565b60606040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250905090565b60008061108e612016565b90506110ab84828560405180602001604052806000815250611f84565b91505092915050565b6000806110bf612016565b905061111287828888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087611b63565b91505095945050505050565b611126610910565b73ffffffffffffffffffffffffffffffffffffffff16611144612016565b73ffffffffffffffffffffffffffffffffffffffff161461119a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119190613e86565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff166111b9610910565b73ffffffffffffffffffffffffffffffffffffffff16146112095760006111de61201e565b6040516111ec929190613c2a565b604051809103902090505b80611202600261202b565b036111f757505b61121281612107565b50565b600080611220612016565b905061127286828787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611f84565b915050949350505050565b600061128761159a565b6112a4611292612016565b60014361129f9190613ed5565b611949565b10156112e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112dc90613f7b565b60405180910390fd5b60006112fa86868686805190602001206117b5565b90508451865114611340576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113379061400d565b60405180910390fd5b8351865114611384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137b9061400d565b60405180910390fd5b60008651116113c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bf90614079565b60405180910390fd5b6000600160008381526020019081526020016000209050611428816000016040518060200160405290816000820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff168152505061214c565b611467576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145e9061410b565b60405180910390fd5b6000611479611474610df6565b612166565b61148243612166565b61148c919061413f565b905060006114a061149b610a7d565b612166565b826114ab919061413f565b90506114c382846000016121bd90919063ffffffff16565b6114d981846001016121bd90919063ffffffff16565b7f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e084611503612016565b8b8b8d5167ffffffffffffffff8111156115205761151f612ce9565b5b60405190808252806020026020018201604052801561155357816020015b606081526020019060019003908161153e5790505b508c88888e60405161156d9998979695949392919061455a565b60405180910390a183945050505050949350505050565b60006115918484846121ec565b90509392505050565b60006115a46122a1565b905090565b600063bc197c8160e01b905095945050505050565b600061161b600160008481526020019081526020016000206001016040518060200160405290816000820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050611f6c565b67ffffffffffffffff169050919050565b611634610910565b73ffffffffffffffffffffffffffffffffffffffff16611652612016565b73ffffffffffffffffffffffffffffffffffffffff16146116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169f90613e86565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff166116c7610910565b73ffffffffffffffffffffffffffffffffffffffff16146117175760006116ec61201e565b6040516116fa929190613c2a565b604051809103902090505b80611710600261202b565b0361170557505b6000808573ffffffffffffffffffffffffffffffffffffffff16858585604051611742929190613c2a565b60006040518083038185875af1925050503d806000811461177f576040519150601f19603f3d011682016040523d82523d6000602084013e611784565b606091505b50915091506117ac8282604051806060016040528060288152602001614e9d602891396122ab565b50505050505050565b6000848484846040516020016117ce949392919061460a565b6040516020818303038152906040528051906020012060001c9050949350505050565b60606040518060400160405280602081526020017f737570706f72743d627261766f2671756f72756d3d666f722c6162737461696e815250905090565b7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b61185a610910565b73ffffffffffffffffffffffffffffffffffffffff16611878612016565b73ffffffffffffffffffffffffffffffffffffffff16146118ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c590613e86565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff166118ed610910565b73ffffffffffffffffffffffffffffffffffffffff161461193d57600061191261201e565b604051611920929190613c2a565b604051809103902090505b80611936600261202b565b0361192b57505b611946816122cd565b50565b600061195d8383611958612355565b6121ec565b905092915050565b61196d610910565b73ffffffffffffffffffffffffffffffffffffffff1661198b612016565b73ffffffffffffffffffffffffffffffffffffffff16146119e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d890613e86565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16611a00610910565b73ffffffffffffffffffffffffffffffffffffffff1614611a50576000611a2561201e565b604051611a33929190613c2a565b604051809103902090505b80611a49600261202b565b03611a3e57505b611a598161236c565b50565b600063f23a6e6160e01b905095945050505050565b60006a01fc3842bd1f071c0000009050919050565b7f0000000000000000000000003446dd70b2d52a6bf4a5a192d9b0a161295ab7f981565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000600554905090565b6000611b31611b2b6123b1565b836124cb565b9050919050565b6000806000611b49878787876124fe565b91509150611b56816125e0565b8192505050949350505050565b60008060016000888152602001908152602001600020905060016007811115611b8f57611b8e6134c8565b5b611b9888610e8f565b6007811115611baa57611ba96134c8565b5b14611bea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be1906146d6565b60405180910390fd5b6000611c4987611c39846000016040518060200160405290816000820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050611f6c565b67ffffffffffffffff16866121ec565b9050611c588888888488612746565b6000845103611cba578673ffffffffffffffffffffffffffffffffffffffff167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda489888489604051611cad94939291906146f6565b60405180910390a2611d11565b8673ffffffffffffffffffffffffffffffffffffffff167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb87128988848989604051611d0895949392919061478c565b60405180910390a25b809250505095945050505050565b3073ffffffffffffffffffffffffffffffffffffffff16611d3e610910565b73ffffffffffffffffffffffffffffffffffffffff1614611dfb5760005b8451811015611df9573073ffffffffffffffffffffffffffffffffffffffff16858281518110611d8f57611d8e6147ed565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611de857611de7838281518110611dc857611dc76147ed565b5b602002602001015180519060200120600261294a90919063ffffffff16565b5b80611df29061481c565b9050611d5c565b505b5050505050565b6000604051806060016040528060278152602001614ec560279139905060005b8551811015611f0857600080878381518110611e4157611e406147ed565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16878481518110611e7257611e716147ed565b5b6020026020010151878581518110611e8d57611e8c6147ed565b5b6020026020010151604051611ea29190614895565b60006040518083038185875af1925050503d8060008114611edf576040519150601f19603f3d011682016040523d82523d6000602084013e611ee4565b606091505b5091509150611ef48282866122ab565b50505080611f019061481c565b9050611e22565b50505050505050565b3073ffffffffffffffffffffffffffffffffffffffff16611f30610910565b73ffffffffffffffffffffffffffffffffffffffff1614611f6557611f5560026129c6565b611f6457611f6360026129fb565b5b5b5050505050565b600081600001519050919050565b6000600454905090565b6000611f9a85858585611f95612355565b611b63565b9050949350505050565b60008060076000848152602001908152602001600020905080600201548160010154611fd091906148ac565b611fe1611fdc85610d64565b611a71565b1115915050919050565b6000806007600084815260200190815260200160002090508060000154816001015411915050919050565b600033905090565b3660008036915091509091565b6000612036826129c6565b1561206d576040517f3db2a12a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008260000160009054906101000a9004600f0b905082600101600082600f0b600f0b815260200190815260200160002054915082600101600082600f0b600f0b815260200190815260200160002060009055600181018360000160006101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff16021790555050919050565b7fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a936004548260405161213a9291906148e0565b60405180910390a18060048190555050565b600080826000015167ffffffffffffffff16149050919050565b600067ffffffffffffffff80168211156121b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ac9061497b565b60405180910390fd5b819050919050565b808260000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050565b60007f0000000000000000000000003446dd70b2d52a6bf4a5a192d9b0a161295ab7f973ffffffffffffffffffffffffffffffffffffffff1663782d6fe185856040518363ffffffff1660e01b815260040161224992919061499b565b602060405180830381865afa158015612266573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228a9190614a08565b6bffffffffffffffffffffffff1690509392505050565b6000600654905090565b606083156122bb578290506122c6565b6122c58383612a7c565b5b9392505050565b60008111612310576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230790614aa7565b60405180910390fd5b7f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828600554826040516123439291906148e0565b60405180910390a18060058190555050565b606060405180602001604052806000815250905090565b7fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc054616006548260405161239f9291906148e0565b60405180910390a18060068190555050565b60007f0000000000000000000000006853f8865ba8e9fbd9c8cce3155ce5023fb7eeb073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561242d57507f000000000000000000000000000000000000000000000000000000000000000146145b1561245a577f300060c9d892e6d51e095a16f1194a0d0ef16625ff2ec3f2465507a9f0b34e3b90506124c8565b6124c57f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7fe2308e69d0715b6d261e3647a1a534cb74640542db10ec1be3fc0e26621b55027fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6612acc565b90505b90565b600082826040516020016124e0929190614b3f565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c11156125395760006003915091506125d7565b60006001878787876040516000815260200160405260405161255e9493929190614b76565b6020604051602081039080840390855afa158015612580573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036125ce576000600192509250506125d7565b80600092509250505b94509492505050565b600060048111156125f4576125f36134c8565b5b816004811115612607576126066134c8565b5b03156127435760016004811115612621576126206134c8565b5b816004811115612634576126336134c8565b5b03612674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161266b90614c07565b60405180910390fd5b60026004811115612688576126876134c8565b5b81600481111561269b5761269a6134c8565b5b036126db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d290614c73565b60405180910390fd5b600360048111156126ef576126ee6134c8565b5b816004811115612702576127016134c8565b5b03612742576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161273990614d05565b60405180910390fd5b5b50565b60006007600087815260200190815260200160002090508060030160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156127ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127e390614d97565b60405180910390fd5b60018160030160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506000600281111561285a576128596134c8565b5b60ff168460ff1603612886578281600001600082825461287a91906148ac565b92505081905550612942565b6001600281111561289a576128996134c8565b5b60ff168460ff16036128c657828160010160008282546128ba91906148ac565b92505081905550612941565b6002808111156128d9576128d86134c8565b5b60ff168460ff160361290557828160020160008282546128f991906148ac565b92505081905550612940565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161293790614e29565b60405180910390fd5b5b5b505050505050565b60008260000160109054906101000a9004600f0b90508183600101600083600f0b600f0b815260200190815260200160002081905550600181018360000160106101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff160217905550505050565b60008160000160009054906101000a9004600f0b600f0b8260000160109054906101000a9004600f0b600f0b13159050919050565b60008160000160006101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff16021790555060008160000160106101000a8154816fffffffffffffffffffffffffffffffff0219169083600f0b6fffffffffffffffffffffffffffffffff16021790555050565b600082511115612a8f5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac39190612fa7565b60405180910390fd5b60008383834630604051602001612ae7959493929190614e49565b6040516020818303038152906040528051906020012090509392505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b4f81612b1a565b8114612b5a57600080fd5b50565b600081359050612b6c81612b46565b92915050565b600060208284031215612b8857612b87612b10565b5b6000612b9684828501612b5d565b91505092915050565b60008115159050919050565b612bb481612b9f565b82525050565b6000602082019050612bcf6000830184612bab565b92915050565b6000819050919050565b612be881612bd5565b82525050565b6000602082019050612c036000830184612bdf565b92915050565b612c1281612bd5565b8114612c1d57600080fd5b50565b600081359050612c2f81612c09565b92915050565b600060ff82169050919050565b612c4b81612c35565b8114612c5657600080fd5b50565b600081359050612c6881612c42565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612c9357612c92612c6e565b5b8235905067ffffffffffffffff811115612cb057612caf612c73565b5b602083019150836001820283011115612ccc57612ccb612c78565b5b9250929050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612d2182612cd8565b810181811067ffffffffffffffff82111715612d4057612d3f612ce9565b5b80604052505050565b6000612d53612b06565b9050612d5f8282612d18565b919050565b600067ffffffffffffffff821115612d7f57612d7e612ce9565b5b612d8882612cd8565b9050602081019050919050565b82818337600083830152505050565b6000612db7612db284612d64565b612d49565b905082815260208101848484011115612dd357612dd2612cd3565b5b612dde848285612d95565b509392505050565b600082601f830112612dfb57612dfa612c6e565b5b8135612e0b848260208601612da4565b91505092915050565b6000819050919050565b612e2781612e14565b8114612e3257600080fd5b50565b600081359050612e4481612e1e565b92915050565b60008060008060008060008060e0898b031215612e6a57612e69612b10565b5b6000612e788b828c01612c20565b9850506020612e898b828c01612c59565b975050604089013567ffffffffffffffff811115612eaa57612ea9612b15565b5b612eb68b828c01612c7d565b9650965050606089013567ffffffffffffffff811115612ed957612ed8612b15565b5b612ee58b828c01612de6565b9450506080612ef68b828c01612c59565b93505060a0612f078b828c01612e35565b92505060c0612f188b828c01612e35565b9150509295985092959890939650565b600081519050919050565b600082825260208201905092915050565b60005b83811015612f62578082015181840152602081019050612f47565b60008484015250505050565b6000612f7982612f28565b612f838185612f33565b9350612f93818560208601612f44565b612f9c81612cd8565b840191505092915050565b60006020820190508181036000830152612fc18184612f6e565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ff482612fc9565b9050919050565b61300481612fe9565b811461300f57600080fd5b50565b60008135905061302181612ffb565b92915050565b6000806000806080858703121561304157613040612b10565b5b600061304f87828801613012565b945050602061306087828801613012565b935050604061307187828801612c20565b925050606085013567ffffffffffffffff81111561309257613091612b15565b5b61309e87828801612de6565b91505092959194509250565b6130b381612b1a565b82525050565b60006020820190506130ce60008301846130aa565b92915050565b600067ffffffffffffffff8211156130ef576130ee612ce9565b5b602082029050602081019050919050565b600061311361310e846130d4565b612d49565b9050808382526020820190506020840283018581111561313657613135612c78565b5b835b8181101561315f578061314b8882613012565b845260208401935050602081019050613138565b5050509392505050565b600082601f83011261317e5761317d612c6e565b5b813561318e848260208601613100565b91505092915050565b600067ffffffffffffffff8211156131b2576131b1612ce9565b5b602082029050602081019050919050565b60006131d66131d184613197565b612d49565b905080838252602082019050602084028301858111156131f9576131f8612c78565b5b835b81811015613222578061320e8882612c20565b8452602084019350506020810190506131fb565b5050509392505050565b600082601f83011261324157613240612c6e565b5b81356132518482602086016131c3565b91505092915050565b600067ffffffffffffffff82111561327557613274612ce9565b5b602082029050602081019050919050565b60006132996132948461325a565b612d49565b905080838252602082019050602084028301858111156132bc576132bb612c78565b5b835b8181101561330357803567ffffffffffffffff8111156132e1576132e0612c6e565b5b8086016132ee8982612de6565b855260208501945050506020810190506132be565b5050509392505050565b600082601f83011261332257613321612c6e565b5b8135613332848260208601613286565b91505092915050565b6000806000806080858703121561335557613354612b10565b5b600085013567ffffffffffffffff81111561337357613372612b15565b5b61337f87828801613169565b945050602085013567ffffffffffffffff8111156133a05761339f612b15565b5b6133ac8782880161322c565b935050604085013567ffffffffffffffff8111156133cd576133cc612b15565b5b6133d98782880161330d565b92505060606133ea87828801612e35565b91505092959194509250565b60006020828403121561340c5761340b612b10565b5b600061341a84828501612c20565b91505092915050565b61342c81612e14565b82525050565b60006020820190506134476000830184613423565b92915050565b600080600080600060a0868803121561346957613468612b10565b5b600061347788828901612c20565b955050602061348888828901612c59565b945050604061349988828901612c59565b93505060606134aa88828901612e35565b92505060806134bb88828901612e35565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60088110613508576135076134c8565b5b50565b6000819050613519826134f7565b919050565b60006135298261350b565b9050919050565b6135398161351e565b82525050565b60006020820190506135546000830184613530565b92915050565b6000806040838503121561357157613570612b10565b5b600061357f85828601612c20565b925050602061359085828601613012565b9150509250929050565b60006060820190506135af6000830186612bdf565b6135bc6020830185612bdf565b6135c96040830184612bdf565b949350505050565b600080604083850312156135e8576135e7612b10565b5b60006135f685828601612c20565b925050602061360785828601612c59565b9150509250929050565b60008060008060006080868803121561362d5761362c612b10565b5b600061363b88828901612c20565b955050602061364c88828901612c59565b945050604086013567ffffffffffffffff81111561366d5761366c612b15565b5b61367988828901612c7d565b9350935050606086013567ffffffffffffffff81111561369c5761369b612b15565b5b6136a888828901612de6565b9150509295509295909350565b600080600080606085870312156136cf576136ce612b10565b5b60006136dd87828801612c20565b94505060206136ee87828801612c59565b935050604085013567ffffffffffffffff81111561370f5761370e612b15565b5b61371b87828801612c7d565b925092505092959194509250565b600067ffffffffffffffff82111561374457613743612ce9565b5b61374d82612cd8565b9050602081019050919050565b600061376d61376884613729565b612d49565b90508281526020810184848401111561378957613788612cd3565b5b613794848285612d95565b509392505050565b600082601f8301126137b1576137b0612c6e565b5b81356137c184826020860161375a565b91505092915050565b600080600080608085870312156137e4576137e3612b10565b5b600085013567ffffffffffffffff81111561380257613801612b15565b5b61380e87828801613169565b945050602085013567ffffffffffffffff81111561382f5761382e612b15565b5b61383b8782880161322c565b935050604085013567ffffffffffffffff81111561385c5761385b612b15565b5b6138688782880161330d565b925050606085013567ffffffffffffffff81111561388957613888612b15565b5b6138958782880161379c565b91505092959194509250565b6000806000606084860312156138ba576138b9612b10565b5b60006138c886828701613012565b93505060206138d986828701612c20565b925050604084013567ffffffffffffffff8111156138fa576138f9612b15565b5b61390686828701612de6565b9150509250925092565b600080600080600060a0868803121561392c5761392b612b10565b5b600061393a88828901613012565b955050602061394b88828901613012565b945050604086013567ffffffffffffffff81111561396c5761396b612b15565b5b6139788882890161322c565b935050606086013567ffffffffffffffff81111561399957613998612b15565b5b6139a58882890161322c565b925050608086013567ffffffffffffffff8111156139c6576139c5612b15565b5b6139d288828901612de6565b9150509295509295909350565b60008083601f8401126139f5576139f4612c6e565b5b8235905067ffffffffffffffff811115613a1257613a11612c73565b5b602083019150836001820283011115613a2e57613a2d612c78565b5b9250929050565b60008060008060608587031215613a4f57613a4e612b10565b5b6000613a5d87828801613012565b9450506020613a6e87828801612c20565b935050604085013567ffffffffffffffff811115613a8f57613a8e612b15565b5b613a9b878288016139df565b925092505092959194509250565b60008060408385031215613ac057613abf612b10565b5b6000613ace85828601613012565b9250506020613adf85828601612c20565b9150509250929050565b600080600080600060a08688031215613b0557613b04612b10565b5b6000613b1388828901613012565b9550506020613b2488828901613012565b9450506040613b3588828901612c20565b9350506060613b4688828901612c20565b925050608086013567ffffffffffffffff811115613b6757613b66612b15565b5b613b7388828901612de6565b9150509295509295909350565b6000819050919050565b6000613ba5613ba0613b9b84612fc9565b613b80565b612fc9565b9050919050565b6000613bb782613b8a565b9050919050565b6000613bc982613bac565b9050919050565b613bd981613bbe565b82525050565b6000602082019050613bf46000830184613bd0565b92915050565b600081905092915050565b6000613c118385613bfa565b9350613c1e838584612d95565b82840190509392505050565b6000613c37828486613c05565b91508190509392505050565b613c4c81612c35565b82525050565b600060a082019050613c676000830188613423565b613c746020830187612bdf565b613c816040830186613c43565b613c8e6060830185613423565b613c9b6080830184613423565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613cec57607f821691505b602082108103613cff57613cfe613ca5565b5b50919050565b7f476f7665726e6f723a2070726f706f73616c206e6f742073756363657373667560008201527f6c00000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d61602183612f33565b9150613d6c82613d05565b604082019050919050565b60006020820190508181036000830152613d9081613d54565b9050919050565b6000606082019050613dac6000830186613423565b613db96020830185612bdf565b613dc66040830184613c43565b949350505050565b7f476f7665726e6f723a20756e6b6e6f776e2070726f706f73616c206964000000600082015250565b6000613e04601d83612f33565b9150613e0f82613dce565b602082019050919050565b60006020820190508181036000830152613e3381613df7565b9050919050565b7f476f7665726e6f723a206f6e6c79476f7665726e616e63650000000000000000600082015250565b6000613e70601883612f33565b9150613e7b82613e3a565b602082019050919050565b60006020820190508181036000830152613e9f81613e63565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613ee082612bd5565b9150613eeb83612bd5565b9250828203905081811115613f0357613f02613ea6565b5b92915050565b7f476f7665726e6f723a2070726f706f73657220766f7465732062656c6f77207060008201527f726f706f73616c207468726573686f6c64000000000000000000000000000000602082015250565b6000613f65603183612f33565b9150613f7082613f09565b604082019050919050565b60006020820190508181036000830152613f9481613f58565b9050919050565b7f476f7665726e6f723a20696e76616c69642070726f706f73616c206c656e677460008201527f6800000000000000000000000000000000000000000000000000000000000000602082015250565b6000613ff7602183612f33565b915061400282613f9b565b604082019050919050565b6000602082019050818103600083015261402681613fea565b9050919050565b7f476f7665726e6f723a20656d7074792070726f706f73616c0000000000000000600082015250565b6000614063601883612f33565b915061406e8261402d565b602082019050919050565b6000602082019050818103600083015261409281614056565b9050919050565b7f476f7665726e6f723a2070726f706f73616c20616c726561647920657869737460008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006140f5602183612f33565b915061410082614099565b604082019050919050565b60006020820190508181036000830152614124816140e8565b9050919050565b600067ffffffffffffffff82169050919050565b600061414a8261412b565b91506141558361412b565b9250828201905067ffffffffffffffff81111561417557614174613ea6565b5b92915050565b61418481612fe9565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6141bf81612fe9565b82525050565b60006141d183836141b6565b60208301905092915050565b6000602082019050919050565b60006141f58261418a565b6141ff8185614195565b935061420a836141a6565b8060005b8381101561423b57815161422288826141c5565b975061422d836141dd565b92505060018101905061420e565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61427d81612bd5565b82525050565b600061428f8383614274565b60208301905092915050565b6000602082019050919050565b60006142b382614248565b6142bd8185614253565b93506142c883614264565b8060005b838110156142f95781516142e08882614283565b97506142eb8361429b565b9250506001810190506142cc565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b600061434e82612f28565b6143588185614332565b9350614368818560208601612f44565b61437181612cd8565b840191505092915050565b60006143888383614343565b905092915050565b6000602082019050919050565b60006143a882614306565b6143b28185614311565b9350836020820285016143c485614322565b8060005b8581101561440057848403895281516143e1858261437c565b94506143ec83614390565b925060208a019950506001810190506143c8565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60006144658261443e565b61446f8185614449565b935061447f818560208601612f44565b61448881612cd8565b840191505092915050565b600061449f838361445a565b905092915050565b6000602082019050919050565b60006144bf82614412565b6144c9818561441d565b9350836020820285016144db8561442e565b8060005b8581101561451757848403895281516144f88582614493565b9450614503836144a7565b925060208a019950506001810190506144df565b50829750879550505050505092915050565b600061454461453f61453a8461412b565b613b80565b612bd5565b9050919050565b61455481614529565b82525050565b600061012082019050614570600083018c612bdf565b61457d602083018b61417b565b818103604083015261458f818a6141ea565b905081810360608301526145a381896142a8565b905081810360808301526145b7818861439d565b905081810360a08301526145cb81876144b4565b90506145da60c083018661454b565b6145e760e083018561454b565b8181036101008301526145fa8184612f6e565b90509a9950505050505050505050565b6000608082019050818103600083015261462481876141ea565b9050818103602083015261463881866142a8565b9050818103604083015261464c81856144b4565b905061465b6060830184613423565b95945050505050565b7f476f7665726e6f723a20766f7465206e6f742063757272656e746c792061637460008201527f6976650000000000000000000000000000000000000000000000000000000000602082015250565b60006146c0602383612f33565b91506146cb82614664565b604082019050919050565b600060208201905081810360008301526146ef816146b3565b9050919050565b600060808201905061470b6000830187612bdf565b6147186020830186613c43565b6147256040830185612bdf565b81810360608301526147378184612f6e565b905095945050505050565b600082825260208201905092915050565b600061475e8261443e565b6147688185614742565b9350614778818560208601612f44565b61478181612cd8565b840191505092915050565b600060a0820190506147a16000830188612bdf565b6147ae6020830187613c43565b6147bb6040830186612bdf565b81810360608301526147cd8185612f6e565b905081810360808301526147e18184614753565b90509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061482782612bd5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361485957614858613ea6565b5b600182019050919050565b600061486f8261443e565b6148798185613bfa565b9350614889818560208601612f44565b80840191505092915050565b60006148a18284614864565b915081905092915050565b60006148b782612bd5565b91506148c283612bd5565b92508282019050808211156148da576148d9613ea6565b5b92915050565b60006040820190506148f56000830185612bdf565b6149026020830184612bdf565b9392505050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203660008201527f3420626974730000000000000000000000000000000000000000000000000000602082015250565b6000614965602683612f33565b915061497082614909565b604082019050919050565b6000602082019050818103600083015261499481614958565b9050919050565b60006040820190506149b0600083018561417b565b6149bd6020830184612bdf565b9392505050565b60006bffffffffffffffffffffffff82169050919050565b6149e5816149c4565b81146149f057600080fd5b50565b600081519050614a02816149dc565b92915050565b600060208284031215614a1e57614a1d612b10565b5b6000614a2c848285016149f3565b91505092915050565b7f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f642060008201527f746f6f206c6f7700000000000000000000000000000000000000000000000000602082015250565b6000614a91602783612f33565b9150614a9c82614a35565b604082019050919050565b60006020820190508181036000830152614ac081614a84565b9050919050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000614b08600283614ac7565b9150614b1382614ad2565b600282019050919050565b6000819050919050565b614b39614b3482612e14565b614b1e565b82525050565b6000614b4a82614afb565b9150614b568285614b28565b602082019150614b668284614b28565b6020820191508190509392505050565b6000608082019050614b8b6000830187613423565b614b986020830186613c43565b614ba56040830185613423565b614bb26060830184613423565b95945050505050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000614bf1601883612f33565b9150614bfc82614bbb565b602082019050919050565b60006020820190508181036000830152614c2081614be4565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614c5d601f83612f33565b9150614c6882614c27565b602082019050919050565b60006020820190508181036000830152614c8c81614c50565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614cef602283612f33565b9150614cfa82614c93565b604082019050919050565b60006020820190508181036000830152614d1e81614ce2565b9050919050565b7f476f7665726e6f72566f74696e6753696d706c653a20766f746520616c72656160008201527f6479206361737400000000000000000000000000000000000000000000000000602082015250565b6000614d81602783612f33565b9150614d8c82614d25565b604082019050919050565b60006020820190508181036000830152614db081614d74565b9050919050565b7f476f7665726e6f72566f74696e6753696d706c653a20696e76616c696420766160008201527f6c756520666f7220656e756d20566f7465547970650000000000000000000000602082015250565b6000614e13603583612f33565b9150614e1e82614db7565b604082019050919050565b60006020820190508181036000830152614e4281614e06565b9050919050565b600060a082019050614e5e6000830188613423565b614e6b6020830187613423565b614e786040830186613423565b614e856060830185612bdf565b614e92608083018461417b565b969550505050505056fe476f7665726e6f723a2072656c617920726576657274656420776974686f7574206d657373616765476f7665726e6f723a2063616c6c20726576657274656420776974686f7574206d657373616765a264697066735822122007d0065dfa1b0b6d01e855d84d3bda7886cec984eb729e8e1da32f15f3ffd0d564736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003446dd70b2d52a6bf4a5a192d9b0a161295ab7f9
-----Decoded View---------------
Arg [0] : _token (address): 0x3446Dd70B2D52A6Bf4a5a192D9b0A161295aB7F9
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000003446dd70b2d52a6bf4a5a192d9b0a161295ab7f9
Deployed Bytecode Sourcemap
163765:1039:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100897:4;100874:28;;:11;:9;:11::i;:::-;:28;;;100866:37;;;;;;163765:1039;;;;;100983:750;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;164426:179;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113859:811;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101794:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117493:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108108:889;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104415:165;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98438:148;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;164241:177;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113329:441;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103396:946;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122950:169;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123196:401;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;101958:101;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112306:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112939:320;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120065:128;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112582:273;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106597:1447;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112008:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;164613:188;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118094:255;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104653:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;116787:333;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103019:315;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122747:138;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98336:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120375:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;111755:178;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120699:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117781:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;164063:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;163282:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117314:100;117366:7;117401:4;117386:20;;117314:100;:::o;100983:750::-;101085:4;101514:32;;;101448:46;;;101387:41;;;101340:27;:88;:154;:206;101311:236;;;:11;:236;;;;:295;;;;101579:27;101564:42;;;:11;:42;;;;101311:295;:361;;;;101638:34;101623:49;;;:11;:49;;;;101311:361;:414;;;;101689:36;101713:11;101689:23;:36::i;:::-;101311:414;101291:434;;100983:750;;;:::o;164426:179::-;164545:7;164577:20;:18;:20::i;:::-;164570:27;;164426:179;:::o;113859:811::-;114115:7;114135:13;114151:438;114179:351;98498:88;114334:10;114371:7;114421:6;;114405:24;;;;;;;:::i;:::-;;;;;;;;114466:6;114456:17;;;;;;114246:250;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;114214:301;;;;;;114179:16;:351::i;:::-;114545:1;114561;114577;114151:13;:438::i;:::-;114135:454;;114609:53;114619:10;114631:5;114638:7;114647:6;;114609:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114655:6;114609:9;:53::i;:::-;114602:60;;;113859:811;;;;;;;;;;:::o;101794:100::-;101848:13;101881:5;101874:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101794:100;:::o;117493:207::-;117636:6;117662:30;;;117655:37;;117493:207;;;;;;:::o;108108:889::-;108311:7;108331:18;108352:57;108365:7;108374:6;108382:9;108393:15;108352:12;:57::i;:::-;108331:78;;108422:20;108445:17;108451:10;108445:5;:17::i;:::-;108422:40;;108505:23;108495:33;;;;;;;;:::i;:::-;;:6;:33;;;;;;;;:::i;:::-;;;:67;;;;108542:20;108532:30;;;;;;;;:::i;:::-;;:6;:30;;;;;;;;:::i;:::-;;;108495:67;108473:150;;;;;;;;;;;;:::i;:::-;;;;;;;;;108668:4;108634:10;:22;108645:10;108634:22;;;;;;;;;;;:31;;;:38;;;;;;;;;;;;;;;;;;108690:28;108707:10;108690:28;;;;;;:::i;:::-;;;;;;;;108731:71;108746:10;108758:7;108767:6;108775:9;108786:15;108731:14;:71::i;:::-;108813:65;108822:10;108834:7;108843:6;108851:9;108862:15;108813:8;:65::i;:::-;108889:70;108903:10;108915:7;108924:6;108932:9;108943:15;108889:13;:70::i;:::-;108979:10;108972:17;;;;108108:889;;;;;;:::o;104415:165::-;104499:7;104526:46;:10;:22;104537:10;104526:22;;;;;;;;;;;:32;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:46::i;:::-;104519:53;;;;104415:165;;;:::o;98438:148::-;98498:88;98438:148;:::o;164241:177::-;164359:7;164391:19;:17;:19::i;:::-;164384:26;;164241:177;:::o;113329:441::-;113503:7;113523:13;113539:164;113567:77;98378:53;113622:10;113634:7;113594:48;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;113584:59;;;;;;113567:16;:77::i;:::-;113659:1;113675;113691;113539:13;:164::i;:::-;113523:180;;113721:41;113731:10;113743:5;113750:7;113721:41;;;;;;;;;;;;:9;:41::i;:::-;113714:48;;;113329:441;;;;;;;:::o;103396:946::-;103469:13;103495:29;103527:10;:22;103538:10;103527:22;;;;;;;;;;;103495:54;;103566:8;:17;;;;;;;;;;;;103562:79;;;103607:22;103600:29;;;;;103562:79;103657:8;:17;;;;;;;;;;;;103653:79;;;103698:22;103691:29;;;;;103653:79;103744:16;103763:28;103780:10;103763:16;:28::i;:::-;103744:47;;103820:1;103808:8;:13;103804:85;;103838:39;;;;;;;;;;:::i;:::-;;;;;;;;103804:85;103917:12;103905:8;:24;103901:85;;103953:21;103946:28;;;;;;103901:85;103998:16;104017:28;104034:10;104017:16;:28::i;:::-;103998:47;;104074:12;104062:8;:24;104058:84;;104110:20;104103:27;;;;;;;104058:84;104158:26;104173:10;104158:14;:26::i;:::-;:56;;;;;104188:26;104203:10;104188:14;:26::i;:::-;104158:56;104154:181;;;104238:23;104231:30;;;;;;;104154:181;104301:22;104294:29;;;;;103396:946;;;;:::o;122950:169::-;123043:4;123067:14;:26;123082:10;123067:26;;;;;;;;;;;:35;;:44;123103:7;123067:44;;;;;;;;;;;;;;;;;;;;;;;;;123060:51;;122950:169;;;;:::o;123196:401::-;123318:20;123353:16;123384:20;123432:33;123468:14;:26;123483:10;123468:26;;;;;;;;;;;123432:62;;123513:12;:25;;;123540:12;:21;;;123563:12;:25;;;123505:84;;;;;;;123196:401;;;;;:::o;101958:101::-;102015:13;102041:10;;;;;;;;;;;;;;;;;;;101958:101;:::o;112306:201::-;112392:7;112412:13;112428:12;:10;:12::i;:::-;112412:28;;112458:41;112468:10;112480:5;112487:7;112458:41;;;;;;;;;;;;:9;:41::i;:::-;112451:48;;;112306:201;;;;:::o;112939:320::-;113132:7;113152:13;113168:12;:10;:12::i;:::-;113152:28;;113198:53;113208:10;113220:5;113227:7;113236:6;;113198:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113244:6;113198:9;:53::i;:::-;113191:60;;;112939:320;;;;;;;:::o;120065:128::-;100151:11;:9;:11::i;:::-;100135:27;;:12;:10;:12::i;:::-;:27;;;100127:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;100229:4;100206:28;;:11;:9;:11::i;:::-;:28;;;100202:281;;100251:19;100283:10;:8;:10::i;:::-;100273:21;;;;;;;:::i;:::-;;;;;;;;100251:43;;100420:52;100457:11;100427:26;:15;:24;:26::i;:::-;:41;100420:52;;100236:247;100202:281;120154:31:::1;120170:14;120154:15;:31::i;:::-;120065:128:::0;:::o;112582:273::-;112736:7;112756:13;112772:12;:10;:12::i;:::-;112756:28;;112802:45;112812:10;112824:5;112831:7;112840:6;;112802:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:9;:45::i;:::-;112795:52;;;112582:273;;;;;;:::o;106597:1447::-;106794:7;106880:19;:17;:19::i;:::-;106836:40;106845:12;:10;:12::i;:::-;106874:1;106859:12;:16;;;;:::i;:::-;106836:8;:40::i;:::-;:63;;106814:162;;;;;;;;;;;;:::i;:::-;;;;;;;;;106989:18;107010:71;107023:7;107032:6;107040:9;107067:11;107051:29;;;;;;107010:12;:71::i;:::-;106989:92;;107120:6;:13;107102:7;:14;:31;107094:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;107208:9;:16;107190:7;:14;:34;107182:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;107298:1;107281:7;:14;:18;107273:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;107341:29;107373:10;:22;107384:10;107373:22;;;;;;;;;;;107341:54;;107414:28;:8;:18;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:28::i;:::-;107406:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;107493:15;107537:24;:13;:11;:13::i;:::-;:22;:24::i;:::-;107511:23;:12;:21;:23::i;:::-;:50;;;;:::i;:::-;107493:68;;107572:15;107601:25;:14;:12;:14::i;:::-;:23;:25::i;:::-;107590:8;:36;;;;:::i;:::-;107572:54;;107639:40;107670:8;107639;:18;;:30;;:40;;;;:::i;:::-;107690:38;107719:8;107690;:16;;:28;;:38;;;;:::i;:::-;107746:260;107776:10;107801:12;:10;:12::i;:::-;107828:7;107850:6;107884:7;:14;107871:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107914:9;107938:8;107961;107984:11;107746:260;;;;;;;;;;;;;;:::i;:::-;;;;;;;;108026:10;108019:17;;;;;;106597:1447;;;;;;:::o;112008:233::-;112167:7;112194:39;112204:7;112213:11;112226:6;112194:9;:39::i;:::-;112187:46;;112008:233;;;;;:::o;164613:188::-;164736:7;164768:25;:23;:25::i;:::-;164761:32;;164613:188;:::o;118094:255::-;118279:6;118305:36;;;118298:43;;118094:255;;;;;;;:::o;104653:163::-;104737:7;104764:44;:10;:22;104775:10;104764:22;;;;;;;;;;;:30;;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:44::i;:::-;104757:51;;;;104653:163;;;:::o;116787:333::-;100151:11;:9;:11::i;:::-;100135:27;;:12;:10;:12::i;:::-;:27;;;100127:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;100229:4;100206:28;;:11;:9;:11::i;:::-;:28;;;100202:281;;100251:19;100283:10;:8;:10::i;:::-;100273:21;;;;;;;:::i;:::-;;;;;;;;100251:43;;100420:52;100457:11;100427:26;:15;:24;:26::i;:::-;:41;100420:52;;100236:247;100202:281;116940:12:::1;116954:23:::0;116981:6:::1;:11;;117000:5;117007:4;;116981:31;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116939:73;;;;117023:89;117048:7;117057:10;117023:89;;;;;;;;;;;;;;;;;:24;:89::i;:::-;;116928:192;;116787:333:::0;;;;:::o;103019:315::-;103224:7;103280;103289:6;103297:9;103308:15;103269:55;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;103259:66;;;;;;103251:75;;103244:82;;103019:315;;;;;;:::o;122747:138::-;122810:13;122836:41;;;;;;;;;;;;;;;;;;;122747:138;:::o;98336:95::-;98378:53;98336:95;:::o;120375:132::-;100151:11;:9;:11::i;:::-;100135:27;;:12;:10;:12::i;:::-;:27;;;100127:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;100229:4;100206:28;;:11;:9;:11::i;:::-;:28;;;100202:281;;100251:19;100283:10;:8;:10::i;:::-;100273:21;;;;;;;:::i;:::-;;;;;;;;100251:43;;100420:52;100457:11;100427:26;:15;:24;:26::i;:::-;:41;100420:52;;100236:247;100202:281;120466:33:::1;120483:15;120466:16;:33::i;:::-;120375:132:::0;:::o;111755:178::-;111849:7;111876:49;111886:7;111895:11;111908:16;:14;:16::i;:::-;111876:9;:49::i;:::-;111869:56;;111755:178;;;;:::o;120699:152::-;100151:11;:9;:11::i;:::-;100135:27;;:12;:10;:12::i;:::-;:27;;;100127:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;100229:4;100206:28;;:11;:9;:11::i;:::-;:28;;;100202:281;;100251:19;100283:10;:8;:10::i;:::-;100273:21;;;;;;;:::i;:::-;;;;;;;;100251:43;;100420:52;100457:11;100427:26;:15;:24;:26::i;:::-;:41;100420:52;;100236:247;100202:281;120800:43:::1;120822:20;120800:21;:43::i;:::-;120699:152:::0;:::o;117781:227::-;117943:6;117969:31;;;117962:38;;117781:227;;;;;;;:::o;164063:100::-;164118:7;164145:10;164138:17;;164063:100;;;:::o;163282:37::-;;;:::o;33362:157::-;33447:4;33486:25;33471:40;;;:11;:40;;;;33464:47;;33362:157;;;:::o;119582:110::-;119644:7;119671:13;;119664:20;;119582:110;:::o;32421:167::-;32498:7;32525:55;32547:20;:18;:20::i;:::-;32569:10;32525:21;:55::i;:::-;32518:62;;32421:167;;;:::o;26164:279::-;26292:7;26313:17;26332:18;26354:25;26365:4;26371:1;26374;26377;26354:10;:25::i;:::-;26312:67;;;;26390:18;26402:5;26390:11;:18::i;:::-;26426:9;26419:16;;;;26164:279;;;;;;:::o;115539:789::-;115731:7;115751:29;115783:10;:22;115794:10;115783:22;;;;;;;;;;;115751:54;;115845:20;115824:41;;;;;;;;:::i;:::-;;:17;115830:10;115824:5;:17::i;:::-;:41;;;;;;;;:::i;:::-;;;115816:89;;;;;;;;;;;;:::i;:::-;;;;;;;;;115918:14;115935:60;115945:7;115954:32;:8;:18;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:32::i;:::-;115935:60;;115988:6;115935:9;:60::i;:::-;115918:77;;116006:56;116017:10;116029:7;116038;116047:6;116055;116006:10;:56::i;:::-;116096:1;116079:6;:13;:18;116075:220;;116128:7;116119:54;;;116137:10;116149:7;116158:6;116166;116119:54;;;;;;;;;:::i;:::-;;;;;;;;116075:220;;;116230:7;116211:72;;;116239:10;116251:7;116260:6;116268;116276;116211:72;;;;;;;;;;:::i;:::-;;;;;;;;116075:220;116314:6;116307:13;;;;115539:789;;;;;;;:::o;109755:513::-;110024:4;110001:28;;:11;:9;:11::i;:::-;:28;;;109997:264;;110051:9;110046:204;110070:7;:14;110066:1;:18;110046:204;;;110136:4;110114:27;;:7;110122:1;110114:10;;;;;;;;:::i;:::-;;;;;;;;:27;;;110110:125;;110166:49;110201:9;110211:1;110201:12;;;;;;;;:::i;:::-;;;;;;;;110191:23;;;;;;110166:15;:24;;:49;;;;:::i;:::-;110110:125;110086:3;;;;:::i;:::-;;;110046:204;;;;109997:264;109755:513;;;;;:::o;109127:553::-;109357:26;:70;;;;;;;;;;;;;;;;;;;109443:9;109438:235;109462:7;:14;109458:1;:18;109438:235;;;109499:12;109513:23;109540:7;109548:1;109540:10;;;;;;;;:::i;:::-;;;;;;;;:15;;109563:6;109570:1;109563:9;;;;;;;;:::i;:::-;;;;;;;;109574;109584:1;109574:12;;;;;;;;:::i;:::-;;;;;;;;109540:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109498:89;;;;109602:59;109627:7;109636:10;109648:12;109602:24;:59::i;:::-;;109483:190;;109478:3;;;;:::i;:::-;;;109438:235;;;;109346:334;109127:553;;;;;:::o;110342:408::-;110622:4;110599:28;;:11;:9;:11::i;:::-;:28;;;110595:148;;110649:23;:15;:21;:23::i;:::-;110644:88;;110693:23;:15;:21;:23::i;:::-;110644:88;110595:148;110342:408;;;;;:::o;86977:119::-;87047:6;87073:5;:15;;;87066:22;;86977:119;;;:::o;119405:108::-;119466:7;119493:12;;119486:19;;119405:108;:::o;114987:262::-;115149:7;115176:65;115186:10;115198:7;115207;115216:6;115224:16;:14;:16::i;:::-;115176:9;:65::i;:::-;115169:72;;114987:262;;;;;;:::o;123667:280::-;123751:4;123768:33;123804:14;:26;123819:10;123804:26;;;;;;;;;;;123768:62;;123914:12;:25;;;123890:12;:21;;;:49;;;;:::i;:::-;123850:36;123857:28;123874:10;123857:16;:28::i;:::-;123850:6;:36::i;:::-;:89;;123843:96;;;123667:280;;;:::o;124086:240::-;124170:4;124187:33;124223:14;:26;124238:10;124223:26;;;;;;;;;;;124187:62;;124293:12;:25;;;124269:12;:21;;;:49;124262:56;;;124086:240;;;:::o;85608:98::-;85661:7;85688:10;85681:17;;85608:98;:::o;85714:101::-;85765:14;;85799:8;;85792:15;;;;85714:101;;:::o;72973:332::-;73037:13;73067:12;73073:5;73067;:12::i;:::-;73063:32;;;73088:7;;;;;;;;;;;;;;73063:32;73106:17;73126:5;:12;;;;;;;;;;;;73106:32;;73157:5;:11;;:23;73169:10;73157:23;;;;;;;;;;;;;;;;73149:31;;73198:5;:11;;:23;73210:10;73198:23;;;;;;;;;;;;;;;73191:30;;;73285:1;73272:10;:14;73257:5;:12;;;:29;;;;;;;;;;;;;;;;;;;;73052:253;72973:332;;;:::o;120976:174::-;121058:44;121073:12;;121087:14;121058:44;;;;;;;:::i;:::-;;;;;;;;121128:14;121113:12;:29;;;;120976:174;:::o;87330:118::-;87396:4;87439:1;87420:5;:15;;;:20;;;87413:27;;87330:118;;;:::o;47107:190::-;47163:6;47199:16;47190:25;;:5;:25;;47182:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;47283:5;47269:20;;47107:190;;;:::o;87104:121::-;87208:9;87190:5;:15;;;:27;;;;;;;;;;;;;;;;;;87104:121;;:::o;163526:232::-;163682:7;163709:5;:19;;;163729:7;163738:11;163709:41;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;163702:48;;;;163526:232;;;;;:::o;119765:120::-;119832:7;119859:18;;119852:25;;119765:120;:::o;84140:305::-;84290:12;84319:7;84315:123;;;84350:10;84343:17;;;;84315:123;84393:33;84401:10;84413:12;84393:7;:33::i;:::-;84140:305;;;;;;:::o;121277:321::-;121440:1;121422:15;:19;121414:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;121501:47;121517:13;;121532:15;121501:47;;;;;;;:::i;:::-;;;;;;;;121575:15;121559:13;:31;;;;121277:321;:::o;106434:99::-;106491:12;106516:9;;;;;;;;;;;;;;106434:99;:::o;121735:216::-;121829:62;121850:18;;121870:20;121829:62;;;;;;;:::i;:::-;;;;;;;;121923:20;121902:18;:41;;;;121735:216;:::o;31194:314::-;31247:7;31288:12;31271:29;;31279:4;31271:29;;;:66;;;;;31321:16;31304:13;:33;31271:66;31267:234;;;31361:24;31354:31;;;;31267:234;31425:64;31447:10;31459:12;31473:15;31425:21;:64::i;:::-;31418:71;;31194:314;;:::o;27855:196::-;27948:7;28014:15;28031:10;27985:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;27975:68;;;;;;27968:75;;27855:196;;;;:::o;24505:1520::-;24636:7;24645:12;25570:66;25565:1;25557:10;;:79;25553:163;;;25669:1;25673:30;25653:51;;;;;;25553:163;25813:14;25830:24;25840:4;25846:1;25849;25852;25830:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25813:41;;25887:1;25869:20;;:6;:20;;;25865:103;;25922:1;25926:29;25906:50;;;;;;;25865:103;25988:6;25996:20;25980:37;;;;;24505:1520;;;;;;;;:::o;19897:521::-;19975:20;19966:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;19962:449;20012:7;19962:449;20073:29;20064:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;20060:351;;20119:34;;;;;;;;;;:::i;:::-;;;;;;;;20060:351;20184:35;20175:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;20171:240;;20236:41;;;;;;;;;;:::i;:::-;;;;;;;;20171:240;20308:30;20299:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;20295:116;;20355:44;;;;;;;;;;:::i;:::-;;;;;;;;20295:116;19897:521;;:::o;124471:833::-;124672:33;124708:14;:26;124723:10;124708:26;;;;;;;;;;;124672:62;;124756:12;:21;;:30;124778:7;124756:30;;;;;;;;;;;;;;;;;;;;;;;;;124755:31;124747:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;124874:4;124841:12;:21;;:30;124863:7;124841:30;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;124912:16;124906:23;;;;;;;;:::i;:::-;;124895:34;;:7;:34;;;124891:406;;124975:6;124946:12;:25;;;:35;;;;;;;:::i;:::-;;;;;;;;124891:406;;;125020:12;125014:19;;;;;;;;:::i;:::-;;125003:30;;:7;:30;;;124999:298;;125075:6;125050:12;:21;;;:31;;;;;;;:::i;:::-;;;;;;;;124999:298;;;125120:16;125114:23;;;;;;;;:::i;:::-;;125103:34;;:7;:34;;;125099:198;;125183:6;125154:12;:25;;;:35;;;;;;;:::i;:::-;;;;;;;;125099:198;;;125222:63;;;;;;;;;;:::i;:::-;;;;;;;;125099:198;124999:298;124891:406;124661:643;124471:833;;;;;:::o;71733:232::-;71814:16;71833:5;:10;;;;;;;;;;;;71814:29;;71879:5;71854;:11;;:22;71866:9;71854:22;;;;;;;;;;;;;;;:30;;;;71945:1;71933:9;:13;71920:5;:10;;;:26;;;;;;;;;;;;;;;;;;;;71803:162;71733:232;;:::o;75536:124::-;75602:4;75640:5;:12;;;;;;;;;;;;75626:26;;:5;:10;;;;;;;;;;;;:26;;;;75619:33;;75536:124;;;:::o;74899:112::-;74977:1;74962:5;:12;;;:16;;;;;;;;;;;;;;;;;;;;75002:1;74989:5;:10;;;:14;;;;;;;;;;;;;;;;;;;;74899:112;:::o;84453:552::-;84634:1;84614:10;:17;:21;84610:388;;;84846:10;84840:17;84903:15;84890:10;84886:2;84882:19;84875:44;84610:388;84973:12;84966:20;;;;;;;;;;;:::i;:::-;;;;;;;;31516:263;31660:7;31708:8;31718;31728:11;31741:13;31764:4;31697:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;31687:84;;;;;;31680:91;;31516:263;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:118::-;1688:24;1706:5;1688:24;:::i;:::-;1683:3;1676:37;1601:118;;:::o;1725:222::-;1818:4;1856:2;1845:9;1841:18;1833:26;;1869:71;1937:1;1926:9;1922:17;1913:6;1869:71;:::i;:::-;1725:222;;;;:::o;1953:122::-;2026:24;2044:5;2026:24;:::i;:::-;2019:5;2016:35;2006:63;;2065:1;2062;2055:12;2006:63;1953:122;:::o;2081:139::-;2127:5;2165:6;2152:20;2143:29;;2181:33;2208:5;2181:33;:::i;:::-;2081:139;;;;:::o;2226:86::-;2261:7;2301:4;2294:5;2290:16;2279:27;;2226:86;;;:::o;2318:118::-;2389:22;2405:5;2389:22;:::i;:::-;2382:5;2379:33;2369:61;;2426:1;2423;2416:12;2369:61;2318:118;:::o;2442:135::-;2486:5;2524:6;2511:20;2502:29;;2540:31;2565:5;2540:31;:::i;:::-;2442:135;;;;:::o;2583:117::-;2692:1;2689;2682:12;2706:117;2815:1;2812;2805:12;2829:117;2938:1;2935;2928:12;2966:553;3024:8;3034:6;3084:3;3077:4;3069:6;3065:17;3061:27;3051:122;;3092:79;;:::i;:::-;3051:122;3205:6;3192:20;3182:30;;3235:18;3227:6;3224:30;3221:117;;;3257:79;;:::i;:::-;3221:117;3371:4;3363:6;3359:17;3347:29;;3425:3;3417:4;3409:6;3405:17;3395:8;3391:32;3388:41;3385:128;;;3432:79;;:::i;:::-;3385:128;2966:553;;;;;:::o;3525:117::-;3634:1;3631;3624:12;3648:102;3689:6;3740:2;3736:7;3731:2;3724:5;3720:14;3716:28;3706:38;;3648:102;;;:::o;3756:180::-;3804:77;3801:1;3794:88;3901:4;3898:1;3891:15;3925:4;3922:1;3915:15;3942:281;4025:27;4047:4;4025:27;:::i;:::-;4017:6;4013:40;4155:6;4143:10;4140:22;4119:18;4107:10;4104:34;4101:62;4098:88;;;4166:18;;:::i;:::-;4098:88;4206:10;4202:2;4195:22;3985:238;3942:281;;:::o;4229:129::-;4263:6;4290:20;;:::i;:::-;4280:30;;4319:33;4347:4;4339:6;4319:33;:::i;:::-;4229:129;;;:::o;4364:307::-;4425:4;4515:18;4507:6;4504:30;4501:56;;;4537:18;;:::i;:::-;4501:56;4575:29;4597:6;4575:29;:::i;:::-;4567:37;;4659:4;4653;4649:15;4641:23;;4364:307;;;:::o;4677:146::-;4774:6;4769:3;4764;4751:30;4815:1;4806:6;4801:3;4797:16;4790:27;4677:146;;;:::o;4829:423::-;4906:5;4931:65;4947:48;4988:6;4947:48;:::i;:::-;4931:65;:::i;:::-;4922:74;;5019:6;5012:5;5005:21;5057:4;5050:5;5046:16;5095:3;5086:6;5081:3;5077:16;5074:25;5071:112;;;5102:79;;:::i;:::-;5071:112;5192:54;5239:6;5234:3;5229;5192:54;:::i;:::-;4912:340;4829:423;;;;;:::o;5271:338::-;5326:5;5375:3;5368:4;5360:6;5356:17;5352:27;5342:122;;5383:79;;:::i;:::-;5342:122;5500:6;5487:20;5525:78;5599:3;5591:6;5584:4;5576:6;5572:17;5525:78;:::i;:::-;5516:87;;5332:277;5271:338;;;;:::o;5615:77::-;5652:7;5681:5;5670:16;;5615:77;;;:::o;5698:122::-;5771:24;5789:5;5771:24;:::i;:::-;5764:5;5761:35;5751:63;;5810:1;5807;5800:12;5751:63;5698:122;:::o;5826:139::-;5872:5;5910:6;5897:20;5888:29;;5926:33;5953:5;5926:33;:::i;:::-;5826:139;;;;:::o;5971:1573::-;6101:6;6109;6117;6125;6133;6141;6149;6157;6206:3;6194:9;6185:7;6181:23;6177:33;6174:120;;;6213:79;;:::i;:::-;6174:120;6333:1;6358:53;6403:7;6394:6;6383:9;6379:22;6358:53;:::i;:::-;6348:63;;6304:117;6460:2;6486:51;6529:7;6520:6;6509:9;6505:22;6486:51;:::i;:::-;6476:61;;6431:116;6614:2;6603:9;6599:18;6586:32;6645:18;6637:6;6634:30;6631:117;;;6667:79;;:::i;:::-;6631:117;6780:65;6837:7;6828:6;6817:9;6813:22;6780:65;:::i;:::-;6762:83;;;;6557:298;6922:2;6911:9;6907:18;6894:32;6953:18;6945:6;6942:30;6939:117;;;6975:79;;:::i;:::-;6939:117;7080:62;7134:7;7125:6;7114:9;7110:22;7080:62;:::i;:::-;7070:72;;6865:287;7191:3;7218:51;7261:7;7252:6;7241:9;7237:22;7218:51;:::i;:::-;7208:61;;7162:117;7318:3;7345:53;7390:7;7381:6;7370:9;7366:22;7345:53;:::i;:::-;7335:63;;7289:119;7447:3;7474:53;7519:7;7510:6;7499:9;7495:22;7474:53;:::i;:::-;7464:63;;7418:119;5971:1573;;;;;;;;;;;:::o;7550:99::-;7602:6;7636:5;7630:12;7620:22;;7550:99;;;:::o;7655:169::-;7739:11;7773:6;7768:3;7761:19;7813:4;7808:3;7804:14;7789:29;;7655:169;;;;:::o;7830:246::-;7911:1;7921:113;7935:6;7932:1;7929:13;7921:113;;;8020:1;8015:3;8011:11;8005:18;8001:1;7996:3;7992:11;7985:39;7957:2;7954:1;7950:10;7945:15;;7921:113;;;8068:1;8059:6;8054:3;8050:16;8043:27;7892:184;7830:246;;;:::o;8082:377::-;8170:3;8198:39;8231:5;8198:39;:::i;:::-;8253:71;8317:6;8312:3;8253:71;:::i;:::-;8246:78;;8333:65;8391:6;8386:3;8379:4;8372:5;8368:16;8333:65;:::i;:::-;8423:29;8445:6;8423:29;:::i;:::-;8418:3;8414:39;8407:46;;8174:285;8082:377;;;;:::o;8465:313::-;8578:4;8616:2;8605:9;8601:18;8593:26;;8665:9;8659:4;8655:20;8651:1;8640:9;8636:17;8629:47;8693:78;8766:4;8757:6;8693:78;:::i;:::-;8685:86;;8465:313;;;;:::o;8784:126::-;8821:7;8861:42;8854:5;8850:54;8839:65;;8784:126;;;:::o;8916:96::-;8953:7;8982:24;9000:5;8982:24;:::i;:::-;8971:35;;8916:96;;;:::o;9018:122::-;9091:24;9109:5;9091:24;:::i;:::-;9084:5;9081:35;9071:63;;9130:1;9127;9120:12;9071:63;9018:122;:::o;9146:139::-;9192:5;9230:6;9217:20;9208:29;;9246:33;9273:5;9246:33;:::i;:::-;9146:139;;;;:::o;9291:943::-;9386:6;9394;9402;9410;9459:3;9447:9;9438:7;9434:23;9430:33;9427:120;;;9466:79;;:::i;:::-;9427:120;9586:1;9611:53;9656:7;9647:6;9636:9;9632:22;9611:53;:::i;:::-;9601:63;;9557:117;9713:2;9739:53;9784:7;9775:6;9764:9;9760:22;9739:53;:::i;:::-;9729:63;;9684:118;9841:2;9867:53;9912:7;9903:6;9892:9;9888:22;9867:53;:::i;:::-;9857:63;;9812:118;9997:2;9986:9;9982:18;9969:32;10028:18;10020:6;10017:30;10014:117;;;10050:79;;:::i;:::-;10014:117;10155:62;10209:7;10200:6;10189:9;10185:22;10155:62;:::i;:::-;10145:72;;9940:287;9291:943;;;;;;;:::o;10240:115::-;10325:23;10342:5;10325:23;:::i;:::-;10320:3;10313:36;10240:115;;:::o;10361:218::-;10452:4;10490:2;10479:9;10475:18;10467:26;;10503:69;10569:1;10558:9;10554:17;10545:6;10503:69;:::i;:::-;10361:218;;;;:::o;10585:311::-;10662:4;10752:18;10744:6;10741:30;10738:56;;;10774:18;;:::i;:::-;10738:56;10824:4;10816:6;10812:17;10804:25;;10884:4;10878;10874:15;10866:23;;10585:311;;;:::o;10919:710::-;11015:5;11040:81;11056:64;11113:6;11056:64;:::i;:::-;11040:81;:::i;:::-;11031:90;;11141:5;11170:6;11163:5;11156:21;11204:4;11197:5;11193:16;11186:23;;11257:4;11249:6;11245:17;11237:6;11233:30;11286:3;11278:6;11275:15;11272:122;;;11305:79;;:::i;:::-;11272:122;11420:6;11403:220;11437:6;11432:3;11429:15;11403:220;;;11512:3;11541:37;11574:3;11562:10;11541:37;:::i;:::-;11536:3;11529:50;11608:4;11603:3;11599:14;11592:21;;11479:144;11463:4;11458:3;11454:14;11447:21;;11403:220;;;11407:21;11021:608;;10919:710;;;;;:::o;11652:370::-;11723:5;11772:3;11765:4;11757:6;11753:17;11749:27;11739:122;;11780:79;;:::i;:::-;11739:122;11897:6;11884:20;11922:94;12012:3;12004:6;11997:4;11989:6;11985:17;11922:94;:::i;:::-;11913:103;;11729:293;11652:370;;;;:::o;12028:311::-;12105:4;12195:18;12187:6;12184:30;12181:56;;;12217:18;;:::i;:::-;12181:56;12267:4;12259:6;12255:17;12247:25;;12327:4;12321;12317:15;12309:23;;12028:311;;;:::o;12362:710::-;12458:5;12483:81;12499:64;12556:6;12499:64;:::i;:::-;12483:81;:::i;:::-;12474:90;;12584:5;12613:6;12606:5;12599:21;12647:4;12640:5;12636:16;12629:23;;12700:4;12692:6;12688:17;12680:6;12676:30;12729:3;12721:6;12718:15;12715:122;;;12748:79;;:::i;:::-;12715:122;12863:6;12846:220;12880:6;12875:3;12872:15;12846:220;;;12955:3;12984:37;13017:3;13005:10;12984:37;:::i;:::-;12979:3;12972:50;13051:4;13046:3;13042:14;13035:21;;12922:144;12906:4;12901:3;12897:14;12890:21;;12846:220;;;12850:21;12464:608;;12362:710;;;;;:::o;13095:370::-;13166:5;13215:3;13208:4;13200:6;13196:17;13192:27;13182:122;;13223:79;;:::i;:::-;13182:122;13340:6;13327:20;13365:94;13455:3;13447:6;13440:4;13432:6;13428:17;13365:94;:::i;:::-;13356:103;;13172:293;13095:370;;;;:::o;13471:320::-;13557:4;13647:18;13639:6;13636:30;13633:56;;;13669:18;;:::i;:::-;13633:56;13719:4;13711:6;13707:17;13699:25;;13779:4;13773;13769:15;13761:23;;13471:320;;;:::o;13812:942::-;13917:5;13942:90;13958:73;14024:6;13958:73;:::i;:::-;13942:90;:::i;:::-;13933:99;;14052:5;14081:6;14074:5;14067:21;14115:4;14108:5;14104:16;14097:23;;14168:4;14160:6;14156:17;14148:6;14144:30;14197:3;14189:6;14186:15;14183:122;;;14216:79;;:::i;:::-;14183:122;14331:6;14314:434;14348:6;14343:3;14340:15;14314:434;;;14437:3;14424:17;14473:18;14460:11;14457:35;14454:122;;;14495:79;;:::i;:::-;14454:122;14619:11;14611:6;14607:24;14657:46;14699:3;14687:10;14657:46;:::i;:::-;14652:3;14645:59;14733:4;14728:3;14724:14;14717:21;;14390:358;;14374:4;14369:3;14365:14;14358:21;;14314:434;;;14318:21;13923:831;;13812:942;;;;;:::o;14775:388::-;14855:5;14904:3;14897:4;14889:6;14885:17;14881:27;14871:122;;14912:79;;:::i;:::-;14871:122;15029:6;15016:20;15054:103;15153:3;15145:6;15138:4;15130:6;15126:17;15054:103;:::i;:::-;15045:112;;14861:302;14775:388;;;;:::o;15169:1413::-;15339:6;15347;15355;15363;15412:3;15400:9;15391:7;15387:23;15383:33;15380:120;;;15419:79;;:::i;:::-;15380:120;15567:1;15556:9;15552:17;15539:31;15597:18;15589:6;15586:30;15583:117;;;15619:79;;:::i;:::-;15583:117;15724:78;15794:7;15785:6;15774:9;15770:22;15724:78;:::i;:::-;15714:88;;15510:302;15879:2;15868:9;15864:18;15851:32;15910:18;15902:6;15899:30;15896:117;;;15932:79;;:::i;:::-;15896:117;16037:78;16107:7;16098:6;16087:9;16083:22;16037:78;:::i;:::-;16027:88;;15822:303;16192:2;16181:9;16177:18;16164:32;16223:18;16215:6;16212:30;16209:117;;;16245:79;;:::i;:::-;16209:117;16350:87;16429:7;16420:6;16409:9;16405:22;16350:87;:::i;:::-;16340:97;;16135:312;16486:2;16512:53;16557:7;16548:6;16537:9;16533:22;16512:53;:::i;:::-;16502:63;;16457:118;15169:1413;;;;;;;:::o;16588:329::-;16647:6;16696:2;16684:9;16675:7;16671:23;16667:32;16664:119;;;16702:79;;:::i;:::-;16664:119;16822:1;16847:53;16892:7;16883:6;16872:9;16868:22;16847:53;:::i;:::-;16837:63;;16793:117;16588:329;;;;:::o;16923:118::-;17010:24;17028:5;17010:24;:::i;:::-;17005:3;16998:37;16923:118;;:::o;17047:222::-;17140:4;17178:2;17167:9;17163:18;17155:26;;17191:71;17259:1;17248:9;17244:17;17235:6;17191:71;:::i;:::-;17047:222;;;;:::o;17275:903::-;17366:6;17374;17382;17390;17398;17447:3;17435:9;17426:7;17422:23;17418:33;17415:120;;;17454:79;;:::i;:::-;17415:120;17574:1;17599:53;17644:7;17635:6;17624:9;17620:22;17599:53;:::i;:::-;17589:63;;17545:117;17701:2;17727:51;17770:7;17761:6;17750:9;17746:22;17727:51;:::i;:::-;17717:61;;17672:116;17827:2;17853:51;17896:7;17887:6;17876:9;17872:22;17853:51;:::i;:::-;17843:61;;17798:116;17953:2;17979:53;18024:7;18015:6;18004:9;18000:22;17979:53;:::i;:::-;17969:63;;17924:118;18081:3;18108:53;18153:7;18144:6;18133:9;18129:22;18108:53;:::i;:::-;18098:63;;18052:119;17275:903;;;;;;;;:::o;18184:180::-;18232:77;18229:1;18222:88;18329:4;18326:1;18319:15;18353:4;18350:1;18343:15;18370:123;18461:1;18454:5;18451:12;18441:46;;18467:18;;:::i;:::-;18441:46;18370:123;:::o;18499:147::-;18554:7;18583:5;18572:16;;18589:51;18634:5;18589:51;:::i;:::-;18499:147;;;:::o;18652:::-;18718:9;18751:42;18787:5;18751:42;:::i;:::-;18738:55;;18652:147;;;:::o;18805:163::-;18908:53;18955:5;18908:53;:::i;:::-;18903:3;18896:66;18805:163;;:::o;18974:254::-;19083:4;19121:2;19110:9;19106:18;19098:26;;19134:87;19218:1;19207:9;19203:17;19194:6;19134:87;:::i;:::-;18974:254;;;;:::o;19234:474::-;19302:6;19310;19359:2;19347:9;19338:7;19334:23;19330:32;19327:119;;;19365:79;;:::i;:::-;19327:119;19485:1;19510:53;19555:7;19546:6;19535:9;19531:22;19510:53;:::i;:::-;19500:63;;19456:117;19612:2;19638:53;19683:7;19674:6;19663:9;19659:22;19638:53;:::i;:::-;19628:63;;19583:118;19234:474;;;;;:::o;19714:442::-;19863:4;19901:2;19890:9;19886:18;19878:26;;19914:71;19982:1;19971:9;19967:17;19958:6;19914:71;:::i;:::-;19995:72;20063:2;20052:9;20048:18;20039:6;19995:72;:::i;:::-;20077;20145:2;20134:9;20130:18;20121:6;20077:72;:::i;:::-;19714:442;;;;;;:::o;20162:470::-;20228:6;20236;20285:2;20273:9;20264:7;20260:23;20256:32;20253:119;;;20291:79;;:::i;:::-;20253:119;20411:1;20436:53;20481:7;20472:6;20461:9;20457:22;20436:53;:::i;:::-;20426:63;;20382:117;20538:2;20564:51;20607:7;20598:6;20587:9;20583:22;20564:51;:::i;:::-;20554:61;;20509:116;20162:470;;;;;:::o;20638:1139::-;20743:6;20751;20759;20767;20775;20824:3;20812:9;20803:7;20799:23;20795:33;20792:120;;;20831:79;;:::i;:::-;20792:120;20951:1;20976:53;21021:7;21012:6;21001:9;20997:22;20976:53;:::i;:::-;20966:63;;20922:117;21078:2;21104:51;21147:7;21138:6;21127:9;21123:22;21104:51;:::i;:::-;21094:61;;21049:116;21232:2;21221:9;21217:18;21204:32;21263:18;21255:6;21252:30;21249:117;;;21285:79;;:::i;:::-;21249:117;21398:65;21455:7;21446:6;21435:9;21431:22;21398:65;:::i;:::-;21380:83;;;;21175:298;21540:2;21529:9;21525:18;21512:32;21571:18;21563:6;21560:30;21557:117;;;21593:79;;:::i;:::-;21557:117;21698:62;21752:7;21743:6;21732:9;21728:22;21698:62;:::i;:::-;21688:72;;21483:287;20638:1139;;;;;;;;:::o;21783:815::-;21870:6;21878;21886;21894;21943:2;21931:9;21922:7;21918:23;21914:32;21911:119;;;21949:79;;:::i;:::-;21911:119;22069:1;22094:53;22139:7;22130:6;22119:9;22115:22;22094:53;:::i;:::-;22084:63;;22040:117;22196:2;22222:51;22265:7;22256:6;22245:9;22241:22;22222:51;:::i;:::-;22212:61;;22167:116;22350:2;22339:9;22335:18;22322:32;22381:18;22373:6;22370:30;22367:117;;;22403:79;;:::i;:::-;22367:117;22516:65;22573:7;22564:6;22553:9;22549:22;22516:65;:::i;:::-;22498:83;;;;22293:298;21783:815;;;;;;;:::o;22604:308::-;22666:4;22756:18;22748:6;22745:30;22742:56;;;22778:18;;:::i;:::-;22742:56;22816:29;22838:6;22816:29;:::i;:::-;22808:37;;22900:4;22894;22890:15;22882:23;;22604:308;;;:::o;22918:425::-;22996:5;23021:66;23037:49;23079:6;23037:49;:::i;:::-;23021:66;:::i;:::-;23012:75;;23110:6;23103:5;23096:21;23148:4;23141:5;23137:16;23186:3;23177:6;23172:3;23168:16;23165:25;23162:112;;;23193:79;;:::i;:::-;23162:112;23283:54;23330:6;23325:3;23320;23283:54;:::i;:::-;23002:341;22918:425;;;;;:::o;23363:340::-;23419:5;23468:3;23461:4;23453:6;23449:17;23445:27;23435:122;;23476:79;;:::i;:::-;23435:122;23593:6;23580:20;23618:79;23693:3;23685:6;23678:4;23670:6;23666:17;23618:79;:::i;:::-;23609:88;;23425:278;23363:340;;;;:::o;23709:1593::-;23889:6;23897;23905;23913;23962:3;23950:9;23941:7;23937:23;23933:33;23930:120;;;23969:79;;:::i;:::-;23930:120;24117:1;24106:9;24102:17;24089:31;24147:18;24139:6;24136:30;24133:117;;;24169:79;;:::i;:::-;24133:117;24274:78;24344:7;24335:6;24324:9;24320:22;24274:78;:::i;:::-;24264:88;;24060:302;24429:2;24418:9;24414:18;24401:32;24460:18;24452:6;24449:30;24446:117;;;24482:79;;:::i;:::-;24446:117;24587:78;24657:7;24648:6;24637:9;24633:22;24587:78;:::i;:::-;24577:88;;24372:303;24742:2;24731:9;24727:18;24714:32;24773:18;24765:6;24762:30;24759:117;;;24795:79;;:::i;:::-;24759:117;24900:87;24979:7;24970:6;24959:9;24955:22;24900:87;:::i;:::-;24890:97;;24685:312;25064:2;25053:9;25049:18;25036:32;25095:18;25087:6;25084:30;25081:117;;;25117:79;;:::i;:::-;25081:117;25222:63;25277:7;25268:6;25257:9;25253:22;25222:63;:::i;:::-;25212:73;;25007:288;23709:1593;;;;;;;:::o;25308:797::-;25394:6;25402;25410;25459:2;25447:9;25438:7;25434:23;25430:32;25427:119;;;25465:79;;:::i;:::-;25427:119;25585:1;25610:53;25655:7;25646:6;25635:9;25631:22;25610:53;:::i;:::-;25600:63;;25556:117;25712:2;25738:53;25783:7;25774:6;25763:9;25759:22;25738:53;:::i;:::-;25728:63;;25683:118;25868:2;25857:9;25853:18;25840:32;25899:18;25891:6;25888:30;25885:117;;;25921:79;;:::i;:::-;25885:117;26026:62;26080:7;26071:6;26060:9;26056:22;26026:62;:::i;:::-;26016:72;;25811:287;25308:797;;;;;:::o;26111:1509::-;26265:6;26273;26281;26289;26297;26346:3;26334:9;26325:7;26321:23;26317:33;26314:120;;;26353:79;;:::i;:::-;26314:120;26473:1;26498:53;26543:7;26534:6;26523:9;26519:22;26498:53;:::i;:::-;26488:63;;26444:117;26600:2;26626:53;26671:7;26662:6;26651:9;26647:22;26626:53;:::i;:::-;26616:63;;26571:118;26756:2;26745:9;26741:18;26728:32;26787:18;26779:6;26776:30;26773:117;;;26809:79;;:::i;:::-;26773:117;26914:78;26984:7;26975:6;26964:9;26960:22;26914:78;:::i;:::-;26904:88;;26699:303;27069:2;27058:9;27054:18;27041:32;27100:18;27092:6;27089:30;27086:117;;;27122:79;;:::i;:::-;27086:117;27227:78;27297:7;27288:6;27277:9;27273:22;27227:78;:::i;:::-;27217:88;;27012:303;27382:3;27371:9;27367:19;27354:33;27414:18;27406:6;27403:30;27400:117;;;27436:79;;:::i;:::-;27400:117;27541:62;27595:7;27586:6;27575:9;27571:22;27541:62;:::i;:::-;27531:72;;27325:288;26111:1509;;;;;;;;:::o;27639:552::-;27696:8;27706:6;27756:3;27749:4;27741:6;27737:17;27733:27;27723:122;;27764:79;;:::i;:::-;27723:122;27877:6;27864:20;27854:30;;27907:18;27899:6;27896:30;27893:117;;;27929:79;;:::i;:::-;27893:117;28043:4;28035:6;28031:17;28019:29;;28097:3;28089:4;28081:6;28077:17;28067:8;28063:32;28060:41;28057:128;;;28104:79;;:::i;:::-;28057:128;27639:552;;;;;:::o;28197:817::-;28285:6;28293;28301;28309;28358:2;28346:9;28337:7;28333:23;28329:32;28326:119;;;28364:79;;:::i;:::-;28326:119;28484:1;28509:53;28554:7;28545:6;28534:9;28530:22;28509:53;:::i;:::-;28499:63;;28455:117;28611:2;28637:53;28682:7;28673:6;28662:9;28658:22;28637:53;:::i;:::-;28627:63;;28582:118;28767:2;28756:9;28752:18;28739:32;28798:18;28790:6;28787:30;28784:117;;;28820:79;;:::i;:::-;28784:117;28933:64;28989:7;28980:6;28969:9;28965:22;28933:64;:::i;:::-;28915:82;;;;28710:297;28197:817;;;;;;;:::o;29020:474::-;29088:6;29096;29145:2;29133:9;29124:7;29120:23;29116:32;29113:119;;;29151:79;;:::i;:::-;29113:119;29271:1;29296:53;29341:7;29332:6;29321:9;29317:22;29296:53;:::i;:::-;29286:63;;29242:117;29398:2;29424:53;29469:7;29460:6;29449:9;29445:22;29424:53;:::i;:::-;29414:63;;29369:118;29020:474;;;;;:::o;29500:1089::-;29604:6;29612;29620;29628;29636;29685:3;29673:9;29664:7;29660:23;29656:33;29653:120;;;29692:79;;:::i;:::-;29653:120;29812:1;29837:53;29882:7;29873:6;29862:9;29858:22;29837:53;:::i;:::-;29827:63;;29783:117;29939:2;29965:53;30010:7;30001:6;29990:9;29986:22;29965:53;:::i;:::-;29955:63;;29910:118;30067:2;30093:53;30138:7;30129:6;30118:9;30114:22;30093:53;:::i;:::-;30083:63;;30038:118;30195:2;30221:53;30266:7;30257:6;30246:9;30242:22;30221:53;:::i;:::-;30211:63;;30166:118;30351:3;30340:9;30336:19;30323:33;30383:18;30375:6;30372:30;30369:117;;;30405:79;;:::i;:::-;30369:117;30510:62;30564:7;30555:6;30544:9;30540:22;30510:62;:::i;:::-;30500:72;;30294:288;29500:1089;;;;;;;;:::o;30595:60::-;30623:3;30644:5;30637:12;;30595:60;;;:::o;30661:142::-;30711:9;30744:53;30762:34;30771:24;30789:5;30771:24;:::i;:::-;30762:34;:::i;:::-;30744:53;:::i;:::-;30731:66;;30661:142;;;:::o;30809:126::-;30859:9;30892:37;30923:5;30892:37;:::i;:::-;30879:50;;30809:126;;;:::o;30941:149::-;31014:9;31047:37;31078:5;31047:37;:::i;:::-;31034:50;;30941:149;;;:::o;31096:177::-;31206:60;31260:5;31206:60;:::i;:::-;31201:3;31194:73;31096:177;;:::o;31279:268::-;31395:4;31433:2;31422:9;31418:18;31410:26;;31446:94;31537:1;31526:9;31522:17;31513:6;31446:94;:::i;:::-;31279:268;;;;:::o;31553:147::-;31654:11;31691:3;31676:18;;31553:147;;;;:::o;31728:327::-;31842:3;31863:88;31944:6;31939:3;31863:88;:::i;:::-;31856:95;;31961:56;32010:6;32005:3;31998:5;31961:56;:::i;:::-;32042:6;32037:3;32033:16;32026:23;;31728:327;;;;;:::o;32061:291::-;32201:3;32223:103;32322:3;32313:6;32305;32223:103;:::i;:::-;32216:110;;32343:3;32336:10;;32061:291;;;;;:::o;32358:112::-;32441:22;32457:5;32441:22;:::i;:::-;32436:3;32429:35;32358:112;;:::o;32476:656::-;32677:4;32715:3;32704:9;32700:19;32692:27;;32729:71;32797:1;32786:9;32782:17;32773:6;32729:71;:::i;:::-;32810:72;32878:2;32867:9;32863:18;32854:6;32810:72;:::i;:::-;32892:68;32956:2;32945:9;32941:18;32932:6;32892:68;:::i;:::-;32970:72;33038:2;33027:9;33023:18;33014:6;32970:72;:::i;:::-;33052:73;33120:3;33109:9;33105:19;33096:6;33052:73;:::i;:::-;32476:656;;;;;;;;:::o;33138:180::-;33186:77;33183:1;33176:88;33283:4;33280:1;33273:15;33307:4;33304:1;33297:15;33324:320;33368:6;33405:1;33399:4;33395:12;33385:22;;33452:1;33446:4;33442:12;33473:18;33463:81;;33529:4;33521:6;33517:17;33507:27;;33463:81;33591:2;33583:6;33580:14;33560:18;33557:38;33554:84;;33610:18;;:::i;:::-;33554:84;33375:269;33324:320;;;:::o;33650:220::-;33790:34;33786:1;33778:6;33774:14;33767:58;33859:3;33854:2;33846:6;33842:15;33835:28;33650:220;:::o;33876:366::-;34018:3;34039:67;34103:2;34098:3;34039:67;:::i;:::-;34032:74;;34115:93;34204:3;34115:93;:::i;:::-;34233:2;34228:3;34224:12;34217:19;;33876:366;;;:::o;34248:419::-;34414:4;34452:2;34441:9;34437:18;34429:26;;34501:9;34495:4;34491:20;34487:1;34476:9;34472:17;34465:47;34529:131;34655:4;34529:131;:::i;:::-;34521:139;;34248:419;;;:::o;34673:434::-;34818:4;34856:2;34845:9;34841:18;34833:26;;34869:71;34937:1;34926:9;34922:17;34913:6;34869:71;:::i;:::-;34950:72;35018:2;35007:9;35003:18;34994:6;34950:72;:::i;:::-;35032:68;35096:2;35085:9;35081:18;35072:6;35032:68;:::i;:::-;34673:434;;;;;;:::o;35113:179::-;35253:31;35249:1;35241:6;35237:14;35230:55;35113:179;:::o;35298:366::-;35440:3;35461:67;35525:2;35520:3;35461:67;:::i;:::-;35454:74;;35537:93;35626:3;35537:93;:::i;:::-;35655:2;35650:3;35646:12;35639:19;;35298:366;;;:::o;35670:419::-;35836:4;35874:2;35863:9;35859:18;35851:26;;35923:9;35917:4;35913:20;35909:1;35898:9;35894:17;35887:47;35951:131;36077:4;35951:131;:::i;:::-;35943:139;;35670:419;;;:::o;36095:174::-;36235:26;36231:1;36223:6;36219:14;36212:50;36095:174;:::o;36275:366::-;36417:3;36438:67;36502:2;36497:3;36438:67;:::i;:::-;36431:74;;36514:93;36603:3;36514:93;:::i;:::-;36632:2;36627:3;36623:12;36616:19;;36275:366;;;:::o;36647:419::-;36813:4;36851:2;36840:9;36836:18;36828:26;;36900:9;36894:4;36890:20;36886:1;36875:9;36871:17;36864:47;36928:131;37054:4;36928:131;:::i;:::-;36920:139;;36647:419;;;:::o;37072:180::-;37120:77;37117:1;37110:88;37217:4;37214:1;37207:15;37241:4;37238:1;37231:15;37258:194;37298:4;37318:20;37336:1;37318:20;:::i;:::-;37313:25;;37352:20;37370:1;37352:20;:::i;:::-;37347:25;;37396:1;37393;37389:9;37381:17;;37420:1;37414:4;37411:11;37408:37;;;37425:18;;:::i;:::-;37408:37;37258:194;;;;:::o;37458:236::-;37598:34;37594:1;37586:6;37582:14;37575:58;37667:19;37662:2;37654:6;37650:15;37643:44;37458:236;:::o;37700:366::-;37842:3;37863:67;37927:2;37922:3;37863:67;:::i;:::-;37856:74;;37939:93;38028:3;37939:93;:::i;:::-;38057:2;38052:3;38048:12;38041:19;;37700:366;;;:::o;38072:419::-;38238:4;38276:2;38265:9;38261:18;38253:26;;38325:9;38319:4;38315:20;38311:1;38300:9;38296:17;38289:47;38353:131;38479:4;38353:131;:::i;:::-;38345:139;;38072:419;;;:::o;38497:220::-;38637:34;38633:1;38625:6;38621:14;38614:58;38706:3;38701:2;38693:6;38689:15;38682:28;38497:220;:::o;38723:366::-;38865:3;38886:67;38950:2;38945:3;38886:67;:::i;:::-;38879:74;;38962:93;39051:3;38962:93;:::i;:::-;39080:2;39075:3;39071:12;39064:19;;38723:366;;;:::o;39095:419::-;39261:4;39299:2;39288:9;39284:18;39276:26;;39348:9;39342:4;39338:20;39334:1;39323:9;39319:17;39312:47;39376:131;39502:4;39376:131;:::i;:::-;39368:139;;39095:419;;;:::o;39520:174::-;39660:26;39656:1;39648:6;39644:14;39637:50;39520:174;:::o;39700:366::-;39842:3;39863:67;39927:2;39922:3;39863:67;:::i;:::-;39856:74;;39939:93;40028:3;39939:93;:::i;:::-;40057:2;40052:3;40048:12;40041:19;;39700:366;;;:::o;40072:419::-;40238:4;40276:2;40265:9;40261:18;40253:26;;40325:9;40319:4;40315:20;40311:1;40300:9;40296:17;40289:47;40353:131;40479:4;40353:131;:::i;:::-;40345:139;;40072:419;;;:::o;40497:220::-;40637:34;40633:1;40625:6;40621:14;40614:58;40706:3;40701:2;40693:6;40689:15;40682:28;40497:220;:::o;40723:366::-;40865:3;40886:67;40950:2;40945:3;40886:67;:::i;:::-;40879:74;;40962:93;41051:3;40962:93;:::i;:::-;41080:2;41075:3;41071:12;41064:19;;40723:366;;;:::o;41095:419::-;41261:4;41299:2;41288:9;41284:18;41276:26;;41348:9;41342:4;41338:20;41334:1;41323:9;41319:17;41312:47;41376:131;41502:4;41376:131;:::i;:::-;41368:139;;41095:419;;;:::o;41520:101::-;41556:7;41596:18;41589:5;41585:30;41574:41;;41520:101;;;:::o;41627:205::-;41666:3;41685:19;41702:1;41685:19;:::i;:::-;41680:24;;41718:19;41735:1;41718:19;:::i;:::-;41713:24;;41760:1;41757;41753:9;41746:16;;41783:18;41778:3;41775:27;41772:53;;;41805:18;;:::i;:::-;41772:53;41627:205;;;;:::o;41838:118::-;41925:24;41943:5;41925:24;:::i;:::-;41920:3;41913:37;41838:118;;:::o;41962:114::-;42029:6;42063:5;42057:12;42047:22;;41962:114;;;:::o;42082:184::-;42181:11;42215:6;42210:3;42203:19;42255:4;42250:3;42246:14;42231:29;;42082:184;;;;:::o;42272:132::-;42339:4;42362:3;42354:11;;42392:4;42387:3;42383:14;42375:22;;42272:132;;;:::o;42410:108::-;42487:24;42505:5;42487:24;:::i;:::-;42482:3;42475:37;42410:108;;:::o;42524:179::-;42593:10;42614:46;42656:3;42648:6;42614:46;:::i;:::-;42692:4;42687:3;42683:14;42669:28;;42524:179;;;;:::o;42709:113::-;42779:4;42811;42806:3;42802:14;42794:22;;42709:113;;;:::o;42858:732::-;42977:3;43006:54;43054:5;43006:54;:::i;:::-;43076:86;43155:6;43150:3;43076:86;:::i;:::-;43069:93;;43186:56;43236:5;43186:56;:::i;:::-;43265:7;43296:1;43281:284;43306:6;43303:1;43300:13;43281:284;;;43382:6;43376:13;43409:63;43468:3;43453:13;43409:63;:::i;:::-;43402:70;;43495:60;43548:6;43495:60;:::i;:::-;43485:70;;43341:224;43328:1;43325;43321:9;43316:14;;43281:284;;;43285:14;43581:3;43574:10;;42982:608;;;42858:732;;;;:::o;43596:114::-;43663:6;43697:5;43691:12;43681:22;;43596:114;;;:::o;43716:184::-;43815:11;43849:6;43844:3;43837:19;43889:4;43884:3;43880:14;43865:29;;43716:184;;;;:::o;43906:132::-;43973:4;43996:3;43988:11;;44026:4;44021:3;44017:14;44009:22;;43906:132;;;:::o;44044:108::-;44121:24;44139:5;44121:24;:::i;:::-;44116:3;44109:37;44044:108;;:::o;44158:179::-;44227:10;44248:46;44290:3;44282:6;44248:46;:::i;:::-;44326:4;44321:3;44317:14;44303:28;;44158:179;;;;:::o;44343:113::-;44413:4;44445;44440:3;44436:14;44428:22;;44343:113;;;:::o;44492:732::-;44611:3;44640:54;44688:5;44640:54;:::i;:::-;44710:86;44789:6;44784:3;44710:86;:::i;:::-;44703:93;;44820:56;44870:5;44820:56;:::i;:::-;44899:7;44930:1;44915:284;44940:6;44937:1;44934:13;44915:284;;;45016:6;45010:13;45043:63;45102:3;45087:13;45043:63;:::i;:::-;45036:70;;45129:60;45182:6;45129:60;:::i;:::-;45119:70;;44975:224;44962:1;44959;44955:9;44950:14;;44915:284;;;44919:14;45215:3;45208:10;;44616:608;;;44492:732;;;;:::o;45230:124::-;45307:6;45341:5;45335:12;45325:22;;45230:124;;;:::o;45360:194::-;45469:11;45503:6;45498:3;45491:19;45543:4;45538:3;45534:14;45519:29;;45360:194;;;;:::o;45560:142::-;45637:4;45660:3;45652:11;;45690:4;45685:3;45681:14;45673:22;;45560:142;;;:::o;45708:159::-;45782:11;45816:6;45811:3;45804:19;45856:4;45851:3;45847:14;45832:29;;45708:159;;;;:::o;45873:357::-;45951:3;45979:39;46012:5;45979:39;:::i;:::-;46034:61;46088:6;46083:3;46034:61;:::i;:::-;46027:68;;46104:65;46162:6;46157:3;46150:4;46143:5;46139:16;46104:65;:::i;:::-;46194:29;46216:6;46194:29;:::i;:::-;46189:3;46185:39;46178:46;;45955:275;45873:357;;;;:::o;46236:196::-;46325:10;46360:66;46422:3;46414:6;46360:66;:::i;:::-;46346:80;;46236:196;;;;:::o;46438:123::-;46518:4;46550;46545:3;46541:14;46533:22;;46438:123;;;:::o;46595:991::-;46734:3;46763:64;46821:5;46763:64;:::i;:::-;46843:96;46932:6;46927:3;46843:96;:::i;:::-;46836:103;;46965:3;47010:4;47002:6;46998:17;46993:3;46989:27;47040:66;47100:5;47040:66;:::i;:::-;47129:7;47160:1;47145:396;47170:6;47167:1;47164:13;47145:396;;;47241:9;47235:4;47231:20;47226:3;47219:33;47292:6;47286:13;47320:84;47399:4;47384:13;47320:84;:::i;:::-;47312:92;;47427:70;47490:6;47427:70;:::i;:::-;47417:80;;47526:4;47521:3;47517:14;47510:21;;47205:336;47192:1;47189;47185:9;47180:14;;47145:396;;;47149:14;47557:4;47550:11;;47577:3;47570:10;;46739:847;;;;;46595:991;;;;:::o;47592:123::-;47668:6;47702:5;47696:12;47686:22;;47592:123;;;:::o;47721:193::-;47829:11;47863:6;47858:3;47851:19;47903:4;47898:3;47894:14;47879:29;;47721:193;;;;:::o;47920:141::-;47996:4;48019:3;48011:11;;48049:4;48044:3;48040:14;48032:22;;47920:141;;;:::o;48067:98::-;48118:6;48152:5;48146:12;48136:22;;48067:98;;;:::o;48171:158::-;48244:11;48278:6;48273:3;48266:19;48318:4;48313:3;48309:14;48294:29;;48171:158;;;;:::o;48335:353::-;48411:3;48439:38;48471:5;48439:38;:::i;:::-;48493:60;48546:6;48541:3;48493:60;:::i;:::-;48486:67;;48562:65;48620:6;48615:3;48608:4;48601:5;48597:16;48562:65;:::i;:::-;48652:29;48674:6;48652:29;:::i;:::-;48647:3;48643:39;48636:46;;48415:273;48335:353;;;;:::o;48694:192::-;48781:10;48816:64;48876:3;48868:6;48816:64;:::i;:::-;48802:78;;48694:192;;;;:::o;48892:122::-;48971:4;49003;48998:3;48994:14;48986:22;;48892:122;;;:::o;49046:983::-;49183:3;49212:63;49269:5;49212:63;:::i;:::-;49291:95;49379:6;49374:3;49291:95;:::i;:::-;49284:102;;49412:3;49457:4;49449:6;49445:17;49440:3;49436:27;49487:65;49546:5;49487:65;:::i;:::-;49575:7;49606:1;49591:393;49616:6;49613:1;49610:13;49591:393;;;49687:9;49681:4;49677:20;49672:3;49665:33;49738:6;49732:13;49766:82;49843:4;49828:13;49766:82;:::i;:::-;49758:90;;49871:69;49933:6;49871:69;:::i;:::-;49861:79;;49969:4;49964:3;49960:14;49953:21;;49651:333;49638:1;49635;49631:9;49626:14;;49591:393;;;49595:14;50000:4;49993:11;;50020:3;50013:10;;49188:841;;;;;49046:983;;;;:::o;50035:140::-;50084:9;50117:52;50135:33;50144:23;50161:5;50144:23;:::i;:::-;50135:33;:::i;:::-;50117:52;:::i;:::-;50104:65;;50035:140;;;:::o;50181:129::-;50267:36;50297:5;50267:36;:::i;:::-;50262:3;50255:49;50181:129;;:::o;50316:1875::-;50889:4;50927:3;50916:9;50912:19;50904:27;;50941:71;51009:1;50998:9;50994:17;50985:6;50941:71;:::i;:::-;51022:72;51090:2;51079:9;51075:18;51066:6;51022:72;:::i;:::-;51141:9;51135:4;51131:20;51126:2;51115:9;51111:18;51104:48;51169:108;51272:4;51263:6;51169:108;:::i;:::-;51161:116;;51324:9;51318:4;51314:20;51309:2;51298:9;51294:18;51287:48;51352:108;51455:4;51446:6;51352:108;:::i;:::-;51344:116;;51508:9;51502:4;51498:20;51492:3;51481:9;51477:19;51470:49;51536:128;51659:4;51650:6;51536:128;:::i;:::-;51528:136;;51712:9;51706:4;51702:20;51696:3;51685:9;51681:19;51674:49;51740:126;51861:4;51852:6;51740:126;:::i;:::-;51732:134;;51876:72;51943:3;51932:9;51928:19;51919:6;51876:72;:::i;:::-;51958;52025:3;52014:9;52010:19;52001:6;51958:72;:::i;:::-;52078:9;52072:4;52068:20;52062:3;52051:9;52047:19;52040:49;52106:78;52179:4;52170:6;52106:78;:::i;:::-;52098:86;;50316:1875;;;;;;;;;;;;:::o;52197:1042::-;52542:4;52580:3;52569:9;52565:19;52557:27;;52630:9;52624:4;52620:20;52616:1;52605:9;52601:17;52594:47;52658:108;52761:4;52752:6;52658:108;:::i;:::-;52650:116;;52813:9;52807:4;52803:20;52798:2;52787:9;52783:18;52776:48;52841:108;52944:4;52935:6;52841:108;:::i;:::-;52833:116;;52996:9;52990:4;52986:20;52981:2;52970:9;52966:18;52959:48;53024:126;53145:4;53136:6;53024:126;:::i;:::-;53016:134;;53160:72;53228:2;53217:9;53213:18;53204:6;53160:72;:::i;:::-;52197:1042;;;;;;;:::o;53245:222::-;53385:34;53381:1;53373:6;53369:14;53362:58;53454:5;53449:2;53441:6;53437:15;53430:30;53245:222;:::o;53473:366::-;53615:3;53636:67;53700:2;53695:3;53636:67;:::i;:::-;53629:74;;53712:93;53801:3;53712:93;:::i;:::-;53830:2;53825:3;53821:12;53814:19;;53473:366;;;:::o;53845:419::-;54011:4;54049:2;54038:9;54034:18;54026:26;;54098:9;54092:4;54088:20;54084:1;54073:9;54069:17;54062:47;54126:131;54252:4;54126:131;:::i;:::-;54118:139;;53845:419;;;:::o;54270:636::-;54463:4;54501:3;54490:9;54486:19;54478:27;;54515:71;54583:1;54572:9;54568:17;54559:6;54515:71;:::i;:::-;54596:68;54660:2;54649:9;54645:18;54636:6;54596:68;:::i;:::-;54674:72;54742:2;54731:9;54727:18;54718:6;54674:72;:::i;:::-;54793:9;54787:4;54783:20;54778:2;54767:9;54763:18;54756:48;54821:78;54894:4;54885:6;54821:78;:::i;:::-;54813:86;;54270:636;;;;;;;:::o;54912:168::-;54995:11;55029:6;55024:3;55017:19;55069:4;55064:3;55060:14;55045:29;;54912:168;;;;:::o;55086:373::-;55172:3;55200:38;55232:5;55200:38;:::i;:::-;55254:70;55317:6;55312:3;55254:70;:::i;:::-;55247:77;;55333:65;55391:6;55386:3;55379:4;55372:5;55368:16;55333:65;:::i;:::-;55423:29;55445:6;55423:29;:::i;:::-;55418:3;55414:39;55407:46;;55176:283;55086:373;;;;:::o;55465:834::-;55704:4;55742:3;55731:9;55727:19;55719:27;;55756:71;55824:1;55813:9;55809:17;55800:6;55756:71;:::i;:::-;55837:68;55901:2;55890:9;55886:18;55877:6;55837:68;:::i;:::-;55915:72;55983:2;55972:9;55968:18;55959:6;55915:72;:::i;:::-;56034:9;56028:4;56024:20;56019:2;56008:9;56004:18;55997:48;56062:78;56135:4;56126:6;56062:78;:::i;:::-;56054:86;;56188:9;56182:4;56178:20;56172:3;56161:9;56157:19;56150:49;56216:76;56287:4;56278:6;56216:76;:::i;:::-;56208:84;;55465:834;;;;;;;;:::o;56305:180::-;56353:77;56350:1;56343:88;56450:4;56447:1;56440:15;56474:4;56471:1;56464:15;56491:233;56530:3;56553:24;56571:5;56553:24;:::i;:::-;56544:33;;56599:66;56592:5;56589:77;56586:103;;56669:18;;:::i;:::-;56586:103;56716:1;56709:5;56705:13;56698:20;;56491:233;;;:::o;56730:386::-;56834:3;56862:38;56894:5;56862:38;:::i;:::-;56916:88;56997:6;56992:3;56916:88;:::i;:::-;56909:95;;57013:65;57071:6;57066:3;57059:4;57052:5;57048:16;57013:65;:::i;:::-;57103:6;57098:3;57094:16;57087:23;;56838:278;56730:386;;;;:::o;57122:271::-;57252:3;57274:93;57363:3;57354:6;57274:93;:::i;:::-;57267:100;;57384:3;57377:10;;57122:271;;;;:::o;57399:191::-;57439:3;57458:20;57476:1;57458:20;:::i;:::-;57453:25;;57492:20;57510:1;57492:20;:::i;:::-;57487:25;;57535:1;57532;57528:9;57521:16;;57556:3;57553:1;57550:10;57547:36;;;57563:18;;:::i;:::-;57547:36;57399:191;;;;:::o;57596:332::-;57717:4;57755:2;57744:9;57740:18;57732:26;;57768:71;57836:1;57825:9;57821:17;57812:6;57768:71;:::i;:::-;57849:72;57917:2;57906:9;57902:18;57893:6;57849:72;:::i;:::-;57596:332;;;;;:::o;57934:225::-;58074:34;58070:1;58062:6;58058:14;58051:58;58143:8;58138:2;58130:6;58126:15;58119:33;57934:225;:::o;58165:366::-;58307:3;58328:67;58392:2;58387:3;58328:67;:::i;:::-;58321:74;;58404:93;58493:3;58404:93;:::i;:::-;58522:2;58517:3;58513:12;58506:19;;58165:366;;;:::o;58537:419::-;58703:4;58741:2;58730:9;58726:18;58718:26;;58790:9;58784:4;58780:20;58776:1;58765:9;58761:17;58754:47;58818:131;58944:4;58818:131;:::i;:::-;58810:139;;58537:419;;;:::o;58962:332::-;59083:4;59121:2;59110:9;59106:18;59098:26;;59134:71;59202:1;59191:9;59187:17;59178:6;59134:71;:::i;:::-;59215:72;59283:2;59272:9;59268:18;59259:6;59215:72;:::i;:::-;58962:332;;;;;:::o;59300:109::-;59336:7;59376:26;59369:5;59365:38;59354:49;;59300:109;;;:::o;59415:120::-;59487:23;59504:5;59487:23;:::i;:::-;59480:5;59477:34;59467:62;;59525:1;59522;59515:12;59467:62;59415:120;:::o;59541:141::-;59597:5;59628:6;59622:13;59613:22;;59644:32;59670:5;59644:32;:::i;:::-;59541:141;;;;:::o;59688:349::-;59757:6;59806:2;59794:9;59785:7;59781:23;59777:32;59774:119;;;59812:79;;:::i;:::-;59774:119;59932:1;59957:63;60012:7;60003:6;59992:9;59988:22;59957:63;:::i;:::-;59947:73;;59903:127;59688:349;;;;:::o;60043:226::-;60183:34;60179:1;60171:6;60167:14;60160:58;60252:9;60247:2;60239:6;60235:15;60228:34;60043:226;:::o;60275:366::-;60417:3;60438:67;60502:2;60497:3;60438:67;:::i;:::-;60431:74;;60514:93;60603:3;60514:93;:::i;:::-;60632:2;60627:3;60623:12;60616:19;;60275:366;;;:::o;60647:419::-;60813:4;60851:2;60840:9;60836:18;60828:26;;60900:9;60894:4;60890:20;60886:1;60875:9;60871:17;60864:47;60928:131;61054:4;60928:131;:::i;:::-;60920:139;;60647:419;;;:::o;61072:148::-;61174:11;61211:3;61196:18;;61072:148;;;;:::o;61226:214::-;61366:66;61362:1;61354:6;61350:14;61343:90;61226:214;:::o;61446:400::-;61606:3;61627:84;61709:1;61704:3;61627:84;:::i;:::-;61620:91;;61720:93;61809:3;61720:93;:::i;:::-;61838:1;61833:3;61829:11;61822:18;;61446:400;;;:::o;61852:79::-;61891:7;61920:5;61909:16;;61852:79;;;:::o;61937:157::-;62042:45;62062:24;62080:5;62062:24;:::i;:::-;62042:45;:::i;:::-;62037:3;62030:58;61937:157;;:::o;62100:663::-;62341:3;62363:148;62507:3;62363:148;:::i;:::-;62356:155;;62521:75;62592:3;62583:6;62521:75;:::i;:::-;62621:2;62616:3;62612:12;62605:19;;62634:75;62705:3;62696:6;62634:75;:::i;:::-;62734:2;62729:3;62725:12;62718:19;;62754:3;62747:10;;62100:663;;;;;:::o;62769:545::-;62942:4;62980:3;62969:9;62965:19;62957:27;;62994:71;63062:1;63051:9;63047:17;63038:6;62994:71;:::i;:::-;63075:68;63139:2;63128:9;63124:18;63115:6;63075:68;:::i;:::-;63153:72;63221:2;63210:9;63206:18;63197:6;63153:72;:::i;:::-;63235;63303:2;63292:9;63288:18;63279:6;63235:72;:::i;:::-;62769:545;;;;;;;:::o;63320:174::-;63460:26;63456:1;63448:6;63444:14;63437:50;63320:174;:::o;63500:366::-;63642:3;63663:67;63727:2;63722:3;63663:67;:::i;:::-;63656:74;;63739:93;63828:3;63739:93;:::i;:::-;63857:2;63852:3;63848:12;63841:19;;63500:366;;;:::o;63872:419::-;64038:4;64076:2;64065:9;64061:18;64053:26;;64125:9;64119:4;64115:20;64111:1;64100:9;64096:17;64089:47;64153:131;64279:4;64153:131;:::i;:::-;64145:139;;63872:419;;;:::o;64297:181::-;64437:33;64433:1;64425:6;64421:14;64414:57;64297:181;:::o;64484:366::-;64626:3;64647:67;64711:2;64706:3;64647:67;:::i;:::-;64640:74;;64723:93;64812:3;64723:93;:::i;:::-;64841:2;64836:3;64832:12;64825:19;;64484:366;;;:::o;64856:419::-;65022:4;65060:2;65049:9;65045:18;65037:26;;65109:9;65103:4;65099:20;65095:1;65084:9;65080:17;65073:47;65137:131;65263:4;65137:131;:::i;:::-;65129:139;;64856:419;;;:::o;65281:221::-;65421:34;65417:1;65409:6;65405:14;65398:58;65490:4;65485:2;65477:6;65473:15;65466:29;65281:221;:::o;65508:366::-;65650:3;65671:67;65735:2;65730:3;65671:67;:::i;:::-;65664:74;;65747:93;65836:3;65747:93;:::i;:::-;65865:2;65860:3;65856:12;65849:19;;65508:366;;;:::o;65880:419::-;66046:4;66084:2;66073:9;66069:18;66061:26;;66133:9;66127:4;66123:20;66119:1;66108:9;66104:17;66097:47;66161:131;66287:4;66161:131;:::i;:::-;66153:139;;65880:419;;;:::o;66305:226::-;66445:34;66441:1;66433:6;66429:14;66422:58;66514:9;66509:2;66501:6;66497:15;66490:34;66305:226;:::o;66537:366::-;66679:3;66700:67;66764:2;66759:3;66700:67;:::i;:::-;66693:74;;66776:93;66865:3;66776:93;:::i;:::-;66894:2;66889:3;66885:12;66878:19;;66537:366;;;:::o;66909:419::-;67075:4;67113:2;67102:9;67098:18;67090:26;;67162:9;67156:4;67152:20;67148:1;67137:9;67133:17;67126:47;67190:131;67316:4;67190:131;:::i;:::-;67182:139;;66909:419;;;:::o;67334:240::-;67474:34;67470:1;67462:6;67458:14;67451:58;67543:23;67538:2;67530:6;67526:15;67519:48;67334:240;:::o;67580:366::-;67722:3;67743:67;67807:2;67802:3;67743:67;:::i;:::-;67736:74;;67819:93;67908:3;67819:93;:::i;:::-;67937:2;67932:3;67928:12;67921:19;;67580:366;;;:::o;67952:419::-;68118:4;68156:2;68145:9;68141:18;68133:26;;68205:9;68199:4;68195:20;68191:1;68180:9;68176:17;68169:47;68233:131;68359:4;68233:131;:::i;:::-;68225:139;;67952:419;;;:::o;68377:664::-;68582:4;68620:3;68609:9;68605:19;68597:27;;68634:71;68702:1;68691:9;68687:17;68678:6;68634:71;:::i;:::-;68715:72;68783:2;68772:9;68768:18;68759:6;68715:72;:::i;:::-;68797;68865:2;68854:9;68850:18;68841:6;68797:72;:::i;:::-;68879;68947:2;68936:9;68932:18;68923:6;68879:72;:::i;:::-;68961:73;69029:3;69018:9;69014:19;69005:6;68961:73;:::i;:::-;68377:664;;;;;;;;:::o
Swarm Source
ipfs://07d0065dfa1b0b6d01e855d84d3bda7886cec984eb729e8e1da32f15f3ffd0d5
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.