ERC-721
Overview
Max Total Supply
356 CFRACTALS
Holders
134
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 CFRACTALSLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Fractal
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-11-12 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/math/SafeMath.sol pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ 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) { unchecked { 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) { unchecked { 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) { unchecked { // 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) { unchecked { 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) { unchecked { 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) { return a + b; } /** * @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) { 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) { return a * b; } /** * @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. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { 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) { 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) { unchecked { 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. * * 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) { unchecked { 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) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File: @openzeppelin/contracts/utils/Counters.sol pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File: @openzeppelin/contracts/utils/Strings.sol pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal 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); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } // File: @openzeppelin/contracts/utils/Context.sol pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _setOwner(_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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/utils/Address.sol pragma solidity ^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; 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"); (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"); (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"); (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"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, 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/extensions/IERC721Enumerable.sol pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 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/extensions/IERC721Metadata.sol pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not 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 _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[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); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[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"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @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` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol pragma solidity ^0.8.0; /** * @title ERC721 Burnable Token * @dev ERC721 Token that can be irreversibly burned (destroyed). */ abstract contract ERC721Burnable is Context, ERC721 { /** * @dev Burns `tokenId`. See {ERC721-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved"); _burn(tokenId); } } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol pragma solidity ^0.8.0; /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is ERC721 { using Strings for uint256; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721URIStorage: 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)); } return super.tokenURI(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), "ERC721URIStorage: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @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 override { super._burn(tokenId); if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev 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 override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // File: contracts/fractals.sol // @author: @0x1337_BEEF // B E E F J U S T B E E F J U S T S O M E 1 3 3 7 B E E F // <pls accept this as my attempt for cool & very hip minmalistic pixel art> pragma solidity ^0.8.4; abstract contract ContextMixin { function msgSender() internal view returns (address payable sender) { if (msg.sender == address(this)) { bytes memory array = msg.data; uint256 index = msg.data.length; // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those. assembly { sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff) } } else { sender = payable(msg.sender); } return sender; } } contract Initializable { bool inited = false; modifier initializer() { require(!inited, "already inited"); _; inited = true; } } contract EIP712Base is Initializable { struct EIP712Domain { string name; string version; address verifyingContract; bytes32 salt; } string constant public ERC712_VERSION = "1"; bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256( bytes( "EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)" ) ); bytes32 internal domainSeperator; // supposed to be called once while initializing. // one of the contracts that inherits this contract follows proxy pattern // so it is not possible to do this in a constructor function _initializeEIP712( string memory name ) internal initializer { _setDomainSeperator(name); } function _setDomainSeperator(string memory name) internal { domainSeperator = keccak256( abi.encode( EIP712_DOMAIN_TYPEHASH, keccak256(bytes(name)), keccak256(bytes(ERC712_VERSION)), address(this), bytes32(getChainId()) ) ); } function getDomainSeperator() public view returns (bytes32) { return domainSeperator; } function getChainId() public view returns (uint256) { uint256 id; assembly { id := chainid() } return id; } /** * Accept message hash and returns hash message in EIP712 compatible form * So that it can be used to recover signer from signature signed using EIP712 formatted data * https://eips.ethereum.org/EIPS/eip-712 * "\\x19" makes the encoding deterministic * "\\x01" is the version byte to make it compatible to EIP-191 */ function toTypedMessageHash(bytes32 messageHash) internal view returns (bytes32) { return keccak256( abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash) ); } } contract NativeMetaTransaction is EIP712Base { using SafeMath for uint256; bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256( bytes( "MetaTransaction(uint256 nonce,address from,bytes functionSignature)" ) ); event MetaTransactionExecuted( address userAddress, address payable relayerAddress, bytes functionSignature ); mapping(address => uint256) nonces; /* * Meta transaction structure. * No point of including value field here as if user is doing value transfer then he has the funds to pay for gas * He should call the desired function directly in that case. */ struct MetaTransaction { uint256 nonce; address from; bytes functionSignature; } function executeMetaTransaction( address userAddress, bytes memory functionSignature, bytes32 sigR, bytes32 sigS, uint8 sigV ) public payable returns (bytes memory) { MetaTransaction memory metaTx = MetaTransaction({ nonce: nonces[userAddress], from: userAddress, functionSignature: functionSignature }); require( verify(userAddress, metaTx, sigR, sigS, sigV), "Signer and signature do not match" ); // increase nonce for user (to avoid re-use) nonces[userAddress] = nonces[userAddress].add(1); emit MetaTransactionExecuted( userAddress, payable(msg.sender), functionSignature ); // Append userAddress and relayer address at the end to extract it from calling context (bool success, bytes memory returnData) = address(this).call( abi.encodePacked(functionSignature, userAddress) ); require(success, "Function call not successful"); return returnData; } function hashMetaTransaction(MetaTransaction memory metaTx) internal pure returns (bytes32) { return keccak256( abi.encode( META_TRANSACTION_TYPEHASH, metaTx.nonce, metaTx.from, keccak256(metaTx.functionSignature) ) ); } function getNonce(address user) public view returns (uint256 nonce) { nonce = nonces[user]; } function verify( address signer, MetaTransaction memory metaTx, bytes32 sigR, bytes32 sigS, uint8 sigV ) internal view returns (bool) { require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER"); return signer == ecrecover( toTypedMessageHash(hashMetaTransaction(metaTx)), sigV, sigR, sigS ); } } contract OwnableDelegateProxy {} contract ProxyRegistry { mapping(address => OwnableDelegateProxy) public proxies; } abstract contract ERC721Tradable is ContextMixin, ERC721Enumerable, NativeMetaTransaction, ERC721URIStorage, Ownable, ERC721Burnable { using SafeMath for uint; using Counters for Counters.Counter; using ECDSA for bytes32; //Has to be the first variable to recieve address address proxyRegistryAddress = 0xa5409ec958C83C3f309868babACA7c86DCB077c1; Counters.Counter private _tokenIdCounter; //Trying something new, please no DMCA or crap, reachout first thanks! string constant ArtLicense = "All rights reserved to token owner"; //Fractonomics 101 uint public constant maxFractals = 4333; uint public constant fractalPrice = 0.03 ether; uint public publicSale = 0; mapping(uint => uint) public minted; constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) { _initializeEIP712(_name); } function baseTokenURI() virtual public view returns (string memory); function tokenURI(uint256 _tokenId) override(ERC721, ERC721URIStorage) public view returns (string memory) { return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId))); } /** * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings. */ function isApprovedForAll(address owner, address operator) override public view returns (bool) { // Whitelist OpenSea proxy contract for easy trading. ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); if (address(proxyRegistry.proxies(owner)) == operator) { return true; } return super.isApprovedForAll(owner, operator); } /** * This is used instead of msg.sender as transactions won't be sent by the original token owner, but by OpenSea. */ function _msgSender() internal override view returns (address sender) { return ContextMixin.msgSender(); } function mintX(address to, uint amount) private { for(uint i = 0; i < amount; i++){ _tokenIdCounter.increment(); _safeMint(to, _tokenIdCounter.current()); } } function hashTransaction(uint amount, uint nonce) public pure returns (bytes32) { bytes32 _hash = keccak256(abi.encode(amount, nonce)); return _hash; } function signTransaction(bytes32 _hash) public pure returns (bytes32) { return _hash.toEthSignedMessageHash(); } function matchSignerAdmin(bytes32 messageHash, bytes memory _signature) public pure returns (bool) { return messageHash.recover(_signature) == 0xe2BB689629B990B35af2D15DF43E908CaD3f6D30; } function privMint(uint amount, uint nonce, bytes memory _signature) public payable { uint total = totalSupply(); address dearestFractalOwner = _msgSender(); require(total + amount <= maxFractals, "Not that many fractals left!"); require(msg.value >= fractalPrice.mul(amount), "Not enuf moulah! NGMI"); bytes32 hash = hashTransaction(amount, nonce); require(minted[uint(hash)] == 0, "Token already minted"); require(matchSignerAdmin(signTransaction(hash), _signature), "Signature mismatch"); mintX(dearestFractalOwner, amount); minted[uint(hash)] = 1; } function mint(uint amount) public payable { uint total = totalSupply(); address dearestFractalOwner = _msgSender(); require(publicSale > 0, "Public sale disabled!"); require(total + amount <= maxFractals, "Not that many fractals left!"); require(msg.value >= fractalPrice.mul(amount), "Not enuf moulah! NGMI"); mintX(dearestFractalOwner, amount); } function reserve(address to, uint amount) public onlyOwner { uint total = totalSupply(); require(total + amount <= maxFractals, "Not that many fractals left!"); mintX(to, amount); } function setPublicState(uint stateValue) public onlyOwner { publicSale = stateValue; } function getFractalsByOwner(address _owner) public view returns (uint[] memory) { uint tokenCount = balanceOf(_owner); uint[] memory fractalIDs = new uint[](tokenCount); for (uint i = 0; i < tokenCount; i++) { fractalIDs[i] = tokenOfOwnerByIndex(_owner, i); } return fractalIDs; } function withdrawAll() public onlyOwner { uint balance = address(this).balance; require(balance > 0, "Address: Zero balance"); (bool success2, ) = msg.sender.call{value: address(this).balance}(""); require(success2, "Transfer failiure!"); } function _beforeTokenTransfer(address from, address to, uint tokenId) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId); } function _burn(uint tokenId) internal override(ERC721, ERC721URIStorage) onlyOwner { super._burn(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } } contract Fractal is ERC721Tradable { constructor() ERC721Tradable("CodeFractal", "CFRACTALS") { } //API to be migrated after minting => IPFS/ARWEAVE string public baseTokenURIs = "https://www.codefractals.xyz/api/metadata/"; function setBaseURI(string memory baseURI) public onlyOwner { baseTokenURIs = baseURI; } function baseTokenURI() override public view returns (string memory) { return baseTokenURIs; } function _baseURI() internal view virtual override returns (string memory) { return baseTokenURIs; } }
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":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address payable","name":"relayerAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","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":"ERC712_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURIs","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes","name":"functionSignature","type":"bytes"},{"internalType":"bytes32","name":"sigR","type":"bytes32"},{"internalType":"bytes32","name":"sigS","type":"bytes32"},{"internalType":"uint8","name":"sigV","type":"uint8"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fractalPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeperator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getFractalsByOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"hashTransaction","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"matchSignerAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"maxFractals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"minted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"privMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"reserve","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":[{"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":"uint256","name":"stateValue","type":"uint256"}],"name":"setPublicState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"signTransaction","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","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":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
600a805460ff19169055600f80546001600160a01b03191673a5409ec958c83c3f309868babaca7c86dcb077c1179055600060115560e0604052602a60808181529062003c5d60a03980516200005e91601391602090910190620002de565b503480156200006c57600080fd5b50604080518082018252600b81526a10dbd919519c9858dd185b60aa1b602080830191825283518085019094526009845268434652414354414c5360b81b90840152815191929183918391620000c591600091620002de565b508051620000db906001906020840190620002de565b505050620000f8620000f26200010b60201b60201c565b62000127565b620001038262000179565b5050620003c1565b600062000122620001dd60201b62001c771760201c565b905090565b600e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a5460ff1615620001c25760405162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015260640160405180910390fd5b620001cd816200023c565b50600a805460ff19166001179055565b6000333014156200023657600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b03169150620002399050565b50335b90565b6040518060800160405280604f815260200162003c87604f9139805160209182012082519282019290922060408051808201825260018152603160f81b90840152805180840194909452838101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401523060808401524660a0808501919091528151808503909101815260c090930190528151910120600b55565b828054620002ec9062000384565b90600052602060002090601f0160209004810192826200031057600085556200035b565b82601f106200032b57805160ff19168380011785556200035b565b828001600101855582156200035b579182015b828111156200035b5782518255916020019190600101906200033e565b50620003699291506200036d565b5090565b5b808211156200036957600081556001016200036e565b600181811c908216806200039957607f821691505b60208210811415620003bb57634e487b7160e01b600052602260045260246000fd5b50919050565b61388c80620003d16000396000f3fe6080604052600436106102c65760003560e01c8063715018a611610179578063a0712d68116100d6578063cc47a40b1161008a578063e985e9c511610064578063e985e9c514610790578063f2fde38b146107b0578063f3fb2b5c146107d057600080fd5b8063cc47a40b1461073b578063d547cfb71461075b578063e0f4ea901461077057600080fd5b8063a5f46763116100bb578063a5f46763146106e0578063b88d4fde146106fb578063c87b56dd1461071b57600080fd5b8063a0712d68146106ad578063a22cb465146106c057600080fd5b806386dc46b71161012d578063955c20b211610112578063955c20b21461065857806395d89b41146106785780639ec9dd751461068d57600080fd5b806386dc46b71461061a5780638da5cb5b1461063a57600080fd5b80637fb289be1161015e5780637fb289be146105c257806381be25ac146105ef578063853828b61461060557600080fd5b8063715018a6146105805780637dc0bf3f1461059557600080fd5b80632d0335ab1161022757806342966c68116101db57806355f804b3116101c057806355f804b3146105205780636352211e1461054057806370a082311461056057600080fd5b806342966c68146104e05780634f6ccce71461050057600080fd5b806333bc1c5c1161020c57806333bc1c5c146104975780633408e470146104ad57806342842e0e146104c057600080fd5b80632d0335ab146104415780632f745c591461047757600080fd5b80630c53c51c1161027e57806318160ddd1161026357806318160ddd146103ed57806320379ee51461040c57806323b872dd1461042157600080fd5b80630c53c51c146103915780630f7e5970146103a457600080fd5b8063081812fc116102af578063081812fc14610322578063095ea7b31461035a5780630a27b52b1461037c57600080fd5b806301ffc9a7146102cb57806306fdde0314610300575b600080fd5b3480156102d757600080fd5b506102eb6102e63660046133e4565b6107e3565b60405190151581526020015b60405180910390f35b34801561030c57600080fd5b506103156107f4565b6040516102f79190613659565b34801561032e57600080fd5b5061034261033d366004613384565b610886565b6040516001600160a01b0390911681526020016102f7565b34801561036657600080fd5b5061037a610375366004613358565b610931565b005b34801561038857600080fd5b50610315610a75565b61031561039f3660046132da565b610b03565b3480156103b057600080fd5b506103156040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b3480156103f957600080fd5b506008545b6040519081526020016102f7565b34801561041857600080fd5b50600b546103fe565b34801561042d57600080fd5b5061037a61043c3660046131fa565b610d09565b34801561044d57600080fd5b506103fe61045c3660046131a4565b6001600160a01b03166000908152600c602052604090205490565b34801561048357600080fd5b506103fe610492366004613358565b610d97565b3480156104a357600080fd5b506103fe60115481565b3480156104b957600080fd5b50466103fe565b3480156104cc57600080fd5b5061037a6104db3660046131fa565b610e3f565b3480156104ec57600080fd5b5061037a6104fb366004613384565b610e5a565b34801561050c57600080fd5b506103fe61051b366004613384565b610ee3565b34801561052c57600080fd5b5061037a61053b36600461343b565b610f87565b34801561054c57600080fd5b5061034261055b366004613384565b611017565b34801561056c57600080fd5b506103fe61057b3660046131a4565b6110a2565b34801561058c57600080fd5b5061037a61113c565b3480156105a157600080fd5b506103fe6105b0366004613384565b60126020526000908152604090205481565b3480156105ce57600080fd5b506105e26105dd3660046131a4565b6111c1565b6040516102f79190613615565b3480156105fb57600080fd5b506103fe6110ed81565b34801561061157600080fd5b5061037a611263565b34801561062657600080fd5b506103fe610635366004613484565b6113c2565b34801561064657600080fd5b50600e546001600160a01b0316610342565b34801561066457600080fd5b506103fe610673366004613384565b611401565b34801561068457600080fd5b5061031561140c565b34801561069957600080fd5b5061037a6106a8366004613384565b61141b565b61037a6106bb366004613384565b611499565b3480156106cc57600080fd5b5061037a6106db3660046132a7565b6115c9565b3480156106ec57600080fd5b506103fe666a94d74f43000081565b34801561070757600080fd5b5061037a61071636600461323b565b6116cb565b34801561072757600080fd5b50610315610736366004613384565b611760565b34801561074757600080fd5b5061037a610756366004613358565b61179a565b34801561076757600080fd5b50610315611885565b34801561077c57600080fd5b506102eb61078b36600461339d565b611894565b34801561079c57600080fd5b506102eb6107ab3660046131c1565b6118d0565b3480156107bc57600080fd5b5061037a6107cb3660046131a4565b6119b9565b61037a6107de3660046134a6565b611ab7565b60006107ee82611cd4565b92915050565b606060008054610803906136fa565b80601f016020809104026020016040519081016040528092919081815260200182805461082f906136fa565b801561087c5780601f106108515761010080835404028352916020019161087c565b820191906000526020600020905b81548152906001019060200180831161085f57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166109155760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061093c82611017565b9050806001600160a01b0316836001600160a01b031614156109c65760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f7200000000000000000000000000000000000000000000000000000000000000606482015260840161090c565b806001600160a01b03166109d8611d12565b6001600160a01b031614806109f457506109f4816107ab611d12565b610a665760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161090c565b610a708383611d21565b505050565b60138054610a82906136fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610aae906136fa565b8015610afb5780601f10610ad057610100808354040283529160200191610afb565b820191906000526020600020905b815481529060010190602001808311610ade57829003601f168201915b505050505081565b60408051606081810183526001600160a01b0388166000818152600c602090815290859020548452830152918101869052610b418782878787611d9c565b610bb35760405162461bcd60e51b815260206004820152602160248201527f5369676e657220616e64207369676e617475726520646f206e6f74206d61746360448201527f6800000000000000000000000000000000000000000000000000000000000000606482015260840161090c565b6001600160a01b0387166000908152600c6020526040902054610bd7906001611ea4565b6001600160a01b0388166000908152600c60205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b90610c2790899033908a906135a4565b60405180910390a1600080306001600160a01b0316888a604051602001610c4f92919061353e565b60408051601f1981840301815290829052610c6991613522565b6000604051808303816000865af19150503d8060008114610ca6576040519150601f19603f3d011682016040523d82523d6000602084013e610cab565b606091505b509150915081610cfd5760405162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604482015260640161090c565b98975050505050505050565b610d1a610d14611d12565b82611eb7565b610d8c5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f766564000000000000000000000000000000606482015260840161090c565b610a70838383611f97565b6000610da2836110a2565b8210610e165760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e6473000000000000000000000000000000000000000000606482015260840161090c565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610a70838383604051806020016040528060008152506116cb565b610e65610d14611d12565b610ed75760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656400000000000000000000000000000000606482015260840161090c565b610ee08161217c565b50565b6000610eee60085490565b8210610f625760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e64730000000000000000000000000000000000000000606482015260840161090c565b60088281548110610f7557610f756137bc565b90600052602060002001549050919050565b610f8f611d12565b6001600160a01b0316610faa600e546001600160a01b031690565b6001600160a01b0316146110005760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b805161101390601390602084019061303f565b5050565b6000818152600260205260408120546001600160a01b0316806107ee5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e0000000000000000000000000000000000000000000000606482015260840161090c565b60006001600160a01b0382166111205760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f206164647265737300000000000000000000000000000000000000000000606482015260840161090c565b506001600160a01b031660009081526003602052604090205490565b611144611d12565b6001600160a01b031661115f600e546001600160a01b031690565b6001600160a01b0316146111b55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b6111bf60006121fe565b565b606060006111ce836110a2565b905060008167ffffffffffffffff8111156111eb576111eb6137d2565b604051908082528060200260200182016040528015611214578160200160208202803683370190505b50905060005b8281101561125b5761122c8582610d97565b82828151811061123e5761123e6137bc565b60209081029190910101528061125381613735565b91505061121a565b509392505050565b61126b611d12565b6001600160a01b0316611286600e546001600160a01b031690565b6001600160a01b0316146112dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b478061132a5760405162461bcd60e51b815260206004820152601560248201527f416464726573733a205a65726f2062616c616e63650000000000000000000000604482015260640161090c565b604051600090339047908381818185875af1925050503d806000811461136c576040519150601f19603f3d011682016040523d82523d6000602084013e611371565b606091505b50509050806110135760405162461bcd60e51b815260206004820152601260248201527f5472616e73666572206661696c69757265210000000000000000000000000000604482015260640161090c565b60008083836040516020016113e1929190918252602082015260400190565b60408051808303601f190181529190528051602090910120949350505050565b60006107ee8261225d565b606060018054610803906136fa565b611423611d12565b6001600160a01b031661143e600e546001600160a01b031690565b6001600160a01b0316146114945760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b601155565b60006114a460085490565b905060006114b0611d12565b90506000601154116115045760405162461bcd60e51b815260206004820152601560248201527f5075626c69632073616c652064697361626c6564210000000000000000000000604482015260640161090c565b6110ed611511848461366c565b111561155f5760405162461bcd60e51b815260206004820152601c60248201527f4e6f742074686174206d616e79206672616374616c73206c6566742100000000604482015260640161090c565b611570666a94d74f430000846122b1565b3410156115bf5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420656e7566206d6f756c616821204e474d490000000000000000000000604482015260640161090c565b610a7081846122bd565b6115d1611d12565b6001600160a01b0316826001600160a01b031614156116325760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161090c565b806005600061163f611d12565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611683611d12565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116bf911515815260200190565b60405180910390a35050565b6116dc6116d6611d12565b83611eb7565b61174e5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f766564000000000000000000000000000000606482015260840161090c565b61175a848484846122fa565b50505050565b606061176a611885565b61177383612383565b604051602001611784929190613575565b6040516020818303038152906040529050919050565b6117a2611d12565b6001600160a01b03166117bd600e546001600160a01b031690565b6001600160a01b0316146118135760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b600061181e60085490565b90506110ed61182d838361366c565b111561187b5760405162461bcd60e51b815260206004820152601c60248201527f4e6f742074686174206d616e79206672616374616c73206c6566742100000000604482015260640161090c565b610a7083836122bd565b606060138054610803906136fa565b60006118a083836124b5565b6001600160a01b031673e2bb689629b990b35af2d15df43e908cad3f6d306001600160a01b031614905092915050565b600f546040517fc45527910000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015260009281169190841690829063c45527919060240160206040518083038186803b15801561193657600080fd5b505afa15801561194a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196e919061341e565b6001600160a01b031614156119875760019150506107ee565b6001600160a01b0380851660009081526005602090815260408083209387168352929052205460ff165b949350505050565b6119c1611d12565b6001600160a01b03166119dc600e546001600160a01b031690565b6001600160a01b031614611a325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b6001600160a01b038116611aae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161090c565b610ee0816121fe565b6000611ac260085490565b90506000611ace611d12565b90506110ed611add868461366c565b1115611b2b5760405162461bcd60e51b815260206004820152601c60248201527f4e6f742074686174206d616e79206672616374616c73206c6566742100000000604482015260640161090c565b611b3c666a94d74f430000866122b1565b341015611b8b5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420656e7566206d6f756c616821204e474d490000000000000000000000604482015260640161090c565b6000611b9786866113c2565b60008181526012602052604090205490915015611bf65760405162461bcd60e51b815260206004820152601460248201527f546f6b656e20616c7265616479206d696e746564000000000000000000000000604482015260640161090c565b611c08611c0282611401565b85611894565b611c545760405162461bcd60e51b815260206004820152601260248201527f5369676e6174757265206d69736d617463680000000000000000000000000000604482015260640161090c565b611c5e82876122bd565b6000908152601260205260409020600190555050505050565b600033301415611cce57600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b03169150611cd19050565b50335b90565b60006001600160e01b031982167f780e9d630000000000000000000000000000000000000000000000000000000014806107ee57506107ee826124d1565b6000611d1c611c77565b905090565b6000818152600460205260409020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091558190611d6382611017565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006001600160a01b038616611e1a5760405162461bcd60e51b815260206004820152602560248201527f4e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5360448201527f49474e4552000000000000000000000000000000000000000000000000000000606482015260840161090c565b6001611e2d611e288761256c565b6125cc565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015611e7b573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b6000611eb0828461366c565b9392505050565b6000818152600260205260408120546001600160a01b0316611f415760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e0000000000000000000000000000000000000000606482015260840161090c565b6000611f4c83611017565b9050806001600160a01b0316846001600160a01b03161480611f875750836001600160a01b0316611f7c84610886565b6001600160a01b0316145b806119b157506119b181856118d0565b826001600160a01b0316611faa82611017565b6001600160a01b0316146120265760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e0000000000000000000000000000000000000000000000606482015260840161090c565b6001600160a01b0382166120a15760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161090c565b6120ac838383612617565b6120b7600082611d21565b6001600160a01b03831660009081526003602052604081208054600192906120e09084906136b7565b90915550506001600160a01b038216600090815260036020526040812080546001929061210e90849061366c565b9091555050600081815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b612184611d12565b6001600160a01b031661219f600e546001600160a01b031690565b6001600160a01b0316146121f55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b610ee081612622565b600e80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c015b604051602081830303815290604052805190602001209050919050565b6000611eb08284613698565b60005b81811015610a70576122d6601080546001019055565b6122e8836122e360105490565b612662565b806122f281613735565b9150506122c0565b612305848484611f97565b6123118484848461267c565b61175a5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161090c565b6060816123c357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156123ed57806123d781613735565b91506123e69050600a83613684565b91506123c7565b60008167ffffffffffffffff811115612408576124086137d2565b6040519080825280601f01601f191660200182016040528015612432576020820181803683370190505b5090505b84156119b1576124476001836136b7565b9150612454600a86613750565b61245f90603061366c565b60f81b818381518110612474576124746137bc565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506124ae600a86613684565b9450612436565b60008060006124c485856127ff565b9150915061125b8161286f565b60006001600160e01b031982167f80ac58cd00000000000000000000000000000000000000000000000000000000148061253457506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806107ee57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146107ee565b60006040518060800160405280604381526020016138146043913980516020918201208351848301516040808701518051908601209051612294950193845260208401929092526001600160a01b03166040830152606082015260800190565b60006125d7600b5490565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201612294565b610a70838383612a2a565b61262b81612ae2565b6000818152600d602052604090208054612644906136fa565b159050610ee0576000818152600d60205260408120610ee0916130c3565b611013828260405180602001604052806000815250612b96565b60006001600160a01b0384163b156127f457836001600160a01b031663150b7a026126a5611d12565b8786866040518563ffffffff1660e01b81526004016126c794939291906135d9565b602060405180830381600087803b1580156126e157600080fd5b505af1925050508015612711575060408051601f3d908101601f1916820190925261270e91810190613401565b60015b6127c1573d80801561273f576040519150601f19603f3d011682016040523d82523d6000602084013e612744565b606091505b5080516127b95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161090c565b805181602001fd5b6001600160e01b0319167f150b7a02000000000000000000000000000000000000000000000000000000001490506119b1565b506001949350505050565b6000808251604114156128365760208301516040840151606085015160001a61282a87828585612c1f565b94509450505050612868565b8251604014156128605760208301516040840151612855868383612d0c565b935093505050612868565b506000905060025b9250929050565b600081600481111561288357612883613790565b141561288c5750565b60018160048111156128a0576128a0613790565b14156128ee5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161090c565b600281600481111561290257612902613790565b14156129505760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161090c565b600381600481111561296457612964613790565b14156129bd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161090c565b60048160048111156129d1576129d1613790565b1415610ee05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161090c565b6001600160a01b038316612a8557612a8081600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612aa8565b816001600160a01b0316836001600160a01b031614612aa857612aa88382612d54565b6001600160a01b038216612abf57610a7081612df1565b826001600160a01b0316826001600160a01b031614610a7057610a708282612ea0565b6000612aed82611017565b9050612afb81600084612617565b612b06600083611d21565b6001600160a01b0381166000908152600360205260408120805460019290612b2f9084906136b7565b9091555050600082815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff19169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b612ba08383612ee4565b612bad600084848461267c565b610a705760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161090c565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c565750600090506003612d03565b8460ff16601b14158015612c6e57508460ff16601c14155b15612c7f5750600090506004612d03565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612cd3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612cfc57600060019250925050612d03565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831660ff84901c601b01612d4687828885612c1f565b935093505050935093915050565b60006001612d61846110a2565b612d6b91906136b7565b600083815260076020526040902054909150808214612dbe576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612e03906001906136b7565b60008381526009602052604081205460088054939450909284908110612e2b57612e2b6137bc565b906000526020600020015490508060088381548110612e4c57612e4c6137bc565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612e8457612e846137a6565b6001900381819060005260206000200160009055905550505050565b6000612eab836110a2565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216612f3a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161090c565b6000818152600260205260409020546001600160a01b031615612f9f5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161090c565b612fab60008383612617565b6001600160a01b0382166000908152600360205260408120805460019290612fd490849061366c565b9091555050600081815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461304b906136fa565b90600052602060002090601f01602090048101928261306d57600085556130b3565b82601f1061308657805160ff19168380011785556130b3565b828001600101855582156130b3579182015b828111156130b3578251825591602001919060010190613098565b506130bf9291506130f9565b5090565b5080546130cf906136fa565b6000825580601f106130df575050565b601f016020900490600052602060002090810190610ee091905b5b808211156130bf57600081556001016130fa565b600067ffffffffffffffff80841115613129576131296137d2565b604051601f8501601f19908116603f01168101908282118183101715613151576131516137d2565b8160405280935085815286868601111561316a57600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261319557600080fd5b611eb08383356020850161310e565b6000602082840312156131b657600080fd5b8135611eb0816137e8565b600080604083850312156131d457600080fd5b82356131df816137e8565b915060208301356131ef816137e8565b809150509250929050565b60008060006060848603121561320f57600080fd5b833561321a816137e8565b9250602084013561322a816137e8565b929592945050506040919091013590565b6000806000806080858703121561325157600080fd5b843561325c816137e8565b9350602085013561326c816137e8565b925060408501359150606085013567ffffffffffffffff81111561328f57600080fd5b61329b87828801613184565b91505092959194509250565b600080604083850312156132ba57600080fd5b82356132c5816137e8565b9150602083013580151581146131ef57600080fd5b600080600080600060a086880312156132f257600080fd5b85356132fd816137e8565b9450602086013567ffffffffffffffff81111561331957600080fd5b61332588828901613184565b9450506040860135925060608601359150608086013560ff8116811461334a57600080fd5b809150509295509295909350565b6000806040838503121561336b57600080fd5b8235613376816137e8565b946020939093013593505050565b60006020828403121561339657600080fd5b5035919050565b600080604083850312156133b057600080fd5b82359150602083013567ffffffffffffffff8111156133ce57600080fd5b6133da85828601613184565b9150509250929050565b6000602082840312156133f657600080fd5b8135611eb0816137fd565b60006020828403121561341357600080fd5b8151611eb0816137fd565b60006020828403121561343057600080fd5b8151611eb0816137e8565b60006020828403121561344d57600080fd5b813567ffffffffffffffff81111561346457600080fd5b8201601f8101841361347557600080fd5b6119b18482356020840161310e565b6000806040838503121561349757600080fd5b50508035926020909101359150565b6000806000606084860312156134bb57600080fd5b8335925060208401359150604084013567ffffffffffffffff8111156134e057600080fd5b6134ec86828701613184565b9150509250925092565b6000815180845261350e8160208601602086016136ce565b601f01601f19169290920160200192915050565b600082516135348184602087016136ce565b9190910192915050565b600083516135508184602088016136ce565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b600083516135878184602088016136ce565b83519083019061359b8183602088016136ce565b01949350505050565b60006001600160a01b038086168352808516602084015250606060408301526135d060608301846134f6565b95945050505050565b60006001600160a01b0380871683528086166020840152508360408301526080606083015261360b60808301846134f6565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561364d57835183529284019291840191600101613631565b50909695505050505050565b602081526000611eb060208301846134f6565b6000821982111561367f5761367f613764565b500190565b6000826136935761369361377a565b500490565b60008160001904831182151516156136b2576136b2613764565b500290565b6000828210156136c9576136c9613764565b500390565b60005b838110156136e95781810151838201526020016136d1565b8381111561175a5750506000910152565b600181811c9082168061370e57607f821691505b6020821081141561372f57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561374957613749613764565b5060010190565b60008261375f5761375f61377a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610ee057600080fd5b6001600160e01b031981168114610ee057600080fdfe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529a2646970667358221220baecad6163a1a1f6cb12ad35fd26927be07a6b11326d177e2059bab27ba990b064736f6c6343000807003368747470733a2f2f7777772e636f64656672616374616c732e78797a2f6170692f6d657461646174612f454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c7429
Deployed Bytecode
0x6080604052600436106102c65760003560e01c8063715018a611610179578063a0712d68116100d6578063cc47a40b1161008a578063e985e9c511610064578063e985e9c514610790578063f2fde38b146107b0578063f3fb2b5c146107d057600080fd5b8063cc47a40b1461073b578063d547cfb71461075b578063e0f4ea901461077057600080fd5b8063a5f46763116100bb578063a5f46763146106e0578063b88d4fde146106fb578063c87b56dd1461071b57600080fd5b8063a0712d68146106ad578063a22cb465146106c057600080fd5b806386dc46b71161012d578063955c20b211610112578063955c20b21461065857806395d89b41146106785780639ec9dd751461068d57600080fd5b806386dc46b71461061a5780638da5cb5b1461063a57600080fd5b80637fb289be1161015e5780637fb289be146105c257806381be25ac146105ef578063853828b61461060557600080fd5b8063715018a6146105805780637dc0bf3f1461059557600080fd5b80632d0335ab1161022757806342966c68116101db57806355f804b3116101c057806355f804b3146105205780636352211e1461054057806370a082311461056057600080fd5b806342966c68146104e05780634f6ccce71461050057600080fd5b806333bc1c5c1161020c57806333bc1c5c146104975780633408e470146104ad57806342842e0e146104c057600080fd5b80632d0335ab146104415780632f745c591461047757600080fd5b80630c53c51c1161027e57806318160ddd1161026357806318160ddd146103ed57806320379ee51461040c57806323b872dd1461042157600080fd5b80630c53c51c146103915780630f7e5970146103a457600080fd5b8063081812fc116102af578063081812fc14610322578063095ea7b31461035a5780630a27b52b1461037c57600080fd5b806301ffc9a7146102cb57806306fdde0314610300575b600080fd5b3480156102d757600080fd5b506102eb6102e63660046133e4565b6107e3565b60405190151581526020015b60405180910390f35b34801561030c57600080fd5b506103156107f4565b6040516102f79190613659565b34801561032e57600080fd5b5061034261033d366004613384565b610886565b6040516001600160a01b0390911681526020016102f7565b34801561036657600080fd5b5061037a610375366004613358565b610931565b005b34801561038857600080fd5b50610315610a75565b61031561039f3660046132da565b610b03565b3480156103b057600080fd5b506103156040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b3480156103f957600080fd5b506008545b6040519081526020016102f7565b34801561041857600080fd5b50600b546103fe565b34801561042d57600080fd5b5061037a61043c3660046131fa565b610d09565b34801561044d57600080fd5b506103fe61045c3660046131a4565b6001600160a01b03166000908152600c602052604090205490565b34801561048357600080fd5b506103fe610492366004613358565b610d97565b3480156104a357600080fd5b506103fe60115481565b3480156104b957600080fd5b50466103fe565b3480156104cc57600080fd5b5061037a6104db3660046131fa565b610e3f565b3480156104ec57600080fd5b5061037a6104fb366004613384565b610e5a565b34801561050c57600080fd5b506103fe61051b366004613384565b610ee3565b34801561052c57600080fd5b5061037a61053b36600461343b565b610f87565b34801561054c57600080fd5b5061034261055b366004613384565b611017565b34801561056c57600080fd5b506103fe61057b3660046131a4565b6110a2565b34801561058c57600080fd5b5061037a61113c565b3480156105a157600080fd5b506103fe6105b0366004613384565b60126020526000908152604090205481565b3480156105ce57600080fd5b506105e26105dd3660046131a4565b6111c1565b6040516102f79190613615565b3480156105fb57600080fd5b506103fe6110ed81565b34801561061157600080fd5b5061037a611263565b34801561062657600080fd5b506103fe610635366004613484565b6113c2565b34801561064657600080fd5b50600e546001600160a01b0316610342565b34801561066457600080fd5b506103fe610673366004613384565b611401565b34801561068457600080fd5b5061031561140c565b34801561069957600080fd5b5061037a6106a8366004613384565b61141b565b61037a6106bb366004613384565b611499565b3480156106cc57600080fd5b5061037a6106db3660046132a7565b6115c9565b3480156106ec57600080fd5b506103fe666a94d74f43000081565b34801561070757600080fd5b5061037a61071636600461323b565b6116cb565b34801561072757600080fd5b50610315610736366004613384565b611760565b34801561074757600080fd5b5061037a610756366004613358565b61179a565b34801561076757600080fd5b50610315611885565b34801561077c57600080fd5b506102eb61078b36600461339d565b611894565b34801561079c57600080fd5b506102eb6107ab3660046131c1565b6118d0565b3480156107bc57600080fd5b5061037a6107cb3660046131a4565b6119b9565b61037a6107de3660046134a6565b611ab7565b60006107ee82611cd4565b92915050565b606060008054610803906136fa565b80601f016020809104026020016040519081016040528092919081815260200182805461082f906136fa565b801561087c5780601f106108515761010080835404028352916020019161087c565b820191906000526020600020905b81548152906001019060200180831161085f57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166109155760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061093c82611017565b9050806001600160a01b0316836001600160a01b031614156109c65760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f7200000000000000000000000000000000000000000000000000000000000000606482015260840161090c565b806001600160a01b03166109d8611d12565b6001600160a01b031614806109f457506109f4816107ab611d12565b610a665760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161090c565b610a708383611d21565b505050565b60138054610a82906136fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610aae906136fa565b8015610afb5780601f10610ad057610100808354040283529160200191610afb565b820191906000526020600020905b815481529060010190602001808311610ade57829003601f168201915b505050505081565b60408051606081810183526001600160a01b0388166000818152600c602090815290859020548452830152918101869052610b418782878787611d9c565b610bb35760405162461bcd60e51b815260206004820152602160248201527f5369676e657220616e64207369676e617475726520646f206e6f74206d61746360448201527f6800000000000000000000000000000000000000000000000000000000000000606482015260840161090c565b6001600160a01b0387166000908152600c6020526040902054610bd7906001611ea4565b6001600160a01b0388166000908152600c60205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b90610c2790899033908a906135a4565b60405180910390a1600080306001600160a01b0316888a604051602001610c4f92919061353e565b60408051601f1981840301815290829052610c6991613522565b6000604051808303816000865af19150503d8060008114610ca6576040519150601f19603f3d011682016040523d82523d6000602084013e610cab565b606091505b509150915081610cfd5760405162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604482015260640161090c565b98975050505050505050565b610d1a610d14611d12565b82611eb7565b610d8c5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f766564000000000000000000000000000000606482015260840161090c565b610a70838383611f97565b6000610da2836110a2565b8210610e165760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e6473000000000000000000000000000000000000000000606482015260840161090c565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610a70838383604051806020016040528060008152506116cb565b610e65610d14611d12565b610ed75760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656400000000000000000000000000000000606482015260840161090c565b610ee08161217c565b50565b6000610eee60085490565b8210610f625760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e64730000000000000000000000000000000000000000606482015260840161090c565b60088281548110610f7557610f756137bc565b90600052602060002001549050919050565b610f8f611d12565b6001600160a01b0316610faa600e546001600160a01b031690565b6001600160a01b0316146110005760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b805161101390601390602084019061303f565b5050565b6000818152600260205260408120546001600160a01b0316806107ee5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e0000000000000000000000000000000000000000000000606482015260840161090c565b60006001600160a01b0382166111205760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f206164647265737300000000000000000000000000000000000000000000606482015260840161090c565b506001600160a01b031660009081526003602052604090205490565b611144611d12565b6001600160a01b031661115f600e546001600160a01b031690565b6001600160a01b0316146111b55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b6111bf60006121fe565b565b606060006111ce836110a2565b905060008167ffffffffffffffff8111156111eb576111eb6137d2565b604051908082528060200260200182016040528015611214578160200160208202803683370190505b50905060005b8281101561125b5761122c8582610d97565b82828151811061123e5761123e6137bc565b60209081029190910101528061125381613735565b91505061121a565b509392505050565b61126b611d12565b6001600160a01b0316611286600e546001600160a01b031690565b6001600160a01b0316146112dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b478061132a5760405162461bcd60e51b815260206004820152601560248201527f416464726573733a205a65726f2062616c616e63650000000000000000000000604482015260640161090c565b604051600090339047908381818185875af1925050503d806000811461136c576040519150601f19603f3d011682016040523d82523d6000602084013e611371565b606091505b50509050806110135760405162461bcd60e51b815260206004820152601260248201527f5472616e73666572206661696c69757265210000000000000000000000000000604482015260640161090c565b60008083836040516020016113e1929190918252602082015260400190565b60408051808303601f190181529190528051602090910120949350505050565b60006107ee8261225d565b606060018054610803906136fa565b611423611d12565b6001600160a01b031661143e600e546001600160a01b031690565b6001600160a01b0316146114945760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b601155565b60006114a460085490565b905060006114b0611d12565b90506000601154116115045760405162461bcd60e51b815260206004820152601560248201527f5075626c69632073616c652064697361626c6564210000000000000000000000604482015260640161090c565b6110ed611511848461366c565b111561155f5760405162461bcd60e51b815260206004820152601c60248201527f4e6f742074686174206d616e79206672616374616c73206c6566742100000000604482015260640161090c565b611570666a94d74f430000846122b1565b3410156115bf5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420656e7566206d6f756c616821204e474d490000000000000000000000604482015260640161090c565b610a7081846122bd565b6115d1611d12565b6001600160a01b0316826001600160a01b031614156116325760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161090c565b806005600061163f611d12565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611683611d12565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116bf911515815260200190565b60405180910390a35050565b6116dc6116d6611d12565b83611eb7565b61174e5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f766564000000000000000000000000000000606482015260840161090c565b61175a848484846122fa565b50505050565b606061176a611885565b61177383612383565b604051602001611784929190613575565b6040516020818303038152906040529050919050565b6117a2611d12565b6001600160a01b03166117bd600e546001600160a01b031690565b6001600160a01b0316146118135760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b600061181e60085490565b90506110ed61182d838361366c565b111561187b5760405162461bcd60e51b815260206004820152601c60248201527f4e6f742074686174206d616e79206672616374616c73206c6566742100000000604482015260640161090c565b610a7083836122bd565b606060138054610803906136fa565b60006118a083836124b5565b6001600160a01b031673e2bb689629b990b35af2d15df43e908cad3f6d306001600160a01b031614905092915050565b600f546040517fc45527910000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015260009281169190841690829063c45527919060240160206040518083038186803b15801561193657600080fd5b505afa15801561194a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196e919061341e565b6001600160a01b031614156119875760019150506107ee565b6001600160a01b0380851660009081526005602090815260408083209387168352929052205460ff165b949350505050565b6119c1611d12565b6001600160a01b03166119dc600e546001600160a01b031690565b6001600160a01b031614611a325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b6001600160a01b038116611aae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161090c565b610ee0816121fe565b6000611ac260085490565b90506000611ace611d12565b90506110ed611add868461366c565b1115611b2b5760405162461bcd60e51b815260206004820152601c60248201527f4e6f742074686174206d616e79206672616374616c73206c6566742100000000604482015260640161090c565b611b3c666a94d74f430000866122b1565b341015611b8b5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420656e7566206d6f756c616821204e474d490000000000000000000000604482015260640161090c565b6000611b9786866113c2565b60008181526012602052604090205490915015611bf65760405162461bcd60e51b815260206004820152601460248201527f546f6b656e20616c7265616479206d696e746564000000000000000000000000604482015260640161090c565b611c08611c0282611401565b85611894565b611c545760405162461bcd60e51b815260206004820152601260248201527f5369676e6174757265206d69736d617463680000000000000000000000000000604482015260640161090c565b611c5e82876122bd565b6000908152601260205260409020600190555050505050565b600033301415611cce57600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b03169150611cd19050565b50335b90565b60006001600160e01b031982167f780e9d630000000000000000000000000000000000000000000000000000000014806107ee57506107ee826124d1565b6000611d1c611c77565b905090565b6000818152600460205260409020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091558190611d6382611017565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006001600160a01b038616611e1a5760405162461bcd60e51b815260206004820152602560248201527f4e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5360448201527f49474e4552000000000000000000000000000000000000000000000000000000606482015260840161090c565b6001611e2d611e288761256c565b6125cc565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015611e7b573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b6000611eb0828461366c565b9392505050565b6000818152600260205260408120546001600160a01b0316611f415760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e0000000000000000000000000000000000000000606482015260840161090c565b6000611f4c83611017565b9050806001600160a01b0316846001600160a01b03161480611f875750836001600160a01b0316611f7c84610886565b6001600160a01b0316145b806119b157506119b181856118d0565b826001600160a01b0316611faa82611017565b6001600160a01b0316146120265760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e0000000000000000000000000000000000000000000000606482015260840161090c565b6001600160a01b0382166120a15760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161090c565b6120ac838383612617565b6120b7600082611d21565b6001600160a01b03831660009081526003602052604081208054600192906120e09084906136b7565b90915550506001600160a01b038216600090815260036020526040812080546001929061210e90849061366c565b9091555050600081815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b612184611d12565b6001600160a01b031661219f600e546001600160a01b031690565b6001600160a01b0316146121f55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090c565b610ee081612622565b600e80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c015b604051602081830303815290604052805190602001209050919050565b6000611eb08284613698565b60005b81811015610a70576122d6601080546001019055565b6122e8836122e360105490565b612662565b806122f281613735565b9150506122c0565b612305848484611f97565b6123118484848461267c565b61175a5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161090c565b6060816123c357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156123ed57806123d781613735565b91506123e69050600a83613684565b91506123c7565b60008167ffffffffffffffff811115612408576124086137d2565b6040519080825280601f01601f191660200182016040528015612432576020820181803683370190505b5090505b84156119b1576124476001836136b7565b9150612454600a86613750565b61245f90603061366c565b60f81b818381518110612474576124746137bc565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506124ae600a86613684565b9450612436565b60008060006124c485856127ff565b9150915061125b8161286f565b60006001600160e01b031982167f80ac58cd00000000000000000000000000000000000000000000000000000000148061253457506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806107ee57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146107ee565b60006040518060800160405280604381526020016138146043913980516020918201208351848301516040808701518051908601209051612294950193845260208401929092526001600160a01b03166040830152606082015260800190565b60006125d7600b5490565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201612294565b610a70838383612a2a565b61262b81612ae2565b6000818152600d602052604090208054612644906136fa565b159050610ee0576000818152600d60205260408120610ee0916130c3565b611013828260405180602001604052806000815250612b96565b60006001600160a01b0384163b156127f457836001600160a01b031663150b7a026126a5611d12565b8786866040518563ffffffff1660e01b81526004016126c794939291906135d9565b602060405180830381600087803b1580156126e157600080fd5b505af1925050508015612711575060408051601f3d908101601f1916820190925261270e91810190613401565b60015b6127c1573d80801561273f576040519150601f19603f3d011682016040523d82523d6000602084013e612744565b606091505b5080516127b95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161090c565b805181602001fd5b6001600160e01b0319167f150b7a02000000000000000000000000000000000000000000000000000000001490506119b1565b506001949350505050565b6000808251604114156128365760208301516040840151606085015160001a61282a87828585612c1f565b94509450505050612868565b8251604014156128605760208301516040840151612855868383612d0c565b935093505050612868565b506000905060025b9250929050565b600081600481111561288357612883613790565b141561288c5750565b60018160048111156128a0576128a0613790565b14156128ee5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161090c565b600281600481111561290257612902613790565b14156129505760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161090c565b600381600481111561296457612964613790565b14156129bd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161090c565b60048160048111156129d1576129d1613790565b1415610ee05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161090c565b6001600160a01b038316612a8557612a8081600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612aa8565b816001600160a01b0316836001600160a01b031614612aa857612aa88382612d54565b6001600160a01b038216612abf57610a7081612df1565b826001600160a01b0316826001600160a01b031614610a7057610a708282612ea0565b6000612aed82611017565b9050612afb81600084612617565b612b06600083611d21565b6001600160a01b0381166000908152600360205260408120805460019290612b2f9084906136b7565b9091555050600082815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff19169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b612ba08383612ee4565b612bad600084848461267c565b610a705760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e7465720000000000000000000000000000606482015260840161090c565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c565750600090506003612d03565b8460ff16601b14158015612c6e57508460ff16601c14155b15612c7f5750600090506004612d03565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612cd3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612cfc57600060019250925050612d03565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831660ff84901c601b01612d4687828885612c1f565b935093505050935093915050565b60006001612d61846110a2565b612d6b91906136b7565b600083815260076020526040902054909150808214612dbe576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612e03906001906136b7565b60008381526009602052604081205460088054939450909284908110612e2b57612e2b6137bc565b906000526020600020015490508060088381548110612e4c57612e4c6137bc565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612e8457612e846137a6565b6001900381819060005260206000200160009055905550505050565b6000612eab836110a2565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216612f3a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161090c565b6000818152600260205260409020546001600160a01b031615612f9f5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161090c565b612fab60008383612617565b6001600160a01b0382166000908152600360205260408120805460019290612fd490849061366c565b9091555050600081815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461304b906136fa565b90600052602060002090601f01602090048101928261306d57600085556130b3565b82601f1061308657805160ff19168380011785556130b3565b828001600101855582156130b3579182015b828111156130b3578251825591602001919060010190613098565b506130bf9291506130f9565b5090565b5080546130cf906136fa565b6000825580601f106130df575050565b601f016020900490600052602060002090810190610ee091905b5b808211156130bf57600081556001016130fa565b600067ffffffffffffffff80841115613129576131296137d2565b604051601f8501601f19908116603f01168101908282118183101715613151576131516137d2565b8160405280935085815286868601111561316a57600080fd5b858560208301376000602087830101525050509392505050565b600082601f83011261319557600080fd5b611eb08383356020850161310e565b6000602082840312156131b657600080fd5b8135611eb0816137e8565b600080604083850312156131d457600080fd5b82356131df816137e8565b915060208301356131ef816137e8565b809150509250929050565b60008060006060848603121561320f57600080fd5b833561321a816137e8565b9250602084013561322a816137e8565b929592945050506040919091013590565b6000806000806080858703121561325157600080fd5b843561325c816137e8565b9350602085013561326c816137e8565b925060408501359150606085013567ffffffffffffffff81111561328f57600080fd5b61329b87828801613184565b91505092959194509250565b600080604083850312156132ba57600080fd5b82356132c5816137e8565b9150602083013580151581146131ef57600080fd5b600080600080600060a086880312156132f257600080fd5b85356132fd816137e8565b9450602086013567ffffffffffffffff81111561331957600080fd5b61332588828901613184565b9450506040860135925060608601359150608086013560ff8116811461334a57600080fd5b809150509295509295909350565b6000806040838503121561336b57600080fd5b8235613376816137e8565b946020939093013593505050565b60006020828403121561339657600080fd5b5035919050565b600080604083850312156133b057600080fd5b82359150602083013567ffffffffffffffff8111156133ce57600080fd5b6133da85828601613184565b9150509250929050565b6000602082840312156133f657600080fd5b8135611eb0816137fd565b60006020828403121561341357600080fd5b8151611eb0816137fd565b60006020828403121561343057600080fd5b8151611eb0816137e8565b60006020828403121561344d57600080fd5b813567ffffffffffffffff81111561346457600080fd5b8201601f8101841361347557600080fd5b6119b18482356020840161310e565b6000806040838503121561349757600080fd5b50508035926020909101359150565b6000806000606084860312156134bb57600080fd5b8335925060208401359150604084013567ffffffffffffffff8111156134e057600080fd5b6134ec86828701613184565b9150509250925092565b6000815180845261350e8160208601602086016136ce565b601f01601f19169290920160200192915050565b600082516135348184602087016136ce565b9190910192915050565b600083516135508184602088016136ce565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b600083516135878184602088016136ce565b83519083019061359b8183602088016136ce565b01949350505050565b60006001600160a01b038086168352808516602084015250606060408301526135d060608301846134f6565b95945050505050565b60006001600160a01b0380871683528086166020840152508360408301526080606083015261360b60808301846134f6565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561364d57835183529284019291840191600101613631565b50909695505050505050565b602081526000611eb060208301846134f6565b6000821982111561367f5761367f613764565b500190565b6000826136935761369361377a565b500490565b60008160001904831182151516156136b2576136b2613764565b500290565b6000828210156136c9576136c9613764565b500390565b60005b838110156136e95781810151838201526020016136d1565b8381111561175a5750506000910152565b600181811c9082168061370e57607f821691505b6020821081141561372f57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561374957613749613764565b5060010190565b60008261375f5761375f61377a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610ee057600080fd5b6001600160e01b031981168114610ee057600080fdfe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529a2646970667358221220baecad6163a1a1f6cb12ad35fd26927be07a6b11326d177e2059bab27ba990b064736f6c63430008070033
Deployed Bytecode Sourcemap
75117:600:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74937:171;;;;;;;;;;-1:-1:-1;74937:171:0;;;;;:::i;:::-;;:::i;:::-;;;11364:14:1;;11357:22;11339:41;;11327:2;11312:18;74937:171:0;;;;;;;;33261:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;34818:221::-;;;;;;;;;;-1:-1:-1;34818:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9520:55:1;;;9502:74;;9490:2;9475:18;34818:221:0;9356:226:1;34341:411:0;;;;;;;;;;-1:-1:-1;34341:411:0;;;;;:::i;:::-;;:::i;:::-;;75289:74;;;;;;;;;;;;;:::i;67495:1151::-;;;;;;:::i;:::-;;:::i;64760:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48640:113;;;;;;;;;;-1:-1:-1;48728:10:0;:17;48640:113;;;11537:25:1;;;11525:2;11510:18;48640:113:0;11391:177:1;65769:101:0;;;;;;;;;;-1:-1:-1;65847:15:0;;65769:101;;35708:339;;;;;;;;;;-1:-1:-1;35708:339:0;;;;;:::i;:::-;;:::i;69072:107::-;;;;;;;;;;-1:-1:-1;69072:107:0;;;;;:::i;:::-;-1:-1:-1;;;;;69159:12:0;69125:13;69159:12;;;:6;:12;;;;;;;69072:107;48308:256;;;;;;;;;;-1:-1:-1;48308:256:0;;;;;:::i;:::-;;:::i;70510:26::-;;;;;;;;;;;;;;;;65878:161;;;;;;;;;;-1:-1:-1;65992:9:0;65878:161;;36118:185;;;;;;;;;;-1:-1:-1;36118:185:0;;;;;:::i;:::-;;:::i;44894:245::-;;;;;;;;;;-1:-1:-1;44894:245:0;;;;;:::i;:::-;;:::i;48830:233::-;;;;;;;;;;-1:-1:-1;48830:233:0;;;;;:::i;:::-;;:::i;75372:102::-;;;;;;;;;;-1:-1:-1;75372:102:0;;;;;:::i;:::-;;:::i;32955:239::-;;;;;;;;;;-1:-1:-1;32955:239:0;;;;;:::i;:::-;;:::i;32685:208::-;;;;;;;;;;-1:-1:-1;32685:208:0;;;;;:::i;:::-;;:::i;12960:94::-;;;;;;;;;;;;;:::i;70549:35::-;;;;;;;;;;-1:-1:-1;70549:35:0;;;;;:::i;:::-;;;;;;;;;;;;;;73977:343;;;;;;;;;;-1:-1:-1;73977:343:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;70411:39::-;;;;;;;;;;;;70446:4;70411:39;;74332:281;;;;;;;;;;;;;:::i;72025:174::-;;;;;;;;;;-1:-1:-1;72025:174:0;;;;;:::i;:::-;;:::i;12309:87::-;;;;;;;;;;-1:-1:-1;12382:6:0;;-1:-1:-1;;;;;12382:6:0;12309:87;;72215:126;;;;;;;;;;-1:-1:-1;72215:126:0;;;;;:::i;:::-;;:::i;33430:104::-;;;;;;;;;;;;;:::i;73865:100::-;;;;;;;;;;-1:-1:-1;73865:100:0;;;;;:::i;:::-;;:::i;73219:407::-;;;;;;:::i;:::-;;:::i;35111:295::-;;;;;;;;;;-1:-1:-1;35111:295:0;;;;;:::i;:::-;;:::i;70457:46::-;;;;;;;;;;;;70493:10;70457:46;;36374:328;;;;;;;;;;-1:-1:-1;36374:328:0;;;;;:::i;:::-;;:::i;70799:201::-;;;;;;;;;;-1:-1:-1;70799:201:0;;;;;:::i;:::-;;:::i;73640:213::-;;;;;;;;;;-1:-1:-1;73640:213:0;;;;;:::i;:::-;;:::i;75482:108::-;;;;;;;;;;;;;:::i;72349:202::-;;;;;;;;;;-1:-1:-1;72349:202:0;;;;;:::i;:::-;;:::i;71132:402::-;;;;;;;;;;-1:-1:-1;71132:402:0;;;;;:::i;:::-;;:::i;13209:192::-;;;;;;;;;;-1:-1:-1;13209:192:0;;;;;:::i;:::-;;:::i;72563:638::-;;;;;;:::i;:::-;;:::i;74937:171::-;75040:4;75064:36;75088:11;75064:23;:36::i;:::-;75057:43;74937:171;-1:-1:-1;;74937:171:0:o;33261:100::-;33315:13;33348:5;33341:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33261:100;:::o;34818:221::-;34894:7;38301:16;;;:7;:16;;;;;;-1:-1:-1;;;;;38301:16:0;34914:73;;;;-1:-1:-1;;;34914:73:0;;21825:2:1;34914:73:0;;;21807:21:1;21864:2;21844:18;;;21837:30;21903:34;21883:18;;;21876:62;21974:14;21954:18;;;21947:42;22006:19;;34914:73:0;;;;;;;;;-1:-1:-1;35007:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;35007:24:0;;34818:221::o;34341:411::-;34422:13;34438:23;34453:7;34438:14;:23::i;:::-;34422:39;;34486:5;-1:-1:-1;;;;;34480:11:0;:2;-1:-1:-1;;;;;34480:11:0;;;34472:57;;;;-1:-1:-1;;;34472:57:0;;23411:2:1;34472:57:0;;;23393:21:1;23450:2;23430:18;;;23423:30;23489:34;23469:18;;;23462:62;23560:3;23540:18;;;23533:31;23581:19;;34472:57:0;23209:397:1;34472:57:0;34580:5;-1:-1:-1;;;;;34564:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;34564:21:0;;:62;;;;34589:37;34606:5;34613:12;:10;:12::i;34589:37::-;34542:168;;;;-1:-1:-1;;;34542:168:0;;19468:2:1;34542:168:0;;;19450:21:1;19507:2;19487:18;;;19480:30;19546:34;19526:18;;;19519:62;19617:26;19597:18;;;19590:54;19661:19;;34542:168:0;19266:420:1;34542:168:0;34723:21;34732:2;34736:7;34723:8;:21::i;:::-;34411:341;34341:411;;:::o;75289:74::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;67495:1151::-;67753:152;;;67696:12;67753:152;;;;;-1:-1:-1;;;;;67791:19:0;;67721:29;67791:19;;;:6;:19;;;;;;;;;67753:152;;;;;;;;;;;67940:45;67798:11;67753:152;67968:4;67974;67980;67940:6;:45::i;:::-;67918:128;;;;-1:-1:-1;;;67918:128:0;;23009:2:1;67918:128:0;;;22991:21:1;23048:2;23028:18;;;23021:30;23087:34;23067:18;;;23060:62;23158:3;23138:18;;;23131:31;23179:19;;67918:128:0;22807:397:1;67918:128:0;-1:-1:-1;;;;;68135:19:0;;;;;;:6;:19;;;;;;:26;;68159:1;68135:23;:26::i;:::-;-1:-1:-1;;;;;68113:19:0;;;;;;:6;:19;;;;;;;:48;;;;68179:126;;;;;68120:11;;68251:10;;68277:17;;68179:126;:::i;:::-;;;;;;;;68416:12;68430:23;68465:4;-1:-1:-1;;;;;68457:18:0;68507:17;68526:11;68490:48;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;68490:48:0;;;;;;;;;;68457:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68415:134;;;;68568:7;68560:48;;;;-1:-1:-1;;;68560:48:0;;15719:2:1;68560:48:0;;;15701:21:1;15758:2;15738:18;;;15731:30;15797;15777:18;;;15770:58;15845:18;;68560:48:0;15517:352:1;68560:48:0;68628:10;67495:1151;-1:-1:-1;;;;;;;;67495:1151:0:o;35708:339::-;35903:41;35922:12;:10;:12::i;:::-;35936:7;35903:18;:41::i;:::-;35895:103;;;;-1:-1:-1;;;35895:103:0;;23813:2:1;35895:103:0;;;23795:21:1;23852:2;23832:18;;;23825:30;23891:34;23871:18;;;23864:62;23962:19;23942:18;;;23935:47;23999:19;;35895:103:0;23611:413:1;35895:103:0;36011:28;36021:4;36027:2;36031:7;36011:9;:28::i;48308:256::-;48405:7;48441:23;48458:5;48441:16;:23::i;:::-;48433:5;:31;48425:87;;;;-1:-1:-1;;;48425:87:0;;14131:2:1;48425:87:0;;;14113:21:1;14170:2;14150:18;;;14143:30;14209:34;14189:18;;;14182:62;14280:13;14260:18;;;14253:41;14311:19;;48425:87:0;13929:407:1;48425:87:0;-1:-1:-1;;;;;;48530:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;48308:256::o;36118:185::-;36256:39;36273:4;36279:2;36283:7;36256:39;;;;;;;;;;;;:16;:39::i;44894:245::-;45012:41;45031:12;:10;:12::i;45012:41::-;45004:102;;;;-1:-1:-1;;;45004:102:0;;24644:2:1;45004:102:0;;;24626:21:1;24683:2;24663:18;;;24656:30;24722:34;24702:18;;;24695:62;24793:18;24773;;;24766:46;24829:19;;45004:102:0;24442:412:1;45004:102:0;45117:14;45123:7;45117:5;:14::i;:::-;44894:245;:::o;48830:233::-;48905:7;48941:30;48728:10;:17;;48640:113;48941:30;48933:5;:38;48925:95;;;;-1:-1:-1;;;48925:95:0;;24231:2:1;48925:95:0;;;24213:21:1;24270:2;24250:18;;;24243:30;24309:34;24289:18;;;24282:62;24380:14;24360:18;;;24353:42;24412:19;;48925:95:0;24029:408:1;48925:95:0;49038:10;49049:5;49038:17;;;;;;;;:::i;:::-;;;;;;;;;49031:24;;48830:233;;;:::o;75372:102::-;12540:12;:10;:12::i;:::-;-1:-1:-1;;;;;12529:23:0;:7;12382:6;;-1:-1:-1;;;;;12382:6:0;;12309:87;12529:7;-1:-1:-1;;;;;12529:23:0;;12521:68;;;;-1:-1:-1;;;12521:68:0;;22238:2:1;12521:68:0;;;22220:21:1;;;22257:18;;;22250:30;22316:34;22296:18;;;22289:62;22368:18;;12521:68:0;22036:356:1;12521:68:0;75443:23;;::::1;::::0;:13:::1;::::0;:23:::1;::::0;::::1;::::0;::::1;:::i;:::-;;75372:102:::0;:::o;32955:239::-;33027:7;33063:16;;;:7;:16;;;;;;-1:-1:-1;;;;;33063:16:0;33098:19;33090:73;;;;-1:-1:-1;;;33090:73:0;;20304:2:1;33090:73:0;;;20286:21:1;20343:2;20323:18;;;20316:30;20382:34;20362:18;;;20355:62;20453:11;20433:18;;;20426:39;20482:19;;33090:73:0;20102:405:1;32685:208:0;32757:7;-1:-1:-1;;;;;32785:19:0;;32777:74;;;;-1:-1:-1;;;32777:74:0;;19893:2:1;32777:74:0;;;19875:21:1;19932:2;19912:18;;;19905:30;19971:34;19951:18;;;19944:62;20042:12;20022:18;;;20015:40;20072:19;;32777:74:0;19691:406:1;32777:74:0;-1:-1:-1;;;;;;32869:16:0;;;;;:9;:16;;;;;;;32685:208::o;12960:94::-;12540:12;:10;:12::i;:::-;-1:-1:-1;;;;;12529:23:0;:7;12382:6;;-1:-1:-1;;;;;12382:6:0;;12309:87;12529:7;-1:-1:-1;;;;;12529:23:0;;12521:68;;;;-1:-1:-1;;;12521:68:0;;22238:2:1;12521:68:0;;;22220:21:1;;;22257:18;;;22250:30;22316:34;22296:18;;;22289:62;22368:18;;12521:68:0;22036:356:1;12521:68:0;13025:21:::1;13043:1;13025:9;:21::i;:::-;12960:94::o:0;73977:343::-;74042:13;74068:15;74086:17;74096:6;74086:9;:17::i;:::-;74068:35;;74114:24;74152:10;74141:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74141:22:0;;74114:49;;74179:6;74174:111;74195:10;74191:1;:14;74174:111;;;74243:30;74263:6;74271:1;74243:19;:30::i;:::-;74227:10;74238:1;74227:13;;;;;;;;:::i;:::-;;;;;;;;;;:46;74207:3;;;;:::i;:::-;;;;74174:111;;;-1:-1:-1;74302:10:0;73977:343;-1:-1:-1;;;73977:343:0:o;74332:281::-;12540:12;:10;:12::i;:::-;-1:-1:-1;;;;;12529:23:0;:7;12382:6;;-1:-1:-1;;;;;12382:6:0;;12309:87;12529:7;-1:-1:-1;;;;;12529:23:0;;12521:68;;;;-1:-1:-1;;;12521:68:0;;22238:2:1;12521:68:0;;;22220:21:1;;;22257:18;;;22250:30;22316:34;22296:18;;;22289:62;22368:18;;12521:68:0;22036:356:1;12521:68:0;74398:21:::1;74438:11:::0;74430:45:::1;;;::::0;-1:-1:-1;;;74430:45:0;;16790:2:1;74430:45:0::1;::::0;::::1;16772:21:1::0;16829:2;16809:18;;;16802:30;16868:23;16848:18;;;16841:51;16909:18;;74430:45:0::1;16588:345:1::0;74430:45:0::1;74506:49;::::0;74487:13:::1;::::0;74506:10:::1;::::0;74529:21:::1;::::0;74487:13;74506:49;74487:13;74506:49;74529:21;74506:10;:49:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74486:69;;;74574:8;74566:39;;;::::0;-1:-1:-1;;;74566:39:0;;17140:2:1;74566:39:0::1;::::0;::::1;17122:21:1::0;17179:2;17159:18;;;17152:30;17218:20;17198:18;;;17191:48;17256:18;;74566:39:0::1;16938:342:1::0;72025:174:0;72096:7;72116:13;72153:6;72161:5;72142:25;;;;;;;;25565::1;;;25621:2;25606:18;;25599:34;25553:2;25538:18;;25391:248;72142:25:0;;;;;;;-1:-1:-1;;72142:25:0;;;;;;72132:36;;72142:25;72132:36;;;;;72025:174;-1:-1:-1;;;;72025:174:0:o;72215:126::-;72276:7;72303:30;:5;:28;:30::i;33430:104::-;33486:13;33519:7;33512:14;;;;;:::i;73865:100::-;12540:12;:10;:12::i;:::-;-1:-1:-1;;;;;12529:23:0;:7;12382:6;;-1:-1:-1;;;;;12382:6:0;;12309:87;12529:7;-1:-1:-1;;;;;12529:23:0;;12521:68;;;;-1:-1:-1;;;12521:68:0;;22238:2:1;12521:68:0;;;22220:21:1;;;22257:18;;;22250:30;22316:34;22296:18;;;22289:62;22368:18;;12521:68:0;22036:356:1;12521:68:0;73934:10:::1;:23:::0;73865:100::o;73219:407::-;73272:10;73285:13;48728:10;:17;;48640:113;73285:13;73272:26;;73309:27;73339:12;:10;:12::i;:::-;73309:42;;73383:1;73370:10;;:14;73362:48;;;;-1:-1:-1;;;73362:48:0;;14962:2:1;73362:48:0;;;14944:21:1;15001:2;14981:18;;;14974:30;15040:23;15020:18;;;15013:51;15081:18;;73362:48:0;14760:345:1;73362:48:0;70446:4;73429:14;73437:6;73429:5;:14;:::i;:::-;:29;;73421:70;;;;-1:-1:-1;;;73421:70:0;;16076:2:1;73421:70:0;;;16058:21:1;16115:2;16095:18;;;16088:30;16154;16134:18;;;16127:58;16202:18;;73421:70:0;15874:352:1;73421:70:0;73523:24;70493:10;73540:6;73523:16;:24::i;:::-;73510:9;:37;;73502:71;;;;-1:-1:-1;;;73502:71:0;;25061:2:1;73502:71:0;;;25043:21:1;25100:2;25080:18;;;25073:30;25139:23;25119:18;;;25112:51;25180:18;;73502:71:0;24859:345:1;73502:71:0;73584:34;73590:19;73611:6;73584:5;:34::i;35111:295::-;35226:12;:10;:12::i;:::-;-1:-1:-1;;;;;35214:24:0;:8;-1:-1:-1;;;;;35214:24:0;;;35206:62;;;;-1:-1:-1;;;35206:62:0;;17892:2:1;35206:62:0;;;17874:21:1;17931:2;17911:18;;;17904:30;17970:27;17950:18;;;17943:55;18015:18;;35206:62:0;17690:349:1;35206:62:0;35326:8;35281:18;:32;35300:12;:10;:12::i;:::-;-1:-1:-1;;;;;35281:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;35281:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;35281:53:0;;;;;;;;;;;35365:12;:10;:12::i;:::-;-1:-1:-1;;;;;35350:48:0;;35389:8;35350:48;;;;11364:14:1;11357:22;11339:41;;11327:2;11312:18;;11199:187;35350:48:0;;;;;;;;35111:295;;:::o;36374:328::-;36549:41;36568:12;:10;:12::i;:::-;36582:7;36549:18;:41::i;:::-;36541:103;;;;-1:-1:-1;;;36541:103:0;;23813:2:1;36541:103:0;;;23795:21:1;23852:2;23832:18;;;23825:30;23891:34;23871:18;;;23864:62;23962:19;23942:18;;;23935:47;23999:19;;36541:103:0;23611:413:1;36541:103:0;36655:39;36669:4;36675:2;36679:7;36688:5;36655:13;:39::i;:::-;36374:328;;;;:::o;70799:201::-;70891:13;70948:14;:12;:14::i;:::-;70964:26;70981:8;70964:16;:26::i;:::-;70931:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;70917:75;;70799:201;;;:::o;73640:213::-;12540:12;:10;:12::i;:::-;-1:-1:-1;;;;;12529:23:0;:7;12382:6;;-1:-1:-1;;;;;12382:6:0;;12309:87;12529:7;-1:-1:-1;;;;;12529:23:0;;12521:68;;;;-1:-1:-1;;;12521:68:0;;22238:2:1;12521:68:0;;;22220:21:1;;;22257:18;;;22250:30;22316:34;22296:18;;;22289:62;22368:18;;12521:68:0;22036:356:1;12521:68:0;73710:10:::1;73723:13;48728:10:::0;:17;;48640:113;73723:13:::1;73710:26:::0;-1:-1:-1;70446:4:0::1;73755:14;73763:6:::0;73710:26;73755:14:::1;:::i;:::-;:29;;73747:70;;;::::0;-1:-1:-1;;;73747:70:0;;16076:2:1;73747:70:0::1;::::0;::::1;16058:21:1::0;16115:2;16095:18;;;16088:30;16154;16134:18;;;16127:58;16202:18;;73747:70:0::1;15874:352:1::0;73747:70:0::1;73828:17;73834:2;73838:6;73828:5;:17::i;75482:108::-:0;75536:13;75569;75562:20;;;;;:::i;72349:202::-;72442:4;72466:31;:11;72486:10;72466:19;:31::i;:::-;-1:-1:-1;;;;;72466:77:0;72501:42;-1:-1:-1;;;;;72466:77:0;;72459:84;;72349:202;;;;:::o;71132:402::-;71345:20;;71389:28;;;;;-1:-1:-1;;;;;9520:55:1;;;71389:28:0;;;9502:74:1;71221:4:0;;71345:20;;;71381:49;;;;71345:20;;71389:21;;9475:18:1;;71389:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;71381:49:0;;71377:93;;;71454:4;71447:11;;;;;71377:93;-1:-1:-1;;;;;35598:25:0;;;35574:4;35598:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;71487:39;71480:46;71132:402;-1:-1:-1;;;;71132:402:0:o;13209:192::-;12540:12;:10;:12::i;:::-;-1:-1:-1;;;;;12529:23:0;:7;12382:6;;-1:-1:-1;;;;;12382:6:0;;12309:87;12529:7;-1:-1:-1;;;;;12529:23:0;;12521:68;;;;-1:-1:-1;;;12521:68:0;;22238:2:1;12521:68:0;;;22220:21:1;;;22257:18;;;22250:30;22316:34;22296:18;;;22289:62;22368:18;;12521:68:0;22036:356:1;12521:68:0;-1:-1:-1;;;;;13298:22:0;::::1;13290:73;;;::::0;-1:-1:-1;;;13290:73:0;;15312:2:1;13290:73:0::1;::::0;::::1;15294:21:1::0;15351:2;15331:18;;;15324:30;15390:34;15370:18;;;15363:62;15461:8;15441:18;;;15434:36;15487:19;;13290:73:0::1;15110:402:1::0;13290:73:0::1;13374:19;13384:8;13374:9;:19::i;72563:638::-:0;72657:10;72670:13;48728:10;:17;;48640:113;72670:13;72657:26;;72694:27;72724:12;:10;:12::i;:::-;72694:42;-1:-1:-1;70446:4:0;72755:14;72763:6;72755:5;:14;:::i;:::-;:29;;72747:70;;;;-1:-1:-1;;;72747:70:0;;16076:2:1;72747:70:0;;;16058:21:1;16115:2;16095:18;;;16088:30;16154;16134:18;;;16127:58;16202:18;;72747:70:0;15874:352:1;72747:70:0;72849:24;70493:10;72866:6;72849:16;:24::i;:::-;72836:9;:37;;72828:71;;;;-1:-1:-1;;;72828:71:0;;25061:2:1;72828:71:0;;;25043:21:1;25100:2;25080:18;;;25073:30;25139:23;25119:18;;;25112:51;25180:18;;72828:71:0;24859:345:1;72828:71:0;72910:12;72925:30;72941:6;72949:5;72925:15;:30::i;:::-;72974:18;;;;:6;:18;;;;;;72910:45;;-1:-1:-1;72974:23:0;72966:56;;;;-1:-1:-1;;;72966:56:0;;13782:2:1;72966:56:0;;;13764:21:1;13821:2;13801:18;;;13794:30;13860:22;13840:18;;;13833:50;13900:18;;72966:56:0;13580:344:1;72966:56:0;73041:51;73058:21;73074:4;73058:15;:21::i;:::-;73081:10;73041:16;:51::i;:::-;73033:82;;;;-1:-1:-1;;;73033:82:0;;21478:2:1;73033:82:0;;;21460:21:1;21517:2;21497:18;;;21490:30;21556:20;21536:18;;;21529:48;21594:18;;73033:82:0;21276:342:1;73033:82:0;73126:34;73132:19;73153:6;73126:5;:34::i;:::-;73171:18;;;;:6;:18;;;;;73192:1;73171:22;;-1:-1:-1;;;;;72563:638:0:o;63869:523::-;63913:22;63952:10;63974:4;63952:27;63948:413;;;63996:18;64017:8;;63996:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;64056:8:0;64224:17;64218:24;-1:-1:-1;;;;;64214:73:0;;-1:-1:-1;63948:413:0;;-1:-1:-1;63948:413:0;;-1:-1:-1;64338:10:0;63948:413;63869:523;:::o;48000:224::-;48102:4;-1:-1:-1;;;;;;48126:50:0;;48141:35;48126:50;;:90;;;48180:36;48204:11;48180:23;:36::i;71678:120::-;71732:14;71766:24;:22;:24::i;:::-;71759:31;;71678:120;:::o;42194:174::-;42269:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;42269:29:0;-1:-1:-1;;;;;42269:29:0;;;;;;;;:24;;42323:23;42269:24;42323:14;:23::i;:::-;-1:-1:-1;;;;;42314:46:0;;;;;;;;;;;42194:174;;:::o;69187:486::-;69365:4;-1:-1:-1;;;;;69390:20:0;;69382:70;;;;-1:-1:-1;;;69382:70:0;;19062:2:1;69382:70:0;;;19044:21:1;19101:2;19081:18;;;19074:30;19140:34;19120:18;;;19113:62;19211:7;19191:18;;;19184:35;19236:19;;69382:70:0;18860:401:1;69382:70:0;69506:159;69534:47;69553:27;69573:6;69553:19;:27::i;:::-;69534:18;:47::i;:::-;69506:159;;;;;;;;;;;;12245:25:1;;;;12318:4;12306:17;;12286:18;;;12279:45;12340:18;;;12333:34;;;12383:18;;;12376:34;;;12217:19;;69506:159:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;69483:182:0;:6;-1:-1:-1;;;;;69483:182:0;;69463:202;;69187:486;;;;;;;:::o;2827:98::-;2885:7;2912:5;2916:1;2912;:5;:::i;:::-;2905:12;2827:98;-1:-1:-1;;;2827:98:0:o;38506:348::-;38599:4;38301:16;;;:7;:16;;;;;;-1:-1:-1;;;;;38301:16:0;38616:73;;;;-1:-1:-1;;;38616:73:0;;18649:2:1;38616:73:0;;;18631:21:1;18688:2;18668:18;;;18661:30;18727:34;18707:18;;;18700:62;18798:14;18778:18;;;18771:42;18830:19;;38616:73:0;18447:408:1;38616:73:0;38700:13;38716:23;38731:7;38716:14;:23::i;:::-;38700:39;;38769:5;-1:-1:-1;;;;;38758:16:0;:7;-1:-1:-1;;;;;38758:16:0;;:51;;;;38802:7;-1:-1:-1;;;;;38778:31:0;:20;38790:7;38778:11;:20::i;:::-;-1:-1:-1;;;;;38778:31:0;;38758:51;:87;;;;38813:32;38830:5;38837:7;38813:16;:32::i;41498:578::-;41657:4;-1:-1:-1;;;;;41630:31:0;:23;41645:7;41630:14;:23::i;:::-;-1:-1:-1;;;;;41630:31:0;;41622:85;;;;-1:-1:-1;;;41622:85:0;;22599:2:1;41622:85:0;;;22581:21:1;22638:2;22618:18;;;22611:30;22677:34;22657:18;;;22650:62;22748:11;22728:18;;;22721:39;22777:19;;41622:85:0;22397:405:1;41622:85:0;-1:-1:-1;;;;;41726:16:0;;41718:65;;;;-1:-1:-1;;;41718:65:0;;17487:2:1;41718:65:0;;;17469:21:1;17526:2;17506:18;;;17499:30;17565:34;17545:18;;;17538:62;17636:6;17616:18;;;17609:34;17660:19;;41718:65:0;17285:400:1;41718:65:0;41796:39;41817:4;41823:2;41827:7;41796:20;:39::i;:::-;41900:29;41917:1;41921:7;41900:8;:29::i;:::-;-1:-1:-1;;;;;41942:15:0;;;;;;:9;:15;;;;;:20;;41961:1;;41942:15;:20;;41961:1;;41942:20;:::i;:::-;;;;-1:-1:-1;;;;;;;41973:13:0;;;;;;:9;:13;;;;;:18;;41990:1;;41973:13;:18;;41990:1;;41973:18;:::i;:::-;;;;-1:-1:-1;;42002:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;42002:21:0;-1:-1:-1;;;;;42002:21:0;;;;;;;;;42041:27;;42002:16;;42041:27;;;;;;;41498:578;;;:::o;74807:122::-;12540:12;:10;:12::i;:::-;-1:-1:-1;;;;;12529:23:0;:7;12382:6;;-1:-1:-1;;;;;12382:6:0;;12309:87;12529:7;-1:-1:-1;;;;;12529:23:0;;12521:68;;;;-1:-1:-1;;;12521:68:0;;22238:2:1;12521:68:0;;;22220:21:1;;;22257:18;;;22250:30;22316:34;22296:18;;;22289:62;22368:18;;12521:68:0;22036:356:1;12521:68:0;74901:20:::1;74913:7;74901:11;:20::i;13409:173::-:0;13484:6;;;-1:-1:-1;;;;;13501:17:0;;;-1:-1:-1;;13501:17:0;;;;;;;13534:40;;13484:6;;;13501:17;13484:6;;13534:40;;13465:16;;13534:40;13454:128;13409:173;:::o;62271:269::-;62473:58;;8554:66:1;62473:58:0;;;8542:79:1;8637:12;;;8630:28;;;62340:7:0;;8674:12:1;;62473:58:0;;;;;;;;;;;;;62463:69;;;;;;62456:76;;62271:269;;;:::o;3565:98::-;3623:7;3650:5;3654:1;3650;:5;:::i;71806:207::-;71869:6;71865:141;71885:6;71881:1;:10;71865:141;;;71912:27;:15;8020:19;;8038:1;8020:19;;;7931:127;71912:27;71954:40;71964:2;71968:25;:15;7901:14;;7809:114;71968:25;71954:9;:40::i;:::-;71893:3;;;;:::i;:::-;;;;71865:141;;37584:315;37741:28;37751:4;37757:2;37761:7;37741:9;:28::i;:::-;37788:48;37811:4;37817:2;37821:7;37830:5;37788:22;:48::i;:::-;37780:111;;;;-1:-1:-1;;;37780:111:0;;14543:2:1;37780:111:0;;;14525:21:1;14582:2;14562:18;;;14555:30;14621:34;14601:18;;;14594:62;14692:20;14672:18;;;14665:48;14730:19;;37780:111:0;14341:414:1;8713:723:0;8769:13;8990:10;8986:53;;-1:-1:-1;;9017:10:0;;;;;;;;;;;;;;;;;;8713:723::o;8986:53::-;9064:5;9049:12;9105:78;9112:9;;9105:78;;9138:8;;;;:::i;:::-;;-1:-1:-1;9161:10:0;;-1:-1:-1;9169:2:0;9161:10;;:::i;:::-;;;9105:78;;;9193:19;9225:6;9215:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9215:17:0;;9193:39;;9243:154;9250:10;;9243:154;;9277:11;9287:1;9277:11;;:::i;:::-;;-1:-1:-1;9346:10:0;9354:2;9346:5;:10;:::i;:::-;9333:24;;:2;:24;:::i;:::-;9320:39;;9303:6;9310;9303:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;9374:11:0;9383:2;9374:11;;:::i;:::-;;;9243:154;;58422:231;58500:7;58521:17;58540:18;58562:27;58573:4;58579:9;58562:10;:27::i;:::-;58520:69;;;;58600:18;58612:5;58600:11;:18::i;32316:305::-;32418:4;-1:-1:-1;;;;;;32455:40:0;;32470:25;32455:40;;:105;;-1:-1:-1;;;;;;;32512:48:0;;32527:33;32512:48;32455:105;:158;;;-1:-1:-1;24419:25:0;-1:-1:-1;;;;;;24404:40:0;;;32577:36;24295:157;68654:410;68764:7;66831:100;;;;;;;;;;;;;;;;;66811:127;;;;;;;68918:12;;68953:11;;;;68997:24;;;;;68987:35;;;;;;68837:204;;;;;11804:25:1;;;11860:2;11845:18;;11838:34;;;;-1:-1:-1;;;;;11908:55:1;11903:2;11888:18;;11881:83;11995:2;11980:18;;11973:34;11791:3;11776:19;;11573:440;66408:258:0;66507:7;66609:20;65847:15;;;65769:101;66609:20;66580:63;;8967:66:1;66580:63:0;;;8955:79:1;9050:11;;;9043:27;;;;9086:12;;;9079:28;;;9123:12;;66580:63:0;8697:444:1;74621:178:0;74746:45;74773:4;74779:2;74783:7;74746:26;:45::i;46857:206::-;46926:20;46938:7;46926:11;:20::i;:::-;46969:19;;;;:10;:19;;;;;46963:33;;;;;:::i;:::-;:38;;-1:-1:-1;46959:97:0;;47025:19;;;;:10;:19;;;;;47018:26;;;:::i;39196:110::-;39272:26;39282:2;39286:7;39272:26;;;;;;;;;;;;:9;:26::i;42933:799::-;43088:4;-1:-1:-1;;;;;43109:13:0;;14678:20;14726:8;43105:620;;43161:2;-1:-1:-1;;;;;43145:36:0;;43182:12;:10;:12::i;:::-;43196:4;43202:7;43211:5;43145:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43145:72:0;;;;;;;;-1:-1:-1;;43145:72:0;;;;;;;;;;;;:::i;:::-;;;43141:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43387:13:0;;43383:272;;43430:60;;-1:-1:-1;;;43430:60:0;;14543:2:1;43430:60:0;;;14525:21:1;14582:2;14562:18;;;14555:30;14621:34;14601:18;;;14594:62;14692:20;14672:18;;;14665:48;14730:19;;43430:60:0;14341:414:1;43383:272:0;43605:6;43599:13;43590:6;43586:2;43582:15;43575:38;43141:529;-1:-1:-1;;;;;;43268:51:0;43278:41;43268:51;;-1:-1:-1;43261:58:0;;43105:620;-1:-1:-1;43709:4:0;42933:799;;;;;;:::o;56312:1308::-;56393:7;56402:12;56627:9;:16;56647:2;56627:22;56623:990;;;56923:4;56908:20;;56902:27;56973:4;56958:20;;56952:27;57031:4;57016:20;;57010:27;56666:9;57002:36;57074:25;57085:4;57002:36;56902:27;56952;57074:10;:25::i;:::-;57067:32;;;;;;;;;56623:990;57121:9;:16;57141:2;57121:22;57117:496;;;57396:4;57381:20;;57375:27;57447:4;57432:20;;57426:27;57489:23;57500:4;57375:27;57426;57489:10;:23::i;:::-;57482:30;;;;;;;;57117:496;-1:-1:-1;57561:1:0;;-1:-1:-1;57565:35:0;57117:496;56312:1308;;;;;:::o;54583:643::-;54661:20;54652:5;:29;;;;;;;;:::i;:::-;;54648:571;;;54583:643;:::o;54648:571::-;54759:29;54750:5;:38;;;;;;;;:::i;:::-;;54746:473;;;54805:34;;-1:-1:-1;;;54805:34:0;;13069:2:1;54805:34:0;;;13051:21:1;13108:2;13088:18;;;13081:30;13147:26;13127:18;;;13120:54;13191:18;;54805:34:0;12867:348:1;54746:473:0;54870:35;54861:5;:44;;;;;;;;:::i;:::-;;54857:362;;;54922:41;;-1:-1:-1;;;54922:41:0;;13422:2:1;54922:41:0;;;13404:21:1;13461:2;13441:18;;;13434:30;13500:33;13480:18;;;13473:61;13551:18;;54922:41:0;13220:355:1;54857:362:0;54994:30;54985:5;:39;;;;;;;;:::i;:::-;;54981:238;;;55041:44;;-1:-1:-1;;;55041:44:0;;18246:2:1;55041:44:0;;;18228:21:1;18285:2;18265:18;;;18258:30;18324:34;18304:18;;;18297:62;-1:-1:-1;;;18375:18:1;;;18368:32;18417:19;;55041:44:0;18044:398:1;54981:238:0;55116:30;55107:5;:39;;;;;;;;:::i;:::-;;55103:116;;;55163:44;;-1:-1:-1;;;55163:44:0;;20714:2:1;55163:44:0;;;20696:21:1;20753:2;20733:18;;;20726:30;20792:34;20772:18;;;20765:62;-1:-1:-1;;;20843:18:1;;;20836:32;20885:19;;55163:44:0;20512:398:1;49676:589:0;-1:-1:-1;;;;;49882:18:0;;49878:187;;49917:40;49949:7;51092:10;:17;;51065:24;;;;:15;:24;;;;;:44;;;51120:24;;;;;;;;;;;;50988:164;49917:40;49878:187;;;49987:2;-1:-1:-1;;;;;49979:10:0;:4;-1:-1:-1;;;;;49979:10:0;;49975:90;;50006:47;50039:4;50045:7;50006:32;:47::i;:::-;-1:-1:-1;;;;;50079:16:0;;50075:183;;50112:45;50149:7;50112:36;:45::i;50075:183::-;50185:4;-1:-1:-1;;;;;50179:10:0;:2;-1:-1:-1;;;;;50179:10:0;;50175:83;;50206:40;50234:2;50238:7;50206:27;:40::i;40801:360::-;40861:13;40877:23;40892:7;40877:14;:23::i;:::-;40861:39;;40913:48;40934:5;40949:1;40953:7;40913:20;:48::i;:::-;41002:29;41019:1;41023:7;41002:8;:29::i;:::-;-1:-1:-1;;;;;41044:16:0;;;;;;:9;:16;;;;;:21;;41064:1;;41044:16;:21;;41064:1;;41044:21;:::i;:::-;;;;-1:-1:-1;;41083:16:0;;;;:7;:16;;;;;;41076:23;;-1:-1:-1;;41076:23:0;;;41117:36;41091:7;;41083:16;-1:-1:-1;;;;;41117:36:0;;;;;41083:16;;41117:36;40850:311;40801:360;:::o;39533:321::-;39663:18;39669:2;39673:7;39663:5;:18::i;:::-;39714:54;39745:1;39749:2;39753:7;39762:5;39714:22;:54::i;:::-;39692:154;;;;-1:-1:-1;;;39692:154:0;;14543:2:1;39692:154:0;;;14525:21:1;14582:2;14562:18;;;14555:30;14621:34;14601:18;;;14594:62;14692:20;14672:18;;;14665:48;14730:19;;39692:154:0;14341:414:1;59921:1632:0;60052:7;;60986:66;60973:79;;60969:163;;;-1:-1:-1;61085:1:0;;-1:-1:-1;61089:30:0;61069:51;;60969:163;61146:1;:7;;61151:2;61146:7;;:18;;;;;61157:1;:7;;61162:2;61157:7;;61146:18;61142:102;;;-1:-1:-1;61197:1:0;;-1:-1:-1;61201:30:0;61181:51;;61142:102;61358:24;;;61341:14;61358:24;;;;;;;;;12245:25:1;;;12318:4;12306:17;;12286:18;;;12279:45;;;;12340:18;;;12333:34;;;12383:18;;;12376:34;;;61358:24:0;;12217:19:1;;61358:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;61358:24:0;;-1:-1:-1;;61358:24:0;;;-1:-1:-1;;;;;;;61397:20:0;;61393:103;;61450:1;61454:29;61434:50;;;;;;;61393:103;61516:6;-1:-1:-1;61524:20:0;;-1:-1:-1;59921:1632:0;;;;;;;;:::o;58916:391::-;59030:7;;59139:66;59131:75;;59233:3;59229:12;;;59243:2;59225:21;59274:25;59285:4;59225:21;59294:1;59131:75;59274:10;:25::i;:::-;59267:32;;;;;;58916:391;;;;;;:::o;51779:988::-;52045:22;52095:1;52070:22;52087:4;52070:16;:22::i;:::-;:26;;;;:::i;:::-;52107:18;52128:26;;;:17;:26;;;;;;52045:51;;-1:-1:-1;52261:28:0;;;52257:328;;-1:-1:-1;;;;;52328:18:0;;52306:19;52328:18;;;:12;:18;;;;;;;;:34;;;;;;;;;52379:30;;;;;;:44;;;52496:30;;:17;:30;;;;;:43;;;52257:328;-1:-1:-1;52681:26:0;;;;:17;:26;;;;;;;;52674:33;;;-1:-1:-1;;;;;52725:18:0;;;;;:12;:18;;;;;:34;;;;;;;52718:41;51779:988::o;53062:1079::-;53340:10;:17;53315:22;;53340:21;;53360:1;;53340:21;:::i;:::-;53372:18;53393:24;;;:15;:24;;;;;;53766:10;:26;;53315:46;;-1:-1:-1;53393:24:0;;53315:46;;53766:26;;;;;;:::i;:::-;;;;;;;;;53744:48;;53830:11;53805:10;53816;53805:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;53910:28;;;:15;:28;;;;;;;:41;;;54082:24;;;;;54075:31;54117:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;53133:1008;;;53062:1079;:::o;50566:221::-;50651:14;50668:20;50685:2;50668:16;:20::i;:::-;-1:-1:-1;;;;;50699:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;50744:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;50566:221:0:o;40190:382::-;-1:-1:-1;;;;;40270:16:0;;40262:61;;;;-1:-1:-1;;;40262:61:0;;21117:2:1;40262:61:0;;;21099:21:1;;;21136:18;;;21129:30;21195:34;21175:18;;;21168:62;21247:18;;40262:61:0;20915:356:1;40262:61:0;38277:4;38301:16;;;:7;:16;;;;;;-1:-1:-1;;;;;38301:16:0;:30;40334:58;;;;-1:-1:-1;;;40334:58:0;;16433:2:1;40334:58:0;;;16415:21:1;16472:2;16452:18;;;16445:30;16511;16491:18;;;16484:58;16559:18;;40334:58:0;16231:352:1;40334:58:0;40405:45;40434:1;40438:2;40442:7;40405:20;:45::i;:::-;-1:-1:-1;;;;;40463:13:0;;;;;;:9;:13;;;;;:18;;40480:1;;40463:13;:18;;40480:1;;40463:18;:::i;:::-;;;;-1:-1:-1;;40492:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;40492:21:0;-1:-1:-1;;;;;40492:21:0;;;;;;;;40531:33;;40492:16;;;40531:33;;40492:16;;40531:33;40190:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:631:1;78:5;108:18;149:2;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:220::-;692:5;745:3;738:4;730:6;726:17;722:27;712:55;;763:1;760;753:12;712:55;785:79;860:3;851:6;838:20;831:4;823:6;819:17;785:79;:::i;875:247::-;934:6;987:2;975:9;966:7;962:23;958:32;955:52;;;1003:1;1000;993:12;955:52;1042:9;1029:23;1061:31;1086:5;1061:31;:::i;1127:388::-;1195:6;1203;1256:2;1244:9;1235:7;1231:23;1227:32;1224:52;;;1272:1;1269;1262:12;1224:52;1311:9;1298:23;1330:31;1355:5;1330:31;:::i;:::-;1380:5;-1:-1:-1;1437:2:1;1422:18;;1409:32;1450:33;1409:32;1450:33;:::i;:::-;1502:7;1492:17;;;1127:388;;;;;:::o;1520:456::-;1597:6;1605;1613;1666:2;1654:9;1645:7;1641:23;1637:32;1634:52;;;1682:1;1679;1672:12;1634:52;1721:9;1708:23;1740:31;1765:5;1740:31;:::i;:::-;1790:5;-1:-1:-1;1847:2:1;1832:18;;1819:32;1860:33;1819:32;1860:33;:::i;:::-;1520:456;;1912:7;;-1:-1:-1;;;1966:2:1;1951:18;;;;1938:32;;1520:456::o;1981:665::-;2076:6;2084;2092;2100;2153:3;2141:9;2132:7;2128:23;2124:33;2121:53;;;2170:1;2167;2160:12;2121:53;2209:9;2196:23;2228:31;2253:5;2228:31;:::i;:::-;2278:5;-1:-1:-1;2335:2:1;2320:18;;2307:32;2348:33;2307:32;2348:33;:::i;:::-;2400:7;-1:-1:-1;2454:2:1;2439:18;;2426:32;;-1:-1:-1;2509:2:1;2494:18;;2481:32;2536:18;2525:30;;2522:50;;;2568:1;2565;2558:12;2522:50;2591:49;2632:7;2623:6;2612:9;2608:22;2591:49;:::i;:::-;2581:59;;;1981:665;;;;;;;:::o;2651:416::-;2716:6;2724;2777:2;2765:9;2756:7;2752:23;2748:32;2745:52;;;2793:1;2790;2783:12;2745:52;2832:9;2819:23;2851:31;2876:5;2851:31;:::i;:::-;2901:5;-1:-1:-1;2958:2:1;2943:18;;2930:32;3000:15;;2993:23;2981:36;;2971:64;;3031:1;3028;3021:12;3072:758;3174:6;3182;3190;3198;3206;3259:3;3247:9;3238:7;3234:23;3230:33;3227:53;;;3276:1;3273;3266:12;3227:53;3315:9;3302:23;3334:31;3359:5;3334:31;:::i;:::-;3384:5;-1:-1:-1;3440:2:1;3425:18;;3412:32;3467:18;3456:30;;3453:50;;;3499:1;3496;3489:12;3453:50;3522:49;3563:7;3554:6;3543:9;3539:22;3522:49;:::i;:::-;3512:59;;;3618:2;3607:9;3603:18;3590:32;3580:42;;3669:2;3658:9;3654:18;3641:32;3631:42;;3725:3;3714:9;3710:19;3697:33;3774:4;3765:7;3761:18;3752:7;3749:31;3739:59;;3794:1;3791;3784:12;3739:59;3817:7;3807:17;;;3072:758;;;;;;;;:::o;3835:315::-;3903:6;3911;3964:2;3952:9;3943:7;3939:23;3935:32;3932:52;;;3980:1;3977;3970:12;3932:52;4019:9;4006:23;4038:31;4063:5;4038:31;:::i;:::-;4088:5;4140:2;4125:18;;;;4112:32;;-1:-1:-1;;;3835:315:1:o;4155:180::-;4214:6;4267:2;4255:9;4246:7;4242:23;4238:32;4235:52;;;4283:1;4280;4273:12;4235:52;-1:-1:-1;4306:23:1;;4155:180;-1:-1:-1;4155:180:1:o;4340:388::-;4417:6;4425;4478:2;4466:9;4457:7;4453:23;4449:32;4446:52;;;4494:1;4491;4484:12;4446:52;4530:9;4517:23;4507:33;;4591:2;4580:9;4576:18;4563:32;4618:18;4610:6;4607:30;4604:50;;;4650:1;4647;4640:12;4604:50;4673:49;4714:7;4705:6;4694:9;4690:22;4673:49;:::i;:::-;4663:59;;;4340:388;;;;;:::o;4733:245::-;4791:6;4844:2;4832:9;4823:7;4819:23;4815:32;4812:52;;;4860:1;4857;4850:12;4812:52;4899:9;4886:23;4918:30;4942:5;4918:30;:::i;4983:249::-;5052:6;5105:2;5093:9;5084:7;5080:23;5076:32;5073:52;;;5121:1;5118;5111:12;5073:52;5153:9;5147:16;5172:30;5196:5;5172:30;:::i;5237:280::-;5336:6;5389:2;5377:9;5368:7;5364:23;5360:32;5357:52;;;5405:1;5402;5395:12;5357:52;5437:9;5431:16;5456:31;5481:5;5456:31;:::i;5522:450::-;5591:6;5644:2;5632:9;5623:7;5619:23;5615:32;5612:52;;;5660:1;5657;5650:12;5612:52;5700:9;5687:23;5733:18;5725:6;5722:30;5719:50;;;5765:1;5762;5755:12;5719:50;5788:22;;5841:4;5833:13;;5829:27;-1:-1:-1;5819:55:1;;5870:1;5867;5860:12;5819:55;5893:73;5958:7;5953:2;5940:16;5935:2;5931;5927:11;5893:73;:::i;6162:248::-;6230:6;6238;6291:2;6279:9;6270:7;6266:23;6262:32;6259:52;;;6307:1;6304;6297:12;6259:52;-1:-1:-1;;6330:23:1;;;6400:2;6385:18;;;6372:32;;-1:-1:-1;6162:248:1:o;6415:456::-;6501:6;6509;6517;6570:2;6558:9;6549:7;6545:23;6541:32;6538:52;;;6586:1;6583;6576:12;6538:52;6622:9;6609:23;6599:33;;6679:2;6668:9;6664:18;6651:32;6641:42;;6734:2;6723:9;6719:18;6706:32;6761:18;6753:6;6750:30;6747:50;;;6793:1;6790;6783:12;6747:50;6816:49;6857:7;6848:6;6837:9;6833:22;6816:49;:::i;:::-;6806:59;;;6415:456;;;;;:::o;6876:257::-;6917:3;6955:5;6949:12;6982:6;6977:3;6970:19;6998:63;7054:6;7047:4;7042:3;7038:14;7031:4;7024:5;7020:16;6998:63;:::i;:::-;7115:2;7094:15;-1:-1:-1;;7090:29:1;7081:39;;;;7122:4;7077:50;;6876:257;-1:-1:-1;;6876:257:1:o;7138:274::-;7267:3;7305:6;7299:13;7321:53;7367:6;7362:3;7355:4;7347:6;7343:17;7321:53;:::i;:::-;7390:16;;;;;7138:274;-1:-1:-1;;7138:274:1:o;7417:415::-;7574:3;7612:6;7606:13;7628:53;7674:6;7669:3;7662:4;7654:6;7650:17;7628:53;:::i;:::-;7750:2;7746:15;;;;-1:-1:-1;;7742:53:1;7703:16;;;;7728:68;;;7823:2;7812:14;;7417:415;-1:-1:-1;;7417:415:1:o;7837:470::-;8016:3;8054:6;8048:13;8070:53;8116:6;8111:3;8104:4;8096:6;8092:17;8070:53;:::i;:::-;8186:13;;8145:16;;;;8208:57;8186:13;8145:16;8242:4;8230:17;;8208:57;:::i;:::-;8281:20;;7837:470;-1:-1:-1;;;;7837:470:1:o;9587:454::-;9769:4;-1:-1:-1;;;;;9879:2:1;9871:6;9867:15;9856:9;9849:34;9931:2;9923:6;9919:15;9914:2;9903:9;9899:18;9892:43;;9971:2;9966;9955:9;9951:18;9944:30;9991:44;10031:2;10020:9;10016:18;10008:6;9991:44;:::i;:::-;9983:52;9587:454;-1:-1:-1;;;;;9587:454:1:o;10046:511::-;10240:4;-1:-1:-1;;;;;10350:2:1;10342:6;10338:15;10327:9;10320:34;10402:2;10394:6;10390:15;10385:2;10374:9;10370:18;10363:43;;10442:6;10437:2;10426:9;10422:18;10415:34;10485:3;10480:2;10469:9;10465:18;10458:31;10506:45;10546:3;10535:9;10531:19;10523:6;10506:45;:::i;:::-;10498:53;10046:511;-1:-1:-1;;;;;;10046:511:1:o;10562:632::-;10733:2;10785:21;;;10855:13;;10758:18;;;10877:22;;;10704:4;;10733:2;10956:15;;;;10930:2;10915:18;;;10704:4;10999:169;11013:6;11010:1;11007:13;10999:169;;;11074:13;;11062:26;;11143:15;;;;11108:12;;;;11035:1;11028:9;10999:169;;;-1:-1:-1;11185:3:1;;10562:632;-1:-1:-1;;;;;;10562:632:1:o;12421:217::-;12568:2;12557:9;12550:21;12531:4;12588:44;12628:2;12617:9;12613:18;12605:6;12588:44;:::i;25644:128::-;25684:3;25715:1;25711:6;25708:1;25705:13;25702:39;;;25721:18;;:::i;:::-;-1:-1:-1;25757:9:1;;25644:128::o;25777:120::-;25817:1;25843;25833:35;;25848:18;;:::i;:::-;-1:-1:-1;25882:9:1;;25777:120::o;25902:168::-;25942:7;26008:1;26004;26000:6;25996:14;25993:1;25990:21;25985:1;25978:9;25971:17;25967:45;25964:71;;;26015:18;;:::i;:::-;-1:-1:-1;26055:9:1;;25902:168::o;26075:125::-;26115:4;26143:1;26140;26137:8;26134:34;;;26148:18;;:::i;:::-;-1:-1:-1;26185:9:1;;26075:125::o;26205:258::-;26277:1;26287:113;26301:6;26298:1;26295:13;26287:113;;;26377:11;;;26371:18;26358:11;;;26351:39;26323:2;26316:10;26287:113;;;26418:6;26415:1;26412:13;26409:48;;;-1:-1:-1;;26453:1:1;26435:16;;26428:27;26205:258::o;26468:437::-;26547:1;26543:12;;;;26590;;;26611:61;;26665:4;26657:6;26653:17;26643:27;;26611:61;26718:2;26710:6;26707:14;26687:18;26684:38;26681:218;;;-1:-1:-1;;;26752:1:1;26745:88;26856:4;26853:1;26846:15;26884:4;26881:1;26874:15;26681:218;;26468:437;;;:::o;26910:135::-;26949:3;-1:-1:-1;;26970:17:1;;26967:43;;;26990:18;;:::i;:::-;-1:-1:-1;27037:1:1;27026:13;;26910:135::o;27050:112::-;27082:1;27108;27098:35;;27113:18;;:::i;:::-;-1:-1:-1;27147:9:1;;27050:112::o;27167:184::-;-1:-1:-1;;;27216:1:1;27209:88;27316:4;27313:1;27306:15;27340:4;27337:1;27330:15;27356:184;-1:-1:-1;;;27405:1:1;27398:88;27505:4;27502:1;27495:15;27529:4;27526:1;27519:15;27545:184;-1:-1:-1;;;27594:1:1;27587:88;27694:4;27691:1;27684:15;27718:4;27715:1;27708:15;27734:184;-1:-1:-1;;;27783:1:1;27776:88;27883:4;27880:1;27873:15;27907:4;27904:1;27897:15;27923:184;-1:-1:-1;;;27972:1:1;27965:88;28072:4;28069:1;28062:15;28096:4;28093:1;28086:15;28112:184;-1:-1:-1;;;28161:1:1;28154:88;28261:4;28258:1;28251:15;28285:4;28282:1;28275:15;28301:154;-1:-1:-1;;;;;28380:5:1;28376:54;28369:5;28366:65;28356:93;;28445:1;28442;28435:12;28460:177;-1:-1:-1;;;;;;28538:5:1;28534:78;28527:5;28524:89;28514:117;;28627:1;28624;28617:12
Swarm Source
ipfs://baecad6163a1a1f6cb12ad35fd26927be07a6b11326d177e2059bab27ba990b0
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.