NFT
Overview
TokenID
8802
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
EarthOnChain
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-09-24 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/Context.sol pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts/introspection/IERC165.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol pragma solidity >=0.6.2 <0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; } // File: @openzeppelin/contracts/token/ERC721/IERC721Metadata.sol pragma solidity >=0.6.2 <0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol pragma solidity >=0.6.2 <0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol pragma solidity >=0.6.0 <0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); } // File: @openzeppelin/contracts/introspection/ERC165.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () internal { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } } // File: @openzeppelin/contracts/math/SafeMath.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when 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. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } } // File: @openzeppelin/contracts/utils/Address.sol pragma solidity >=0.6.2 <0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/utils/EnumerableSet.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File: @openzeppelin/contracts/utils/EnumerableMap.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct MapEntry { bytes32 _key; bytes32 _value; } struct Map { // Storage of map keys and values MapEntry[] _entries; // Position of the entry defined by a key in the `entries` array, plus 1 // because index 0 means a key is not in the map. mapping (bytes32 => uint256) _indexes; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) { // Equivalent to !contains(map, key) map._entries.push(MapEntry({ _key: key, _value: value })); // The entry is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value map._indexes[key] = map._entries.length; return true; } else { map._entries[keyIndex - 1]._value = value; return false; } } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex != 0) { // Equivalent to contains(map, key) // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one // in the array, and then remove the last entry (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = keyIndex - 1; uint256 lastIndex = map._entries.length - 1; // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. MapEntry storage lastEntry = map._entries[lastIndex]; // Move the last entry to the index where the entry to delete is map._entries[toDeleteIndex] = lastEntry; // Update the index for the moved entry map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved entry was stored map._entries.pop(); // Delete the index for the deleted slot delete map._indexes[key]; return true; } else { return false; } } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._indexes[key] != 0; } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._entries.length; } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { require(map._entries.length > index, "EnumerableMap: index out of bounds"); MapEntry storage entry = map._entries[index]; return (entry._key, entry._value); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key) return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {_tryGet}. */ function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } } // File: @openzeppelin/contracts/utils/Strings.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev String operations. */ library Strings { /** * @dev Converts a `uint256` to its ASCII `string` representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); uint256 index = digits - 1; temp = value; while (temp != 0) { buffer[index--] = bytes1(uint8(48 + temp % 10)); temp /= 10; } return string(buffer); } } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol pragma solidity >=0.6.0 <0.8.0; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using SafeMath for uint256; using Address for address; using EnumerableSet for EnumerableSet.UintSet; using EnumerableMap for EnumerableMap.UintToAddressMap; using Strings for uint256; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from holder address to their (enumerable) set of owned tokens mapping (address => EnumerableSet.UintSet) private _holderTokens; // Enumerable mapping from token ids to their owners EnumerableMap.UintToAddressMap private _tokenOwners; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; // Token name string private _name; // Token symbol string private _symbol; // Optional mapping for token URIs mapping (uint256 => string) private _tokenURIs; // Base URI string private _baseURI; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor (string memory name_, string memory symbol_) public { _name = name_; _symbol = symbol_; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); _registerInterface(_INTERFACE_ID_ERC721_METADATA); _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _holderTokens[owner].length(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI. return string(abi.encodePacked(base, tokenId.toString())); } /** * @dev Returns the base URI set via {_setBaseURI}. This will be * automatically added as a prefix in {tokenURI} to each token's URI, or * to the token ID if no specific URI is set for that token ID. */ function baseURI() public view virtual returns (string memory) { return _baseURI; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { return _holderTokens[owner].at(index); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds return _tokenOwners.length(); } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { (uint256 tokenId, ) = _tokenOwners.at(index); return tokenId; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _tokenOwners.contains(tokenId); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: d* * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); // internal owner _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); // Clear metadata (if any) if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } _holderTokens[owner].remove(tokenId); _tokenOwners.remove(tokenId); emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _holderTokens[from].remove(tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(from, to, tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev Internal function to set the base URI for all token IDs. It is * automatically added as a prefix to the value returned in {tokenURI}, * or to the token ID if {tokenURI} is empty. */ function _setBaseURI(string memory baseURI_) internal virtual { _baseURI = baseURI_; } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) { if (!to.isContract()) { return true; } bytes memory returndata = to.functionCall(abi.encodeWithSelector( IERC721Receiver(to).onERC721Received.selector, _msgSender(), from, tokenId, _data ), "ERC721: transfer to non ERC721Receiver implementer"); bytes4 retval = abi.decode(returndata, (bytes4)); return (retval == _ERC721_RECEIVED); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { } } // File: @openzeppelin/contracts/access/Ownable.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } pragma solidity ^0.7.0 < 0.8.0; /// @title Base64 /// @author Brecht Devos - <[email protected]> /// @notice Provides a function for encoding some bytes in base64 library Base64 { string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function encode(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; // load the table into memory string memory table = TABLE; // multiply by 4/3 rounded up uint256 encodedLen = 4 * ((data.length + 2) / 3); // add some extra buffer at the end required for the writing string memory result = new string(encodedLen + 32); assembly { // set the actual output length mstore(result, encodedLen) // prepare the lookup table let tablePtr := add(table, 1) // input ptr let dataPtr := data let endPtr := add(dataPtr, mload(data)) // result ptr, jump over length let resultPtr := add(result, 32) // run over the input, 3 bytes at a time for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) // read 3 bytes let input := mload(dataPtr) // write 4 characters mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F))))) resultPtr := add(resultPtr, 1) } // padding with '=' switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } } pragma solidity ^0.7.0; pragma abicoder v2; contract EarthOnChain is ERC721, Ownable { using SafeMath for uint256; string public constant LICENSE_TEXT = "MIT"; bool public saleIsActive = false; bool public enforceOnePerWallet = true; uint256 public constant MAX_NFT = 10000; uint256 public constant MAX_LAT = 90; uint256 public constant MAX_LONG = 180; uint256 public nftReserve = 100; mapping (address => bool) public Minted; constructor() ERC721("Earth OnChain", "EOC") { } function random(uint _id) internal pure returns (uint256) { return uint256(keccak256(abi.encodePacked(uint2str(_id)))); } // https://etherscan.io/address/0x05a46f1e545526fb803ff974c790acea34d1f2d6#code#F11#L14 function uint2str(uint value) internal pure returns (string memory) { if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } function getLat(uint _id) internal pure returns (string memory) { uint rand = random((_id + 1) * 2); uint number = rand % (MAX_LAT * 2); uint tmp; string memory operator = ''; if (number > MAX_LAT) { operator = '-'; tmp = number - MAX_LAT; } else { tmp = number; } return string(abi.encodePacked(operator, uint2str(tmp), '.', getLatFloat(_id))); } function getLatFloat(uint256 _id) internal pure returns (string memory) { return uint2str(getFloat((_id + 1) * 2)); } function getLong(uint _id) internal pure returns (string memory) { uint rand = random((_id + 1) * 3); uint number = rand % (MAX_LONG * 2); uint tmp; string memory operator = ''; if (number > MAX_LONG) { operator = '-'; tmp = number - MAX_LONG; } else { tmp = number; } return string(abi.encodePacked(operator, uint2str(tmp), '.', getLongFloat(_id))); } function getLongFloat(uint256 _id) internal pure returns (string memory) { return uint2str(getFloat((_id + 1) * 3)); } function getFloat(uint256 _number) internal pure returns (uint256) { uint256 rand = uint256(keccak256(abi.encodePacked(uint2str(_number), uint2str(random(_number))))); return rand % 99999; } function tokenURI(uint256 _id) public view virtual override(ERC721) returns (string memory) { require(_id <= totalSupply(), "This token ID does not exist."); string memory lat = getLat(_id); string memory long = getLong(_id); string memory image = Base64.encode(bytes(generateSVGImage(lat, long))); return string( abi.encodePacked( 'data:application/json;base64,', Base64.encode( bytes( abi.encodePacked( '{', '"image":"', 'data:image/svg+xml;base64,', image, '",', '"description": "Your latitude and longitude stored on chain",', '"attributes":[', '{', '"trait_type": "Latitude",', '"value": "', lat, '"', '},', '{', '"trait_type": "Longitude",', '"value": "', long, '"', '}', ']', '}' ) ) ) ) ); } function generateSVGImage(string memory lat, string memory long) internal pure returns (string memory) { return string( abi.encodePacked( '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 350 350"><style>.base { fill: white; font-family: serif; font-size: 20px; }</style><rect width="100%" height="100%" fill="black"/>', '<text x="10" y="187" class="base">Latitude: ', lat, ' °</text>', '<text x="10" y="210" class="base">Longitude: ', long, ' °</text>', '</svg>' ) ); } function withdraw() public onlyOwner { uint balance = address(this).balance; msg.sender.transfer(balance); } function reserveNft(address _to, uint256 _reserveAmount) public onlyOwner { uint supply = totalSupply(); require(_reserveAmount > 0 && _reserveAmount <= nftReserve, "Not enough reserve left for team"); for (uint i = 0; i < _reserveAmount; i++) { _safeMint(_to, supply + i); } nftReserve = nftReserve.sub(_reserveAmount); } function setBaseURI(string memory baseURI) public onlyOwner { } function flipSaleState() public onlyOwner { saleIsActive = !saleIsActive; } function flipEnforceOnePerWallet() public onlyOwner { enforceOnePerWallet = !enforceOnePerWallet; } function tokensOfOwner(address _owner) external view returns(uint256[] memory ) { uint256 tokenCount = balanceOf(_owner); if (tokenCount == 0) { // Return an empty array return new uint256[](0); } else { uint256[] memory result = new uint256[](tokenCount); uint256 index; for (index = 0; index < tokenCount; index++) { result[index] = tokenOfOwnerByIndex(_owner, index); } return result; } } function tokenLicense() public pure returns(string memory) { return LICENSE_TEXT; } function mintNFT() public payable { require(saleIsActive, "Sale must be active to mint NFT"); require(totalSupply().add(1) <= MAX_NFT, "Purchase would exceed max supply of NFTs"); if (enforceOnePerWallet) { require(!Minted[msg.sender], "Only 1 per wallet."); } uint mintIndex = totalSupply(); if (totalSupply() < MAX_NFT) { _safeMint(msg.sender, mintIndex); Minted[msg.sender] = true; } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"LICENSE_TEXT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LAT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LONG","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"Minted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enforceOnePerWallet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipEnforceOnePerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_reserveAmount","type":"uint256"}],"name":"reserveNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenLicense","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526000600a60146101000a81548160ff0219169083151502179055506001600a60156101000a81548160ff0219169083151502179055506064600b553480156200004c57600080fd5b506040518060400160405280600d81526020017f4561727468204f6e436861696e000000000000000000000000000000000000008152506040518060400160405280600381526020017f454f430000000000000000000000000000000000000000000000000000000000815250620000d16301ffc9a760e01b6200020460201b60201c565b8160069080519060200190620000e9929190620002e4565b50806007908051906020019062000102929190620002e4565b506200011b6380ac58cd60e01b6200020460201b60201c565b62000133635b5e139f60e01b6200020460201b60201c565b6200014b63780e9d6360e01b6200020460201b60201c565b505060006200015f620002dc60201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506200040f565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000270576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200026790620003dc565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200031c576000855562000368565b82601f106200033757805160ff191683800117855562000368565b8280016001018555821562000368579182015b82811115620003675782518255916020019190600101906200034a565b5b5090506200037791906200037b565b5090565b5b80821115620003965760008160009055506001016200037c565b5090565b6000620003a9601c83620003fe565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b60006020820190508181036000830152620003f7816200039a565b9050919050565b600082825260208201905092915050565b614d51806200041f6000396000f3fe60806040526004361061020f5760003560e01c80636fdaddf111610118578063b4ff622f116100a0578063d33639f61161006f578063d33639f614610782578063e6af037d14610799578063e985e9c5146107c2578063eb8d2444146107ff578063f2fde38b1461082a5761020f565b8063b4ff622f146106c6578063b88d4fde146106f1578063c0e3a7b21461071a578063c87b56dd146107455761020f565b80638da5cb5b116100e75780638da5cb5b146105df57806390ddedd51461060a57806395d89b41146106475780639c3e72bd14610672578063a22cb4651461069d5761020f565b80636fdaddf11461052357806370a082311461054e578063715018a61461058b5780638462151c146105a25761020f565b80633ccfd60b1161019b57806354e584f61161016a57806354e584f61461043c57806355f804b31461046757806357fdfde8146104905780636352211e146104bb5780636c0360eb146104f85761020f565b80633ccfd60b1461039457806342842e0e146103ab578063475489d3146103d45780634f6ccce7146103ff5761020f565b806314f710fe116101e257806314f710fe146102e257806318160ddd146102ec57806323b872dd146103175780632f745c591461034057806334918dfd1461037d5761020f565b806301ffc9a71461021457806306fdde0314610251578063081812fc1461027c578063095ea7b3146102b9575b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190613328565b610853565b60405161024891906146b9565b60405180910390f35b34801561025d57600080fd5b506102666108ba565b60405161027391906146d4565b60405180910390f35b34801561028857600080fd5b506102a3600480360381019061029e91906133bb565b61095c565b6040516102b09190614630565b60405180910390f35b3480156102c557600080fd5b506102e060048036038101906102db91906132ec565b6109e1565b005b6102ea610af9565b005b3480156102f857600080fd5b50610301610ccd565b60405161030e9190614a16565b60405180910390f35b34801561032357600080fd5b5061033e600480360381019061033991906131e6565b610cde565b005b34801561034c57600080fd5b50610367600480360381019061036291906132ec565b610d3e565b6040516103749190614a16565b60405180910390f35b34801561038957600080fd5b50610392610d99565b005b3480156103a057600080fd5b506103a9610e41565b005b3480156103b757600080fd5b506103d260048036038101906103cd91906131e6565b610f0c565b005b3480156103e057600080fd5b506103e9610f2c565b6040516103f69190614a16565b60405180910390f35b34801561040b57600080fd5b50610426600480360381019061042191906133bb565b610f32565b6040516104339190614a16565b60405180910390f35b34801561044857600080fd5b50610451610f55565b60405161045e91906146b9565b60405180910390f35b34801561047357600080fd5b5061048e6004803603810190610489919061337a565b610f68565b005b34801561049c57600080fd5b506104a5610fe7565b6040516104b29190614a16565b60405180910390f35b3480156104c757600080fd5b506104e260048036038101906104dd91906133bb565b610fec565b6040516104ef9190614630565b60405180910390f35b34801561050457600080fd5b5061050d611023565b60405161051a91906146d4565b60405180910390f35b34801561052f57600080fd5b506105386110c5565b6040516105459190614a16565b60405180910390f35b34801561055a57600080fd5b5061057560048036038101906105709190613181565b6110cb565b6040516105829190614a16565b60405180910390f35b34801561059757600080fd5b506105a061118a565b005b3480156105ae57600080fd5b506105c960048036038101906105c49190613181565b6112c7565b6040516105d69190614697565b60405180910390f35b3480156105eb57600080fd5b506105f46113c0565b6040516106019190614630565b60405180910390f35b34801561061657600080fd5b50610631600480360381019061062c9190613181565b6113ea565b60405161063e91906146b9565b60405180910390f35b34801561065357600080fd5b5061065c61140a565b60405161066991906146d4565b60405180910390f35b34801561067e57600080fd5b506106876114ac565b60405161069491906146d4565b60405180910390f35b3480156106a957600080fd5b506106c460048036038101906106bf91906132b0565b6114e5565b005b3480156106d257600080fd5b506106db611666565b6040516106e89190614a16565b60405180910390f35b3480156106fd57600080fd5b5061071860048036038101906107139190613235565b61166b565b005b34801561072657600080fd5b5061072f6116cd565b60405161073c91906146d4565b60405180910390f35b34801561075157600080fd5b5061076c600480360381019061076791906133bb565b61170a565b60405161077991906146d4565b60405180910390f35b34801561078e57600080fd5b506107976117db565b005b3480156107a557600080fd5b506107c060048036038101906107bb91906132ec565b611883565b005b3480156107ce57600080fd5b506107e960048036038101906107e491906131aa565b6119a1565b6040516107f691906146b9565b60405180910390f35b34801561080b57600080fd5b50610814611a35565b60405161082191906146b9565b60405180910390f35b34801561083657600080fd5b50610851600480360381019061084c9190613181565b611a48565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109525780601f1061092757610100808354040283529160200191610952565b820191906000526020600020905b81548152906001019060200180831161093557829003601f168201915b5050505050905090565b600061096782611bf4565b6109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099d90614936565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109ec82610fec565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a54906149b6565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a7c611c11565b73ffffffffffffffffffffffffffffffffffffffff161480610aab5750610aaa81610aa5611c11565b6119a1565b5b610aea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae1906148b6565b60405180910390fd5b610af48383611c19565b505050565b600a60149054906101000a900460ff16610b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3f90614716565b60405180910390fd5b612710610b666001610b58610ccd565b611cd290919063ffffffff16565b1115610ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9e90614756565b60405180910390fd5b600a60159054906101000a900460ff1615610c4a57600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4090614996565b60405180910390fd5b5b6000610c54610ccd565b9050612710610c61610ccd565b1015610cca57610c713382611d27565b6001600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b6000610cd96002611d45565b905090565b610cef610ce9611c11565b82611d5a565b610d2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d25906149d6565b60405180910390fd5b610d39838383611e38565b505050565b6000610d9182600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061204f90919063ffffffff16565b905092915050565b610da1611c11565b73ffffffffffffffffffffffffffffffffffffffff16610dbf6113c0565b73ffffffffffffffffffffffffffffffffffffffff1614610e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0c90614956565b60405180910390fd5b600a60149054906101000a900460ff1615600a60146101000a81548160ff021916908315150217905550565b610e49611c11565b73ffffffffffffffffffffffffffffffffffffffff16610e676113c0565b73ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490614956565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610f08573d6000803e3d6000fd5b5050565b610f278383836040518060200160405280600081525061166b565b505050565b600b5481565b600080610f4983600261206990919063ffffffff16565b50905080915050919050565b600a60159054906101000a900460ff1681565b610f70611c11565b73ffffffffffffffffffffffffffffffffffffffff16610f8e6113c0565b73ffffffffffffffffffffffffffffffffffffffff1614610fe4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdb90614956565b60405180910390fd5b50565b60b481565b600061101c82604051806060016040528060298152602001614cb36029913960026120959092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110bb5780601f10611090576101008083540402835291602001916110bb565b820191906000526020600020905b81548152906001019060200180831161109e57829003601f168201915b5050505050905090565b61271081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561113c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611133906148d6565b60405180910390fd5b611183600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120b4565b9050919050565b611192611c11565b73ffffffffffffffffffffffffffffffffffffffff166111b06113c0565b73ffffffffffffffffffffffffffffffffffffffff1614611206576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fd90614956565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060006112d4836110cb565b9050600081141561132f57600067ffffffffffffffff811180156112f757600080fd5b506040519080825280602002602001820160405280156113265781602001602082028036833780820191505090505b509150506113bb565b60008167ffffffffffffffff8111801561134857600080fd5b506040519080825280602002602001820160405280156113775781602001602082028036833780820191505090505b50905060005b828110156113b45761138f8582610d3e565b82828151811061139b57fe5b602002602001018181525050808060010191505061137d565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600c6020528060005260406000206000915054906101000a900460ff1681565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114a25780601f10611477576101008083540402835291602001916114a2565b820191906000526020600020905b81548152906001019060200180831161148557829003601f168201915b5050505050905090565b6040518060400160405280600381526020017f4d4954000000000000000000000000000000000000000000000000000000000081525081565b6114ed611c11565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614836565b60405180910390fd5b8060056000611568611c11565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611615611c11565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161165a91906146b9565b60405180910390a35050565b605a81565b61167c611676611c11565b83611d5a565b6116bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b2906149d6565b60405180910390fd5b6116c7848484846120c9565b50505050565b60606040518060400160405280600381526020017f4d49540000000000000000000000000000000000000000000000000000000000815250905090565b6060611714610ccd565b821115611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174d906147d6565b60405180910390fd5b600061176183612125565b9050600061176e846121f0565b9050600061178461177f84846122bb565b6122e7565b90506117b281848460405160200161179e93929190614517565b6040516020818303038152906040526122e7565b6040516020016117c2919061460e565b6040516020818303038152906040529350505050919050565b6117e3611c11565b73ffffffffffffffffffffffffffffffffffffffff166118016113c0565b73ffffffffffffffffffffffffffffffffffffffff1614611857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184e90614956565b60405180910390fd5b600a60159054906101000a900460ff1615600a60156101000a81548160ff021916908315150217905550565b61188b611c11565b73ffffffffffffffffffffffffffffffffffffffff166118a96113c0565b73ffffffffffffffffffffffffffffffffffffffff16146118ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f690614956565b60405180910390fd5b6000611909610ccd565b905060008211801561191d5750600b548211155b61195c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611953906147f6565b60405180910390fd5b60005b828110156119805761197384828401611d27565b808060010191505061195f565b5061199682600b5461244d90919063ffffffff16565b600b81905550505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600a60149054906101000a900460ff1681565b611a50611c11565b73ffffffffffffffffffffffffffffffffffffffff16611a6e6113c0565b73ffffffffffffffffffffffffffffffffffffffff1614611ac4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abb90614956565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2b90614776565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611c0a82600261249d90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c8c83610fec565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080828401905083811015611d1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d14906147b6565b60405180910390fd5b8091505092915050565b611d418282604051806020016040528060008152506124b7565b5050565b6000611d5382600001612512565b9050919050565b6000611d6582611bf4565b611da4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9b90614896565b60405180910390fd5b6000611daf83610fec565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e1e57508373ffffffffffffffffffffffffffffffffffffffff16611e068461095c565b73ffffffffffffffffffffffffffffffffffffffff16145b80611e2f5750611e2e81856119a1565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611e5882610fec565b73ffffffffffffffffffffffffffffffffffffffff1614611eae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea590614976565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1590614816565b60405180910390fd5b611f29838383612523565b611f34600082611c19565b611f8581600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061252890919063ffffffff16565b50611fd781600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061254290919063ffffffff16565b50611fee8183600261255c9092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061205e8360000183612591565b60001c905092915050565b60008060008061207c86600001866125fe565b915091508160001c8160001c9350935050509250929050565b60006120a8846000018460001b84612681565b60001c90509392505050565b60006120c282600001612712565b9050919050565b6120d4848484611e38565b6120e084848484612723565b61211f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211690614736565b60405180910390fd5b50505050565b6060600061213860026001850102612887565b905060006002605a02828161214957fe5b069050600080604051806020016040528060008152509050605a8311156121ad576040518060400160405280600181526020017f2d000000000000000000000000000000000000000000000000000000000000008152509050605a830391506121b1565b8291505b806121bb836128c2565b6121c4886129fc565b6040516020016121d693929190614475565b604051602081830303815290604052945050505050919050565b6060600061220360036001850102612887565b90506000600260b402828161221457fe5b06905060008060405180602001604052806000815250905060b4831115612278576040518060400160405280600181526020017f2d00000000000000000000000000000000000000000000000000000000000000815250905060b48303915061227c565b8291505b80612286836128c2565b61228f88612a1c565b6040516020016122a193929190614475565b604051602081830303815290604052945050505050919050565b606082826040516020016122d09291906144b1565b604051602081830303815290604052905092915050565b606060008251141561230a57604051806020016040528060008152509050612448565b6000604051806060016040528060408152602001614cdc6040913990506000600360028551018161233757fe5b04600402905060006020820167ffffffffffffffff8111801561235957600080fd5b506040519080825280601f01601f19166020018201604052801561238c5781602001600182028036833780820191505090505b509050818152600183018586518101602084015b81831015612407576003830192508251603f8160121c1685015160f81b8252600182019150603f81600c1c1685015160f81b8252600182019150603f8160061c1685015160f81b8252600182019150603f811685015160f81b8252600182019150506123a0565b60038951066001811461242157600281146124315761243c565b613d3d60f01b600283035261243c565b603d60f81b60018303525b50505050508093505050505b919050565b600082821115612492576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248990614856565b60405180910390fd5b818303905092915050565b60006124af836000018360001b612a3c565b905092915050565b6124c18383612a5f565b6124ce6000848484612723565b61250d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250490614736565b60405180910390fd5b505050565b600081600001805490509050919050565b505050565b600061253a836000018360001b612bed565b905092915050565b6000612554836000018360001b612cd5565b905092915050565b6000612588846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612d45565b90509392505050565b6000818360000180549050116125dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125d3906146f6565b60405180910390fd5b8260000182815481106125eb57fe5b9060005260206000200154905092915050565b6000808284600001805490501161264a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612641906148f6565b60405180910390fd5b600084600001848154811061265b57fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600080846001016000858152602001908152602001600020549050600081141583906126e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126da91906146d4565b60405180910390fd5b508460000160018203815481106126f657fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b60006127448473ffffffffffffffffffffffffffffffffffffffff16612e21565b612751576001905061287f565b600061281863150b7a0260e01b612766611c11565b88878760405160240161277c949392919061464b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001614c81603291398773ffffffffffffffffffffffffffffffffffffffff16612e349092919063ffffffff16565b90506000818060200190518101906128309190613351565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b6000612892826128c2565b6040516020016128a2919061443a565b6040516020818303038152906040528051906020012060001c9050919050565b6060600082141561290a576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506129f7565b600082905060005b60008214612934578080600101915050600a828161292c57fe5b049150612912565b60008167ffffffffffffffff8111801561294d57600080fd5b506040519080825280601f01601f1916602001820160405280156129805781602001600182028036833780820191505090505b5090505b600085146129f057600182039150600a858161299c57fe5b0660300160f81b8183815181106129af57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85816129e857fe5b049450612984565b8093505050505b919050565b6060612a15612a1060026001850102612e4c565b6128c2565b9050919050565b6060612a35612a3060036001850102612e4c565b6128c2565b9050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612acf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac690614916565b60405180910390fd5b612ad881611bf4565b15612b18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0f90614796565b60405180910390fd5b612b2460008383612523565b612b7581600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061254290919063ffffffff16565b50612b8c8183600261255c9092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60008083600101600084815260200190815260200160002054905060008114612cc95760006001820390506000600186600001805490500390506000866000018281548110612c3857fe5b9060005260206000200154905080876000018481548110612c5557fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480612c8d57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612ccf565b60009150505b92915050565b6000612ce18383612eaa565b612d3a578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612d3f565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612dec57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612e1a565b82856000016001830381548110612dff57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600080823b905060008111915050919050565b6060612e438484600085612ecd565b90509392505050565b600080612e58836128c2565b612e69612e6485612887565b6128c2565b604051602001612e7a929190614451565b6040516020818303038152906040528051906020012060001c90506201869f8181612ea157fe5b06915050919050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015612f12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0990614876565b60405180910390fd5b612f1b85612e21565b612f5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f51906149f6565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612f839190614423565b60006040518083038185875af1925050503d8060008114612fc0576040519150601f19603f3d011682016040523d82523d6000602084013e612fc5565b606091505b5091509150612fd5828286612fe1565b92505050949350505050565b60608315612ff157829050613041565b6000835111156130045782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161303891906146d4565b60405180910390fd5b9392505050565b600061305b61305684614a62565b614a31565b90508281526020810184848401111561307357600080fd5b61307e848285614bcf565b509392505050565b600061309961309484614a92565b614a31565b9050828152602081018484840111156130b157600080fd5b6130bc848285614bcf565b509392505050565b6000813590506130d381614c24565b92915050565b6000813590506130e881614c3b565b92915050565b6000813590506130fd81614c52565b92915050565b60008151905061311281614c52565b92915050565b600082601f83011261312957600080fd5b8135613139848260208601613048565b91505092915050565b600082601f83011261315357600080fd5b8135613163848260208601613086565b91505092915050565b60008135905061317b81614c69565b92915050565b60006020828403121561319357600080fd5b60006131a1848285016130c4565b91505092915050565b600080604083850312156131bd57600080fd5b60006131cb858286016130c4565b92505060206131dc858286016130c4565b9150509250929050565b6000806000606084860312156131fb57600080fd5b6000613209868287016130c4565b935050602061321a868287016130c4565b925050604061322b8682870161316c565b9150509250925092565b6000806000806080858703121561324b57600080fd5b6000613259878288016130c4565b945050602061326a878288016130c4565b935050604061327b8782880161316c565b925050606085013567ffffffffffffffff81111561329857600080fd5b6132a487828801613118565b91505092959194509250565b600080604083850312156132c357600080fd5b60006132d1858286016130c4565b92505060206132e2858286016130d9565b9150509250929050565b600080604083850312156132ff57600080fd5b600061330d858286016130c4565b925050602061331e8582860161316c565b9150509250929050565b60006020828403121561333a57600080fd5b6000613348848285016130ee565b91505092915050565b60006020828403121561336357600080fd5b600061337184828501613103565b91505092915050565b60006020828403121561338c57600080fd5b600082013567ffffffffffffffff8111156133a657600080fd5b6133b284828501613142565b91505092915050565b6000602082840312156133cd57600080fd5b60006133db8482850161316c565b91505092915050565b60006133f08383614405565b60208301905092915050565b61340581614b5b565b82525050565b61341481614b49565b82525050565b600061342582614ad2565b61342f8185614b00565b935061343a83614ac2565b8060005b8381101561346b57815161345288826133e4565b975061345d83614af3565b92505060018101905061343e565b5085935050505092915050565b61348181614b6d565b82525050565b600061349282614add565b61349c8185614b11565b93506134ac818560208601614bde565b6134b581614c13565b840191505092915050565b60006134cb82614add565b6134d58185614b22565b93506134e5818560208601614bde565b80840191505092915050565b60006134fc82614ae8565b6135068185614b2d565b9350613516818560208601614bde565b61351f81614c13565b840191505092915050565b600061353582614ae8565b61353f8185614b3e565b935061354f818560208601614bde565b80840191505092915050565b6000613568600283614b3e565b91507f7d2c0000000000000000000000000000000000000000000000000000000000006000830152600282019050919050565b60006135a8602283614b2d565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061360e601f83614b2d565b91507f53616c65206d7573742062652061637469766520746f206d696e74204e4654006000830152602082019050919050565b600061364e603283614b2d565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006136b4602883614b2d565b91507f507572636861736520776f756c6420657863656564206d617820737570706c7960008301527f206f66204e4654730000000000000000000000000000000000000000000000006020830152604082019050919050565b600061371a602683614b2d565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613780600283614b3e565b91507f222c0000000000000000000000000000000000000000000000000000000000006000830152600282019050919050565b60006137c0601c83614b2d565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b6000613800602c83614b3e565b91507f3c7465787420783d2231302220793d223138372220636c6173733d226261736560008301527f223e4c617469747564653a2000000000000000000000000000000000000000006020830152602c82019050919050565b6000613866601b83614b2d565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b60006138a6601d83614b2d565b91507f5468697320746f6b656e20494420646f6573206e6f742065786973742e0000006000830152602082019050919050565b60006138e660db83614b3e565b91507f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323060008301527f30302f73766722207072657365727665417370656374526174696f3d22784d6960208301527f6e594d696e206d656574222076696577426f783d22302030203335302033353060408301527f223e3c7374796c653e2e62617365207b2066696c6c3a2077686974653b20666f60608301527f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a2032307060808301527f783b207d3c2f7374796c653e3c726563742077696474683d223130302522206860a08301527f65696768743d2231303025222066696c6c3d22626c61636b222f3e000000000060c083015260db82019050919050565b6000613a0a602083614b2d565b91507f4e6f7420656e6f7567682072657365727665206c65667420666f72207465616d6000830152602082019050919050565b6000613a4a602483614b2d565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ab0601983614b2d565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613af0601e83614b2d565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613b30602683614b2d565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b96602c83614b2d565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613bfc602d83614b3e565b91507f3c7465787420783d2231302220793d223231302220636c6173733d226261736560008301527f223e4c6f6e6769747564653a20000000000000000000000000000000000000006020830152602d82019050919050565b6000613c62603883614b2d565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613cc8600183614b3e565b91507f22000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000613d08600183614b3e565b91507f2e000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000613d48602a83614b2d565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000613dae603d83614b3e565b91507f226465736372697074696f6e223a2022596f7572206c6174697475646520616e60008301527f64206c6f6e6769747564652073746f726564206f6e20636861696e222c0000006020830152603d82019050919050565b6000613e14600983614b3e565b91507f22696d616765223a2200000000000000000000000000000000000000000000006000830152600982019050919050565b6000613e54602283614b2d565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613eba602083614b2d565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613efa600183614b3e565b91507f7d000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000613f3a602c83614b2d565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613fa0602083614b2d565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613fe0602983614b2d565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000614046600183614b3e565b91507f7b000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000614086600a83614b3e565b91507f2276616c7565223a2022000000000000000000000000000000000000000000006000830152600a82019050919050565b60006140c6601283614b2d565b91507f4f6e6c792031207065722077616c6c65742e00000000000000000000000000006000830152602082019050919050565b6000614106600183614b3e565b91507f5d000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000614146602183614b2d565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006141ac601d83614b3e565b91507f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000006000830152601d82019050919050565b60006141ec600e83614b3e565b91507f2026233137363b3c2f746578743e0000000000000000000000000000000000006000830152600e82019050919050565b600061422c603183614b2d565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000614292601d83614b2d565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b60006142d2600683614b3e565b91507f3c2f7376673e00000000000000000000000000000000000000000000000000006000830152600682019050919050565b6000614312601a83614b3e565b91507f2274726169745f74797065223a20224c6f6e676974756465222c0000000000006000830152601a82019050919050565b6000614352601983614b3e565b91507f2274726169745f74797065223a20224c61746974756465222c000000000000006000830152601982019050919050565b6000614392601a83614b3e565b91507f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000006000830152601a82019050919050565b60006143d2600e83614b3e565b91507f2261747472696275746573223a5b0000000000000000000000000000000000006000830152600e82019050919050565b61440e81614bc5565b82525050565b61441d81614bc5565b82525050565b600061442f82846134c0565b915081905092915050565b6000614446828461352a565b915081905092915050565b600061445d828561352a565b9150614469828461352a565b91508190509392505050565b6000614481828661352a565b915061448d828561352a565b915061449882613cfb565b91506144a4828461352a565b9150819050949350505050565b60006144bc826138d9565b91506144c7826137f3565b91506144d3828561352a565b91506144de826141df565b91506144e982613bef565b91506144f5828461352a565b9150614500826141df565b915061450b826142c5565b91508190509392505050565b600061452282614039565b915061452d82613e07565b915061453882614385565b9150614544828661352a565b915061454f82613773565b915061455a82613da1565b9150614565826143c5565b915061457082614039565b915061457b82614345565b915061458682614079565b9150614592828561352a565b915061459d82613cbb565b91506145a88261355b565b91506145b382614039565b91506145be82614305565b91506145c982614079565b91506145d5828461352a565b91506145e082613cbb565b91506145eb82613eed565b91506145f6826140f9565b915061460182613eed565b9150819050949350505050565b60006146198261419f565b9150614625828461352a565b915081905092915050565b6000602082019050614645600083018461340b565b92915050565b600060808201905061466060008301876133fc565b61466d602083018661340b565b61467a6040830185614414565b818103606083015261468c8184613487565b905095945050505050565b600060208201905081810360008301526146b1818461341a565b905092915050565b60006020820190506146ce6000830184613478565b92915050565b600060208201905081810360008301526146ee81846134f1565b905092915050565b6000602082019050818103600083015261470f8161359b565b9050919050565b6000602082019050818103600083015261472f81613601565b9050919050565b6000602082019050818103600083015261474f81613641565b9050919050565b6000602082019050818103600083015261476f816136a7565b9050919050565b6000602082019050818103600083015261478f8161370d565b9050919050565b600060208201905081810360008301526147af816137b3565b9050919050565b600060208201905081810360008301526147cf81613859565b9050919050565b600060208201905081810360008301526147ef81613899565b9050919050565b6000602082019050818103600083015261480f816139fd565b9050919050565b6000602082019050818103600083015261482f81613a3d565b9050919050565b6000602082019050818103600083015261484f81613aa3565b9050919050565b6000602082019050818103600083015261486f81613ae3565b9050919050565b6000602082019050818103600083015261488f81613b23565b9050919050565b600060208201905081810360008301526148af81613b89565b9050919050565b600060208201905081810360008301526148cf81613c55565b9050919050565b600060208201905081810360008301526148ef81613d3b565b9050919050565b6000602082019050818103600083015261490f81613e47565b9050919050565b6000602082019050818103600083015261492f81613ead565b9050919050565b6000602082019050818103600083015261494f81613f2d565b9050919050565b6000602082019050818103600083015261496f81613f93565b9050919050565b6000602082019050818103600083015261498f81613fd3565b9050919050565b600060208201905081810360008301526149af816140b9565b9050919050565b600060208201905081810360008301526149cf81614139565b9050919050565b600060208201905081810360008301526149ef8161421f565b9050919050565b60006020820190508181036000830152614a0f81614285565b9050919050565b6000602082019050614a2b6000830184614414565b92915050565b6000604051905081810181811067ffffffffffffffff82111715614a5857614a57614c11565b5b8060405250919050565b600067ffffffffffffffff821115614a7d57614a7c614c11565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115614aad57614aac614c11565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614b5482614ba5565b9050919050565b6000614b6682614ba5565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015614bfc578082015181840152602081019050614be1565b83811115614c0b576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b614c2d81614b49565b8114614c3857600080fd5b50565b614c4481614b6d565b8114614c4f57600080fd5b50565b614c5b81614b79565b8114614c6657600080fd5b50565b614c7281614bc5565b8114614c7d57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212205a2c9b7f8bb8a0598bccb97e5b8f389dfe4d1e4c95bbdaeba04ee98c00fff51164736f6c63430007060033
Deployed Bytecode
0x60806040526004361061020f5760003560e01c80636fdaddf111610118578063b4ff622f116100a0578063d33639f61161006f578063d33639f614610782578063e6af037d14610799578063e985e9c5146107c2578063eb8d2444146107ff578063f2fde38b1461082a5761020f565b8063b4ff622f146106c6578063b88d4fde146106f1578063c0e3a7b21461071a578063c87b56dd146107455761020f565b80638da5cb5b116100e75780638da5cb5b146105df57806390ddedd51461060a57806395d89b41146106475780639c3e72bd14610672578063a22cb4651461069d5761020f565b80636fdaddf11461052357806370a082311461054e578063715018a61461058b5780638462151c146105a25761020f565b80633ccfd60b1161019b57806354e584f61161016a57806354e584f61461043c57806355f804b31461046757806357fdfde8146104905780636352211e146104bb5780636c0360eb146104f85761020f565b80633ccfd60b1461039457806342842e0e146103ab578063475489d3146103d45780634f6ccce7146103ff5761020f565b806314f710fe116101e257806314f710fe146102e257806318160ddd146102ec57806323b872dd146103175780632f745c591461034057806334918dfd1461037d5761020f565b806301ffc9a71461021457806306fdde0314610251578063081812fc1461027c578063095ea7b3146102b9575b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190613328565b610853565b60405161024891906146b9565b60405180910390f35b34801561025d57600080fd5b506102666108ba565b60405161027391906146d4565b60405180910390f35b34801561028857600080fd5b506102a3600480360381019061029e91906133bb565b61095c565b6040516102b09190614630565b60405180910390f35b3480156102c557600080fd5b506102e060048036038101906102db91906132ec565b6109e1565b005b6102ea610af9565b005b3480156102f857600080fd5b50610301610ccd565b60405161030e9190614a16565b60405180910390f35b34801561032357600080fd5b5061033e600480360381019061033991906131e6565b610cde565b005b34801561034c57600080fd5b50610367600480360381019061036291906132ec565b610d3e565b6040516103749190614a16565b60405180910390f35b34801561038957600080fd5b50610392610d99565b005b3480156103a057600080fd5b506103a9610e41565b005b3480156103b757600080fd5b506103d260048036038101906103cd91906131e6565b610f0c565b005b3480156103e057600080fd5b506103e9610f2c565b6040516103f69190614a16565b60405180910390f35b34801561040b57600080fd5b50610426600480360381019061042191906133bb565b610f32565b6040516104339190614a16565b60405180910390f35b34801561044857600080fd5b50610451610f55565b60405161045e91906146b9565b60405180910390f35b34801561047357600080fd5b5061048e6004803603810190610489919061337a565b610f68565b005b34801561049c57600080fd5b506104a5610fe7565b6040516104b29190614a16565b60405180910390f35b3480156104c757600080fd5b506104e260048036038101906104dd91906133bb565b610fec565b6040516104ef9190614630565b60405180910390f35b34801561050457600080fd5b5061050d611023565b60405161051a91906146d4565b60405180910390f35b34801561052f57600080fd5b506105386110c5565b6040516105459190614a16565b60405180910390f35b34801561055a57600080fd5b5061057560048036038101906105709190613181565b6110cb565b6040516105829190614a16565b60405180910390f35b34801561059757600080fd5b506105a061118a565b005b3480156105ae57600080fd5b506105c960048036038101906105c49190613181565b6112c7565b6040516105d69190614697565b60405180910390f35b3480156105eb57600080fd5b506105f46113c0565b6040516106019190614630565b60405180910390f35b34801561061657600080fd5b50610631600480360381019061062c9190613181565b6113ea565b60405161063e91906146b9565b60405180910390f35b34801561065357600080fd5b5061065c61140a565b60405161066991906146d4565b60405180910390f35b34801561067e57600080fd5b506106876114ac565b60405161069491906146d4565b60405180910390f35b3480156106a957600080fd5b506106c460048036038101906106bf91906132b0565b6114e5565b005b3480156106d257600080fd5b506106db611666565b6040516106e89190614a16565b60405180910390f35b3480156106fd57600080fd5b5061071860048036038101906107139190613235565b61166b565b005b34801561072657600080fd5b5061072f6116cd565b60405161073c91906146d4565b60405180910390f35b34801561075157600080fd5b5061076c600480360381019061076791906133bb565b61170a565b60405161077991906146d4565b60405180910390f35b34801561078e57600080fd5b506107976117db565b005b3480156107a557600080fd5b506107c060048036038101906107bb91906132ec565b611883565b005b3480156107ce57600080fd5b506107e960048036038101906107e491906131aa565b6119a1565b6040516107f691906146b9565b60405180910390f35b34801561080b57600080fd5b50610814611a35565b60405161082191906146b9565b60405180910390f35b34801561083657600080fd5b50610851600480360381019061084c9190613181565b611a48565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109525780601f1061092757610100808354040283529160200191610952565b820191906000526020600020905b81548152906001019060200180831161093557829003601f168201915b5050505050905090565b600061096782611bf4565b6109a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099d90614936565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109ec82610fec565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a54906149b6565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a7c611c11565b73ffffffffffffffffffffffffffffffffffffffff161480610aab5750610aaa81610aa5611c11565b6119a1565b5b610aea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae1906148b6565b60405180910390fd5b610af48383611c19565b505050565b600a60149054906101000a900460ff16610b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3f90614716565b60405180910390fd5b612710610b666001610b58610ccd565b611cd290919063ffffffff16565b1115610ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9e90614756565b60405180910390fd5b600a60159054906101000a900460ff1615610c4a57600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4090614996565b60405180910390fd5b5b6000610c54610ccd565b9050612710610c61610ccd565b1015610cca57610c713382611d27565b6001600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b50565b6000610cd96002611d45565b905090565b610cef610ce9611c11565b82611d5a565b610d2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d25906149d6565b60405180910390fd5b610d39838383611e38565b505050565b6000610d9182600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061204f90919063ffffffff16565b905092915050565b610da1611c11565b73ffffffffffffffffffffffffffffffffffffffff16610dbf6113c0565b73ffffffffffffffffffffffffffffffffffffffff1614610e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0c90614956565b60405180910390fd5b600a60149054906101000a900460ff1615600a60146101000a81548160ff021916908315150217905550565b610e49611c11565b73ffffffffffffffffffffffffffffffffffffffff16610e676113c0565b73ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490614956565b60405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610f08573d6000803e3d6000fd5b5050565b610f278383836040518060200160405280600081525061166b565b505050565b600b5481565b600080610f4983600261206990919063ffffffff16565b50905080915050919050565b600a60159054906101000a900460ff1681565b610f70611c11565b73ffffffffffffffffffffffffffffffffffffffff16610f8e6113c0565b73ffffffffffffffffffffffffffffffffffffffff1614610fe4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdb90614956565b60405180910390fd5b50565b60b481565b600061101c82604051806060016040528060298152602001614cb36029913960026120959092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110bb5780601f10611090576101008083540402835291602001916110bb565b820191906000526020600020905b81548152906001019060200180831161109e57829003601f168201915b5050505050905090565b61271081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561113c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611133906148d6565b60405180910390fd5b611183600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206120b4565b9050919050565b611192611c11565b73ffffffffffffffffffffffffffffffffffffffff166111b06113c0565b73ffffffffffffffffffffffffffffffffffffffff1614611206576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fd90614956565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060006112d4836110cb565b9050600081141561132f57600067ffffffffffffffff811180156112f757600080fd5b506040519080825280602002602001820160405280156113265781602001602082028036833780820191505090505b509150506113bb565b60008167ffffffffffffffff8111801561134857600080fd5b506040519080825280602002602001820160405280156113775781602001602082028036833780820191505090505b50905060005b828110156113b45761138f8582610d3e565b82828151811061139b57fe5b602002602001018181525050808060010191505061137d565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600c6020528060005260406000206000915054906101000a900460ff1681565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114a25780601f10611477576101008083540402835291602001916114a2565b820191906000526020600020905b81548152906001019060200180831161148557829003601f168201915b5050505050905090565b6040518060400160405280600381526020017f4d4954000000000000000000000000000000000000000000000000000000000081525081565b6114ed611c11565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614836565b60405180910390fd5b8060056000611568611c11565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611615611c11565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161165a91906146b9565b60405180910390a35050565b605a81565b61167c611676611c11565b83611d5a565b6116bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b2906149d6565b60405180910390fd5b6116c7848484846120c9565b50505050565b60606040518060400160405280600381526020017f4d49540000000000000000000000000000000000000000000000000000000000815250905090565b6060611714610ccd565b821115611756576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174d906147d6565b60405180910390fd5b600061176183612125565b9050600061176e846121f0565b9050600061178461177f84846122bb565b6122e7565b90506117b281848460405160200161179e93929190614517565b6040516020818303038152906040526122e7565b6040516020016117c2919061460e565b6040516020818303038152906040529350505050919050565b6117e3611c11565b73ffffffffffffffffffffffffffffffffffffffff166118016113c0565b73ffffffffffffffffffffffffffffffffffffffff1614611857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184e90614956565b60405180910390fd5b600a60159054906101000a900460ff1615600a60156101000a81548160ff021916908315150217905550565b61188b611c11565b73ffffffffffffffffffffffffffffffffffffffff166118a96113c0565b73ffffffffffffffffffffffffffffffffffffffff16146118ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f690614956565b60405180910390fd5b6000611909610ccd565b905060008211801561191d5750600b548211155b61195c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611953906147f6565b60405180910390fd5b60005b828110156119805761197384828401611d27565b808060010191505061195f565b5061199682600b5461244d90919063ffffffff16565b600b81905550505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600a60149054906101000a900460ff1681565b611a50611c11565b73ffffffffffffffffffffffffffffffffffffffff16611a6e6113c0565b73ffffffffffffffffffffffffffffffffffffffff1614611ac4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abb90614956565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2b90614776565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611c0a82600261249d90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611c8c83610fec565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080828401905083811015611d1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d14906147b6565b60405180910390fd5b8091505092915050565b611d418282604051806020016040528060008152506124b7565b5050565b6000611d5382600001612512565b9050919050565b6000611d6582611bf4565b611da4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9b90614896565b60405180910390fd5b6000611daf83610fec565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e1e57508373ffffffffffffffffffffffffffffffffffffffff16611e068461095c565b73ffffffffffffffffffffffffffffffffffffffff16145b80611e2f5750611e2e81856119a1565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611e5882610fec565b73ffffffffffffffffffffffffffffffffffffffff1614611eae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea590614976565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1590614816565b60405180910390fd5b611f29838383612523565b611f34600082611c19565b611f8581600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061252890919063ffffffff16565b50611fd781600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061254290919063ffffffff16565b50611fee8183600261255c9092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061205e8360000183612591565b60001c905092915050565b60008060008061207c86600001866125fe565b915091508160001c8160001c9350935050509250929050565b60006120a8846000018460001b84612681565b60001c90509392505050565b60006120c282600001612712565b9050919050565b6120d4848484611e38565b6120e084848484612723565b61211f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161211690614736565b60405180910390fd5b50505050565b6060600061213860026001850102612887565b905060006002605a02828161214957fe5b069050600080604051806020016040528060008152509050605a8311156121ad576040518060400160405280600181526020017f2d000000000000000000000000000000000000000000000000000000000000008152509050605a830391506121b1565b8291505b806121bb836128c2565b6121c4886129fc565b6040516020016121d693929190614475565b604051602081830303815290604052945050505050919050565b6060600061220360036001850102612887565b90506000600260b402828161221457fe5b06905060008060405180602001604052806000815250905060b4831115612278576040518060400160405280600181526020017f2d00000000000000000000000000000000000000000000000000000000000000815250905060b48303915061227c565b8291505b80612286836128c2565b61228f88612a1c565b6040516020016122a193929190614475565b604051602081830303815290604052945050505050919050565b606082826040516020016122d09291906144b1565b604051602081830303815290604052905092915050565b606060008251141561230a57604051806020016040528060008152509050612448565b6000604051806060016040528060408152602001614cdc6040913990506000600360028551018161233757fe5b04600402905060006020820167ffffffffffffffff8111801561235957600080fd5b506040519080825280601f01601f19166020018201604052801561238c5781602001600182028036833780820191505090505b509050818152600183018586518101602084015b81831015612407576003830192508251603f8160121c1685015160f81b8252600182019150603f81600c1c1685015160f81b8252600182019150603f8160061c1685015160f81b8252600182019150603f811685015160f81b8252600182019150506123a0565b60038951066001811461242157600281146124315761243c565b613d3d60f01b600283035261243c565b603d60f81b60018303525b50505050508093505050505b919050565b600082821115612492576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248990614856565b60405180910390fd5b818303905092915050565b60006124af836000018360001b612a3c565b905092915050565b6124c18383612a5f565b6124ce6000848484612723565b61250d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250490614736565b60405180910390fd5b505050565b600081600001805490509050919050565b505050565b600061253a836000018360001b612bed565b905092915050565b6000612554836000018360001b612cd5565b905092915050565b6000612588846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612d45565b90509392505050565b6000818360000180549050116125dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125d3906146f6565b60405180910390fd5b8260000182815481106125eb57fe5b9060005260206000200154905092915050565b6000808284600001805490501161264a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612641906148f6565b60405180910390fd5b600084600001848154811061265b57fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b600080846001016000858152602001908152602001600020549050600081141583906126e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126da91906146d4565b60405180910390fd5b508460000160018203815481106126f657fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b60006127448473ffffffffffffffffffffffffffffffffffffffff16612e21565b612751576001905061287f565b600061281863150b7a0260e01b612766611c11565b88878760405160240161277c949392919061464b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001614c81603291398773ffffffffffffffffffffffffffffffffffffffff16612e349092919063ffffffff16565b90506000818060200190518101906128309190613351565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b6000612892826128c2565b6040516020016128a2919061443a565b6040516020818303038152906040528051906020012060001c9050919050565b6060600082141561290a576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506129f7565b600082905060005b60008214612934578080600101915050600a828161292c57fe5b049150612912565b60008167ffffffffffffffff8111801561294d57600080fd5b506040519080825280601f01601f1916602001820160405280156129805781602001600182028036833780820191505090505b5090505b600085146129f057600182039150600a858161299c57fe5b0660300160f81b8183815181106129af57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85816129e857fe5b049450612984565b8093505050505b919050565b6060612a15612a1060026001850102612e4c565b6128c2565b9050919050565b6060612a35612a3060036001850102612e4c565b6128c2565b9050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612acf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ac690614916565b60405180910390fd5b612ad881611bf4565b15612b18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0f90614796565b60405180910390fd5b612b2460008383612523565b612b7581600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061254290919063ffffffff16565b50612b8c8183600261255c9092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60008083600101600084815260200190815260200160002054905060008114612cc95760006001820390506000600186600001805490500390506000866000018281548110612c3857fe5b9060005260206000200154905080876000018481548110612c5557fe5b9060005260206000200181905550600183018760010160008381526020019081526020016000208190555086600001805480612c8d57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612ccf565b60009150505b92915050565b6000612ce18383612eaa565b612d3a578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612d3f565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612dec57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612e1a565b82856000016001830381548110612dff57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600080823b905060008111915050919050565b6060612e438484600085612ecd565b90509392505050565b600080612e58836128c2565b612e69612e6485612887565b6128c2565b604051602001612e7a929190614451565b6040516020818303038152906040528051906020012060001c90506201869f8181612ea157fe5b06915050919050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015612f12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0990614876565b60405180910390fd5b612f1b85612e21565b612f5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f51906149f6565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612f839190614423565b60006040518083038185875af1925050503d8060008114612fc0576040519150601f19603f3d011682016040523d82523d6000602084013e612fc5565b606091505b5091509150612fd5828286612fe1565b92505050949350505050565b60608315612ff157829050613041565b6000835111156130045782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161303891906146d4565b60405180910390fd5b9392505050565b600061305b61305684614a62565b614a31565b90508281526020810184848401111561307357600080fd5b61307e848285614bcf565b509392505050565b600061309961309484614a92565b614a31565b9050828152602081018484840111156130b157600080fd5b6130bc848285614bcf565b509392505050565b6000813590506130d381614c24565b92915050565b6000813590506130e881614c3b565b92915050565b6000813590506130fd81614c52565b92915050565b60008151905061311281614c52565b92915050565b600082601f83011261312957600080fd5b8135613139848260208601613048565b91505092915050565b600082601f83011261315357600080fd5b8135613163848260208601613086565b91505092915050565b60008135905061317b81614c69565b92915050565b60006020828403121561319357600080fd5b60006131a1848285016130c4565b91505092915050565b600080604083850312156131bd57600080fd5b60006131cb858286016130c4565b92505060206131dc858286016130c4565b9150509250929050565b6000806000606084860312156131fb57600080fd5b6000613209868287016130c4565b935050602061321a868287016130c4565b925050604061322b8682870161316c565b9150509250925092565b6000806000806080858703121561324b57600080fd5b6000613259878288016130c4565b945050602061326a878288016130c4565b935050604061327b8782880161316c565b925050606085013567ffffffffffffffff81111561329857600080fd5b6132a487828801613118565b91505092959194509250565b600080604083850312156132c357600080fd5b60006132d1858286016130c4565b92505060206132e2858286016130d9565b9150509250929050565b600080604083850312156132ff57600080fd5b600061330d858286016130c4565b925050602061331e8582860161316c565b9150509250929050565b60006020828403121561333a57600080fd5b6000613348848285016130ee565b91505092915050565b60006020828403121561336357600080fd5b600061337184828501613103565b91505092915050565b60006020828403121561338c57600080fd5b600082013567ffffffffffffffff8111156133a657600080fd5b6133b284828501613142565b91505092915050565b6000602082840312156133cd57600080fd5b60006133db8482850161316c565b91505092915050565b60006133f08383614405565b60208301905092915050565b61340581614b5b565b82525050565b61341481614b49565b82525050565b600061342582614ad2565b61342f8185614b00565b935061343a83614ac2565b8060005b8381101561346b57815161345288826133e4565b975061345d83614af3565b92505060018101905061343e565b5085935050505092915050565b61348181614b6d565b82525050565b600061349282614add565b61349c8185614b11565b93506134ac818560208601614bde565b6134b581614c13565b840191505092915050565b60006134cb82614add565b6134d58185614b22565b93506134e5818560208601614bde565b80840191505092915050565b60006134fc82614ae8565b6135068185614b2d565b9350613516818560208601614bde565b61351f81614c13565b840191505092915050565b600061353582614ae8565b61353f8185614b3e565b935061354f818560208601614bde565b80840191505092915050565b6000613568600283614b3e565b91507f7d2c0000000000000000000000000000000000000000000000000000000000006000830152600282019050919050565b60006135a8602283614b2d565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061360e601f83614b2d565b91507f53616c65206d7573742062652061637469766520746f206d696e74204e4654006000830152602082019050919050565b600061364e603283614b2d565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006136b4602883614b2d565b91507f507572636861736520776f756c6420657863656564206d617820737570706c7960008301527f206f66204e4654730000000000000000000000000000000000000000000000006020830152604082019050919050565b600061371a602683614b2d565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613780600283614b3e565b91507f222c0000000000000000000000000000000000000000000000000000000000006000830152600282019050919050565b60006137c0601c83614b2d565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b6000613800602c83614b3e565b91507f3c7465787420783d2231302220793d223138372220636c6173733d226261736560008301527f223e4c617469747564653a2000000000000000000000000000000000000000006020830152602c82019050919050565b6000613866601b83614b2d565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b60006138a6601d83614b2d565b91507f5468697320746f6b656e20494420646f6573206e6f742065786973742e0000006000830152602082019050919050565b60006138e660db83614b3e565b91507f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323060008301527f30302f73766722207072657365727665417370656374526174696f3d22784d6960208301527f6e594d696e206d656574222076696577426f783d22302030203335302033353060408301527f223e3c7374796c653e2e62617365207b2066696c6c3a2077686974653b20666f60608301527f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a2032307060808301527f783b207d3c2f7374796c653e3c726563742077696474683d223130302522206860a08301527f65696768743d2231303025222066696c6c3d22626c61636b222f3e000000000060c083015260db82019050919050565b6000613a0a602083614b2d565b91507f4e6f7420656e6f7567682072657365727665206c65667420666f72207465616d6000830152602082019050919050565b6000613a4a602483614b2d565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ab0601983614b2d565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613af0601e83614b2d565b91507f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006000830152602082019050919050565b6000613b30602683614b2d565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613b96602c83614b2d565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613bfc602d83614b3e565b91507f3c7465787420783d2231302220793d223231302220636c6173733d226261736560008301527f223e4c6f6e6769747564653a20000000000000000000000000000000000000006020830152602d82019050919050565b6000613c62603883614b2d565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613cc8600183614b3e565b91507f22000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000613d08600183614b3e565b91507f2e000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000613d48602a83614b2d565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000613dae603d83614b3e565b91507f226465736372697074696f6e223a2022596f7572206c6174697475646520616e60008301527f64206c6f6e6769747564652073746f726564206f6e20636861696e222c0000006020830152603d82019050919050565b6000613e14600983614b3e565b91507f22696d616765223a2200000000000000000000000000000000000000000000006000830152600982019050919050565b6000613e54602283614b2d565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613eba602083614b2d565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613efa600183614b3e565b91507f7d000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000613f3a602c83614b2d565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613fa0602083614b2d565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613fe0602983614b2d565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000614046600183614b3e565b91507f7b000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000614086600a83614b3e565b91507f2276616c7565223a2022000000000000000000000000000000000000000000006000830152600a82019050919050565b60006140c6601283614b2d565b91507f4f6e6c792031207065722077616c6c65742e00000000000000000000000000006000830152602082019050919050565b6000614106600183614b3e565b91507f5d000000000000000000000000000000000000000000000000000000000000006000830152600182019050919050565b6000614146602183614b2d565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006141ac601d83614b3e565b91507f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000006000830152601d82019050919050565b60006141ec600e83614b3e565b91507f2026233137363b3c2f746578743e0000000000000000000000000000000000006000830152600e82019050919050565b600061422c603183614b2d565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000614292601d83614b2d565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b60006142d2600683614b3e565b91507f3c2f7376673e00000000000000000000000000000000000000000000000000006000830152600682019050919050565b6000614312601a83614b3e565b91507f2274726169745f74797065223a20224c6f6e676974756465222c0000000000006000830152601a82019050919050565b6000614352601983614b3e565b91507f2274726169745f74797065223a20224c61746974756465222c000000000000006000830152601982019050919050565b6000614392601a83614b3e565b91507f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000006000830152601a82019050919050565b60006143d2600e83614b3e565b91507f2261747472696275746573223a5b0000000000000000000000000000000000006000830152600e82019050919050565b61440e81614bc5565b82525050565b61441d81614bc5565b82525050565b600061442f82846134c0565b915081905092915050565b6000614446828461352a565b915081905092915050565b600061445d828561352a565b9150614469828461352a565b91508190509392505050565b6000614481828661352a565b915061448d828561352a565b915061449882613cfb565b91506144a4828461352a565b9150819050949350505050565b60006144bc826138d9565b91506144c7826137f3565b91506144d3828561352a565b91506144de826141df565b91506144e982613bef565b91506144f5828461352a565b9150614500826141df565b915061450b826142c5565b91508190509392505050565b600061452282614039565b915061452d82613e07565b915061453882614385565b9150614544828661352a565b915061454f82613773565b915061455a82613da1565b9150614565826143c5565b915061457082614039565b915061457b82614345565b915061458682614079565b9150614592828561352a565b915061459d82613cbb565b91506145a88261355b565b91506145b382614039565b91506145be82614305565b91506145c982614079565b91506145d5828461352a565b91506145e082613cbb565b91506145eb82613eed565b91506145f6826140f9565b915061460182613eed565b9150819050949350505050565b60006146198261419f565b9150614625828461352a565b915081905092915050565b6000602082019050614645600083018461340b565b92915050565b600060808201905061466060008301876133fc565b61466d602083018661340b565b61467a6040830185614414565b818103606083015261468c8184613487565b905095945050505050565b600060208201905081810360008301526146b1818461341a565b905092915050565b60006020820190506146ce6000830184613478565b92915050565b600060208201905081810360008301526146ee81846134f1565b905092915050565b6000602082019050818103600083015261470f8161359b565b9050919050565b6000602082019050818103600083015261472f81613601565b9050919050565b6000602082019050818103600083015261474f81613641565b9050919050565b6000602082019050818103600083015261476f816136a7565b9050919050565b6000602082019050818103600083015261478f8161370d565b9050919050565b600060208201905081810360008301526147af816137b3565b9050919050565b600060208201905081810360008301526147cf81613859565b9050919050565b600060208201905081810360008301526147ef81613899565b9050919050565b6000602082019050818103600083015261480f816139fd565b9050919050565b6000602082019050818103600083015261482f81613a3d565b9050919050565b6000602082019050818103600083015261484f81613aa3565b9050919050565b6000602082019050818103600083015261486f81613ae3565b9050919050565b6000602082019050818103600083015261488f81613b23565b9050919050565b600060208201905081810360008301526148af81613b89565b9050919050565b600060208201905081810360008301526148cf81613c55565b9050919050565b600060208201905081810360008301526148ef81613d3b565b9050919050565b6000602082019050818103600083015261490f81613e47565b9050919050565b6000602082019050818103600083015261492f81613ead565b9050919050565b6000602082019050818103600083015261494f81613f2d565b9050919050565b6000602082019050818103600083015261496f81613f93565b9050919050565b6000602082019050818103600083015261498f81613fd3565b9050919050565b600060208201905081810360008301526149af816140b9565b9050919050565b600060208201905081810360008301526149cf81614139565b9050919050565b600060208201905081810360008301526149ef8161421f565b9050919050565b60006020820190508181036000830152614a0f81614285565b9050919050565b6000602082019050614a2b6000830184614414565b92915050565b6000604051905081810181811067ffffffffffffffff82111715614a5857614a57614c11565b5b8060405250919050565b600067ffffffffffffffff821115614a7d57614a7c614c11565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115614aad57614aac614c11565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000614b5482614ba5565b9050919050565b6000614b6682614ba5565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015614bfc578082015181840152602081019050614be1565b83811115614c0b576000848401525b50505050565bfe5b6000601f19601f8301169050919050565b614c2d81614b49565b8114614c3857600080fd5b50565b614c4481614b6d565b8114614c4f57600080fd5b50565b614c5b81614b79565b8114614c6657600080fd5b50565b614c7281614bc5565b8114614c7d57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212205a2c9b7f8bb8a0598bccb97e5b8f389dfe4d1e4c95bbdaeba04ee98c00fff51164736f6c63430007060033
Deployed Bytecode Sourcemap
69128:6985:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10231:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51576:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54362:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53892:404;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75611:499;;;:::i;:::-;;53370:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55252:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53132:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74740:89;;;;;;;;;;;;;:::i;:::-;;74132:131;;;;;;;;;;;;;:::i;:::-;;55628:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69485:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53658:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69304:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74664:68;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69440:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51332:177;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52951:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69351:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51049:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66307:148;;;;;;;;;;;;;:::i;:::-;;74958:540;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65656:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69525:39;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51745:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69213:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54655:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69397:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55850:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75506:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71871:1540;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74837:113;;;;;;;;;;;;;:::i;:::-;;74271:385;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55021:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69265:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66610:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10231:150;10316:4;10340:20;:33;10361:11;10340:33;;;;;;;;;;;;;;;;;;;;;;;;;;;10333:40;;10231:150;;;:::o;51576:100::-;51630:13;51663:5;51656:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51576:100;:::o;54362:221::-;54438:7;54466:16;54474:7;54466;:16::i;:::-;54458:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;54551:15;:24;54567:7;54551:24;;;;;;;;;;;;;;;;;;;;;54544:31;;54362:221;;;:::o;53892:404::-;53973:13;53989:23;54004:7;53989:14;:23::i;:::-;53973:39;;54037:5;54031:11;;:2;:11;;;;54023:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;54117:5;54101:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;54126:44;54150:5;54157:12;:10;:12::i;:::-;54126:23;:44::i;:::-;54101:69;54093:161;;;;;;;;;;;;:::i;:::-;;;;;;;;;54267:21;54276:2;54280:7;54267:8;:21::i;:::-;53892:404;;;:::o;75611:499::-;75664:12;;;;;;;;;;;75656:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;69385:5;75731:20;75749:1;75731:13;:11;:13::i;:::-;:17;;:20;;;;:::i;:::-;:31;;75723:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;75824:19;;;;;;;;;;;75820:102;;;75869:6;:18;75876:10;75869:18;;;;;;;;;;;;;;;;;;;;;;;;;75868:19;75860:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;75820:102;75934:14;75951:13;:11;:13::i;:::-;75934:30;;69385:5;75979:13;:11;:13::i;:::-;:23;75975:128;;;76019:32;76029:10;76041:9;76019;:32::i;:::-;76087:4;76066:6;:18;76073:10;76066:18;;;;;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;75975:128;75611:499;:::o;53370:211::-;53431:7;53552:21;:12;:19;:21::i;:::-;53545:28;;53370:211;:::o;55252:305::-;55413:41;55432:12;:10;:12::i;:::-;55446:7;55413:18;:41::i;:::-;55405:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;55521:28;55531:4;55537:2;55541:7;55521:9;:28::i;:::-;55252:305;;;:::o;53132:162::-;53229:7;53256:30;53280:5;53256:13;:20;53270:5;53256:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;53249:37;;53132:162;;;;:::o;74740:89::-;65887:12;:10;:12::i;:::-;65876:23;;:7;:5;:7::i;:::-;:23;;;65868:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74809:12:::1;;;;;;;;;;;74808:13;74793:12;;:28;;;;;;;;;;;;;;;;;;74740:89::o:0;74132:131::-;65887:12;:10;:12::i;:::-;65876:23;;:7;:5;:7::i;:::-;:23;;;65868:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74180:12:::1;74195:21;74180:36;;74227:10;:19;;:28;74247:7;74227:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;65947:1;74132:131::o:0;55628:151::-;55732:39;55749:4;55755:2;55759:7;55732:39;;;;;;;;;;;;:16;:39::i;:::-;55628:151;;;:::o;69485:31::-;;;;:::o;53658:172::-;53733:7;53754:15;53775:22;53791:5;53775:12;:15;;:22;;;;:::i;:::-;53753:44;;;53815:7;53808:14;;;53658:172;;;:::o;69304:38::-;;;;;;;;;;;;;:::o;74664:68::-;65887:12;:10;:12::i;:::-;65876:23;;:7;:5;:7::i;:::-;:23;;;65868:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74664;:::o;69440:38::-;69475:3;69440:38;:::o;51332:177::-;51404:7;51431:70;51448:7;51431:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;51424:77;;51332:177;;;:::o;52951:97::-;52999:13;53032:8;53025:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52951:97;:::o;69351:39::-;69385:5;69351:39;:::o;51049:221::-;51121:7;51166:1;51149:19;;:5;:19;;;;51141:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;51233:29;:13;:20;51247:5;51233:20;;;;;;;;;;;;;;;:27;:29::i;:::-;51226:36;;51049:221;;;:::o;66307:148::-;65887:12;:10;:12::i;:::-;65876:23;;:7;:5;:7::i;:::-;:23;;;65868:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66414:1:::1;66377:40;;66398:6;;;;;;;;;;;66377:40;;;;;;;;;;;;66445:1;66428:6;;:19;;;;;;;;;;;;;;;;;;66307:148::o:0;74958:540::-;75019:16;75049:18;75070:17;75080:6;75070:9;:17::i;:::-;75049:38;;75116:1;75102:10;:15;75098:393;;;75193:1;75179:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75172:23;;;;;75098:393;75228:23;75268:10;75254:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75228:51;;75294:13;75322:130;75346:10;75338:5;:18;75322:130;;;75402:34;75422:6;75430:5;75402:19;:34::i;:::-;75386:6;75393:5;75386:13;;;;;;;;;;;;;:50;;;;;75358:7;;;;;;;75322:130;;;75473:6;75466:13;;;;;74958:540;;;;:::o;65656:87::-;65702:7;65729:6;;;;;;;;;;;65722:13;;65656:87;:::o;69525:39::-;;;;;;;;;;;;;;;;;;;;;;:::o;51745:104::-;51801:13;51834:7;51827:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51745:104;:::o;69213:43::-;;;;;;;;;;;;;;;;;;;:::o;54655:295::-;54770:12;:10;:12::i;:::-;54758:24;;:8;:24;;;;54750:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;54870:8;54825:18;:32;54844:12;:10;:12::i;:::-;54825:32;;;;;;;;;;;;;;;:42;54858:8;54825:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;54923:8;54894:48;;54909:12;:10;:12::i;:::-;54894:48;;;54933:8;54894:48;;;;;;:::i;:::-;;;;;;;;54655:295;;:::o;69397:36::-;69431:2;69397:36;:::o;55850:285::-;55982:41;56001:12;:10;:12::i;:::-;56015:7;55982:18;:41::i;:::-;55974:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;56088:39;56102:4;56108:2;56112:7;56121:5;56088:13;:39::i;:::-;55850:285;;;;:::o;75506:97::-;75550:13;75583:12;;;;;;;;;;;;;;;;;75576:19;;75506:97;:::o;71871:1540::-;71948:13;71989;:11;:13::i;:::-;71982:3;:20;;71974:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;72049:17;72069:11;72076:3;72069:6;:11::i;:::-;72049:31;;72091:18;72112:12;72120:3;72112:7;:12::i;:::-;72091:33;;72135:19;72157:49;72177:27;72194:3;72199:4;72177:16;:27::i;:::-;72157:13;:49::i;:::-;72135:71;;72332:1045;72582:5;72929:3;73168:4;72400:935;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72332:13;:1045::i;:::-;72247:1145;;;;;;;;:::i;:::-;;;;;;;;;;;;;72219:1184;;;;;71871:1540;;;:::o;74837:113::-;65887:12;:10;:12::i;:::-;65876:23;;:7;:5;:7::i;:::-;:23;;;65868:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74923:19:::1;;;;;;;;;;;74922:20;74900:19;;:42;;;;;;;;;;;;;;;;;;74837:113::o:0;74271:385::-;65887:12;:10;:12::i;:::-;65876:23;;:7;:5;:7::i;:::-;:23;;;65868:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74356:11:::1;74370:13;:11;:13::i;:::-;74356:27;;74419:1;74402:14;:18;:50;;;;;74442:10;;74424:14;:28;;74402:50;74394:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;74505:6;74500:95;74521:14;74517:1;:18;74500:95;;;74557:26;74567:3;74581:1;74572:6;:10;74557:9;:26::i;:::-;74537:3;;;;;;;74500:95;;;;74618:30;74633:14;74618:10;;:14;;:30;;;;:::i;:::-;74605:10;:43;;;;65947:1;74271:385:::0;;:::o;55021:164::-;55118:4;55142:18;:25;55161:5;55142:25;;;;;;;;;;;;;;;:35;55168:8;55142:35;;;;;;;;;;;;;;;;;;;;;;;;;55135:42;;55021:164;;;;:::o;69265:32::-;;;;;;;;;;;;;:::o;66610:244::-;65887:12;:10;:12::i;:::-;65876:23;;:7;:5;:7::i;:::-;:23;;;65868:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66719:1:::1;66699:22;;:8;:22;;;;66691:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;66809:8;66780:38;;66801:6;;;;;;;;;;;66780:38;;;;;;;;;;;;66838:8;66829:6;;:17;;;;;;;;;;;;;;;;;;66610:244:::0;:::o;57602:127::-;57667:4;57691:30;57713:7;57691:12;:21;;:30;;;;:::i;:::-;57684:37;;57602:127;;;:::o;667:106::-;720:15;755:10;748:17;;667:106;:::o;63640:192::-;63742:2;63715:15;:24;63731:7;63715:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;63798:7;63794:2;63760:46;;63769:23;63784:7;63769:14;:23::i;:::-;63760:46;;;;;;;;;;;;63640:192;;:::o;13793:179::-;13851:7;13871:9;13887:1;13883;:5;13871:17;;13912:1;13907;:6;;13899:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;13963:1;13956:8;;;13793:179;;;;:::o;58594:110::-;58670:26;58680:2;58684:7;58670:26;;;;;;;;;;;;:9;:26::i;:::-;58594:110;;:::o;44326:123::-;44395:7;44422:19;44430:3;:10;;44422:7;:19::i;:::-;44415:26;;44326:123;;;:::o;57896:355::-;57989:4;58014:16;58022:7;58014;:16::i;:::-;58006:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;58090:13;58106:23;58121:7;58106:14;:23::i;:::-;58090:39;;58159:5;58148:16;;:7;:16;;;:51;;;;58192:7;58168:31;;:20;58180:7;58168:11;:20::i;:::-;:31;;;58148:51;:94;;;;58203:39;58227:5;58234:7;58203:23;:39::i;:::-;58148:94;58140:103;;;57896:355;;;;:::o;61032:599::-;61157:4;61130:31;;:23;61145:7;61130:14;:23::i;:::-;:31;;;61122:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;61258:1;61244:16;;:2;:16;;;;61236:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;61314:39;61335:4;61341:2;61345:7;61314:20;:39::i;:::-;61418:29;61435:1;61439:7;61418:8;:29::i;:::-;61460:35;61487:7;61460:13;:19;61474:4;61460:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;61506:30;61528:7;61506:13;:17;61520:2;61506:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;61549:29;61566:7;61575:2;61549:12;:16;;:29;;;;;:::i;:::-;;61615:7;61611:2;61596:27;;61605:4;61596:27;;;;;;;;;;;;61032:599;;;:::o;36107:137::-;36178:7;36213:22;36217:3;:10;;36229:5;36213:3;:22::i;:::-;36205:31;;36198:38;;36107:137;;;;:::o;44797:236::-;44877:7;44886;44907:11;44920:13;44937:22;44941:3;:10;;44953:5;44937:3;:22::i;:::-;44906:53;;;;44986:3;44978:12;;45016:5;45008:14;;44970:55;;;;;;44797:236;;;;;:::o;46083:213::-;46190:7;46241:44;46246:3;:10;;46266:3;46258:12;;46272;46241:4;:44::i;:::-;46233:53;;46210:78;;46083:213;;;;;:::o;35639:114::-;35699:7;35726:19;35734:3;:10;;35726:7;:19::i;:::-;35719:26;;35639:114;;;:::o;57017:272::-;57131:28;57141:4;57147:2;57151:7;57131:9;:28::i;:::-;57178:48;57201:4;57207:2;57211:7;57220:5;57178:22;:48::i;:::-;57170:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;57017:272;;;;:::o;70402:477::-;70451:13;70477:9;70489:21;70508:1;70503;70497:3;:7;70496:13;70489:6;:21::i;:::-;70477:33;;70521:11;70553:1;69431:2;70543:11;70535:4;:20;;;;;;70521:34;;70568:8;70587:22;:27;;;;;;;;;;;;;;69431:2;70631:6;:16;70627:145;;;70664:14;;;;;;;;;;;;;;;;;;;69431:2;70699:6;:16;70693:22;;70627:145;;;70754:6;70748:12;;70627:145;70823:8;70833:13;70842:3;70833:8;:13::i;:::-;70853:16;70865:3;70853:11;:16::i;:::-;70806:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;70792:79;;;;;;70402:477;;;:::o;71026:474::-;71076:13;71102:9;71114:21;71133:1;71128;71122:3;:7;71121:13;71114:6;:21::i;:::-;71102:33;;71146:11;71179:1;69475:3;71168:12;71160:4;:21;;;;;;71146:35;;71194:8;71213:22;:27;;;;;;;;;;;;;;69475:3;71257:6;:17;71253:147;;;71291:14;;;;;;;;;;;;;;;;;;;69475:3;71326:6;:17;71320:23;;71253:147;;;71382:6;71376:12;;71253:147;71443:8;71453:13;71462:3;71453:8;:13::i;:::-;71473:17;71486:3;71473:12;:17::i;:::-;71426:65;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;71412:80;;;;;;71026:474;;;:::o;73419:705::-;73507:13;73901:3;74024:4;73561:544;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73533:583;;73419:705;;;;:::o;67162:1911::-;67220:13;67265:1;67250:4;:11;:16;67246:31;;;67268:9;;;;;;;;;;;;;;;;67246:31;67329:19;67351:5;;;;;;;;;;;;;;;;;67329:27;;67408:18;67454:1;67449;67435:4;:11;:15;67434:21;;;;;;67429:1;:27;67408:48;;67539:20;67586:2;67573:10;:15;67562:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67539:50;;67682:10;67674:6;67667:26;67773:1;67766:5;67762:13;67828:4;67879;67873:11;67864:7;67860:25;67971:2;67963:6;67959:15;68040:784;68059:6;68050:7;68047:19;68040:784;;;68126:1;68117:7;68113:15;68102:26;;68196:7;68190:14;68326:4;68318:5;68314:2;68310:14;68306:25;68296:8;68292:40;68286:47;68281:3;68277:57;68266:9;68259:76;68381:1;68370:9;68366:17;68353:30;;68468:4;68460:5;68456:2;68452:14;68448:25;68438:8;68434:40;68428:47;68423:3;68419:57;68408:9;68401:76;68523:1;68512:9;68508:17;68495:30;;68610:4;68602:5;68599:1;68594:14;68590:25;68580:8;68576:40;68570:47;68565:3;68561:57;68550:9;68543:76;68665:1;68654:9;68650:17;68637:30;;68752:4;68744:5;68732:25;68722:8;68718:40;68712:47;68707:3;68703:57;68692:9;68685:76;68807:1;68796:9;68792:17;68779:30;;68083:741;68040:784;;;68893:1;68886:4;68880:11;68876:19;68914:1;68909:54;;;;68982:1;68977:52;;;;68869:160;;68909:54;68953:6;68948:3;68944:16;68940:1;68929:9;68925:17;68918:43;68909:54;;68977:52;69021:4;69016:3;69012:14;69008:1;68997:9;68993:17;68986:41;68869:160;;67611:1429;;;;69059:6;69052:13;;;;;67162:1911;;;;:::o;14255:158::-;14313:7;14346:1;14341;:6;;14333:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;14404:1;14400;:5;14393:12;;14255:158;;;;:::o;44087:151::-;44171:4;44195:35;44205:3;:10;;44225:3;44217:12;;44195:9;:35::i;:::-;44188:42;;44087:151;;;;:::o;58931:250::-;59027:18;59033:2;59037:7;59027:5;:18::i;:::-;59064:54;59095:1;59099:2;59103:7;59112:5;59064:22;:54::i;:::-;59056:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;58931:250;;;:::o;40895:110::-;40951:7;40978:3;:12;;:19;;;;40971:26;;40895:110;;;:::o;64445:93::-;;;;:::o;35184:137::-;35254:4;35278:35;35286:3;:10;;35306:5;35298:14;;35278:7;:35::i;:::-;35271:42;;35184:137;;;;:::o;34877:131::-;34944:4;34968:32;34973:3;:10;;34993:5;34985:14;;34968:4;:32::i;:::-;34961:39;;34877:131;;;;:::o;43510:185::-;43599:4;43623:64;43628:3;:10;;43648:3;43640:12;;43678:5;43662:23;;43654:32;;43623:4;:64::i;:::-;43616:71;;43510:185;;;;;:::o;31115:204::-;31182:7;31231:5;31210:3;:11;;:18;;;;:26;31202:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;31293:3;:11;;31305:5;31293:18;;;;;;;;;;;;;;;;31286:25;;31115:204;;;;:::o;41370:279::-;41437:7;41446;41496:5;41474:3;:12;;:19;;;;:27;41466:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;41553:22;41578:3;:12;;41591:5;41578:19;;;;;;;;;;;;;;;;;;41553:44;;41616:5;:10;;;41628:5;:12;;;41608:33;;;;;41370:279;;;;;:::o;42867:319::-;42961:7;42981:16;43000:3;:12;;:17;43013:3;43000:17;;;;;;;;;;;;42981:36;;43048:1;43036:8;:13;;43051:12;43028:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;43118:3;:12;;43142:1;43131:8;:12;43118:26;;;;;;;;;;;;;;;;;;:33;;;43111:40;;;42867:319;;;;;:::o;30652:109::-;30708:7;30735:3;:11;;:18;;;;30728:25;;30652:109;;;:::o;62897:624::-;63014:4;63041:15;:2;:13;;;:15::i;:::-;63036:60;;63080:4;63073:11;;;;63036:60;63106:23;63132:276;63189:45;;;63253:12;:10;:12::i;:::-;63284:4;63307:7;63333:5;63148:205;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63132:276;;;;;;;;;;;;;;;;;:2;:15;;;;:276;;;;;:::i;:::-;63106:302;;63419:13;63446:10;63435:32;;;;;;;;;;;;:::i;:::-;63419:48;;48046:10;63496:16;;63486:26;;;:6;:26;;;;63478:35;;;;62897:624;;;;;;;:::o;69629:135::-;69678:7;69740:13;69749:3;69740:8;:13::i;:::-;69723:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;69713:42;;;;;;69705:51;;69698:58;;69629:135;;;:::o;69865:529::-;69918:13;69957:1;69948:5;:10;69944:53;;;69975:10;;;;;;;;;;;;;;;;;;;;;69944:53;70007:12;70022:5;70007:20;;70038:14;70063:78;70078:1;70070:4;:9;70063:78;;70096:8;;;;;;;70127:2;70119:10;;;;;;;;;70063:78;;;70151:19;70183:6;70173:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70151:39;;70201:154;70217:1;70208:5;:10;70201:154;;70245:1;70235:11;;;;70312:2;70304:5;:10;;;;;;70291:2;:24;70278:39;;70261:6;70268;70261:14;;;;;;;;;;;:56;;;;;;;;;;;70341:2;70332:11;;;;;;;;;70201:154;;;70379:6;70365:21;;;;;69865:529;;;;:::o;70887:131::-;70944:13;70977:33;70986:23;71007:1;71002;70996:3;:7;70995:13;70986:8;:23::i;:::-;70977:8;:33::i;:::-;70970:40;;70887:131;;;:::o;71508:132::-;71566:13;71599:33;71608:23;71629:1;71624;71618:3;:7;71617:13;71608:8;:23::i;:::-;71599:8;:33::i;:::-;71592:40;;71508:132;;;:::o;40675:125::-;40746:4;40791:1;40770:3;:12;;:17;40783:3;40770:17;;;;;;;;;;;;:22;;40763:29;;40675:125;;;;:::o;59517:404::-;59611:1;59597:16;;:2;:16;;;;59589:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;59670:16;59678:7;59670;:16::i;:::-;59669:17;59661:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;59732:45;59761:1;59765:2;59769:7;59732:20;:45::i;:::-;59790:30;59812:7;59790:13;:17;59804:2;59790:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;59833:29;59850:7;59859:2;59833:12;:16;;:29;;;;;:::i;:::-;;59905:7;59901:2;59880:33;;59897:1;59880:33;;;;;;;;;;;;59517:404;;:::o;28807:1544::-;28873:4;28991:18;29012:3;:12;;:19;29025:5;29012:19;;;;;;;;;;;;28991:40;;29062:1;29048:10;:15;29044:1300;;29410:21;29447:1;29434:10;:14;29410:38;;29463:17;29504:1;29483:3;:11;;:18;;;;:22;29463:42;;29750:17;29770:3;:11;;29782:9;29770:22;;;;;;;;;;;;;;;;29750:42;;29916:9;29887:3;:11;;29899:13;29887:26;;;;;;;;;;;;;;;:38;;;;30035:1;30019:13;:17;29993:3;:12;;:23;30006:9;29993:23;;;;;;;;;;;:43;;;;30145:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;30240:3;:12;;:19;30253:5;30240:19;;;;;;;;;;;30233:26;;;30283:4;30276:11;;;;;;;;29044:1300;30327:5;30320:12;;;28807:1544;;;;;:::o;28217:414::-;28280:4;28302:21;28312:3;28317:5;28302:9;:21::i;:::-;28297:327;;28340:3;:11;;28357:5;28340:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28523:3;:11;;:18;;;;28501:3;:12;;:19;28514:5;28501:19;;;;;;;;;;;:40;;;;28563:4;28556:11;;;;28297:327;28607:5;28600:12;;28217:414;;;;;:::o;38175:692::-;38251:4;38367:16;38386:3;:12;;:17;38399:3;38386:17;;;;;;;;;;;;38367:36;;38432:1;38420:8;:13;38416:444;;;38487:3;:12;;38505:38;;;;;;;;38522:3;38505:38;;;;38535:5;38505:38;;;38487:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38702:3;:12;;:19;;;;38682:3;:12;;:17;38695:3;38682:17;;;;;;;;;;;:39;;;;38743:4;38736:11;;;;;38416:444;38816:5;38780:3;:12;;38804:1;38793:8;:12;38780:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;38843:5;38836:12;;;38175:692;;;;;;:::o;19234:422::-;19294:4;19502:12;19613:7;19601:20;19593:28;;19647:1;19640:4;:8;19633:15;;;19234:422;;;:::o;22154:195::-;22257:12;22289:52;22311:6;22319:4;22325:1;22328:12;22289:21;:52::i;:::-;22282:59;;22154:195;;;;;:::o;71648:215::-;71706:7;71726:12;71776:17;71785:7;71776:8;:17::i;:::-;71795:25;71804:15;71811:7;71804:6;:15::i;:::-;71795:8;:25::i;:::-;71759:62;;;;;;;;;:::i;:::-;;;;;;;;;;;;;71749:73;;;;;;71741:82;;71726:97;;71850:5;71843:4;:12;;;;;;71836:19;;;71648:215;;;:::o;30437:129::-;30510:4;30557:1;30534:3;:12;;:19;30547:5;30534:19;;;;;;;;;;;;:24;;30527:31;;30437:129;;;;:::o;23206:530::-;23333:12;23391:5;23366:21;:30;;23358:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;23458:18;23469:6;23458:10;:18::i;:::-;23450:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;23584:12;23598:23;23625:6;:11;;23645:5;23653:4;23625:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23583:75;;;;23676:52;23694:7;23703:10;23715:12;23676:17;:52::i;:::-;23669:59;;;;23206:530;;;;;;:::o;25746:742::-;25861:12;25890:7;25886:595;;;25921:10;25914:17;;;;25886:595;26055:1;26035:10;:17;:21;26031:439;;;26298:10;26292:17;26359:15;26346:10;26342:2;26338:19;26331:44;26246:148;26441:12;26434:20;;;;;;;;;;;:::i;:::-;;;;;;;;25746:742;;;;;;:::o;7:342:1:-;;109:64;124:48;165:6;124:48;:::i;:::-;109:64;:::i;:::-;100:73;;196:6;189:5;182:21;234:4;227:5;223:16;272:3;263:6;258:3;254:16;251:25;248:2;;;289:1;286;279:12;248:2;302:41;336:6;331:3;326;302:41;:::i;:::-;90:259;;;;;;:::o;355:344::-;;458:65;473:49;515:6;473:49;:::i;:::-;458:65;:::i;:::-;449:74;;546:6;539:5;532:21;584:4;577:5;573:16;622:3;613:6;608:3;604:16;601:25;598:2;;;639:1;636;629:12;598:2;652:41;686:6;681:3;676;652:41;:::i;:::-;439:260;;;;;;:::o;705:139::-;;789:6;776:20;767:29;;805:33;832:5;805:33;:::i;:::-;757:87;;;;:::o;850:133::-;;931:6;918:20;909:29;;947:30;971:5;947:30;:::i;:::-;899:84;;;;:::o;989:137::-;;1072:6;1059:20;1050:29;;1088:32;1114:5;1088:32;:::i;:::-;1040:86;;;;:::o;1132:141::-;;1219:6;1213:13;1204:22;;1235:32;1261:5;1235:32;:::i;:::-;1194:79;;;;:::o;1292:271::-;;1396:3;1389:4;1381:6;1377:17;1373:27;1363:2;;1414:1;1411;1404:12;1363:2;1454:6;1441:20;1479:78;1553:3;1545:6;1538:4;1530:6;1526:17;1479:78;:::i;:::-;1470:87;;1353:210;;;;;:::o;1583:273::-;;1688:3;1681:4;1673:6;1669:17;1665:27;1655:2;;1706:1;1703;1696:12;1655:2;1746:6;1733:20;1771:79;1846:3;1838:6;1831:4;1823:6;1819:17;1771:79;:::i;:::-;1762:88;;1645:211;;;;;:::o;1862:139::-;;1946:6;1933:20;1924:29;;1962:33;1989:5;1962:33;:::i;:::-;1914:87;;;;:::o;2007:262::-;;2115:2;2103:9;2094:7;2090:23;2086:32;2083:2;;;2131:1;2128;2121:12;2083:2;2174:1;2199:53;2244:7;2235:6;2224:9;2220:22;2199:53;:::i;:::-;2189:63;;2145:117;2073:196;;;;:::o;2275:407::-;;;2400:2;2388:9;2379:7;2375:23;2371:32;2368:2;;;2416:1;2413;2406:12;2368:2;2459:1;2484:53;2529:7;2520:6;2509:9;2505:22;2484:53;:::i;:::-;2474:63;;2430:117;2586:2;2612:53;2657:7;2648:6;2637:9;2633:22;2612:53;:::i;:::-;2602:63;;2557:118;2358:324;;;;;:::o;2688:552::-;;;;2830:2;2818:9;2809:7;2805:23;2801:32;2798:2;;;2846:1;2843;2836:12;2798:2;2889:1;2914:53;2959:7;2950:6;2939:9;2935:22;2914:53;:::i;:::-;2904:63;;2860:117;3016:2;3042:53;3087:7;3078:6;3067:9;3063:22;3042:53;:::i;:::-;3032:63;;2987:118;3144:2;3170:53;3215:7;3206:6;3195:9;3191:22;3170:53;:::i;:::-;3160:63;;3115:118;2788:452;;;;;:::o;3246:809::-;;;;;3414:3;3402:9;3393:7;3389:23;3385:33;3382:2;;;3431:1;3428;3421:12;3382:2;3474:1;3499:53;3544:7;3535:6;3524:9;3520:22;3499:53;:::i;:::-;3489:63;;3445:117;3601:2;3627:53;3672:7;3663:6;3652:9;3648:22;3627:53;:::i;:::-;3617:63;;3572:118;3729:2;3755:53;3800:7;3791:6;3780:9;3776:22;3755:53;:::i;:::-;3745:63;;3700:118;3885:2;3874:9;3870:18;3857:32;3916:18;3908:6;3905:30;3902:2;;;3948:1;3945;3938:12;3902:2;3976:62;4030:7;4021:6;4010:9;4006:22;3976:62;:::i;:::-;3966:72;;3828:220;3372:683;;;;;;;:::o;4061:401::-;;;4183:2;4171:9;4162:7;4158:23;4154:32;4151:2;;;4199:1;4196;4189:12;4151:2;4242:1;4267:53;4312:7;4303:6;4292:9;4288:22;4267:53;:::i;:::-;4257:63;;4213:117;4369:2;4395:50;4437:7;4428:6;4417:9;4413:22;4395:50;:::i;:::-;4385:60;;4340:115;4141:321;;;;;:::o;4468:407::-;;;4593:2;4581:9;4572:7;4568:23;4564:32;4561:2;;;4609:1;4606;4599:12;4561:2;4652:1;4677:53;4722:7;4713:6;4702:9;4698:22;4677:53;:::i;:::-;4667:63;;4623:117;4779:2;4805:53;4850:7;4841:6;4830:9;4826:22;4805:53;:::i;:::-;4795:63;;4750:118;4551:324;;;;;:::o;4881:260::-;;4988:2;4976:9;4967:7;4963:23;4959:32;4956:2;;;5004:1;5001;4994:12;4956:2;5047:1;5072:52;5116:7;5107:6;5096:9;5092:22;5072:52;:::i;:::-;5062:62;;5018:116;4946:195;;;;:::o;5147:282::-;;5265:2;5253:9;5244:7;5240:23;5236:32;5233:2;;;5281:1;5278;5271:12;5233:2;5324:1;5349:63;5404:7;5395:6;5384:9;5380:22;5349:63;:::i;:::-;5339:73;;5295:127;5223:206;;;;:::o;5435:375::-;;5553:2;5541:9;5532:7;5528:23;5524:32;5521:2;;;5569:1;5566;5559:12;5521:2;5640:1;5629:9;5625:17;5612:31;5670:18;5662:6;5659:30;5656:2;;;5702:1;5699;5692:12;5656:2;5730:63;5785:7;5776:6;5765:9;5761:22;5730:63;:::i;:::-;5720:73;;5583:220;5511:299;;;;:::o;5816:262::-;;5924:2;5912:9;5903:7;5899:23;5895:32;5892:2;;;5940:1;5937;5930:12;5892:2;5983:1;6008:53;6053:7;6044:6;6033:9;6029:22;6008:53;:::i;:::-;5998:63;;5954:117;5882:196;;;;:::o;6084:179::-;;6174:46;6216:3;6208:6;6174:46;:::i;:::-;6252:4;6247:3;6243:14;6229:28;;6164:99;;;;:::o;6269:142::-;6372:32;6398:5;6372:32;:::i;:::-;6367:3;6360:45;6350:61;;:::o;6417:118::-;6504:24;6522:5;6504:24;:::i;:::-;6499:3;6492:37;6482:53;;:::o;6571:732::-;;6719:54;6767:5;6719:54;:::i;:::-;6789:86;6868:6;6863:3;6789:86;:::i;:::-;6782:93;;6899:56;6949:5;6899:56;:::i;:::-;6978:7;7009:1;6994:284;7019:6;7016:1;7013:13;6994:284;;;7095:6;7089:13;7122:63;7181:3;7166:13;7122:63;:::i;:::-;7115:70;;7208:60;7261:6;7208:60;:::i;:::-;7198:70;;7054:224;7041:1;7038;7034:9;7029:14;;6994:284;;;6998:14;7294:3;7287:10;;6695:608;;;;;;;:::o;7309:109::-;7390:21;7405:5;7390:21;:::i;:::-;7385:3;7378:34;7368:50;;:::o;7424:360::-;;7538:38;7570:5;7538:38;:::i;:::-;7592:70;7655:6;7650:3;7592:70;:::i;:::-;7585:77;;7671:52;7716:6;7711:3;7704:4;7697:5;7693:16;7671:52;:::i;:::-;7748:29;7770:6;7748:29;:::i;:::-;7743:3;7739:39;7732:46;;7514:270;;;;;:::o;7790:373::-;;7922:38;7954:5;7922:38;:::i;:::-;7976:88;8057:6;8052:3;7976:88;:::i;:::-;7969:95;;8073:52;8118:6;8113:3;8106:4;8099:5;8095:16;8073:52;:::i;:::-;8150:6;8145:3;8141:16;8134:23;;7898:265;;;;;:::o;8169:364::-;;8285:39;8318:5;8285:39;:::i;:::-;8340:71;8404:6;8399:3;8340:71;:::i;:::-;8333:78;;8420:52;8465:6;8460:3;8453:4;8446:5;8442:16;8420:52;:::i;:::-;8497:29;8519:6;8497:29;:::i;:::-;8492:3;8488:39;8481:46;;8261:272;;;;;:::o;8539:377::-;;8673:39;8706:5;8673:39;:::i;:::-;8728:89;8810:6;8805:3;8728:89;:::i;:::-;8721:96;;8826:52;8871:6;8866:3;8859:4;8852:5;8848:16;8826:52;:::i;:::-;8903:6;8898:3;8894:16;8887:23;;8649:267;;;;;:::o;8922:322::-;;9103:84;9185:1;9180:3;9103:84;:::i;:::-;9096:91;;9213:4;9209:1;9204:3;9200:11;9193:25;9240:1;9235:3;9231:11;9224:18;;9086:158;;;:::o;9246:346::-;;9405:67;9469:2;9464:3;9405:67;:::i;:::-;9398:74;;9498:34;9494:1;9489:3;9485:11;9478:55;9560:4;9555:2;9550:3;9546:12;9539:26;9587:2;9582:3;9578:12;9571:19;;9392:200;;;:::o;9594:313::-;;9753:67;9817:2;9812:3;9753:67;:::i;:::-;9746:74;;9846:33;9842:1;9837:3;9833:11;9826:54;9902:2;9897:3;9893:12;9886:19;;9740:167;;;:::o;9909:362::-;;10068:67;10132:2;10127:3;10068:67;:::i;:::-;10061:74;;10161:34;10157:1;10152:3;10148:11;10141:55;10223:20;10218:2;10213:3;10209:12;10202:42;10266:2;10261:3;10257:12;10250:19;;10055:216;;;:::o;10273:352::-;;10432:67;10496:2;10491:3;10432:67;:::i;:::-;10425:74;;10525:34;10521:1;10516:3;10512:11;10505:55;10587:10;10582:2;10577:3;10573:12;10566:32;10620:2;10615:3;10611:12;10604:19;;10419:206;;;:::o;10627:350::-;;10786:67;10850:2;10845:3;10786:67;:::i;:::-;10779:74;;10879:34;10875:1;10870:3;10866:11;10859:55;10941:8;10936:2;10931:3;10927:12;10920:30;10972:2;10967:3;10963:12;10956:19;;10773:204;;;:::o;10979:380::-;;11156:84;11238:1;11233:3;11156:84;:::i;:::-;11149:91;;11266:66;11262:1;11257:3;11253:11;11246:87;11355:1;11350:3;11346:11;11339:18;;11143:216;;;:::o;11361:310::-;;11520:67;11584:2;11579:3;11520:67;:::i;:::-;11513:74;;11613:30;11609:1;11604:3;11600:11;11593:51;11666:2;11661:3;11657:12;11650:19;;11507:164;;;:::o;11673:476::-;;11850:85;11932:2;11927:3;11850:85;:::i;:::-;11843:92;;11961:66;11957:1;11952:3;11948:11;11941:87;12055:66;12050:2;12045:3;12041:12;12034:88;12144:2;12139:3;12135:12;12128:19;;11837:312;;;:::o;12151:309::-;;12310:67;12374:2;12369:3;12310:67;:::i;:::-;12303:74;;12403:29;12399:1;12394:3;12390:11;12383:50;12455:2;12450:3;12446:12;12439:19;;12297:163;;;:::o;12462:311::-;;12621:67;12685:2;12680:3;12621:67;:::i;:::-;12614:74;;12714:31;12710:1;12705:3;12701:11;12694:52;12768:2;12763:3;12759:12;12752:19;;12608:165;;;:::o;12775:919::-;;12952:86;13034:3;13029;12952:86;:::i;:::-;12945:93;;13064:66;13060:1;13055:3;13051:11;13044:87;13158:66;13153:2;13148:3;13144:12;13137:88;13252:66;13247:2;13242:3;13238:12;13231:88;13346:66;13341:2;13336:3;13332:12;13325:88;13441:34;13435:3;13430;13426:13;13419:57;13504:66;13498:3;13493;13489:13;13482:89;13599:66;13593:3;13588;13584:13;13577:89;13688:3;13683;13679:13;13672:20;;12939:755;;;:::o;13696:314::-;;13855:67;13919:2;13914:3;13855:67;:::i;:::-;13848:74;;13948:34;13944:1;13939:3;13935:11;13928:55;14005:2;14000:3;13996:12;13989:19;;13842:168;;;:::o;14012:348::-;;14171:67;14235:2;14230:3;14171:67;:::i;:::-;14164:74;;14264:34;14260:1;14255:3;14251:11;14244:55;14326:6;14321:2;14316:3;14312:12;14305:28;14355:2;14350:3;14346:12;14339:19;;14158:202;;;:::o;14362:307::-;;14521:67;14585:2;14580:3;14521:67;:::i;:::-;14514:74;;14614:27;14610:1;14605:3;14601:11;14594:48;14664:2;14659:3;14655:12;14648:19;;14508:161;;;:::o;14671:312::-;;14830:67;14894:2;14889:3;14830:67;:::i;:::-;14823:74;;14923:32;14919:1;14914:3;14910:11;14903:53;14978:2;14973:3;14969:12;14962:19;;14817:166;;;:::o;14985:350::-;;15144:67;15208:2;15203:3;15144:67;:::i;:::-;15137:74;;15237:34;15233:1;15228:3;15224:11;15217:55;15299:8;15294:2;15289:3;15285:12;15278:30;15330:2;15325:3;15321:12;15314:19;;15131:204;;;:::o;15337:356::-;;15496:67;15560:2;15555:3;15496:67;:::i;:::-;15489:74;;15589:34;15585:1;15580:3;15576:11;15569:55;15651:14;15646:2;15641:3;15637:12;15630:36;15688:2;15683:3;15679:12;15672:19;;15483:210;;;:::o;15695:476::-;;15872:85;15954:2;15949:3;15872:85;:::i;:::-;15865:92;;15983:66;15979:1;15974:3;15970:11;15963:87;16077:66;16072:2;16067:3;16063:12;16056:88;16166:2;16161:3;16157:12;16150:19;;15859:312;;;:::o;16173:368::-;;16332:67;16396:2;16391:3;16332:67;:::i;:::-;16325:74;;16425:34;16421:1;16416:3;16412:11;16405:55;16487:26;16482:2;16477:3;16473:12;16466:48;16536:2;16531:3;16527:12;16520:19;;16319:222;;;:::o;16543:380::-;;16720:84;16802:1;16797:3;16720:84;:::i;:::-;16713:91;;16830:66;16826:1;16821:3;16817:11;16810:87;16919:1;16914:3;16910:11;16903:18;;16707:216;;;:::o;16925:317::-;;17102:84;17184:1;17179:3;17102:84;:::i;:::-;17095:91;;17212:3;17208:1;17203:3;17199:11;17192:24;17238:1;17233:3;17229:11;17222:18;;17089:153;;;:::o;17244:354::-;;17403:67;17467:2;17462:3;17403:67;:::i;:::-;17396:74;;17496:34;17492:1;17487:3;17483:11;17476:55;17558:12;17553:2;17548:3;17544:12;17537:34;17593:2;17588:3;17584:12;17577:19;;17390:208;;;:::o;17600:476::-;;17777:85;17859:2;17854:3;17777:85;:::i;:::-;17770:92;;17888:66;17884:1;17879:3;17875:11;17868:87;17982:66;17977:2;17972:3;17968:12;17961:88;18071:2;18066:3;18062:12;18055:19;;17764:312;;;:::o;18078:380::-;;18255:84;18337:1;18332:3;18255:84;:::i;:::-;18248:91;;18365:66;18361:1;18356:3;18352:11;18345:87;18454:1;18449:3;18445:11;18438:18;;18242:216;;;:::o;18460:346::-;;18619:67;18683:2;18678:3;18619:67;:::i;:::-;18612:74;;18712:34;18708:1;18703:3;18699:11;18692:55;18774:4;18769:2;18764:3;18760:12;18753:26;18801:2;18796:3;18792:12;18785:19;;18606:200;;;:::o;18808:314::-;;18967:67;19031:2;19026:3;18967:67;:::i;:::-;18960:74;;19060:34;19056:1;19051:3;19047:11;19040:55;19117:2;19112:3;19108:12;19101:19;;18954:168;;;:::o;19124:309::-;;19301:84;19383:1;19378:3;19301:84;:::i;:::-;19294:91;;19407:3;19403:1;19398:3;19394:11;19387:24;19429:1;19424:3;19420:11;19413:18;;19288:145;;;:::o;19435:340::-;;19590:67;19654:2;19649:3;19590:67;:::i;:::-;19583:74;;19679:34;19675:1;19670:3;19666:11;19659:55;19737:14;19732:2;19727:3;19723:12;19716:36;19770:2;19765:3;19761:12;19754:19;;19581:194;;;:::o;19777:302::-;;19932:67;19996:2;19991:3;19932:67;:::i;:::-;19925:74;;20021:34;20017:1;20012:3;20008:11;20001:55;20074:2;20069:3;20065:12;20058:19;;19923:156;;;:::o;20081:337::-;;20236:67;20300:2;20295:3;20236:67;:::i;:::-;20229:74;;20325:34;20321:1;20316:3;20312:11;20305:55;20383:11;20378:2;20373:3;20369:12;20362:33;20413:2;20408:3;20404:12;20397:19;;20227:191;;;:::o;20420:309::-;;20593:84;20675:1;20670:3;20593:84;:::i;:::-;20586:91;;20699:3;20695:1;20690:3;20686:11;20679:24;20725:1;20720:3;20716:11;20709:18;;20584:145;;;:::o;20731:382::-;;20908:85;20990:2;20985:3;20908:85;:::i;:::-;20901:92;;21019:66;21015:1;21010:3;21006:11;20999:87;21108:2;21103:3;21099:12;21092:19;;20895:218;;;:::o;21115:300::-;;21274:67;21338:2;21333:3;21274:67;:::i;:::-;21267:74;;21367:20;21363:1;21358:3;21354:11;21347:41;21410:2;21405:3;21401:12;21394:19;;21261:154;;;:::o;21417:317::-;;21594:84;21676:1;21671:3;21594:84;:::i;:::-;21587:91;;21704:3;21700:1;21695:3;21691:11;21684:24;21730:1;21725:3;21721:11;21714:18;;21581:153;;;:::o;21736:345::-;;21895:67;21959:2;21954:3;21895:67;:::i;:::-;21888:74;;21988:34;21984:1;21979:3;21975:11;21968:55;22050:3;22045:2;22040:3;22036:12;22029:25;22076:2;22071:3;22067:12;22060:19;;21882:199;;;:::o;22083:347::-;;22260:85;22342:2;22337:3;22260:85;:::i;:::-;22253:92;;22371:31;22367:1;22362:3;22358:11;22351:52;22425:2;22420:3;22416:12;22409:19;;22247:183;;;:::o;22432:332::-;;22609:85;22691:2;22686:3;22609:85;:::i;:::-;22602:92;;22720:16;22716:1;22711:3;22707:11;22700:37;22759:2;22754:3;22750:12;22743:19;;22596:168;;;:::o;22766:361::-;;22925:67;22989:2;22984:3;22925:67;:::i;:::-;22918:74;;23018:34;23014:1;23009:3;23005:11;22998:55;23080:19;23075:2;23070:3;23066:12;23059:41;23122:2;23117:3;23113:12;23106:19;;22912:215;;;:::o;23129:311::-;;23288:67;23352:2;23347:3;23288:67;:::i;:::-;23281:74;;23381:31;23377:1;23372:3;23368:11;23361:52;23435:2;23430:3;23426:12;23419:19;;23275:165;;;:::o;23442:322::-;;23619:84;23701:1;23696:3;23619:84;:::i;:::-;23612:91;;23729:8;23725:1;23720:3;23716:11;23709:29;23760:1;23755:3;23751:11;23744:18;;23606:158;;;:::o;23766:382::-;;23943:85;24025:2;24020:3;23943:85;:::i;:::-;23936:92;;24054:66;24050:1;24045:3;24041:11;24034:87;24143:2;24138:3;24134:12;24127:19;;23930:218;;;:::o;24150:382::-;;24327:85;24409:2;24404:3;24327:85;:::i;:::-;24320:92;;24438:66;24434:1;24429:3;24425:11;24418:87;24527:2;24522:3;24518:12;24511:19;;24314:218;;;:::o;24534:344::-;;24711:85;24793:2;24788:3;24711:85;:::i;:::-;24704:92;;24822:28;24818:1;24813:3;24809:11;24802:49;24873:2;24868:3;24864:12;24857:19;;24698:180;;;:::o;24880:382::-;;25057:85;25139:2;25134:3;25057:85;:::i;:::-;25050:92;;25168:66;25164:1;25159:3;25155:11;25148:87;25257:2;25252:3;25248:12;25241:19;;25044:218;;;:::o;25264:100::-;25337:24;25355:5;25337:24;:::i;:::-;25332:3;25325:37;25319:45;;:::o;25366:110::-;25449:24;25467:5;25449:24;:::i;:::-;25444:3;25437:37;25431:45;;:::o;25478:259::-;;25626:93;25715:3;25706:6;25626:93;:::i;:::-;25619:100;;25732:3;25725:10;;25612:125;;;;:::o;25739:263::-;;25889:95;25980:3;25971:6;25889:95;:::i;:::-;25882:102;;25997:3;25990:10;;25875:127;;;;:::o;26004:419::-;;26202:95;26293:3;26284:6;26202:95;:::i;:::-;26195:102;;26310:95;26401:3;26392:6;26310:95;:::i;:::-;26303:102;;26418:3;26411:10;;26188:235;;;;;:::o;26425:837::-;;26772:95;26863:3;26854:6;26772:95;:::i;:::-;26765:102;;26880:95;26971:3;26962:6;26880:95;:::i;:::-;26873:102;;26988:148;27132:3;26988:148;:::i;:::-;26981:155;;27149:95;27240:3;27231:6;27149:95;:::i;:::-;27142:102;;27257:3;27250:10;;26758:504;;;;;;:::o;27264:1991::-;;28068:148;28212:3;28068:148;:::i;:::-;28061:155;;28229:148;28373:3;28229:148;:::i;:::-;28222:155;;28390:95;28481:3;28472:6;28390:95;:::i;:::-;28383:102;;28498:148;28642:3;28498:148;:::i;:::-;28491:155;;28659:148;28803:3;28659:148;:::i;:::-;28652:155;;28820:95;28911:3;28902:6;28820:95;:::i;:::-;28813:102;;28928:148;29072:3;28928:148;:::i;:::-;28921:155;;29089:148;29233:3;29089:148;:::i;:::-;29082:155;;29250:3;29243:10;;28054:1201;;;;;:::o;29257:5291::-;;31321:148;31465:3;31321:148;:::i;:::-;31314:155;;31482:148;31626:3;31482:148;:::i;:::-;31475:155;;31643:148;31787:3;31643:148;:::i;:::-;31636:155;;31804:95;31895:3;31886:6;31804:95;:::i;:::-;31797:102;;31912:148;32056:3;31912:148;:::i;:::-;31905:155;;32073:148;32217:3;32073:148;:::i;:::-;32066:155;;32234:148;32378:3;32234:148;:::i;:::-;32227:155;;32395:148;32539:3;32395:148;:::i;:::-;32388:155;;32556:148;32700:3;32556:148;:::i;:::-;32549:155;;32717:148;32861:3;32717:148;:::i;:::-;32710:155;;32878:95;32969:3;32960:6;32878:95;:::i;:::-;32871:102;;32986:148;33130:3;32986:148;:::i;:::-;32979:155;;33147:148;33291:3;33147:148;:::i;:::-;33140:155;;33308:148;33452:3;33308:148;:::i;:::-;33301:155;;33469:148;33613:3;33469:148;:::i;:::-;33462:155;;33630:148;33774:3;33630:148;:::i;:::-;33623:155;;33791:95;33882:3;33873:6;33791:95;:::i;:::-;33784:102;;33899:148;34043:3;33899:148;:::i;:::-;33892:155;;34060:148;34204:3;34060:148;:::i;:::-;34053:155;;34221:148;34365:3;34221:148;:::i;:::-;34214:155;;34382:148;34526:3;34382:148;:::i;:::-;34375:155;;34543:3;34536:10;;31307:3241;;;;;;:::o;34550:525::-;;34801:148;34945:3;34801:148;:::i;:::-;34794:155;;34962:95;35053:3;35044:6;34962:95;:::i;:::-;34955:102;;35070:3;35063:10;;34787:288;;;;:::o;35077:210::-;;35204:2;35193:9;35189:18;35181:26;;35213:71;35281:1;35270:9;35266:17;35257:6;35213:71;:::i;:::-;35175:112;;;;:::o;35289:644::-;;35534:3;35523:9;35519:19;35511:27;;35544:87;35628:1;35617:9;35613:17;35604:6;35544:87;:::i;:::-;35637:72;35705:2;35694:9;35690:18;35681:6;35637:72;:::i;:::-;35715;35783:2;35772:9;35768:18;35759:6;35715:72;:::i;:::-;35830:9;35824:4;35820:20;35815:2;35804:9;35800:18;35793:48;35854:76;35925:4;35916:6;35854:76;:::i;:::-;35846:84;;35505:428;;;;;;;:::o;35935:357::-;;36112:2;36101:9;36097:18;36089:26;;36157:9;36151:4;36147:20;36143:1;36132:9;36128:17;36121:47;36181:108;36284:4;36275:6;36181:108;:::i;:::-;36173:116;;36083:209;;;;:::o;36294:198::-;;36415:2;36404:9;36400:18;36392:26;;36424:65;36486:1;36475:9;36471:17;36462:6;36424:65;:::i;:::-;36386:106;;;;:::o;36494:297::-;;36641:2;36630:9;36626:18;36618:26;;36686:9;36680:4;36676:20;36672:1;36661:9;36657:17;36650:47;36710:78;36783:4;36774:6;36710:78;:::i;:::-;36702:86;;36612:179;;;;:::o;36793:403::-;;36993:2;36982:9;36978:18;36970:26;;37038:9;37032:4;37028:20;37024:1;37013:9;37009:17;37002:47;37062:131;37188:4;37062:131;:::i;:::-;37054:139;;36964:232;;;:::o;37198:403::-;;37398:2;37387:9;37383:18;37375:26;;37443:9;37437:4;37433:20;37429:1;37418:9;37414:17;37407:47;37467:131;37593:4;37467:131;:::i;:::-;37459:139;;37369:232;;;:::o;37603:403::-;;37803:2;37792:9;37788:18;37780:26;;37848:9;37842:4;37838:20;37834:1;37823:9;37819:17;37812:47;37872:131;37998:4;37872:131;:::i;:::-;37864:139;;37774:232;;;:::o;38008:403::-;;38208:2;38197:9;38193:18;38185:26;;38253:9;38247:4;38243:20;38239:1;38228:9;38224:17;38217:47;38277:131;38403:4;38277:131;:::i;:::-;38269:139;;38179:232;;;:::o;38413:403::-;;38613:2;38602:9;38598:18;38590:26;;38658:9;38652:4;38648:20;38644:1;38633:9;38629:17;38622:47;38682:131;38808:4;38682:131;:::i;:::-;38674:139;;38584:232;;;:::o;38818:403::-;;39018:2;39007:9;39003:18;38995:26;;39063:9;39057:4;39053:20;39049:1;39038:9;39034:17;39027:47;39087:131;39213:4;39087:131;:::i;:::-;39079:139;;38989:232;;;:::o;39223:403::-;;39423:2;39412:9;39408:18;39400:26;;39468:9;39462:4;39458:20;39454:1;39443:9;39439:17;39432:47;39492:131;39618:4;39492:131;:::i;:::-;39484:139;;39394:232;;;:::o;39628:403::-;;39828:2;39817:9;39813:18;39805:26;;39873:9;39867:4;39863:20;39859:1;39848:9;39844:17;39837:47;39897:131;40023:4;39897:131;:::i;:::-;39889:139;;39799:232;;;:::o;40033:403::-;;40233:2;40222:9;40218:18;40210:26;;40278:9;40272:4;40268:20;40264:1;40253:9;40249:17;40242:47;40302:131;40428:4;40302:131;:::i;:::-;40294:139;;40204:232;;;:::o;40438:403::-;;40638:2;40627:9;40623:18;40615:26;;40683:9;40677:4;40673:20;40669:1;40658:9;40654:17;40647:47;40707:131;40833:4;40707:131;:::i;:::-;40699:139;;40609:232;;;:::o;40843:403::-;;41043:2;41032:9;41028:18;41020:26;;41088:9;41082:4;41078:20;41074:1;41063:9;41059:17;41052:47;41112:131;41238:4;41112:131;:::i;:::-;41104:139;;41014:232;;;:::o;41248:403::-;;41448:2;41437:9;41433:18;41425:26;;41493:9;41487:4;41483:20;41479:1;41468:9;41464:17;41457:47;41517:131;41643:4;41517:131;:::i;:::-;41509:139;;41419:232;;;:::o;41653:403::-;;41853:2;41842:9;41838:18;41830:26;;41898:9;41892:4;41888:20;41884:1;41873:9;41869:17;41862:47;41922:131;42048:4;41922:131;:::i;:::-;41914:139;;41824:232;;;:::o;42058:403::-;;42258:2;42247:9;42243:18;42235:26;;42303:9;42297:4;42293:20;42289:1;42278:9;42274:17;42267:47;42327:131;42453:4;42327:131;:::i;:::-;42319:139;;42229:232;;;:::o;42463:403::-;;42663:2;42652:9;42648:18;42640:26;;42708:9;42702:4;42698:20;42694:1;42683:9;42679:17;42672:47;42732:131;42858:4;42732:131;:::i;:::-;42724:139;;42634:232;;;:::o;42868:403::-;;43068:2;43057:9;43053:18;43045:26;;43113:9;43107:4;43103:20;43099:1;43088:9;43084:17;43077:47;43137:131;43263:4;43137:131;:::i;:::-;43129:139;;43039:232;;;:::o;43273:403::-;;43473:2;43462:9;43458:18;43450:26;;43518:9;43512:4;43508:20;43504:1;43493:9;43489:17;43482:47;43542:131;43668:4;43542:131;:::i;:::-;43534:139;;43444:232;;;:::o;43678:403::-;;43878:2;43867:9;43863:18;43855:26;;43923:9;43917:4;43913:20;43909:1;43898:9;43894:17;43887:47;43947:131;44073:4;43947:131;:::i;:::-;43939:139;;43849:232;;;:::o;44083:403::-;;44283:2;44272:9;44268:18;44260:26;;44328:9;44322:4;44318:20;44314:1;44303:9;44299:17;44292:47;44352:131;44478:4;44352:131;:::i;:::-;44344:139;;44254:232;;;:::o;44488:403::-;;44688:2;44677:9;44673:18;44665:26;;44733:9;44727:4;44723:20;44719:1;44708:9;44704:17;44697:47;44757:131;44883:4;44757:131;:::i;:::-;44749:139;;44659:232;;;:::o;44893:403::-;;45093:2;45082:9;45078:18;45070:26;;45138:9;45132:4;45128:20;45124:1;45113:9;45109:17;45102:47;45162:131;45288:4;45162:131;:::i;:::-;45154:139;;45064:232;;;:::o;45298:403::-;;45498:2;45487:9;45483:18;45475:26;;45543:9;45537:4;45533:20;45529:1;45518:9;45514:17;45507:47;45567:131;45693:4;45567:131;:::i;:::-;45559:139;;45469:232;;;:::o;45703:403::-;;45903:2;45892:9;45888:18;45880:26;;45948:9;45942:4;45938:20;45934:1;45923:9;45919:17;45912:47;45972:131;46098:4;45972:131;:::i;:::-;45964:139;;45874:232;;;:::o;46108:403::-;;46308:2;46297:9;46293:18;46285:26;;46353:9;46347:4;46343:20;46339:1;46328:9;46324:17;46317:47;46377:131;46503:4;46377:131;:::i;:::-;46369:139;;46279:232;;;:::o;46513:403::-;;46713:2;46702:9;46698:18;46690:26;;46758:9;46752:4;46748:20;46744:1;46733:9;46729:17;46722:47;46782:131;46908:4;46782:131;:::i;:::-;46774:139;;46684:232;;;:::o;46918:210::-;;47045:2;47034:9;47030:18;47022:26;;47054:71;47122:1;47111:9;47107:17;47098:6;47054:71;:::i;:::-;47016:112;;;;:::o;47130:254::-;;47192:2;47186:9;47176:19;;47230:4;47222:6;47218:17;47329:6;47317:10;47314:22;47293:18;47281:10;47278:34;47275:62;47272:2;;;47340:13;;:::i;:::-;47272:2;47371:10;47367:2;47360:22;47170:214;;;;:::o;47386:298::-;;47529:18;47521:6;47518:30;47515:2;;;47551:13;;:::i;:::-;47515:2;47623:4;47619:9;47612:4;47604:6;47600:17;47596:33;47588:41;;47676:4;47670;47666:15;47658:23;;47452:232;;;:::o;47686:299::-;;47830:18;47822:6;47819:30;47816:2;;;47852:13;;:::i;:::-;47816:2;47924:4;47920:9;47913:4;47905:6;47901:17;47897:33;47889:41;;47977:4;47971;47967:15;47959:23;;47753:232;;;:::o;47987:120::-;;48073:3;48065:11;;48099:4;48094:3;48090:14;48082:22;;48059:48;;;:::o;48109:106::-;;48206:5;48200:12;48190:22;;48183:32;;;:::o;48217:90::-;;48298:5;48292:12;48282:22;;48275:32;;;:::o;48309:91::-;;48391:5;48385:12;48375:22;;48368:32;;;:::o;48402:105::-;;48500:4;48495:3;48491:14;48483:22;;48477:30;;;:::o;48509:172::-;;48638:6;48633:3;48626:19;48674:4;48669:3;48665:14;48650:29;;48620:61;;;;:::o;48683:156::-;;48796:6;48791:3;48784:19;48832:4;48827:3;48823:14;48808:29;;48778:61;;;;:::o;48841:139::-;;48975:3;48960:18;;48954:26;;;;:::o;48982:157::-;;49096:6;49091:3;49084:19;49132:4;49127:3;49123:14;49108:29;;49078:61;;;;:::o;49141:140::-;;49276:3;49261:18;;49255:26;;;;:::o;49283:88::-;;49345:24;49363:5;49345:24;:::i;:::-;49334:35;;49328:43;;;:::o;49373:96::-;;49443:24;49461:5;49443:24;:::i;:::-;49432:35;;49426:43;;;:::o;49471:82::-;;49544:5;49537:13;49530:21;49519:32;;49513:40;;;:::o;49555:141::-;;49627:66;49620:5;49616:78;49605:89;;49599:97;;;:::o;49698:118::-;;49771:42;49764:5;49760:54;49749:65;;49743:73;;;:::o;49818:69::-;;49880:5;49869:16;;49863:24;;;:::o;49889:138::-;49969:6;49964:3;49959;49946:30;50023:1;50014:6;50009:3;50005:16;49998:27;49940:87;;;:::o;50029:263::-;50093:1;50099:101;50113:6;50110:1;50107:13;50099:101;;;50190:1;50185:3;50181:11;50175:18;50171:1;50166:3;50162:11;50155:39;50135:2;50132:1;50128:10;50123:15;;50099:101;;;50214:6;50211:1;50208:13;50205:2;;;50282:1;50273:6;50268:3;50264:16;50257:27;50205:2;50078:214;;;;:::o;50294:40::-;50323:9;50336:94;;50424:2;50420:7;50415:2;50408:5;50404:14;50400:28;50390:38;;50384:46;;;:::o;50432:114::-;50501:24;50519:5;50501:24;:::i;:::-;50494:5;50491:35;50481:2;;50540:1;50537;50530:12;50481:2;50475:71;:::o;50548:108::-;50614:21;50629:5;50614:21;:::i;:::-;50607:5;50604:32;50594:2;;50650:1;50647;50640:12;50594:2;50588:68;:::o;50658:112::-;50726:23;50743:5;50726:23;:::i;:::-;50719:5;50716:34;50706:2;;50764:1;50761;50754:12;50706:2;50700:70;:::o;50772:114::-;50841:24;50859:5;50841:24;:::i;:::-;50834:5;50831:35;50821:2;;50880:1;50877;50870:12;50821:2;50815:71;:::o
Swarm Source
ipfs://5a2c9b7f8bb8a0598bccb97e5b8f389dfe4d1e4c95bbdaeba04ee98c00fff511
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.