Feature Tip: Add private address tag to any address under My Name Tag !
Overview
TokenID
219
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Tokenlandia
Compiler Version
v0.5.14+commit.1f1aaa4
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-01-17 */ // File: @openzeppelin/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @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) { // 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 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts 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. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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 mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: @openzeppelin/contracts/GSN/Context.sol pragma solidity ^0.5.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts/access/Roles.sol pragma solidity ^0.5.0; /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev Give an account access to this role. */ function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } /** * @dev Remove an account's access to this role. */ function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } /** * @dev Check if an account has this role. * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } } // File: @openzeppelin/contracts/access/roles/WhitelistAdminRole.sol pragma solidity ^0.5.0; /** * @title WhitelistAdminRole * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. */ contract WhitelistAdminRole is Context { using Roles for Roles.Role; event WhitelistAdminAdded(address indexed account); event WhitelistAdminRemoved(address indexed account); Roles.Role private _whitelistAdmins; constructor () internal { _addWhitelistAdmin(_msgSender()); } modifier onlyWhitelistAdmin() { require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role"); _; } function isWhitelistAdmin(address account) public view returns (bool) { return _whitelistAdmins.has(account); } function addWhitelistAdmin(address account) public onlyWhitelistAdmin { _addWhitelistAdmin(account); } function renounceWhitelistAdmin() public { _removeWhitelistAdmin(_msgSender()); } function _addWhitelistAdmin(address account) internal { _whitelistAdmins.add(account); emit WhitelistAdminAdded(account); } function _removeWhitelistAdmin(address account) internal { _whitelistAdmins.remove(account); emit WhitelistAdminRemoved(account); } } // File: @openzeppelin/contracts/access/roles/WhitelistedRole.sol pragma solidity ^0.5.0; /** * @title WhitelistedRole * @dev Whitelisted accounts have been approved by a WhitelistAdmin to perform certain actions (e.g. participate in a * crowdsale). This role is special in that the only accounts that can add it are WhitelistAdmins (who can also remove * it), and not Whitelisteds themselves. */ contract WhitelistedRole is Context, WhitelistAdminRole { using Roles for Roles.Role; event WhitelistedAdded(address indexed account); event WhitelistedRemoved(address indexed account); Roles.Role private _whitelisteds; modifier onlyWhitelisted() { require(isWhitelisted(_msgSender()), "WhitelistedRole: caller does not have the Whitelisted role"); _; } function isWhitelisted(address account) public view returns (bool) { return _whitelisteds.has(account); } function addWhitelisted(address account) public onlyWhitelistAdmin { _addWhitelisted(account); } function removeWhitelisted(address account) public onlyWhitelistAdmin { _removeWhitelisted(account); } function renounceWhitelisted() public { _removeWhitelisted(_msgSender()); } function _addWhitelisted(address account) internal { _whitelisteds.add(account); emit WhitelistedAdded(account); } function _removeWhitelisted(address account) internal { _whitelisteds.remove(account); emit WhitelistedRemoved(account); } } // File: @openzeppelin/contracts/drafts/Strings.sol pragma solidity ^0.5.0; /** * @title Strings * @dev String operations. */ library Strings { /** * @dev Converts a `uint256` to a `string`. * via OraclizeAPI - MIT licence * https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol */ function fromUint256(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); uint256 index = digits - 1; temp = value; while (temp != 0) { buffer[index--] = byte(uint8(48 + temp % 10)); temp /= 10; } return string(buffer); } } // File: @openzeppelin/contracts/introspection/IERC165.sol pragma solidity ^0.5.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol pragma solidity ^0.5.0; /** * @dev Required interface of an ERC721 compliant contract. */ contract IERC721 is IERC165 { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of NFTs in `owner`'s account. */ function balanceOf(address owner) public view returns (uint256 balance); /** * @dev Returns the owner of the NFT specified by `tokenId`. */ function ownerOf(uint256 tokenId) public view returns (address owner); /** * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to * another (`to`). * * * * Requirements: * - `from`, `to` cannot be zero. * - `tokenId` must be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this * NFT by either {approve} or {setApprovalForAll}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public; /** * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to * another (`to`). * * Requirements: * - If the caller is not `from`, it must be approved to move this NFT by * either {approve} or {setApprovalForAll}. */ function transferFrom(address from, address to, uint256 tokenId) public; function approve(address to, uint256 tokenId) public; function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; function isApprovedForAll(address owner, address operator) public view returns (bool); function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public; } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol pragma solidity ^0.5.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract IERC721Receiver { /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a {IERC721-safeTransferFrom}. This function MUST return the function selector, * otherwise the caller will revert the transaction. The selector to be * returned can be obtained as `this.onERC721Received.selector`. This * function MAY throw to revert and reject the transfer. * Note: the ERC721 contract address is always the message sender. * @param operator The address which called `safeTransferFrom` function * @param from The address which previously owned the token * @param tokenId The NFT identifier which is being transferred * @param data Additional data with no specified format * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) public returns (bytes4); } // File: @openzeppelin/contracts/utils/Address.sol pragma solidity ^0.5.5; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * This test is non-exhaustive, and there may be false-negatives: during the * execution of a contract's constructor, its address will be reported as * not containing 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. */ function isContract(address account) internal view returns (bool) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != 0x0 && codehash != accountHash); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } /** * @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]. * * _Available since v2.4.0._ */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call.value(amount)(""); require(success, "Address: unable to send value, recipient may have reverted"); } } // File: @openzeppelin/contracts/drafts/Counters.sol pragma solidity ^0.5.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. 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;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; 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 { counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } } // File: @openzeppelin/contracts/introspection/ERC165.sol pragma solidity ^0.5.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () internal { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol pragma solidity ^0.5.0; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is Context, ERC165, IERC721 { using SafeMath for uint256; using Address for address; using Counters for Counters.Counter; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping (uint256 => address) private _tokenOwner; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to number of owned token mapping (address => Counters.Counter) private _ownedTokensCount; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; constructor () public { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); } /** * @dev Gets the balance of the specified address. * @param owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address owner) public view returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _ownedTokensCount[owner].current(); } /** * @dev Gets the owner of the specified token ID. * @param tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { address owner = _tokenOwner[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev Approves another address to transfer the given token ID * The zero address indicates there is no approved address. * There can only be one approved address per token at a given time. * Can only be called by the token owner or an approved operator. * @param to address to be approved for the given token ID * @param tokenId uint256 ID of the token to be approved */ function approve(address to, uint256 tokenId) public { address owner = 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" ); _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev Gets the approved address for a token ID, or zero if no address set * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ function getApproved(uint256 tokenId) public view returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf. * @param to operator address to set the approval * @param approved representing the status of the approval to be set */ function setApprovalForAll(address to, bool approved) public { require(to != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][to] = approved; emit ApprovalForAll(_msgSender(), to, approved); } /** * @dev Tells whether an operator is approved by a given owner. * @param owner owner address which you want to query the approval of * @param operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll(address owner, address operator) public view returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Transfers the ownership of a given token ID to another address. * Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * Requires the msg.sender to be the owner, approved, or operator. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function transferFrom(address from, address to, uint256 tokenId) public { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transferFrom(from, to, tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received}, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received}, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the _msgSender() to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransferFrom(from, to, tokenId, _data); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal { _transferFrom(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether the specified token exists. * @param tokenId uint256 ID of the token to query the existence of * @return bool whether the token exists */ function _exists(uint256 tokenId) internal view returns (bool) { address owner = _tokenOwner[tokenId]; return owner != address(0); } /** * @dev Returns whether the given spender can transfer a given token ID. * @param spender address of the spender to query * @param tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Internal function to safely mint a new token. * Reverts if the given token ID already exists. * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Internal function to safely mint a new token. * Reverts if the given token ID already exists. * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted * @param _data bytes data to send along with a safe transfer check */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Internal function to mint a new token. * Reverts if the given token ID already exists. * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _tokenOwner[tokenId] = to; _ownedTokensCount[to].increment(); emit Transfer(address(0), to, tokenId); } /** * @dev Internal function to burn a specific token. * Reverts if the token does not exist. * Deprecated, use {_burn} instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own"); _clearApproval(tokenId); _ownedTokensCount[owner].decrement(); _tokenOwner[tokenId] = address(0); emit Transfer(owner, address(0), tokenId); } /** * @dev Internal function to burn a specific token. * Reverts if the token does not exist. * @param tokenId uint256 ID of the token being burned */ function _burn(uint256 tokenId) internal { _burn(ownerOf(tokenId), tokenId); } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _clearApproval(tokenId); _ownedTokensCount[from].decrement(); _ownedTokensCount[to].increment(); _tokenOwner[tokenId] = to; emit Transfer(from, 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. * * This function is deprecated. * @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) internal returns (bool) { if (!to.isContract()) { return true; } bytes4 retval = IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data); return (retval == _ERC721_RECEIVED); } /** * @dev Private function to clear current approval of a given token ID. * @param tokenId uint256 ID of the token to be transferred */ function _clearApproval(uint256 tokenId) private { if (_tokenApprovals[tokenId] != address(0)) { _tokenApprovals[tokenId] = address(0); } } } // File: @openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol pragma solidity ^0.5.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721Enumerable is IERC721 { function totalSupply() public view returns (uint256); function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId); function tokenByIndex(uint256 index) public view returns (uint256); } // File: @openzeppelin/contracts/token/ERC721/ERC721Enumerable.sol pragma solidity ^0.5.0; /** * @title ERC-721 Non-Fungible Token with optional enumeration extension logic * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721Enumerable is Context, ERC165, ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => 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; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @dev Constructor function. */ constructor () public { // register the supported interface to conform to ERC721Enumerable via ERC165 _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev Gets the token ID at a given index of the tokens list of the requested owner. * @param owner address owning the tokens list to be accessed * @param index uint256 representing the index to be accessed of the requested tokens list * @return uint256 token ID at the given index of the tokens list owned by the requested address */ function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) { require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev Gets the total amount of tokens stored by the contract. * @return uint256 representing the total amount of tokens */ function totalSupply() public view returns (uint256) { return _allTokens.length; } /** * @dev Gets the token ID at a given index of all the tokens in this contract * Reverts if the index is greater or equal to the total number of tokens. * @param index uint256 representing the index to be accessed of the tokens list * @return uint256 token ID at the given index of the tokens list */ function tokenByIndex(uint256 index) public view returns (uint256) { require(index < totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { super._transferFrom(from, to, tokenId); _removeTokenFromOwnerEnumeration(from, tokenId); _addTokenToOwnerEnumeration(to, tokenId); } /** * @dev Internal function to mint a new token. * Reverts if the given token ID already exists. * @param to address the beneficiary that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { super._mint(to, tokenId); _addTokenToOwnerEnumeration(to, tokenId); _addTokenToAllTokensEnumeration(tokenId); } /** * @dev Internal function to burn a specific token. * Reverts if the token does not exist. * Deprecated, use {ERC721-_burn} instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { super._burn(owner, tokenId); _removeTokenFromOwnerEnumeration(owner, tokenId); // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund _ownedTokensIndex[tokenId] = 0; _removeTokenFromAllTokensEnumeration(tokenId); } /** * @dev Gets the list of token IDs of the requested owner. * @param owner address owning the tokens * @return uint256[] List of token IDs owned by the requested address */ function _tokensOfOwner(address owner) internal view returns (uint256[] storage) { return _ownedTokens[owner]; } /** * @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 { _ownedTokensIndex[tokenId] = _ownedTokens[to].length; _ownedTokens[to].push(tokenId); } /** * @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 = _ownedTokens[from].length.sub(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 _ownedTokens[from].length--; // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by // lastTokenId, or just over the end of the array if the token was the last one). } /** * @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.sub(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 _allTokens.length--; _allTokensIndex[tokenId] = 0; } } // File: @openzeppelin/contracts/token/ERC721/IERC721Metadata.sol pragma solidity ^0.5.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721Metadata is IERC721 { function name() external view returns (string memory); function symbol() external view returns (string memory); function tokenURI(uint256 tokenId) external view returns (string memory); } // File: contracts/interfaces/erc721/ERC721MetadataWithoutTokenURI.sol pragma solidity ^0.5.14; contract ERC721MetadataWithoutTokenURI is ERC165, ERC721, IERC721Metadata { // Token name string private _name; // Token symbol string private _symbol; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /** * @dev Constructor function */ constructor (string memory name, string memory symbol) public { _name = name; _symbol = symbol; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721_METADATA); } /** * @dev Gets the token name. * @return string representing the token name */ function name() external view returns (string memory) { return _name; } /** * @dev Gets the token symbol. * @return string representing the token symbol */ function symbol() external view returns (string memory) { return _symbol; } } // File: contracts/interfaces/erc721/CustomERC721Full.sol pragma solidity ^0.5.14; /** * @title Custom version of the Full ERC721 Token contract produced by OpenZeppelin * This implementation includes all the required, some optional functionality of the ERC721 standard and removes * tokenURIs from the base ERC721Metadata contract. * Moreover, it includes approve all functionality using operator terminology * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract CustomERC721Full is ERC721, ERC721Enumerable, ERC721MetadataWithoutTokenURI { constructor (string memory name, string memory symbol) public ERC721MetadataWithoutTokenURI(name, symbol) { // solhint-disable-previous-line no-empty-blocks } } // File: contracts/interfaces/ITokenlandiaTokenCreator.sol pragma solidity ^0.5.14; contract ITokenlandiaTokenCreator { function mintToken( uint256 _tokenId, address _recipient, string calldata _productCode, string calldata _ipfsHash ) external returns (bool success); } // File: @openzeppelin/contracts/GSN/IRelayRecipient.sol pragma solidity ^0.5.0; /** * @dev Base interface for a contract that will be called via the GSN from {IRelayHub}. * * TIP: You don't need to write an implementation yourself! Inherit from {GSNRecipient} instead. */ contract IRelayRecipient { /** * @dev Returns the address of the {IRelayHub} instance this recipient interacts with. */ function getHubAddr() public view returns (address); /** * @dev Called by {IRelayHub} to validate if this recipient accepts being charged for a relayed call. Note that the * recipient will be charged regardless of the execution result of the relayed call (i.e. if it reverts or not). * * The relay request was originated by `from` and will be served by `relay`. `encodedFunction` is the relayed call * calldata, so its first four bytes are the function selector. The relayed call will be forwarded `gasLimit` gas, * and the transaction executed with a gas price of at least `gasPrice`. `relay`'s fee is `transactionFee`, and the * recipient will be charged at most `maxPossibleCharge` (in wei). `nonce` is the sender's (`from`) nonce for * replay attack protection in {IRelayHub}, and `approvalData` is a optional parameter that can be used to hold a signature * over all or some of the previous values. * * Returns a tuple, where the first value is used to indicate approval (0) or rejection (custom non-zero error code, * values 1 to 10 are reserved) and the second one is data to be passed to the other {IRelayRecipient} functions. * * {acceptRelayedCall} is called with 50k gas: if it runs out during execution, the request will be considered * rejected. A regular revert will also trigger a rejection. */ function acceptRelayedCall( address relay, address from, bytes calldata encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes calldata approvalData, uint256 maxPossibleCharge ) external view returns (uint256, bytes memory); /** * @dev Called by {IRelayHub} on approved relay call requests, before the relayed call is executed. This allows to e.g. * pre-charge the sender of the transaction. * * `context` is the second value returned in the tuple by {acceptRelayedCall}. * * Returns a value to be passed to {postRelayedCall}. * * {preRelayedCall} is called with 100k gas: if it runs out during exection or otherwise reverts, the relayed call * will not be executed, but the recipient will still be charged for the transaction's cost. */ function preRelayedCall(bytes calldata context) external returns (bytes32); /** * @dev Called by {IRelayHub} on approved relay call requests, after the relayed call is executed. This allows to e.g. * charge the user for the relayed call costs, return any overcharges from {preRelayedCall}, or perform * contract-specific bookkeeping. * * `context` is the second value returned in the tuple by {acceptRelayedCall}. `success` is the execution status of * the relayed call. `actualCharge` is an estimate of how much the recipient will be charged for the transaction, * not including any gas used by {postRelayedCall} itself. `preRetVal` is {preRelayedCall}'s return value. * * * {postRelayedCall} is called with 100k gas: if it runs out during execution or otherwise reverts, the relayed call * and the call to {preRelayedCall} will be reverted retroactively, but the recipient will still be charged for the * transaction's cost. */ function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external; } // File: @openzeppelin/contracts/GSN/IRelayHub.sol pragma solidity ^0.5.0; /** * @dev Interface for `RelayHub`, the core contract of the GSN. Users should not need to interact with this contract * directly. * * See the https://github.com/OpenZeppelin/openzeppelin-gsn-helpers[OpenZeppelin GSN helpers] for more information on * how to deploy an instance of `RelayHub` on your local test network. */ contract IRelayHub { // Relay management /** * @dev Adds stake to a relay and sets its `unstakeDelay`. If the relay does not exist, it is created, and the caller * of this function becomes its owner. If the relay already exists, only the owner can call this function. A relay * cannot be its own owner. * * All Ether in this function call will be added to the relay's stake. * Its unstake delay will be assigned to `unstakeDelay`, but the new value must be greater or equal to the current one. * * Emits a {Staked} event. */ function stake(address relayaddr, uint256 unstakeDelay) external payable; /** * @dev Emitted when a relay's stake or unstakeDelay are increased */ event Staked(address indexed relay, uint256 stake, uint256 unstakeDelay); /** * @dev Registers the caller as a relay. * The relay must be staked for, and not be a contract (i.e. this function must be called directly from an EOA). * * This function can be called multiple times, emitting new {RelayAdded} events. Note that the received * `transactionFee` is not enforced by {relayCall}. * * Emits a {RelayAdded} event. */ function registerRelay(uint256 transactionFee, string memory url) public; /** * @dev Emitted when a relay is registered or re-registerd. Looking at these events (and filtering out * {RelayRemoved} events) lets a client discover the list of available relays. */ event RelayAdded(address indexed relay, address indexed owner, uint256 transactionFee, uint256 stake, uint256 unstakeDelay, string url); /** * @dev Removes (deregisters) a relay. Unregistered (but staked for) relays can also be removed. * * Can only be called by the owner of the relay. After the relay's `unstakeDelay` has elapsed, {unstake} will be * callable. * * Emits a {RelayRemoved} event. */ function removeRelayByOwner(address relay) public; /** * @dev Emitted when a relay is removed (deregistered). `unstakeTime` is the time when unstake will be callable. */ event RelayRemoved(address indexed relay, uint256 unstakeTime); /** Deletes the relay from the system, and gives back its stake to the owner. * * Can only be called by the relay owner, after `unstakeDelay` has elapsed since {removeRelayByOwner} was called. * * Emits an {Unstaked} event. */ function unstake(address relay) public; /** * @dev Emitted when a relay is unstaked for, including the returned stake. */ event Unstaked(address indexed relay, uint256 stake); // States a relay can be in enum RelayState { Unknown, // The relay is unknown to the system: it has never been staked for Staked, // The relay has been staked for, but it is not yet active Registered, // The relay has registered itself, and is active (can relay calls) Removed // The relay has been removed by its owner and can no longer relay calls. It must wait for its unstakeDelay to elapse before it can unstake } /** * @dev Returns a relay's status. Note that relays can be deleted when unstaked or penalized, causing this function * to return an empty entry. */ function getRelay(address relay) external view returns (uint256 totalStake, uint256 unstakeDelay, uint256 unstakeTime, address payable owner, RelayState state); // Balance management /** * @dev Deposits Ether for a contract, so that it can receive (and pay for) relayed transactions. * * Unused balance can only be withdrawn by the contract itself, by calling {withdraw}. * * Emits a {Deposited} event. */ function depositFor(address target) public payable; /** * @dev Emitted when {depositFor} is called, including the amount and account that was funded. */ event Deposited(address indexed recipient, address indexed from, uint256 amount); /** * @dev Returns an account's deposits. These can be either a contracts's funds, or a relay owner's revenue. */ function balanceOf(address target) external view returns (uint256); /** * Withdraws from an account's balance, sending it back to it. Relay owners call this to retrieve their revenue, and * contracts can use it to reduce their funding. * * Emits a {Withdrawn} event. */ function withdraw(uint256 amount, address payable dest) public; /** * @dev Emitted when an account withdraws funds from `RelayHub`. */ event Withdrawn(address indexed account, address indexed dest, uint256 amount); // Relaying /** * @dev Checks if the `RelayHub` will accept a relayed operation. * Multiple things must be true for this to happen: * - all arguments must be signed for by the sender (`from`) * - the sender's nonce must be the current one * - the recipient must accept this transaction (via {acceptRelayedCall}) * * Returns a `PreconditionCheck` value (`OK` when the transaction can be relayed), or a recipient-specific error * code if it returns one in {acceptRelayedCall}. */ function canRelay( address relay, address from, address to, bytes memory encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes memory signature, bytes memory approvalData ) public view returns (uint256 status, bytes memory recipientContext); // Preconditions for relaying, checked by canRelay and returned as the corresponding numeric values. enum PreconditionCheck { OK, // All checks passed, the call can be relayed WrongSignature, // The transaction to relay is not signed by requested sender WrongNonce, // The provided nonce has already been used by the sender AcceptRelayedCallReverted, // The recipient rejected this call via acceptRelayedCall InvalidRecipientStatusCode // The recipient returned an invalid (reserved) status code } /** * @dev Relays a transaction. * * For this to succeed, multiple conditions must be met: * - {canRelay} must `return PreconditionCheck.OK` * - the sender must be a registered relay * - the transaction's gas price must be larger or equal to the one that was requested by the sender * - the transaction must have enough gas to not run out of gas if all internal transactions (calls to the * recipient) use all gas available to them * - the recipient must have enough balance to pay the relay for the worst-case scenario (i.e. when all gas is * spent) * * If all conditions are met, the call will be relayed and the recipient charged. {preRelayedCall}, the encoded * function and {postRelayedCall} will be called in that order. * * Parameters: * - `from`: the client originating the request * - `to`: the target {IRelayRecipient} contract * - `encodedFunction`: the function call to relay, including data * - `transactionFee`: fee (%) the relay takes over actual gas cost * - `gasPrice`: gas price the client is willing to pay * - `gasLimit`: gas to forward when calling the encoded function * - `nonce`: client's nonce * - `signature`: client's signature over all previous params, plus the relay and RelayHub addresses * - `approvalData`: dapp-specific data forwared to {acceptRelayedCall}. This value is *not* verified by the * `RelayHub`, but it still can be used for e.g. a signature. * * Emits a {TransactionRelayed} event. */ function relayCall( address from, address to, bytes memory encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes memory signature, bytes memory approvalData ) public; /** * @dev Emitted when an attempt to relay a call failed. * * This can happen due to incorrect {relayCall} arguments, or the recipient not accepting the relayed call. The * actual relayed call was not executed, and the recipient not charged. * * The `reason` parameter contains an error code: values 1-10 correspond to `PreconditionCheck` entries, and values * over 10 are custom recipient error codes returned from {acceptRelayedCall}. */ event CanRelayFailed(address indexed relay, address indexed from, address indexed to, bytes4 selector, uint256 reason); /** * @dev Emitted when a transaction is relayed. * Useful when monitoring a relay's operation and relayed calls to a contract * * Note that the actual encoded function might be reverted: this is indicated in the `status` parameter. * * `charge` is the Ether value deducted from the recipient's balance, paid to the relay's owner. */ event TransactionRelayed(address indexed relay, address indexed from, address indexed to, bytes4 selector, RelayCallStatus status, uint256 charge); // Reason error codes for the TransactionRelayed event enum RelayCallStatus { OK, // The transaction was successfully relayed and execution successful - never included in the event RelayedCallFailed, // The transaction was relayed, but the relayed call failed PreRelayedFailed, // The transaction was not relayed due to preRelatedCall reverting PostRelayedFailed, // The transaction was relayed and reverted due to postRelatedCall reverting RecipientBalanceChanged // The transaction was relayed and reverted due to the recipient's balance changing } /** * @dev Returns how much gas should be forwarded to a call to {relayCall}, in order to relay a transaction that will * spend up to `relayedCallStipend` gas. */ function requiredGas(uint256 relayedCallStipend) public view returns (uint256); /** * @dev Returns the maximum recipient charge, given the amount of gas forwarded, gas price and relay fee. */ function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) public view returns (uint256); // Relay penalization. // Any account can penalize relays, removing them from the system immediately, and rewarding the // reporter with half of the relay's stake. The other half is burned so that, even if the relay penalizes itself, it // still loses half of its stake. /** * @dev Penalize a relay that signed two transactions using the same nonce (making only the first one valid) and * different data (gas price, gas limit, etc. may be different). * * The (unsigned) transaction data and signature for both transactions must be provided. */ function penalizeRepeatedNonce(bytes memory unsignedTx1, bytes memory signature1, bytes memory unsignedTx2, bytes memory signature2) public; /** * @dev Penalize a relay that sent a transaction that didn't target `RelayHub`'s {registerRelay} or {relayCall}. */ function penalizeIllegalTransaction(bytes memory unsignedTx, bytes memory signature) public; /** * @dev Emitted when a relay is penalized. */ event Penalized(address indexed relay, address sender, uint256 amount); /** * @dev Returns an account's nonce in `RelayHub`. */ function getNonce(address from) external view returns (uint256); } // File: @openzeppelin/contracts/GSN/GSNRecipient.sol pragma solidity ^0.5.0; /** * @dev Base GSN recipient contract: includes the {IRelayRecipient} interface * and enables GSN support on all contracts in the inheritance tree. * * TIP: This contract is abstract. The functions {acceptRelayedCall}, * {_preRelayedCall}, and {_postRelayedCall} are not implemented and must be * provided by derived contracts. See the * xref:ROOT:gsn-strategies.adoc#gsn-strategies[GSN strategies] for more * information on how to use the pre-built {GSNRecipientSignature} and * {GSNRecipientERC20Fee}, or how to write your own. */ contract GSNRecipient is IRelayRecipient, Context { // Default RelayHub address, deployed on mainnet and all testnets at the same address address private _relayHub = 0xD216153c06E857cD7f72665E0aF1d7D82172F494; uint256 constant private RELAYED_CALL_ACCEPTED = 0; uint256 constant private RELAYED_CALL_REJECTED = 11; // How much gas is forwarded to postRelayedCall uint256 constant internal POST_RELAYED_CALL_MAX_GAS = 100000; /** * @dev Emitted when a contract changes its {IRelayHub} contract to a new one. */ event RelayHubChanged(address indexed oldRelayHub, address indexed newRelayHub); /** * @dev Returns the address of the {IRelayHub} contract for this recipient. */ function getHubAddr() public view returns (address) { return _relayHub; } /** * @dev Switches to a new {IRelayHub} instance. This method is added for future-proofing: there's no reason to not * use the default instance. * * IMPORTANT: After upgrading, the {GSNRecipient} will no longer be able to receive relayed calls from the old * {IRelayHub} instance. Additionally, all funds should be previously withdrawn via {_withdrawDeposits}. */ function _upgradeRelayHub(address newRelayHub) internal { address currentRelayHub = _relayHub; require(newRelayHub != address(0), "GSNRecipient: new RelayHub is the zero address"); require(newRelayHub != currentRelayHub, "GSNRecipient: new RelayHub is the current one"); emit RelayHubChanged(currentRelayHub, newRelayHub); _relayHub = newRelayHub; } /** * @dev Returns the version string of the {IRelayHub} for which this recipient implementation was built. If * {_upgradeRelayHub} is used, the new {IRelayHub} instance should be compatible with this version. */ // This function is view for future-proofing, it may require reading from // storage in the future. function relayHubVersion() public view returns (string memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return "1.0.0"; } /** * @dev Withdraws the recipient's deposits in `RelayHub`. * * Derived contracts should expose this in an external interface with proper access control. */ function _withdrawDeposits(uint256 amount, address payable payee) internal { IRelayHub(_relayHub).withdraw(amount, payee); } // Overrides for Context's functions: when called from RelayHub, sender and // data require some pre-processing: the actual sender is stored at the end // of the call data, which in turns means it needs to be removed from it // when handling said data. /** * @dev Replacement for msg.sender. Returns the actual sender of a transaction: msg.sender for regular transactions, * and the end-user for GSN relayed calls (where msg.sender is actually `RelayHub`). * * IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.sender`, and use {_msgSender} instead. */ function _msgSender() internal view returns (address payable) { if (msg.sender != _relayHub) { return msg.sender; } else { return _getRelayedCallSender(); } } /** * @dev Replacement for msg.data. Returns the actual calldata of a transaction: msg.data for regular transactions, * and a reduced version for GSN relayed calls (where msg.data contains additional information). * * IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.data`, and use {_msgData} instead. */ function _msgData() internal view returns (bytes memory) { if (msg.sender != _relayHub) { return msg.data; } else { return _getRelayedCallData(); } } // Base implementations for pre and post relayedCall: only RelayHub can invoke them, and data is forwarded to the // internal hook. /** * @dev See `IRelayRecipient.preRelayedCall`. * * This function should not be overriden directly, use `_preRelayedCall` instead. * * * Requirements: * * - the caller must be the `RelayHub` contract. */ function preRelayedCall(bytes calldata context) external returns (bytes32) { require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub"); return _preRelayedCall(context); } /** * @dev See `IRelayRecipient.preRelayedCall`. * * Called by `GSNRecipient.preRelayedCall`, which asserts the caller is the `RelayHub` contract. Derived contracts * must implement this function with any relayed-call preprocessing they may wish to do. * */ function _preRelayedCall(bytes memory context) internal returns (bytes32); /** * @dev See `IRelayRecipient.postRelayedCall`. * * This function should not be overriden directly, use `_postRelayedCall` instead. * * * Requirements: * * - the caller must be the `RelayHub` contract. */ function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external { require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub"); _postRelayedCall(context, success, actualCharge, preRetVal); } /** * @dev See `IRelayRecipient.postRelayedCall`. * * Called by `GSNRecipient.postRelayedCall`, which asserts the caller is the `RelayHub` contract. Derived contracts * must implement this function with any relayed-call postprocessing they may wish to do. * */ function _postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) internal; /** * @dev Return this in acceptRelayedCall to proceed with the execution of a relayed call. Note that this contract * will be charged a fee by RelayHub */ function _approveRelayedCall() internal pure returns (uint256, bytes memory) { return _approveRelayedCall(""); } /** * @dev See `GSNRecipient._approveRelayedCall`. * * This overload forwards `context` to _preRelayedCall and _postRelayedCall. */ function _approveRelayedCall(bytes memory context) internal pure returns (uint256, bytes memory) { return (RELAYED_CALL_ACCEPTED, context); } /** * @dev Return this in acceptRelayedCall to impede execution of a relayed call. No fees will be charged. */ function _rejectRelayedCall(uint256 errorCode) internal pure returns (uint256, bytes memory) { return (RELAYED_CALL_REJECTED + errorCode, ""); } /* * @dev Calculates how much RelayHub will charge a recipient for using `gas` at a `gasPrice`, given a relayer's * `serviceFee`. */ function _computeCharge(uint256 gas, uint256 gasPrice, uint256 serviceFee) internal pure returns (uint256) { // The fee is expressed as a percentage. E.g. a value of 40 stands for a 40% fee, so the recipient will be // charged for 1.4 times the spent amount. return (gas * gasPrice * (100 + serviceFee)) / 100; } function _getRelayedCallSender() private pure returns (address payable result) { // We need to read 20 bytes (an address) located at array index msg.data.length - 20. In memory, the array // is prefixed with a 32-byte length value, so we first add 32 to get the memory read index. However, doing // so would leave the address in the upper 20 bytes of the 32-byte word, which is inconvenient and would // require bit shifting. We therefore subtract 12 from the read index so the address lands on the lower 20 // bytes. This can always be done due to the 32-byte prefix. // The final memory read index is msg.data.length - 20 + 32 - 12 = msg.data.length. Using inline assembly is the // easiest/most-efficient way to perform this operation. // These fields are not accessible from assembly bytes memory array = msg.data; uint256 index = msg.data.length; // solhint-disable-next-line no-inline-assembly assembly { // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those. result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff) } return result; } function _getRelayedCallData() private pure returns (bytes memory) { // RelayHub appends the sender address at the end of the calldata, so in order to retrieve the actual msg.data, // we must strip the last 20 bytes (length of an address type) from it. uint256 actualDataLength = msg.data.length - 20; bytes memory actualData = new bytes(actualDataLength); for (uint256 i = 0; i < actualDataLength; ++i) { actualData[i] = msg.data[i]; } return actualData; } } // File: @openzeppelin/contracts/cryptography/ECDSA.sol pragma solidity ^0.5.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 { /** * @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. * * NOTE: This call _does not revert_ if the signature is invalid, or * if the signer is otherwise unable to be retrieved. In those scenarios, * the zero address is returned. * * 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) { // Check the signature length if (signature.length != 65) { return (address(0)); } // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } // 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 (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): 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); } if (v != 27 && v != 28) { return address(0); } // If the signature is valid (and not malleable), return the signer address return ecrecover(hash, v, r, s); } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * replicates the behavior of the * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`] * JSON-RPC method. * * 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)); } } // File: contracts/GSN/TokenLandiaWhitelistGSNRecipient.sol pragma solidity ^0.5.14; /* Based on v2.4.0 of GSNRecipientSignature from openzeppelin */ contract TokenLandiaWhitelistGSNRecipient is WhitelistedRole, GSNRecipient { using ECDSA for bytes32; enum GSNRecipientSignatureErrorCodes { INVALID_SENDER } constructor() public { super.addWhitelisted(_msgSender()); } /** * @dev Ensures that only transactions with a trusted signature can be relayed through the GSN. */ function acceptRelayedCall( address relay, address from, bytes calldata encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes calldata approvalData, uint256 ) external view returns (uint256, bytes memory) { bytes memory blob = abi.encodePacked( relay, from, encodedFunction, transactionFee, gasPrice, gasLimit, nonce, // Prevents replays on RelayHub getHubAddr(), // Prevents replays in multiple RelayHubs address(this) // Prevents replays in multiple recipients ); bool isOriginalCallerWhitelisted = isWhitelisted(keccak256(blob).toEthSignedMessageHash().recover(approvalData)); if (isOriginalCallerWhitelisted) { return _approveRelayedCall(); } else { return _rejectRelayedCall(uint256(GSNRecipientSignatureErrorCodes.INVALID_SENDER)); } } function _preRelayedCall(bytes memory) internal returns (bytes32) { // solhint-disable-previous-line no-empty-blocks } function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal { // solhint-disable-previous-line no-empty-blocks } function upgradeRelayHub(address newRelayHub) external onlyWhitelistAdmin { _upgradeRelayHub(newRelayHub); } } // File: contracts/token/Tokenlandia.sol pragma solidity ^0.5.14; contract Tokenlandia is CustomERC721Full, ITokenlandiaTokenCreator, TokenLandiaWhitelistGSNRecipient { using SafeMath for uint256; string public tokenBaseURI = ""; struct Token { string productCode; string ipfsHash; } mapping(uint256 => Token) internal tokens; // Reverse mapping so we can lookup the token from the product ID mapping(string => uint256) internal productIdToTokenId; modifier onlyWhenTokenExists(uint256 _tokenId) { require(_exists(_tokenId), "Token ID not valid"); _; } constructor (string memory _tokenBaseURI) public CustomERC721Full("TokenLandia NFT", "TLN") TokenLandiaWhitelistGSNRecipient() { tokenBaseURI = _tokenBaseURI; } /** * Mint a token to a specific recipient * @dev Only callable from whitelisted address * @param _tokenId uint256 id of the token * @param _recipient address of the recipient * @param _productCode string the product code identified - [productCode-tokenId] provides a uniqueness guarantee * @param _ipfsHash string the IPFS hash **/ function mintToken( uint256 _tokenId, address _recipient, string calldata _productCode, string calldata _ipfsHash ) external onlyWhitelisted returns (bool success) { require(bytes(_productCode).length > 0, "Product code invalid"); require(bytes(_ipfsHash).length > 0, "IPFS hash invalid"); // Create Token metadata tokens[_tokenId] = Token({ productCode : _productCode, ipfsHash : _ipfsHash }); // Mint token _mint(_recipient, _tokenId); // Create reverse lookup from productId to tokenId productIdToTokenId[string(abi.encodePacked(_productCode, "-", Strings.fromUint256(_tokenId)))] = _tokenId; return true; } function ipfsUrlForProductId(string calldata productId) external view returns ( string memory _ipfsUrl ) { uint256 tokenId = productIdToTokenId[productId]; require(_exists(tokenId), "Token not found for product ID"); return string(abi.encodePacked(tokenBaseURI, tokens[tokenId].ipfsHash)); } function attributes(uint256 _tokenId) external onlyWhenTokenExists(_tokenId) view returns ( string memory _productCode, string memory _productId, string memory _ipfsUrl ) { Token storage token = tokens[_tokenId]; return ( token.productCode, string(abi.encodePacked(token.productCode, "-", Strings.fromUint256(_tokenId))), string(abi.encodePacked(tokenBaseURI, token.ipfsHash)) ); } function productCode(uint256 _tokenId) external onlyWhenTokenExists(_tokenId) view returns (string memory _productCode) { Token storage token = tokens[_tokenId]; return token.productCode; } function productId(uint256 _tokenId) external onlyWhenTokenExists(_tokenId) view returns (string memory _productId) { Token storage token = tokens[_tokenId]; return string(abi.encodePacked(token.productCode, "-", Strings.fromUint256(_tokenId))); } function tokenIdForProductId(string calldata _productId) external view returns (uint256 _tokenId) { return productIdToTokenId[_productId]; } function tokenURI(uint256 _tokenId) external onlyWhenTokenExists(_tokenId) view returns (string memory) { return string(abi.encodePacked(tokenBaseURI, tokens[_tokenId].ipfsHash)); } function tokensOfOwner(address owner) external view returns (uint256[] memory) { return _tokensOfOwner(owner); } function updateProductCode(uint256 _tokenId, string calldata _productCode) external onlyWhitelisted onlyWhenTokenExists(_tokenId) { Token storage token = tokens[_tokenId]; token.productCode = _productCode; productIdToTokenId[string(abi.encodePacked(_productCode, "-", Strings.fromUint256(_tokenId)))] = _tokenId; } function updateIpfsHash(uint256 _tokenId, string calldata _newIpfsHash) external onlyWhitelisted onlyWhenTokenExists(_tokenId) { require(bytes(_newIpfsHash).length != 0, "New IPFS hash invalid"); tokens[_tokenId].ipfsHash = _newIpfsHash; } function updateTokenBaseURI(string calldata _newBaseURI) external onlyWhitelistAdmin { require(bytes(_newBaseURI).length != 0, "Base URI invalid"); tokenBaseURI = _newBaseURI; } /** * @dev Burns a specific token. * @dev Only callable from whitelisted address * @param _tokenId uint256 id of the token to be burned. */ function burn(uint256 _tokenId) public onlyWhitelistAdmin onlyWhenTokenExists(_tokenId) { // Clean up product ID mapping Token storage token = tokens[_tokenId]; delete productIdToTokenId[string(abi.encodePacked(token.productCode, "-", Strings.fromUint256(_tokenId)))]; _burn(_tokenId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_tokenBaseURI","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldRelayHub","type":"address"},{"indexed":true,"internalType":"address","name":"newRelayHub","type":"address"}],"name":"RelayHubChanged","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistAdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistAdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistedAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistedRemoved","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"relay","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes","name":"encodedFunction","type":"bytes"},{"internalType":"uint256","name":"transactionFee","type":"uint256"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"approvalData","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"acceptRelayedCall","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addWhitelistAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addWhitelisted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"attributes","outputs":[{"internalType":"string","name":"_productCode","type":"string"},{"internalType":"string","name":"_productId","type":"string"},{"internalType":"string","name":"_ipfsUrl","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getHubAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"productId","type":"string"}],"name":"ipfsUrlForProductId","outputs":[{"internalType":"string","name":"_ipfsUrl","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isWhitelistAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"string","name":"_productCode","type":"string"},{"internalType":"string","name":"_ipfsHash","type":"string"}],"name":"mintToken","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"context","type":"bytes"},{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"actualCharge","type":"uint256"},{"internalType":"bytes32","name":"preRetVal","type":"bytes32"}],"name":"postRelayedCall","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"context","type":"bytes"}],"name":"preRelayedCall","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"productCode","outputs":[{"internalType":"string","name":"_productCode","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"productId","outputs":[{"internalType":"string","name":"_productId","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"relayHubVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeWhitelisted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceWhitelistAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceWhitelisted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"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":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenBaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string","name":"_productId","type":"string"}],"name":"tokenIdForProductId","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_newIpfsHash","type":"string"}],"name":"updateIpfsHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_productCode","type":"string"}],"name":"updateProductCode","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"updateTokenBaseURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newRelayHub","type":"address"}],"name":"upgradeRelayHub","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
600d80546001600160a01b03191673d216153c06e857cd7f72665e0af1d7d82172f49417905560a06040819052600060808190526200004191600e91620005b0565b503480156200004f57600080fd5b50604051620044da380380620044da833981810160405260208110156200007557600080fd5b81019080805160405193929190846401000000008211156200009657600080fd5b908301906020820185811115620000ac57600080fd5b8251640100000000811182820188101715620000c757600080fd5b82525081516020918201929091019080838360005b83811015620000f6578181015183820152602001620000dc565b50505050905090810190601f168015620001245780820380516001836020036101000a031916815260200191505b5060408181018152600f82526e151bdad95b93185b991a5848139195608a1b602080840191909152815180830190925260038252622a262760e91b90820152909350915082905081620001876301ffc9a760e01b6001600160e01b036200027016565b620001a26380ac58cd60e01b6001600160e01b036200027016565b620001bd63780e9d6360e01b6001600160e01b036200027016565b8151620001d2906009906020850190620005b0565b508051620001e890600a906020840190620005b0565b5062000204635b5e139f60e01b6001600160e01b036200027016565b505050506200022b6200021c620002f560201b60201c565b6001600160e01b036200032c16565b62000253620002426001600160e01b03620002f516565b6200037e60201b620010aa1760201c565b80516200026890600e906020840190620005b0565b505062000652565b6001600160e01b03198082161415620002d0576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b600d546000906001600160a01b031633146200031357503362000329565b620003266001600160e01b03620003f816565b90505b90565b6200034781600b6200044560201b6200301c1790919060201c565b6040516001600160a01b038216907f22380c05984257a1cb900161c713dd71d39e74820f1aea43bd3f1bdd2096129990600090a250565b620003a4620003956001600160e01b03620002f516565b6001600160e01b03620004d216565b620003e15760405162461bcd60e51b81526004018080602001828103825260408152602001806200449a6040913960400191505060405180910390fd5b620003f5816001600160e01b03620004f516565b50565b600060606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031692915050565b6200045a82826001600160e01b036200054716565b15620004ad576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6000620004ef82600b6200054760201b62002af01790919060201c565b92915050565b6200051081600c6200044560201b6200301c1790919060201c565b6040516001600160a01b038216907fee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f90600090a250565b60006001600160a01b038216620005905760405162461bcd60e51b8152600401808060200182810382526022815260200180620044786022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620005f357805160ff191683800117855562000623565b8280016001018555821562000623579182015b828111156200062357825182559160200191906001019062000606565b506200063192915062000635565b5090565b6200032991905b808211156200063157600081556001016200063c565b613e1680620006626000396000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c806374e861d611610146578063ad61ccd5116100c3578063d6cd947311610087578063d6cd947314610c63578063d940a7ea14610c6b578063e06e0e2214610cd9578063e985e9c514610d55578063ead25d1514610d83578063f1e95a3514610df157610253565b8063ad61ccd5146109f3578063b88d4fde146109fb578063bb5f747b14610abf578063c87b56dd14610ae5578063d05dcc6a14610b0257610253565b80638ed2be821161010a5780638ed2be821461090557806395d89b41146109225780639611c0511461092a5780639e30a5901461099f578063a22cb465146109c557610253565b806374e861d61461068f57806380274db71461069757806383947ea0146107055780638462151c146108725780638b174b1b146108e857610253565b80633af32abf116101d45780634f6ccce7116101985780634f6ccce7146105365780636289fa61146105535780636352211e1461062657806370a08231146106435780637362d9c81461066957610253565b80633af32abf146104ad57806342842e0e146104d357806342966c68146105095780634c5a628c146105265780634e99b8001461052e57610253565b806318160ddd1161021b57806318160ddd1461039d5780632295ee5b146103b757806323b872dd14610425578063291d95491461045b5780632f745c591461048157610253565b806301ffc9a71461025857806306fdde0314610293578063081812fc14610310578063095ea7b31461034957806310154bad14610377575b600080fd5b61027f6004803603602081101561026e57600080fd5b50356001600160e01b031916610e66565b604080519115158252519081900360200190f35b61029b610e89565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102d55781810151838201526020016102bd565b50505050905090810190601f1680156103025780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61032d6004803603602081101561032657600080fd5b5035610f20565b604080516001600160a01b039092168252519081900360200190f35b6103756004803603604081101561035f57600080fd5b506001600160a01b038135169060200135610f82565b005b6103756004803603602081101561038d57600080fd5b50356001600160a01b03166110aa565b6103a5611101565b60408051918252519081900360200190f35b610375600480360360208110156103cd57600080fd5b810190602081018135600160201b8111156103e757600080fd5b8201836020820111156103f957600080fd5b803590602001918460018302840111600160201b8311171561041a57600080fd5b509092509050611107565b6103756004803603606081101561043b57600080fd5b506001600160a01b038135811691602081013590911690604001356111a3565b6103756004803603602081101561047157600080fd5b50356001600160a01b03166111fa565b6103a56004803603604081101561049757600080fd5b506001600160a01b038135169060200135611249565b61027f600480360360208110156104c357600080fd5b50356001600160a01b03166112c9565b610375600480360360608110156104e957600080fd5b506001600160a01b038135811691602081013590911690604001356112dc565b6103756004803603602081101561051f57600080fd5b50356112f7565b6103756114dd565b61029b6114ef565b6103a56004803603602081101561054c57600080fd5b503561157d565b61027f6004803603608081101561056957600080fd5b8135916001600160a01b0360208201351691810190606081016040820135600160201b81111561059857600080fd5b8201836020820111156105aa57600080fd5b803590602001918460018302840111600160201b831117156105cb57600080fd5b919390929091602081019035600160201b8111156105e857600080fd5b8201836020820111156105fa57600080fd5b803590602001918460018302840111600160201b8311171561061b57600080fd5b5090925090506115e3565b61032d6004803603602081101561063c57600080fd5b503561187b565b6103a56004803603602081101561065957600080fd5b50356001600160a01b03166118cf565b6103756004803603602081101561067f57600080fd5b50356001600160a01b0316611937565b61032d611986565b6103a5600480360360208110156106ad57600080fd5b810190602081018135600160201b8111156106c757600080fd5b8201836020820111156106d957600080fd5b803590602001918460018302840111600160201b831117156106fa57600080fd5b509092509050611995565b6107f3600480360361012081101561071c57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561074f57600080fd5b82018360208201111561076157600080fd5b803590602001918460018302840111600160201b8311171561078257600080fd5b9193909282359260208101359260408201359260608301359260a081019060800135600160201b8111156107b557600080fd5b8201836020820111156107c757600080fd5b803590602001918460018302840111600160201b831117156107e857600080fd5b919350915035611a34565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561083657818101518382015260200161081e565b50505050905090810190601f1680156108635780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b6108986004803603602081101561088857600080fd5b50356001600160a01b0316611b74565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156108d45781810151838201526020016108bc565b505050509050019250505060405180910390f35b61029b600480360360208110156108fe57600080fd5b5035611bd5565b61029b6004803603602081101561091b57600080fd5b5035611d14565b61029b611e0b565b6103756004803603604081101561094057600080fd5b81359190810190604081016020820135600160201b81111561096157600080fd5b82018360208201111561097357600080fd5b803590602001918460018302840111600160201b8311171561099457600080fd5b509092509050611e6c565b610375600480360360208110156109b557600080fd5b50356001600160a01b0316611f6f565b610375600480360360408110156109db57600080fd5b506001600160a01b0381351690602001351515611fbe565b61029b6120c3565b61037560048036036080811015610a1157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a4b57600080fd5b820183602082011115610a5d57600080fd5b803590602001918460018302840111600160201b83111715610a7e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506120e2945050505050565b61027f60048036036020811015610ad557600080fd5b50356001600160a01b0316612140565b61029b60048036036020811015610afb57600080fd5b5035612153565b610b1f60048036036020811015610b1857600080fd5b5035612290565b60405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015610b64578181015183820152602001610b4c565b50505050905090810190601f168015610b915780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015610bc4578181015183820152602001610bac565b50505050905090810190601f168015610bf15780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b83811015610c24578181015183820152602001610c0c565b50505050905090810190601f168015610c515780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b610375612534565b61029b60048036036020811015610c8157600080fd5b810190602081018135600160201b811115610c9b57600080fd5b820183602082011115610cad57600080fd5b803590602001918460018302840111600160201b83111715610cce57600080fd5b509092509050612544565b61037560048036036080811015610cef57600080fd5b810190602081018135600160201b811115610d0957600080fd5b820183602082011115610d1b57600080fd5b803590602001918460018302840111600160201b83111715610d3c57600080fd5b91935091508035151590602081013590604001356126b8565b61027f60048036036040811015610d6b57600080fd5b506001600160a01b0381358116916020013516612753565b6103a560048036036020811015610d9957600080fd5b810190602081018135600160201b811115610db357600080fd5b820183602082011115610dc557600080fd5b803590602001918460018302840111600160201b83111715610de657600080fd5b509092509050612781565b61037560048036036040811015610e0757600080fd5b81359190810190604081016020820135600160201b811115610e2857600080fd5b820183602082011115610e3a57600080fd5b803590602001918460018302840111600160201b83111715610e5b57600080fd5b5090925090506127b2565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f155780601f10610eea57610100808354040283529160200191610f15565b820191906000526020600020905b815481529060010190602001808311610ef857829003601f168201915b505050505090505b90565b6000610f2b82612955565b610f665760405162461bcd60e51b815260040180806020018281038252602c815260200180613bfd602c913960400191505060405180910390fd5b506000908152600260205260409020546001600160a01b031690565b6000610f8d8261187b565b9050806001600160a01b0316836001600160a01b03161415610fe05760405162461bcd60e51b8152600401808060200182810382526021815260200180613d1b6021913960400191505060405180910390fd5b806001600160a01b0316610ff2612972565b6001600160a01b0316148061101357506110138161100e612972565b612753565b61104e5760405162461bcd60e51b8152600401808060200182810382526038815260200180613b236038913960400191505060405180910390fd5b60008281526002602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6110ba6110b5612972565b612140565b6110f55760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b6110fe8161299d565b50565b60075490565b6111126110b5612972565b61114d5760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b80611192576040805162461bcd60e51b815260206004820152601060248201526f10985cd948155492481a5b9d985b1a5960821b604482015290519081900360640190fd5b61119e600e838361394f565b505050565b6111b46111ae612972565b826129e5565b6111ef5760405162461bcd60e51b8152600401808060200182810382526031815260200180613d606031913960400191505060405180910390fd5b61119e838383612a89565b6112056110b5612972565b6112405760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b6110fe81612aa8565b6000611254836118cf565b82106112915760405162461bcd60e51b815260040180806020018281038252602b815260200180613a76602b913960400191505060405180910390fd5b6001600160a01b03831660009081526005602052604090208054839081106112b557fe5b906000526020600020015490505b92915050565b60006112c3600c8363ffffffff612af016565b61119e838383604051806020016040528060008152506120e2565b6113026110b5612972565b61133d5760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b8061134781612955565b61138d576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000828152600f602052604090206010816113a785612b57565b60405160200180838054600181600116156101000203166002900480156114055780601f106113e3576101008083540402835291820191611405565b820191906000526020600020905b8154815290600101906020018083116113f1575b505080602d60f81b81525060010182805190602001908083835b6020831061143e5780518252601f19909201916020918201910161141f565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040526040518082805190602001908083835b602083106114a25780518252601f199092019160209182019101611483565b51815160209384036101000a60001901801990921691161790529201948552506040519384900301909220600090555061119e905083612c1b565b6114ed6114e8612972565b612c2d565b565b600e805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156115755780601f1061154a57610100808354040283529160200191611575565b820191906000526020600020905b81548152906001019060200180831161155857829003601f168201915b505050505081565b6000611587611101565b82106115c45760405162461bcd60e51b815260040180806020018281038252602c815260200180613d91602c913960400191505060405180910390fd5b600782815481106115d157fe5b90600052602060002001549050919050565b60006115f56115f0612972565b6112c9565b6116305760405162461bcd60e51b815260040180806020018281038252603a815260200180613ce1603a913960400191505060405180910390fd5b83611679576040805162461bcd60e51b8152602060048201526014602482015273141c9bd91d58dd0818dbd919481a5b9d985b1a5960621b604482015290519081900360640190fd5b816116bf576040805162461bcd60e51b815260206004820152601160248201527012541194c81a185cda081a5b9d985b1a59607a1b604482015290519081900360640190fd5b6040805160606020601f88018190040282018101835291810186815290918291908890889081908501838280828437600092019190915250505090825250604080516020601f8701819004810282018101909252858152918101919086908690819084018382808284376000920182905250939094525050898152600f602090815260409091208351805191935061175b9284929101906139cd565b50602082810151805161177492600185019201906139cd565b509050506117828688612c75565b86601086866117908b612b57565b60405160200180848480828437602d60f81b920191825250825160019091019060208401908083835b602083106117d85780518252601f1990920191602091820191016117b9565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b6020831061183d5780518252601f19909201916020918201910161181e565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209290925550600198975050505050505050565b6000818152600160205260408120546001600160a01b0316806112c35760405162461bcd60e51b8152600401808060200182810382526029815260200180613bb36029913960400191505060405180910390fd5b60006001600160a01b0382166119165760405162461bcd60e51b815260040180806020018281038252602a815260200180613b89602a913960400191505060405180910390fd5b6001600160a01b03821660009081526003602052604090206112c390612c96565b6119426110b5612972565b61197d5760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b6110fe81612c9a565b600d546001600160a01b031690565b600061199f611986565b6001600160a01b0316336001600160a01b0316146119ee5760405162461bcd60e51b8152600401808060200182810382526024815260200180613d3c6024913960400191505060405180910390fd5b611a2d83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612ce292505050565b9392505050565b60006060808d8d8d8d8d8d8d8d611a49611986565b30604051602001808b6001600160a01b03166001600160a01b031660601b81526014018a6001600160a01b03166001600160a01b031660601b81526014018989808284379190910197885250506020808701959095526040808701949094526060808701939093526bffffffffffffffffffffffff1991831b8216608087015290911b1660948401528051608881850301815260c8601f8e018490049093028401830190915260a883018c815290975060009650611b3f95506115f0945092508b918b918291018382808284376000920191909152505086516020880120611b3392509050612ce8565b9063ffffffff612d3916565b90508015611b5a57611b4f612e27565b935093505050611b64565b611b4f6000612e4b565b9b509b9950505050505050505050565b6060611b7f82612e63565b805480602002602001604051908101604052809291908181526020018280548015611bc957602002820191906000526020600020905b815481526020019060010190808311611bb5575b50505050509050919050565b606081611be181612955565b611c27576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000838152600f6020526040902080611c3f85612b57565b6040516020018083805460018160011615610100020316600290048015611c9d5780601f10611c7b576101008083540402835291820191611c9d565b820191906000526020600020905b815481529060010190602001808311611c89575b505080602d60f81b81525060010182805190602001908083835b60208310611cd65780518252601f199092019160209182019101611cb7565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b606081611d2081612955565b611d66576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000838152600f602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909291839190830182828015611dfd5780601f10611dd257610100808354040283529160200191611dfd565b820191906000526020600020905b815481529060010190602001808311611de057829003601f168201915b505050505092505050919050565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f155780601f10610eea57610100808354040283529160200191610f15565b611e776115f0612972565b611eb25760405162461bcd60e51b815260040180806020018281038252603a815260200180613ce1603a913960400191505060405180910390fd5b82611ebc81612955565b611f02576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b81611f4c576040805162461bcd60e51b815260206004820152601560248201527413995dc812541194c81a185cda081a5b9d985b1a59605a1b604482015290519081900360640190fd5b6000848152600f60205260409020611f6890600101848461394f565b5050505050565b611f7a6110b5612972565b611fb55760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b6110fe81612e7d565b611fc6612972565b6001600160a01b0316826001600160a01b0316141561202c576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060046000612039612972565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561207d612972565b60408051841515815290516001600160a01b0392909216917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6040805180820190915260058152640312e302e360dc1b602082015290565b6120f36120ed612972565b836129e5565b61212e5760405162461bcd60e51b8152600401808060200182810382526031815260200180613d606031913960400191505060405180910390fd5b61213a84848484612f7d565b50505050565b60006112c3600b8363ffffffff612af016565b60608161215f81612955565b6121a5576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b600e600f6000858152602001908152602001600020600101604051602001808380546001816001161561010002031660029004801561221b5780601f106121f957610100808354040283529182019161221b565b820191906000526020600020905b815481529060010190602001808311612207575b5050828054600181600116156101000203166002900480156122745780601f10612252576101008083540402835291820191612274565b820191906000526020600020905b815481529060010190602001808311612260575b505060408051601f198184030181529190529695505050505050565b60608060608361229f81612955565b6122e5576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000858152600f6020526040902080806122fe88612b57565b604051602001808380546001816001161561010002031660029004801561235c5780601f1061233a57610100808354040283529182019161235c565b820191906000526020600020905b815481529060010190602001808311612348575b505080602d60f81b81525060010182805190602001908083835b602083106123955780518252601f199092019160209182019101612376565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052600e83600101604051602001808380546001816001161561010002031660029004801561242e5780601f1061240c57610100808354040283529182019161242e565b820191906000526020600020905b81548152906001019060200180831161241a575b5050828054600181600116156101000203166002900480156124875780601f10612465576101008083540402835291820191612487565b820191906000526020600020905b815481529060010190602001808311612473575b505060408051601f1981840301815287546020601f6002600019610100600186161502019093169290920491820181900481028501810190935280845290955091935086925083018282801561251e5780601f106124f35761010080835404028352916020019161251e565b820191906000526020600020905b81548152906001019060200180831161250157829003601f168201915b5050505050925094509450945050509193909250565b6114ed61253f612972565b612aa8565b6060600060108484604051808383808284378083019250505092505050908152602001604051809103902054905061257b81612955565b6125cc576040805162461bcd60e51b815260206004820152601e60248201527f546f6b656e206e6f7420666f756e6420666f722070726f647563742049440000604482015290519081900360640190fd5b600e600f600083815260200190815260200160002060010160405160200180838054600181600116156101000203166002900480156126425780601f10612620576101008083540402835291820191612642565b820191906000526020600020905b81548152906001019060200180831161262e575b50508280546001816001161561010002031660029004801561269b5780601f1061267957610100808354040283529182019161269b565b820191906000526020600020905b815481529060010190602001808311612687575b505060408051601f19818403018152919052979650505050505050565b6126c0611986565b6001600160a01b0316336001600160a01b03161461270f5760405162461bcd60e51b8152600401808060200182810382526024815260200180613d3c6024913960400191505060405180910390fd5b611f6885858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905061213a565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b6000601083836040518083838082843791909101948552505060405192839003602001909220549250505092915050565b6127bd6115f0612972565b6127f85760405162461bcd60e51b815260040180806020018281038252603a815260200180613ce1603a913960400191505060405180910390fd5b8261280281612955565b612848576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000848152600f6020526040902061286181858561394f565b50846010858561287089612b57565b60405160200180848480828437602d60f81b920191825250825160019091019060208401908083835b602083106128b85780518252601f199092019160209182019101612899565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b6020831061291d5780518252601f1990920191602091820191016128fe565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209290925550505050505050565b6000908152600160205260409020546001600160a01b0316151590565b600d546000906001600160a01b0316331461298e575033610f1d565b612996612fcf565b9050610f1d565b6129ae600c8263ffffffff61301c16565b6040516001600160a01b038216907fee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f90600090a250565b60006129f082612955565b612a2b5760405162461bcd60e51b815260040180806020018281038252602c815260200180613af7602c913960400191505060405180910390fd5b6000612a368361187b565b9050806001600160a01b0316846001600160a01b03161480612a715750836001600160a01b0316612a6684610f20565b6001600160a01b0316145b80612a815750612a818185612753565b949350505050565b612a9483838361309d565b612a9e83826131e1565b61119e82826132cf565b612ab9600c8263ffffffff61330d16565b6040516001600160a01b038216907f270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b690600090a250565b60006001600160a01b038216612b375760405162461bcd60e51b8152600401808060200182810382526022815260200180613c296022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b606081612b7c57506040805180820190915260018152600360fc1b6020820152610e84565b8160005b8115612b9457600101600a82049150612b80565b6060816040519080825280601f01601f191660200182016040528015612bc1576020820181803883390190505b50859350905060001982015b8315612c1257600a840660300160f81b82828060019003935081518110612bf057fe5b60200101906001600160f81b031916908160001a905350600a84049350612bcd565b50949350505050565b6110fe612c278261187b565b82613374565b612c3e600b8263ffffffff61330d16565b6040516001600160a01b038216907f0a8eb35e5ca14b3d6f28e4abf2f128dbab231a58b56e89beb5d636115001e16590600090a250565b612c7f82826133a0565b612c8982826132cf565b612c92816134d1565b5050565b5490565b612cab600b8263ffffffff61301c16565b6040516001600160a01b038216907f22380c05984257a1cb900161c713dd71d39e74820f1aea43bd3f1bdd2096129990600090a250565b50600090565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b60008151604114612d4c575060006112c3565b60208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115612d9257600093505050506112c3565b8060ff16601b14158015612daa57508060ff16601c14155b15612dbb57600093505050506112c3565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015612e12573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006060612e4360405180602001604052806000815250613515565b915091509091565b604080516020810190915260008152600b9190910191565b6001600160a01b0316600090815260056020526040902090565b600d546001600160a01b03908116908216612ec95760405162461bcd60e51b815260040180806020018281038252602e815260200180613b5b602e913960400191505060405180910390fd5b806001600160a01b0316826001600160a01b03161415612f1a5760405162461bcd60e51b815260040180806020018281038252602d815260200180613cb4602d913960400191505060405180910390fd5b816001600160a01b0316816001600160a01b03167fb9f84b8e65164b14439ae3620df0a4d8786d896996c0282b683f9d8c08f046e860405160405180910390a350600d80546001600160a01b0319166001600160a01b0392909216919091179055565b612f88848484612a89565b612f948484848461351a565b61213a5760405162461bcd60e51b8152600401808060200182810382526032815260200180613aa16032913960400191505060405180910390fd5b600060606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031692915050565b6130268282612af0565b15613078576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b826001600160a01b03166130b08261187b565b6001600160a01b0316146130f55760405162461bcd60e51b8152600401808060200182810382526029815260200180613c4b6029913960400191505060405180910390fd5b6001600160a01b03821661313a5760405162461bcd60e51b8152600401808060200182810382526024815260200180613ad36024913960400191505060405180910390fd5b61314381613671565b6001600160a01b0383166000908152600360205260409020613164906136ac565b6001600160a01b0382166000908152600360205260409020613185906136c3565b60008181526001602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821660009081526005602052604081205461320b90600163ffffffff6136cc16565b6000838152600660205260409020549091508082146132a6576001600160a01b038416600090815260056020526040812080548490811061324857fe5b906000526020600020015490508060056000876001600160a01b03166001600160a01b03168152602001908152602001600020838154811061328657fe5b600091825260208083209091019290925591825260069052604090208190555b6001600160a01b0384166000908152600560205260409020805490611f68906000198301613a3b565b6001600160a01b0390911660009081526005602081815260408084208054868652600684529185208290559282526001810183559183529091200155565b6133178282612af0565b6133525760405162461bcd60e51b8152600401808060200182810382526021815260200180613bdc6021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b61337e828261370e565b61338882826131e1565b600081815260066020526040812055612c92816137e5565b6001600160a01b0382166133fb576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61340481612955565b15613456576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600081815260016020908152604080832080546001600160a01b0319166001600160a01b038716908117909155835260039091529020613495906136c3565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880155565b600091565b600061352e846001600160a01b0316613881565b61353a57506001612a81565b6000846001600160a01b031663150b7a02613553612972565b8887876040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156135d85781810151838201526020016135c0565b50505050905090810190601f1680156136055780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561362757600080fd5b505af115801561363b573d6000803e3d6000fd5b505050506040513d602081101561365157600080fd5b50516001600160e01b031916630a85bd0160e11b14915050949350505050565b6000818152600260205260409020546001600160a01b0316156110fe57600090815260026020526040902080546001600160a01b0319169055565b80546136bf90600163ffffffff6136cc16565b9055565b80546001019055565b6000611a2d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506138b8565b816001600160a01b03166137218261187b565b6001600160a01b0316146137665760405162461bcd60e51b8152600401808060200182810382526025815260200180613dbd6025913960400191505060405180910390fd5b61376f81613671565b6001600160a01b0382166000908152600360205260409020613790906136ac565b60008181526001602052604080822080546001600160a01b0319169055518291906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6007546000906137fc90600163ffffffff6136cc16565b6000838152600860205260408120546007805493945090928490811061381e57fe5b90600052602060002001549050806007838154811061383957fe5b6000918252602080832090910192909255828152600890915260409020829055600780549061386c906000198301613a3b565b50505060009182525060086020526040812055565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708115801590612a815750141592915050565b600081848411156139475760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561390c5781810151838201526020016138f4565b50505050905090810190601f1680156139395780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106139905782800160ff198235161785556139bd565b828001600101855582156139bd579182015b828111156139bd5782358255916020019190600101906139a2565b506139c9929150613a5b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613a0e57805160ff19168380011785556139bd565b828001600101855582156139bd579182015b828111156139bd578251825591602001919060010190613a20565b81548183558181111561119e5760008381526020902061119e9181019083015b610f1d91905b808211156139c95760008155600101613a6156fe455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c47534e526563697069656e743a206e65772052656c617948756220697320746865207a65726f20616464726573734552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c654552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e526f6c65733a206163636f756e7420697320746865207a65726f20616464726573734552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e57686974656c69737441646d696e526f6c653a2063616c6c657220646f6573206e6f742068617665207468652057686974656c69737441646d696e20726f6c6547534e526563697069656e743a206e65772052656c6179487562206973207468652063757272656e74206f6e6557686974656c6973746564526f6c653a2063616c6c657220646f6573206e6f742068617665207468652057686974656c697374656420726f6c654552433732313a20617070726f76616c20746f2063757272656e74206f776e657247534e526563697069656e743a2063616c6c6572206973206e6f742052656c61794875624552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e64734552433732313a206275726e206f6620746f6b656e2074686174206973206e6f74206f776ea265627a7a72315820b93b24d099220b03f870c50afc3fe9a8da20b24718ccdab067816283bd1e177664736f6c634300050e0032526f6c65733a206163636f756e7420697320746865207a65726f206164647265737357686974656c69737441646d696e526f6c653a2063616c6c657220646f6573206e6f742068617665207468652057686974656c69737441646d696e20726f6c650000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c68747470733a2f2f697066732e696e667572612e696f2f697066732f00000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102535760003560e01c806374e861d611610146578063ad61ccd5116100c3578063d6cd947311610087578063d6cd947314610c63578063d940a7ea14610c6b578063e06e0e2214610cd9578063e985e9c514610d55578063ead25d1514610d83578063f1e95a3514610df157610253565b8063ad61ccd5146109f3578063b88d4fde146109fb578063bb5f747b14610abf578063c87b56dd14610ae5578063d05dcc6a14610b0257610253565b80638ed2be821161010a5780638ed2be821461090557806395d89b41146109225780639611c0511461092a5780639e30a5901461099f578063a22cb465146109c557610253565b806374e861d61461068f57806380274db71461069757806383947ea0146107055780638462151c146108725780638b174b1b146108e857610253565b80633af32abf116101d45780634f6ccce7116101985780634f6ccce7146105365780636289fa61146105535780636352211e1461062657806370a08231146106435780637362d9c81461066957610253565b80633af32abf146104ad57806342842e0e146104d357806342966c68146105095780634c5a628c146105265780634e99b8001461052e57610253565b806318160ddd1161021b57806318160ddd1461039d5780632295ee5b146103b757806323b872dd14610425578063291d95491461045b5780632f745c591461048157610253565b806301ffc9a71461025857806306fdde0314610293578063081812fc14610310578063095ea7b31461034957806310154bad14610377575b600080fd5b61027f6004803603602081101561026e57600080fd5b50356001600160e01b031916610e66565b604080519115158252519081900360200190f35b61029b610e89565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102d55781810151838201526020016102bd565b50505050905090810190601f1680156103025780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61032d6004803603602081101561032657600080fd5b5035610f20565b604080516001600160a01b039092168252519081900360200190f35b6103756004803603604081101561035f57600080fd5b506001600160a01b038135169060200135610f82565b005b6103756004803603602081101561038d57600080fd5b50356001600160a01b03166110aa565b6103a5611101565b60408051918252519081900360200190f35b610375600480360360208110156103cd57600080fd5b810190602081018135600160201b8111156103e757600080fd5b8201836020820111156103f957600080fd5b803590602001918460018302840111600160201b8311171561041a57600080fd5b509092509050611107565b6103756004803603606081101561043b57600080fd5b506001600160a01b038135811691602081013590911690604001356111a3565b6103756004803603602081101561047157600080fd5b50356001600160a01b03166111fa565b6103a56004803603604081101561049757600080fd5b506001600160a01b038135169060200135611249565b61027f600480360360208110156104c357600080fd5b50356001600160a01b03166112c9565b610375600480360360608110156104e957600080fd5b506001600160a01b038135811691602081013590911690604001356112dc565b6103756004803603602081101561051f57600080fd5b50356112f7565b6103756114dd565b61029b6114ef565b6103a56004803603602081101561054c57600080fd5b503561157d565b61027f6004803603608081101561056957600080fd5b8135916001600160a01b0360208201351691810190606081016040820135600160201b81111561059857600080fd5b8201836020820111156105aa57600080fd5b803590602001918460018302840111600160201b831117156105cb57600080fd5b919390929091602081019035600160201b8111156105e857600080fd5b8201836020820111156105fa57600080fd5b803590602001918460018302840111600160201b8311171561061b57600080fd5b5090925090506115e3565b61032d6004803603602081101561063c57600080fd5b503561187b565b6103a56004803603602081101561065957600080fd5b50356001600160a01b03166118cf565b6103756004803603602081101561067f57600080fd5b50356001600160a01b0316611937565b61032d611986565b6103a5600480360360208110156106ad57600080fd5b810190602081018135600160201b8111156106c757600080fd5b8201836020820111156106d957600080fd5b803590602001918460018302840111600160201b831117156106fa57600080fd5b509092509050611995565b6107f3600480360361012081101561071c57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561074f57600080fd5b82018360208201111561076157600080fd5b803590602001918460018302840111600160201b8311171561078257600080fd5b9193909282359260208101359260408201359260608301359260a081019060800135600160201b8111156107b557600080fd5b8201836020820111156107c757600080fd5b803590602001918460018302840111600160201b831117156107e857600080fd5b919350915035611a34565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561083657818101518382015260200161081e565b50505050905090810190601f1680156108635780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b6108986004803603602081101561088857600080fd5b50356001600160a01b0316611b74565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156108d45781810151838201526020016108bc565b505050509050019250505060405180910390f35b61029b600480360360208110156108fe57600080fd5b5035611bd5565b61029b6004803603602081101561091b57600080fd5b5035611d14565b61029b611e0b565b6103756004803603604081101561094057600080fd5b81359190810190604081016020820135600160201b81111561096157600080fd5b82018360208201111561097357600080fd5b803590602001918460018302840111600160201b8311171561099457600080fd5b509092509050611e6c565b610375600480360360208110156109b557600080fd5b50356001600160a01b0316611f6f565b610375600480360360408110156109db57600080fd5b506001600160a01b0381351690602001351515611fbe565b61029b6120c3565b61037560048036036080811015610a1157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a4b57600080fd5b820183602082011115610a5d57600080fd5b803590602001918460018302840111600160201b83111715610a7e57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506120e2945050505050565b61027f60048036036020811015610ad557600080fd5b50356001600160a01b0316612140565b61029b60048036036020811015610afb57600080fd5b5035612153565b610b1f60048036036020811015610b1857600080fd5b5035612290565b60405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015610b64578181015183820152602001610b4c565b50505050905090810190601f168015610b915780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015610bc4578181015183820152602001610bac565b50505050905090810190601f168015610bf15780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b83811015610c24578181015183820152602001610c0c565b50505050905090810190601f168015610c515780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b610375612534565b61029b60048036036020811015610c8157600080fd5b810190602081018135600160201b811115610c9b57600080fd5b820183602082011115610cad57600080fd5b803590602001918460018302840111600160201b83111715610cce57600080fd5b509092509050612544565b61037560048036036080811015610cef57600080fd5b810190602081018135600160201b811115610d0957600080fd5b820183602082011115610d1b57600080fd5b803590602001918460018302840111600160201b83111715610d3c57600080fd5b91935091508035151590602081013590604001356126b8565b61027f60048036036040811015610d6b57600080fd5b506001600160a01b0381358116916020013516612753565b6103a560048036036020811015610d9957600080fd5b810190602081018135600160201b811115610db357600080fd5b820183602082011115610dc557600080fd5b803590602001918460018302840111600160201b83111715610de657600080fd5b509092509050612781565b61037560048036036040811015610e0757600080fd5b81359190810190604081016020820135600160201b811115610e2857600080fd5b820183602082011115610e3a57600080fd5b803590602001918460018302840111600160201b83111715610e5b57600080fd5b5090925090506127b2565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f155780601f10610eea57610100808354040283529160200191610f15565b820191906000526020600020905b815481529060010190602001808311610ef857829003601f168201915b505050505090505b90565b6000610f2b82612955565b610f665760405162461bcd60e51b815260040180806020018281038252602c815260200180613bfd602c913960400191505060405180910390fd5b506000908152600260205260409020546001600160a01b031690565b6000610f8d8261187b565b9050806001600160a01b0316836001600160a01b03161415610fe05760405162461bcd60e51b8152600401808060200182810382526021815260200180613d1b6021913960400191505060405180910390fd5b806001600160a01b0316610ff2612972565b6001600160a01b0316148061101357506110138161100e612972565b612753565b61104e5760405162461bcd60e51b8152600401808060200182810382526038815260200180613b236038913960400191505060405180910390fd5b60008281526002602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6110ba6110b5612972565b612140565b6110f55760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b6110fe8161299d565b50565b60075490565b6111126110b5612972565b61114d5760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b80611192576040805162461bcd60e51b815260206004820152601060248201526f10985cd948155492481a5b9d985b1a5960821b604482015290519081900360640190fd5b61119e600e838361394f565b505050565b6111b46111ae612972565b826129e5565b6111ef5760405162461bcd60e51b8152600401808060200182810382526031815260200180613d606031913960400191505060405180910390fd5b61119e838383612a89565b6112056110b5612972565b6112405760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b6110fe81612aa8565b6000611254836118cf565b82106112915760405162461bcd60e51b815260040180806020018281038252602b815260200180613a76602b913960400191505060405180910390fd5b6001600160a01b03831660009081526005602052604090208054839081106112b557fe5b906000526020600020015490505b92915050565b60006112c3600c8363ffffffff612af016565b61119e838383604051806020016040528060008152506120e2565b6113026110b5612972565b61133d5760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b8061134781612955565b61138d576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000828152600f602052604090206010816113a785612b57565b60405160200180838054600181600116156101000203166002900480156114055780601f106113e3576101008083540402835291820191611405565b820191906000526020600020905b8154815290600101906020018083116113f1575b505080602d60f81b81525060010182805190602001908083835b6020831061143e5780518252601f19909201916020918201910161141f565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040526040518082805190602001908083835b602083106114a25780518252601f199092019160209182019101611483565b51815160209384036101000a60001901801990921691161790529201948552506040519384900301909220600090555061119e905083612c1b565b6114ed6114e8612972565b612c2d565b565b600e805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156115755780601f1061154a57610100808354040283529160200191611575565b820191906000526020600020905b81548152906001019060200180831161155857829003601f168201915b505050505081565b6000611587611101565b82106115c45760405162461bcd60e51b815260040180806020018281038252602c815260200180613d91602c913960400191505060405180910390fd5b600782815481106115d157fe5b90600052602060002001549050919050565b60006115f56115f0612972565b6112c9565b6116305760405162461bcd60e51b815260040180806020018281038252603a815260200180613ce1603a913960400191505060405180910390fd5b83611679576040805162461bcd60e51b8152602060048201526014602482015273141c9bd91d58dd0818dbd919481a5b9d985b1a5960621b604482015290519081900360640190fd5b816116bf576040805162461bcd60e51b815260206004820152601160248201527012541194c81a185cda081a5b9d985b1a59607a1b604482015290519081900360640190fd5b6040805160606020601f88018190040282018101835291810186815290918291908890889081908501838280828437600092019190915250505090825250604080516020601f8701819004810282018101909252858152918101919086908690819084018382808284376000920182905250939094525050898152600f602090815260409091208351805191935061175b9284929101906139cd565b50602082810151805161177492600185019201906139cd565b509050506117828688612c75565b86601086866117908b612b57565b60405160200180848480828437602d60f81b920191825250825160019091019060208401908083835b602083106117d85780518252601f1990920191602091820191016117b9565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b6020831061183d5780518252601f19909201916020918201910161181e565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209290925550600198975050505050505050565b6000818152600160205260408120546001600160a01b0316806112c35760405162461bcd60e51b8152600401808060200182810382526029815260200180613bb36029913960400191505060405180910390fd5b60006001600160a01b0382166119165760405162461bcd60e51b815260040180806020018281038252602a815260200180613b89602a913960400191505060405180910390fd5b6001600160a01b03821660009081526003602052604090206112c390612c96565b6119426110b5612972565b61197d5760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b6110fe81612c9a565b600d546001600160a01b031690565b600061199f611986565b6001600160a01b0316336001600160a01b0316146119ee5760405162461bcd60e51b8152600401808060200182810382526024815260200180613d3c6024913960400191505060405180910390fd5b611a2d83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612ce292505050565b9392505050565b60006060808d8d8d8d8d8d8d8d611a49611986565b30604051602001808b6001600160a01b03166001600160a01b031660601b81526014018a6001600160a01b03166001600160a01b031660601b81526014018989808284379190910197885250506020808701959095526040808701949094526060808701939093526bffffffffffffffffffffffff1991831b8216608087015290911b1660948401528051608881850301815260c8601f8e018490049093028401830190915260a883018c815290975060009650611b3f95506115f0945092508b918b918291018382808284376000920191909152505086516020880120611b3392509050612ce8565b9063ffffffff612d3916565b90508015611b5a57611b4f612e27565b935093505050611b64565b611b4f6000612e4b565b9b509b9950505050505050505050565b6060611b7f82612e63565b805480602002602001604051908101604052809291908181526020018280548015611bc957602002820191906000526020600020905b815481526020019060010190808311611bb5575b50505050509050919050565b606081611be181612955565b611c27576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000838152600f6020526040902080611c3f85612b57565b6040516020018083805460018160011615610100020316600290048015611c9d5780601f10611c7b576101008083540402835291820191611c9d565b820191906000526020600020905b815481529060010190602001808311611c89575b505080602d60f81b81525060010182805190602001908083835b60208310611cd65780518252601f199092019160209182019101611cb7565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b606081611d2081612955565b611d66576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000838152600f602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909291839190830182828015611dfd5780601f10611dd257610100808354040283529160200191611dfd565b820191906000526020600020905b815481529060010190602001808311611de057829003601f168201915b505050505092505050919050565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610f155780601f10610eea57610100808354040283529160200191610f15565b611e776115f0612972565b611eb25760405162461bcd60e51b815260040180806020018281038252603a815260200180613ce1603a913960400191505060405180910390fd5b82611ebc81612955565b611f02576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b81611f4c576040805162461bcd60e51b815260206004820152601560248201527413995dc812541194c81a185cda081a5b9d985b1a59605a1b604482015290519081900360640190fd5b6000848152600f60205260409020611f6890600101848461394f565b5050505050565b611f7a6110b5612972565b611fb55760405162461bcd60e51b8152600401808060200182810382526040815260200180613c746040913960400191505060405180910390fd5b6110fe81612e7d565b611fc6612972565b6001600160a01b0316826001600160a01b0316141561202c576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060046000612039612972565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561207d612972565b60408051841515815290516001600160a01b0392909216917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6040805180820190915260058152640312e302e360dc1b602082015290565b6120f36120ed612972565b836129e5565b61212e5760405162461bcd60e51b8152600401808060200182810382526031815260200180613d606031913960400191505060405180910390fd5b61213a84848484612f7d565b50505050565b60006112c3600b8363ffffffff612af016565b60608161215f81612955565b6121a5576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b600e600f6000858152602001908152602001600020600101604051602001808380546001816001161561010002031660029004801561221b5780601f106121f957610100808354040283529182019161221b565b820191906000526020600020905b815481529060010190602001808311612207575b5050828054600181600116156101000203166002900480156122745780601f10612252576101008083540402835291820191612274565b820191906000526020600020905b815481529060010190602001808311612260575b505060408051601f198184030181529190529695505050505050565b60608060608361229f81612955565b6122e5576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000858152600f6020526040902080806122fe88612b57565b604051602001808380546001816001161561010002031660029004801561235c5780601f1061233a57610100808354040283529182019161235c565b820191906000526020600020905b815481529060010190602001808311612348575b505080602d60f81b81525060010182805190602001908083835b602083106123955780518252601f199092019160209182019101612376565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052600e83600101604051602001808380546001816001161561010002031660029004801561242e5780601f1061240c57610100808354040283529182019161242e565b820191906000526020600020905b81548152906001019060200180831161241a575b5050828054600181600116156101000203166002900480156124875780601f10612465576101008083540402835291820191612487565b820191906000526020600020905b815481529060010190602001808311612473575b505060408051601f1981840301815287546020601f6002600019610100600186161502019093169290920491820181900481028501810190935280845290955091935086925083018282801561251e5780601f106124f35761010080835404028352916020019161251e565b820191906000526020600020905b81548152906001019060200180831161250157829003601f168201915b5050505050925094509450945050509193909250565b6114ed61253f612972565b612aa8565b6060600060108484604051808383808284378083019250505092505050908152602001604051809103902054905061257b81612955565b6125cc576040805162461bcd60e51b815260206004820152601e60248201527f546f6b656e206e6f7420666f756e6420666f722070726f647563742049440000604482015290519081900360640190fd5b600e600f600083815260200190815260200160002060010160405160200180838054600181600116156101000203166002900480156126425780601f10612620576101008083540402835291820191612642565b820191906000526020600020905b81548152906001019060200180831161262e575b50508280546001816001161561010002031660029004801561269b5780601f1061267957610100808354040283529182019161269b565b820191906000526020600020905b815481529060010190602001808311612687575b505060408051601f19818403018152919052979650505050505050565b6126c0611986565b6001600160a01b0316336001600160a01b03161461270f5760405162461bcd60e51b8152600401808060200182810382526024815260200180613d3c6024913960400191505060405180910390fd5b611f6885858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525087925086915085905061213a565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b6000601083836040518083838082843791909101948552505060405192839003602001909220549250505092915050565b6127bd6115f0612972565b6127f85760405162461bcd60e51b815260040180806020018281038252603a815260200180613ce1603a913960400191505060405180910390fd5b8261280281612955565b612848576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881251081b9bdd081d985b1a5960721b604482015290519081900360640190fd5b6000848152600f6020526040902061286181858561394f565b50846010858561287089612b57565b60405160200180848480828437602d60f81b920191825250825160019091019060208401908083835b602083106128b85780518252601f199092019160209182019101612899565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b6020831061291d5780518252601f1990920191602091820191016128fe565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209290925550505050505050565b6000908152600160205260409020546001600160a01b0316151590565b600d546000906001600160a01b0316331461298e575033610f1d565b612996612fcf565b9050610f1d565b6129ae600c8263ffffffff61301c16565b6040516001600160a01b038216907fee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f90600090a250565b60006129f082612955565b612a2b5760405162461bcd60e51b815260040180806020018281038252602c815260200180613af7602c913960400191505060405180910390fd5b6000612a368361187b565b9050806001600160a01b0316846001600160a01b03161480612a715750836001600160a01b0316612a6684610f20565b6001600160a01b0316145b80612a815750612a818185612753565b949350505050565b612a9483838361309d565b612a9e83826131e1565b61119e82826132cf565b612ab9600c8263ffffffff61330d16565b6040516001600160a01b038216907f270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b690600090a250565b60006001600160a01b038216612b375760405162461bcd60e51b8152600401808060200182810382526022815260200180613c296022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b606081612b7c57506040805180820190915260018152600360fc1b6020820152610e84565b8160005b8115612b9457600101600a82049150612b80565b6060816040519080825280601f01601f191660200182016040528015612bc1576020820181803883390190505b50859350905060001982015b8315612c1257600a840660300160f81b82828060019003935081518110612bf057fe5b60200101906001600160f81b031916908160001a905350600a84049350612bcd565b50949350505050565b6110fe612c278261187b565b82613374565b612c3e600b8263ffffffff61330d16565b6040516001600160a01b038216907f0a8eb35e5ca14b3d6f28e4abf2f128dbab231a58b56e89beb5d636115001e16590600090a250565b612c7f82826133a0565b612c8982826132cf565b612c92816134d1565b5050565b5490565b612cab600b8263ffffffff61301c16565b6040516001600160a01b038216907f22380c05984257a1cb900161c713dd71d39e74820f1aea43bd3f1bdd2096129990600090a250565b50600090565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b60008151604114612d4c575060006112c3565b60208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115612d9257600093505050506112c3565b8060ff16601b14158015612daa57508060ff16601c14155b15612dbb57600093505050506112c3565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015612e12573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b60006060612e4360405180602001604052806000815250613515565b915091509091565b604080516020810190915260008152600b9190910191565b6001600160a01b0316600090815260056020526040902090565b600d546001600160a01b03908116908216612ec95760405162461bcd60e51b815260040180806020018281038252602e815260200180613b5b602e913960400191505060405180910390fd5b806001600160a01b0316826001600160a01b03161415612f1a5760405162461bcd60e51b815260040180806020018281038252602d815260200180613cb4602d913960400191505060405180910390fd5b816001600160a01b0316816001600160a01b03167fb9f84b8e65164b14439ae3620df0a4d8786d896996c0282b683f9d8c08f046e860405160405180910390a350600d80546001600160a01b0319166001600160a01b0392909216919091179055565b612f88848484612a89565b612f948484848461351a565b61213a5760405162461bcd60e51b8152600401808060200182810382526032815260200180613aa16032913960400191505060405180910390fd5b600060606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031692915050565b6130268282612af0565b15613078576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b826001600160a01b03166130b08261187b565b6001600160a01b0316146130f55760405162461bcd60e51b8152600401808060200182810382526029815260200180613c4b6029913960400191505060405180910390fd5b6001600160a01b03821661313a5760405162461bcd60e51b8152600401808060200182810382526024815260200180613ad36024913960400191505060405180910390fd5b61314381613671565b6001600160a01b0383166000908152600360205260409020613164906136ac565b6001600160a01b0382166000908152600360205260409020613185906136c3565b60008181526001602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821660009081526005602052604081205461320b90600163ffffffff6136cc16565b6000838152600660205260409020549091508082146132a6576001600160a01b038416600090815260056020526040812080548490811061324857fe5b906000526020600020015490508060056000876001600160a01b03166001600160a01b03168152602001908152602001600020838154811061328657fe5b600091825260208083209091019290925591825260069052604090208190555b6001600160a01b0384166000908152600560205260409020805490611f68906000198301613a3b565b6001600160a01b0390911660009081526005602081815260408084208054868652600684529185208290559282526001810183559183529091200155565b6133178282612af0565b6133525760405162461bcd60e51b8152600401808060200182810382526021815260200180613bdc6021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b61337e828261370e565b61338882826131e1565b600081815260066020526040812055612c92816137e5565b6001600160a01b0382166133fb576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61340481612955565b15613456576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600081815260016020908152604080832080546001600160a01b0319166001600160a01b038716908117909155835260039091529020613495906136c3565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880155565b600091565b600061352e846001600160a01b0316613881565b61353a57506001612a81565b6000846001600160a01b031663150b7a02613553612972565b8887876040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156135d85781810151838201526020016135c0565b50505050905090810190601f1680156136055780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561362757600080fd5b505af115801561363b573d6000803e3d6000fd5b505050506040513d602081101561365157600080fd5b50516001600160e01b031916630a85bd0160e11b14915050949350505050565b6000818152600260205260409020546001600160a01b0316156110fe57600090815260026020526040902080546001600160a01b0319169055565b80546136bf90600163ffffffff6136cc16565b9055565b80546001019055565b6000611a2d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506138b8565b816001600160a01b03166137218261187b565b6001600160a01b0316146137665760405162461bcd60e51b8152600401808060200182810382526025815260200180613dbd6025913960400191505060405180910390fd5b61376f81613671565b6001600160a01b0382166000908152600360205260409020613790906136ac565b60008181526001602052604080822080546001600160a01b0319169055518291906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6007546000906137fc90600163ffffffff6136cc16565b6000838152600860205260408120546007805493945090928490811061381e57fe5b90600052602060002001549050806007838154811061383957fe5b6000918252602080832090910192909255828152600890915260409020829055600780549061386c906000198301613a3b565b50505060009182525060086020526040812055565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708115801590612a815750141592915050565b600081848411156139475760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561390c5781810151838201526020016138f4565b50505050905090810190601f1680156139395780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106139905782800160ff198235161785556139bd565b828001600101855582156139bd579182015b828111156139bd5782358255916020019190600101906139a2565b506139c9929150613a5b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613a0e57805160ff19168380011785556139bd565b828001600101855582156139bd579182015b828111156139bd578251825591602001919060010190613a20565b81548183558181111561119e5760008381526020902061119e9181019083015b610f1d91905b808211156139c95760008155600101613a6156fe455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c47534e526563697069656e743a206e65772052656c617948756220697320746865207a65726f20616464726573734552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c654552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e526f6c65733a206163636f756e7420697320746865207a65726f20616464726573734552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e57686974656c69737441646d696e526f6c653a2063616c6c657220646f6573206e6f742068617665207468652057686974656c69737441646d696e20726f6c6547534e526563697069656e743a206e65772052656c6179487562206973207468652063757272656e74206f6e6557686974656c6973746564526f6c653a2063616c6c657220646f6573206e6f742068617665207468652057686974656c697374656420726f6c654552433732313a20617070726f76616c20746f2063757272656e74206f776e657247534e526563697069656e743a2063616c6c6572206973206e6f742052656c61794875624552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e64734552433732313a206275726e206f6620746f6b656e2074686174206973206e6f74206f776ea265627a7a72315820b93b24d099220b03f870c50afc3fe9a8da20b24718ccdab067816283bd1e177664736f6c634300050e0032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001c68747470733a2f2f697066732e696e667572612e696f2f697066732f00000000
-----Decoded View---------------
Arg [0] : _tokenBaseURI (string): https://ipfs.infura.io/ipfs/
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 000000000000000000000000000000000000000000000000000000000000001c
Arg [2] : 68747470733a2f2f697066732e696e667572612e696f2f697066732f00000000
Deployed Bytecode Sourcemap
81867:5219:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;81867:5219:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21483:135;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21483:135:0;-1:-1:-1;;;;;;21483:135:0;;:::i;:::-;;;;;;;;;;;;;;;;;;48377:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;48377:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26445:204;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26445:204:0;;:::i;:::-;;;;-1:-1:-1;;;;;26445:204:0;;;;;;;;;;;;;;25727:425;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;25727:425:0;;;;;;;;:::i;:::-;;10151:110;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10151:110:0;-1:-1:-1;;;;;10151:110:0;;:::i;40101:96::-;;;:::i;:::-;;;;;;;;;;;;;;;;86354:210;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;86354:210:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;86354:210:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86354:210:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;86354:210:0;;-1:-1:-1;86354:210:0;-1:-1:-1;86354:210:0;:::i;28128:292::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;28128:292:0;;;;;;;;;;;;;;;;;:::i;10269:116::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10269:116:0;-1:-1:-1;;;;;10269:116:0;;:::i;39710:232::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;39710:232:0;;;;;;;;:::i;10024:119::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10024:119:0;-1:-1:-1;;;;;10024:119:0;;:::i;29082:134::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;29082:134:0;;;;;;;;;;;;;;;;;:::i;86741:340::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;86741:340:0;;:::i;8771:95::-;;;:::i;82010:31::-;;;:::i;40543:199::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40543:199:0;;:::i;83024:784::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;83024:784:0;;;-1:-1:-1;;;;;83024:784:0;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;83024:784:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;83024:784:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;83024:784:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;83024:784:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;83024:784:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;83024:784:0;;-1:-1:-1;83024:784:0;-1:-1:-1;83024:784:0;:::i;25068:228::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25068:228:0;;:::i;24631:211::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24631:211:0;-1:-1:-1;;;;;24631:211:0;;:::i;8647:116::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8647:116:0;-1:-1:-1;;;;;8647:116:0;;:::i;67421:87::-;;;:::i;71084:211::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;71084:211:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;71084:211:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;71084:211:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;71084:211:0;;-1:-1:-1;71084:211:0;-1:-1:-1;71084:211:0;:::i;80266:1093::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;80266:1093:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;80266:1093:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;80266:1093:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;80266:1093:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;80266:1093:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;80266:1093:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;80266:1093:0;;-1:-1:-1;80266:1093:0;-1:-1:-1;80266:1093:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;80266:1093:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85564:136;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;85564:136:0;-1:-1:-1;;;;;85564:136:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;85564:136:0;;;;;;;;;;;;;;;;;84891:280;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84891:280:0;;:::i;84661:222::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84661:222:0;;:::i;48577:89::-;;;:::i;86074:272::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;86074:272:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;86074:272:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;86074:272:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;86074:272:0;;-1:-1:-1;86074:272:0;-1:-1:-1;86074:272:0;:::i;81654:122::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;81654:122:0;-1:-1:-1;;;;;81654:122:0;;:::i;26950:254::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;26950:254:0;;;;;;;;;;:::i;68679:230::-;;;:::i;29953:272::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;29953:272:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;29953:272:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;29953:272:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;29953:272:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;29953:272:0;;-1:-1:-1;29953:272:0;;-1:-1:-1;;;;;29953:272:0:i;8514:125::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8514:125:0;-1:-1:-1;;;;;8514:125:0;;:::i;85351:205::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;85351:205:0;;:::i;84171:482::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84171:482:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;84171:482:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84171:482:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;84171:482:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84171:482:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;84171:482:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10393:89;;;:::i;83816:347::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;83816:347:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;83816:347:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;83816:347:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;83816:347:0;;-1:-1:-1;83816:347:0;-1:-1:-1;83816:347:0;:::i;71944:277::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;71944:277:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;71944:277:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;71944:277:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;71944:277:0;;-1:-1:-1;71944:277:0;-1:-1:-1;71944:277:0;;;;;;;;;;;;;;:::i;27534:147::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;27534:147:0;;;;;;;;;;:::i;85179:164::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;85179:164:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;85179:164:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;85179:164:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;85179:164:0;;-1:-1:-1;85179:164:0;-1:-1:-1;85179:164:0;:::i;85708:358::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;85708:358:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;85708:358:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;85708:358:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;85708:358:0;;-1:-1:-1;85708:358:0;-1:-1:-1;85708:358:0;:::i;21483:135::-;-1:-1:-1;;;;;;21577:33:0;;21553:4;21577:33;;;;;;;;;;;;;21483:135;;;;:::o;48377:85::-;48449:5;48442:12;;;;;;;;-1:-1:-1;;48442:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48416:13;;48442:12;;48449:5;;48442:12;;48449:5;48442:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48377:85;;:::o;26445:204::-;26504:7;26532:16;26540:7;26532;:16::i;:::-;26524:73;;;;-1:-1:-1;;;26524:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26617:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;26617:24:0;;26445:204::o;25727:425::-;25791:13;25807:16;25815:7;25807;:16::i;:::-;25791:32;;25848:5;-1:-1:-1;;;;;25842:11:0;:2;-1:-1:-1;;;;;25842:11:0;;;25834:57;;;;-1:-1:-1;;;25834:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25928:5;-1:-1:-1;;;;;25912:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;25912:21:0;;:62;;;;25937:37;25954:5;25961:12;:10;:12::i;:::-;25937:16;:37::i;:::-;25904:154;;;;-1:-1:-1;;;25904:154:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26071:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;26071:29:0;-1:-1:-1;;;;;26071:29:0;;;;;;;;;26116:28;;26071:24;;26116:28;;;;;;;25727:425;;;:::o;10151:110::-;8387:30;8404:12;:10;:12::i;:::-;8387:16;:30::i;:::-;8379:107;;;;-1:-1:-1;;;8379:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10229:24;10245:7;10229:15;:24::i;:::-;10151:110;:::o;40101:96::-;40172:10;:17;40101:96;:::o;86354:210::-;8387:30;8404:12;:10;:12::i;8387:30::-;8379:107;;;;-1:-1:-1;;;8379:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86468:30;86460:59;;;;;-1:-1:-1;;;86460:59:0;;;;;;;;;;;;-1:-1:-1;;;86460:59:0;;;;;;;;;;;;;;;86530:26;:12;86545:11;;86530:26;:::i;:::-;;86354:210;;:::o;28128:292::-;28272:41;28291:12;:10;:12::i;:::-;28305:7;28272:18;:41::i;:::-;28264:103;;;;-1:-1:-1;;;28264:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28380:32;28394:4;28400:2;28404:7;28380:13;:32::i;10269:116::-;8387:30;8404:12;:10;:12::i;8387:30::-;8379:107;;;;-1:-1:-1;;;8379:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10350:27;10369:7;10350:18;:27::i;39710:232::-;39790:7;39826:16;39836:5;39826:9;:16::i;:::-;39818:5;:24;39810:80;;;;-1:-1:-1;;;39810:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39908:19:0;;;;;;:12;:19;;;;;:26;;39928:5;;39908:26;;;;;;;;;;;;;;39901:33;;39710:232;;;;;:::o;10024:119::-;10085:4;10109:26;:13;10127:7;10109:26;:17;:26;:::i;29082:134::-;29169:39;29186:4;29192:2;29196:7;29169:39;;;;;;;;;;;;:16;:39::i;86741:340::-;8387:30;8404:12;:10;:12::i;8387:30::-;8379:107;;;;-1:-1:-1;;;8379:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86829:8;82384:17;82392:8;82384:7;:17::i;:::-;82376:48;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;;;;86890:19;86912:16;;;:6;:16;;;;;86946:18;86912:16;87013:29;86919:8;87013:19;:29::i;:::-;86972:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;86972:71:0;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;86972:71:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;86972:71:0;;;86946:99;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;86946:99:0;;;;;-1:-1:-1;86946:99:0;;;;;;;;;;-1:-1:-1;86939:106:0;;-1:-1:-1;87058:15:0;;-1:-1:-1;87064:8:0;87058:5;:15::i;8771:95::-;8823:35;8845:12;:10;:12::i;:::-;8823:21;:35::i;:::-;8771:95::o;82010:31::-;;;;;;;;;;;;;;;-1:-1:-1;;82010:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;40543:199::-;40601:7;40637:13;:11;:13::i;:::-;40629:5;:21;40621:78;;;;-1:-1:-1;;;40621:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40717:10;40728:5;40717:17;;;;;;;;;;;;;;;;40710:24;;40543:199;;;:::o;83024:784::-;83215:12;9906:27;9920:12;:10;:12::i;:::-;9906:13;:27::i;:::-;9898:98;;;;-1:-1:-1;;;9898:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83248:30;83240:63;;;;;-1:-1:-1;;;83240:63:0;;;;;;;;;;;;-1:-1:-1;;;83240:63:0;;;;;;;;;;;;;;;83322:27;83314:57;;;;;-1:-1:-1;;;83314:57:0;;;;;;;;;;;;-1:-1:-1;;;83314:57:0;;;;;;;;;;;;;;;83437:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83472:12;;;;;;83437:98;;83472:12;;;;83437:98;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;;83437:98:0;;;-1:-1:-1;83437:98:0;;;;137:4:-1;83437:98:0;;;;;;;;;;;;;;;;;;;;;;83510:9;;;;;;83437:98;;83510:9;;;;83437:98;1:33:-1;99:1;81:16;;74:27;;;-1:-1;83437:98:0;;;;-1:-1:-1;;83418:16:0;;;:6;:16;;;;;;;;:117;;;;:16;;-1:-1:-1;83418:117:0;;:16;;:117;;;;:::i;:::-;-1:-1:-1;83418:117:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;83571:27;83577:10;83589:8;83571:5;:27::i;:::-;83768:8;83671:18;83714:12;;83733:29;83753:8;83733:19;:29::i;:::-;83697:66;;;;;;;30:3:-1;22:6;14;1:33;-1:-1;;;45:16;;83697:66:0;;;-1:-1:-1;83697:66:0;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;83697:66:0;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;83697:66:0;;;83671:94;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;83671:94:0;;;;;-1:-1:-1;83671:94:0;;;;;;;;;;:105;;;;-1:-1:-1;274:1;;83024:784:0;-1:-1:-1;;;;;;;;83024:784:0:o;25068:228::-;25123:7;25159:20;;;:11;:20;;;;;;-1:-1:-1;;;;;25159:20:0;25198:19;25190:73;;;;-1:-1:-1;;;25190:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24631:211;24686:7;-1:-1:-1;;;;;24714:19:0;;24706:74;;;;-1:-1:-1;;;24706:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;24800:24:0;;;;;;:17;:24;;;;;:34;;:32;:34::i;8647:116::-;8387:30;8404:12;:10;:12::i;8387:30::-;8379:107;;;;-1:-1:-1;;;8379:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8728:27;8747:7;8728:18;:27::i;67421:87::-;67491:9;;-1:-1:-1;;;;;67491:9:0;67421:87;:::o;71084:211::-;71150:7;71192:12;:10;:12::i;:::-;-1:-1:-1;;;;;71178:26:0;:10;-1:-1:-1;;;;;71178:26:0;;71170:75;;;;-1:-1:-1;;;71170:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71263:24;71279:7;;71263:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;71263:15:0;;-1:-1:-1;;;71263:24:0:i;:::-;71256:31;71084:211;-1:-1:-1;;;71084:211:0:o;80266:1093::-;80593:7;80602:12;80632:17;80683:5;80703:4;80722:15;;80752:14;80781:8;80804;80827:5;80879:12;:10;:12::i;:::-;80956:4;80652:363;;;;;;-1:-1:-1;;;;;80652:363:0;-1:-1:-1;;;;;80652:363:0;;;;;;;;-1:-1:-1;;;;;80652:363:0;-1:-1:-1;;;;;80652:363:0;;;;;;;;;30:3:-1;22:6;14;1:33;45:16;;;;80652:363:0;;;-1:-1:-1;;80652:363:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;80652:363:0;;;;;;;;;;;;;;;;;;;22:32:-1;26:21;;;22:32;6:49;;81075:62:0;;;;;;;;;;;;;;;;;80652:363;;;81075:62;;;80652:363;;-1:-1:-1;;;;81061:77:0;;-1:-1:-1;81075:62:0;;-1:-1:-1;80652:363:0;-1:-1:-1;81124:12:0;;;;;;81075:62;81124:12;;;;81075:62;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;81075:15:0;;;;;;:40;;-1:-1:-1;81075:15:0;-1:-1:-1;81075:38:0;:40::i;:::-;:48;:62;:48;:62;:::i;81061:77::-;81026:112;;81153:27;81149:203;;;81204:21;:19;:21::i;:::-;81197:28;;;;;;;;81149:203;81265:75;81292:46;81265:18;:75::i;80266:1093::-;;;;;;;;;;;;;;;:::o;85564:136::-;85635:16;85671:21;85686:5;85671:14;:21::i;:::-;85664:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85564:136;;;:::o;84891:280::-;84991:24;84967:8;82384:17;82392:8;82384:7;:17::i;:::-;82376:48;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;;;;85028:19;85050:16;;;:6;:16;;;;;;85132:29;85057:8;85132:19;:29::i;:::-;85091:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;85091:71:0;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;85091:71:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;85091:71:0;;;85077:86;;;84891:280;;;;:::o;84661:222::-;84763:26;84739:8;82384:17;82392:8;82384:7;:17::i;:::-;82376:48;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;;;;84802:19;84824:16;;;:6;:16;;;;;;;;;84851:24;;;;;;-1:-1:-1;;84851:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84824:16;;84851:24;84824:16;;84851:24;;;84824:16;84851:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84661:222;;;;:::o;48577:89::-;48651:7;48644:14;;;;;;;;-1:-1:-1;;48644:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48618:13;;48644:14;;48651:7;;48644:14;;48651:7;48644:14;;;;;;;;;;;;;;;;;;;;;;;;86074:272;9906:27;9920:12;:10;:12::i;9906:27::-;9898:98;;;;-1:-1:-1;;;9898:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86201:8;82384:17;82392:8;82384:7;:17::i;:::-;82376:48;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;;;;86230:31;86222:65;;;;;-1:-1:-1;;;86222:65:0;;;;;;;;;;;;-1:-1:-1;;;86222:65:0;;;;;;;;;;;;;;;86298:16;;;;:6;:16;;;;;:40;;:25;;86326:12;;86298:40;:::i;:::-;;10007:1;86074:272;;;:::o;81654:122::-;8387:30;8404:12;:10;:12::i;8387:30::-;8379:107;;;;-1:-1:-1;;;8379:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81739:29;81756:11;81739:16;:29::i;26950:254::-;27036:12;:10;:12::i;:::-;-1:-1:-1;;;;;27030:18:0;:2;-1:-1:-1;;;;;27030:18:0;;;27022:56;;;;;-1:-1:-1;;;27022:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;27130:8;27091:18;:32;27110:12;:10;:12::i;:::-;-1:-1:-1;;;;;27091:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;27091:32:0;;;:36;;;;;;;;;;;;:47;;-1:-1:-1;;27091:47:0;;;;;;;;;;;27169:12;:10;:12::i;:::-;27154:42;;;;;;;;;;-1:-1:-1;;;;;27154:42:0;;;;;;;;;;;;;;26950:254;;:::o;68679:230::-;68887:14;;;;;;;;;;;;-1:-1:-1;;;68887:14:0;;;;68679:230;:::o;29953:272::-;30068:41;30087:12;:10;:12::i;:::-;30101:7;30068:18;:41::i;:::-;30060:103;;;;-1:-1:-1;;;30060:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30174:43;30192:4;30198:2;30202:7;30211:5;30174:17;:43::i;:::-;29953:272;;;;:::o;8514:125::-;8578:4;8602:29;:16;8623:7;8602:29;:20;:29;:::i;85351:205::-;85450:13;85426:8;82384:17;82392:8;82384:7;:17::i;:::-;82376:48;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;;;;85507:12;85521:6;:16;85528:8;85521:16;;;;;;;;;;;:25;;85490:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;85490:57:0;;;-1:-1:-1;;26:21;;;22:32;6:49;;85490:57:0;;;;85351:205;-1:-1:-1;;;;;;85351:205:0:o;84171:482::-;84282:26;84319:24;84354:22;84248:8;82384:17;82392:8;82384:7;:17::i;:::-;82376:48;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;;;;84395:19;84417:16;;;:6;:16;;;;;;;84538:29;84424:8;84538:19;:29::i;:::-;84497:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;84497:71:0;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;84497:71:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;84497:71:0;;;84604:12;84618:5;:14;;84587:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84587:46:0;;;-1:-1:-1;;26:21;;;22:32;6:49;;84444:201:0;;49:4:-1;84444:201:0;;-1:-1:-1;;84444:201:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84587:46;;-1:-1:-1;84587:46:0;;-1:-1:-1;84444:201:0;;-1:-1:-1;84444:201:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84171:482;;;;;;:::o;10393:89::-;10442:32;10461:12;:10;:12::i;:::-;10442:18;:32::i;83816:347::-;83915:22;83956:15;83974:18;83993:9;;83974:29;;;;;30:3:-1;22:6;14;1:33;57:3;49:6;45:16;35:26;;83974:29:0;;;;;;;;;;;;;;;;;;;83956:47;;84022:16;84030:7;84022;:16::i;:::-;84014:59;;;;;-1:-1:-1;;;84014:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;84115:12;84129:6;:15;84136:7;84129:15;;;;;;;;;;;:24;;84098:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84098:56:0;;;-1:-1:-1;;26:21;;;22:32;6:49;;84098:56:0;;;;83816:347;-1:-1:-1;;;;;;;83816:347:0:o;71944:277::-;72090:12;:10;:12::i;:::-;-1:-1:-1;;;;;72076:26:0;:10;-1:-1:-1;;;;;72076:26:0;;72068:75;;;;-1:-1:-1;;;72068:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72154:59;72171:7;;72154:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;72180:7:0;;-1:-1:-1;72189:12:0;;-1:-1:-1;72203:9:0;;-1:-1:-1;72154:16:0;:59::i;27534:147::-;-1:-1:-1;;;;;27638:25:0;;;27614:4;27638:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;27534:147::o;85179:164::-;85269:16;85305:18;85324:10;;85305:30;;;;;30:3:-1;22:6;14;1:33;45:16;;;;85305:30:0;;;-1:-1:-1;;85305:30:0;;;;;;;;;;;;;-1:-1:-1;;;85179:164:0;;;;:::o;85708:358::-;9906:27;9920:12;:10;:12::i;9906:27::-;9898:98;;;;-1:-1:-1;;;9898:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85838:8;82384:17;82392:8;82384:7;:17::i;:::-;82376:48;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;-1:-1:-1;;;82376:48:0;;;;;;;;;;;;;;;85859:19;85881:16;;;:6;:16;;;;;85908:32;85881:16;85928:12;;85908:32;:::i;:::-;;86050:8;85953:18;85996:12;;86015:29;86035:8;86015:19;:29::i;:::-;85979:66;;;;;;;30:3:-1;22:6;14;1:33;-1:-1;;;45:16;;85979:66:0;;;-1:-1:-1;85979:66:0;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;85979:66:0;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;85979:66:0;;;85953:94;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;85953:94:0;;;;;-1:-1:-1;85953:94:0;;;;;;;;;;:105;;;;-1:-1:-1;;;;;;;85708:358:0:o;31418:155::-;31475:4;31508:20;;;:11;:20;;;;;;-1:-1:-1;;;;;31508:20:0;31546:19;;;31418:155::o;69881:216::-;69972:9;;69926:15;;-1:-1:-1;;;;;69972:9:0;69958:10;:23;69954:136;;-1:-1:-1;70005:10:0;69998:17;;69954:136;70055:23;:21;:23::i;:::-;70048:30;;;;10490:137;10552:26;:13;10570:7;10552:26;:17;:26;:::i;:::-;10594:25;;-1:-1:-1;;;;;10594:25:0;;;;;;;;10490:137;:::o;31943:333::-;32028:4;32053:16;32061:7;32053;:16::i;:::-;32045:73;;;;-1:-1:-1;;;32045:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32129:13;32145:16;32153:7;32145;:16::i;:::-;32129:32;;32191:5;-1:-1:-1;;;;;32180:16:0;:7;-1:-1:-1;;;;;32180:16:0;;:51;;;;32224:7;-1:-1:-1;;;;;32200:31:0;:20;32212:7;32200:11;:20::i;:::-;-1:-1:-1;;;;;32200:31:0;;32180:51;:87;;;;32235:32;32252:5;32259:7;32235:16;:32::i;:::-;32172:96;31943:333;-1:-1:-1;;;;31943:333:0:o;41126:245::-;41212:38;41232:4;41238:2;41242:7;41212:19;:38::i;:::-;41263:47;41296:4;41302:7;41263:32;:47::i;:::-;41323:40;41351:2;41355:7;41323:27;:40::i;10635:145::-;10700:29;:13;10721:7;10700:29;:20;:29;:::i;:::-;10745:27;;-1:-1:-1;;;;;10745:27:0;;;;;;;;10635:145;:::o;7569:203::-;7641:4;-1:-1:-1;;;;;7666:21:0;;7658:68;;;;-1:-1:-1;;;7658:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;7744:20:0;:11;:20;;;;;;;;;;;;;;;7569:203::o;11172:556::-;11231:13;11261:10;11257:53;;-1:-1:-1;11288:10:0;;;;;;;;;;;;-1:-1:-1;;;11288:10:0;;;;;;11257:53;11335:5;11320:12;11376:78;11383:9;;11376:78;;11409:8;;11440:2;11432:10;;;;11376:78;;;11464:19;11496:6;11486:17;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;11486:17:0;87:34:-1;135:17;;-1:-1;11486:17:0;-1:-1:-1;11558:5:0;;-1:-1:-1;11464:39:0;-1:-1:-1;;;11530:10:0;;11574:115;11581:9;;11574:115;;11648:2;11641:4;:9;11636:2;:14;11625:27;;11607:6;11614:7;;;;;;;11607:15;;;;;;;;;;;:45;-1:-1:-1;;;;;11607:45:0;;;;;;;;-1:-1:-1;11675:2:0;11667:10;;;;11574:115;;;-1:-1:-1;11713:6:0;11172:556;-1:-1:-1;;;;11172:556:0:o;35161:92::-;35213:32;35219:16;35227:7;35219;:16::i;:::-;35237:7;35213:5;:32::i;9028:154::-;9096:32;:16;9120:7;9096:32;:23;:32;:::i;:::-;9144:30;;-1:-1:-1;;;;;9144:30:0;;;;;;;;9028:154;:::o;41636:202::-;41700:24;41712:2;41716:7;41700:11;:24::i;:::-;41737:40;41765:2;41769:7;41737:27;:40::i;:::-;41790;41822:7;41790:31;:40::i;:::-;41636:202;;:::o;20162:114::-;20254:14;;20162:114::o;8874:146::-;8939:29;:16;8960:7;8939:29;:20;:29;:::i;:::-;8984:28;;-1:-1:-1;;;;;8984:28:0;;;;;;;;8874:146;:::o;81367:132::-;-1:-1:-1;81424:7:0;;81367:132::o;79435:269::-;79637:58;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;79637:58:0;;;;;;;79627:69;;;;;;79435:269::o;77231:1930::-;77309:7;77372:9;:16;77392:2;77372:22;77368:74;;-1:-1:-1;77427:1:0;77411:19;;77368:74;77803:4;77788:20;;77782:27;77849:4;77834:20;;77828:27;77903:4;77888:20;;77882:27;77511:9;77874:36;78833:66;78820:79;;78816:129;;;78931:1;78916:17;;;;;;;78816:129;78961:1;:7;;78966:2;78961:7;;:18;;;;;78972:1;:7;;78977:2;78972:7;;78961:18;78957:68;;;79011:1;78996:17;;;;;;;78957:68;79129:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;79129:24:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;79129:24:0;;-1:-1:-1;;79129:24:0;;;77231:1930;-1:-1:-1;;;;;;;77231:1930:0:o;72830:126::-;72884:7;72893:12;72925:23;;;;;;;;;;;;;:19;:23::i;:::-;72918:30;;;;72830:126;;:::o;73416:158::-;73520:46;;;;;;;;;-1:-1:-1;73520:46:0;;66999:2;73528:33;;;;;73416:158::o;42706:126::-;-1:-1:-1;;;;;42805:19:0;42768:17;42805:19;;;:12;:19;;;;;;42706:126::o;67922:403::-;68015:9;;-1:-1:-1;;;;;68015:9:0;;;;68043:25;;68035:84;;;;-1:-1:-1;;;68035:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68153:15;-1:-1:-1;;;;;68138:30:0;:11;-1:-1:-1;;;;;68138:30:0;;;68130:88;;;;-1:-1:-1;;;68130:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68269:11;-1:-1:-1;;;;;68236:45:0;68252:15;-1:-1:-1;;;;;68236:45:0;;;;;;;;;;;-1:-1:-1;68294:9:0;:23;;-1:-1:-1;;;;;;68294:23:0;-1:-1:-1;;;;;68294:23:0;;;;;;;;;;67922:403::o;30944:272::-;31054:32;31068:4;31074:2;31078:7;31054:13;:32::i;:::-;31105:48;31128:4;31134:2;31138:7;31147:5;31105:22;:48::i;:::-;31097:111;;;;-1:-1:-1;;;31097:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74090:1270;74145:22;74963:18;74984:8;;74963:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;;;75019:8:0;75255:17;75249:24;-1:-1:-1;;;;;75245:73:0;;74090:1270;-1:-1:-1;;74090:1270:0:o;7033:178::-;7111:18;7115:4;7121:7;7111:3;:18::i;:::-;7110:19;7102:63;;;;;-1:-1:-1;;;7102:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7176:20:0;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;7176:27:0;7199:4;7176:27;;;7033:178::o;35639:459::-;35753:4;-1:-1:-1;;;;;35733:24:0;:16;35741:7;35733;:16::i;:::-;-1:-1:-1;;;;;35733:24:0;;35725:78;;;;-1:-1:-1;;;35725:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35822:16:0;;35814:65;;;;-1:-1:-1;;;35814:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35892:23;35907:7;35892:14;:23::i;:::-;-1:-1:-1;;;;;35928:23:0;;;;;;:17;:23;;;;;:35;;:33;:35::i;:::-;-1:-1:-1;;;;;35974:21:0;;;;;;:17;:21;;;;;:33;;:31;:33::i;:::-;36020:20;;;;:11;:20;;;;;;:25;;-1:-1:-1;;;;;;36020:25:0;-1:-1:-1;;;;;36020:25:0;;;;;;;;;36063:27;;36020:20;;36063:27;;;;;;;35639:459;;;:::o;44311:1148::-;-1:-1:-1;;;;;44602:18:0;;44577:22;44602:18;;;:12;:18;;;;;:25;:32;;44632:1;44602:32;:29;:32;:::i;:::-;44645:18;44666:26;;;:17;:26;;;;;;44577:57;;-1:-1:-1;44799:28:0;;;44795:328;;-1:-1:-1;;;;;44866:18:0;;44844:19;44866:18;;;:12;:18;;;;;:34;;44885:14;;44866:34;;;;;;;;;;;;;;44844:56;;44950:11;44917:12;:18;44930:4;-1:-1:-1;;;;;44917:18:0;-1:-1:-1;;;;;44917:18:0;;;;;;;;;;;;44936:10;44917:30;;;;;;;;;;;;;;;;;;;:44;;;;45034:30;;;:17;:30;;;;;:43;;;44795:328;-1:-1:-1;;;;;45212:18:0;;;;;;:12;:18;;;;;:27;;;;;-1:-1:-1;;45212:27:0;;;:::i;43133:186::-;-1:-1:-1;;;;;43247:16:0;;;;;;;:12;:16;;;;;;;;:23;;43218:26;;;:17;:26;;;;;:52;;;43281:16;;;39:1:-1;23:18;;45:23;;43281:30:0;;;;;;;;43133:186::o;7291:183::-;7371:18;7375:4;7381:7;7371:3;:18::i;:::-;7363:64;;;;-1:-1:-1;;;7363:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7438:20:0;7461:5;7438:20;;;;;;;;;;;:28;;-1:-1:-1;;7438:28:0;;;7291:183::o;42122:372::-;42189:27;42201:5;42208:7;42189:11;:27::i;:::-;42229:48;42262:5;42269:7;42229:32;:48::i;:::-;42427:1;42398:26;;;:17;:26;;;;;:30;42441:45;42416:7;42441:36;:45::i;34028:335::-;-1:-1:-1;;;;;34100:16:0;;34092:61;;;;;-1:-1:-1;;;34092:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34173:16;34181:7;34173;:16::i;:::-;34172:17;34164:58;;;;;-1:-1:-1;;;34164:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;34235:20;;;;:11;:20;;;;;;;;:25;;-1:-1:-1;;;;;;34235:25:0;-1:-1:-1;;;;;34235:25:0;;;;;;;;34271:21;;:17;:21;;;;;:33;;:31;:33::i;:::-;34322;;34347:7;;-1:-1:-1;;;;;34322:33:0;;;34339:1;;34322:33;;34339:1;;34322:33;34028:335;;:::o;43520:164::-;43624:10;:17;;43597:24;;;;:15;:24;;;;;:44;;;39:1:-1;23:18;;45:23;;43652:24:0;;;;;;;43520:164::o;73125:155::-;73199:7;;73125:155::o;36700:358::-;36822:4;36849:15;:2;-1:-1:-1;;;;;36849:13:0;;:15::i;:::-;36844:60;;-1:-1:-1;36888:4:0;36881:11;;36844:60;36916:13;36948:2;-1:-1:-1;;;;;36932:36:0;;36969:12;:10;:12::i;:::-;36983:4;36989:7;36998:5;36932:72;;;;;;;;;;;;;-1:-1:-1;;;;;36932:72:0;-1:-1:-1;;;;;36932:72:0;;;;;;-1:-1:-1;;;;;36932:72:0;-1:-1:-1;;;;;36932:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;36932:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36932:72:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36932:72:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36932:72:0;-1:-1:-1;;;;;;37023:26:0;-1:-1:-1;;;37023:26:0;;-1:-1:-1;;36700:358:0;;;;;;:::o;37226:175::-;37326:1;37290:24;;;:15;:24;;;;;;-1:-1:-1;;;;;37290:24:0;:38;37286:108;;37380:1;37345:24;;;:15;:24;;;;;:37;;-1:-1:-1;;;;;;37345:37:0;;;37226:175::o;20383:110::-;20464:14;;:21;;20483:1;20464:21;:18;:21;:::i;:::-;20447:38;;20383:110::o;20284:91::-;20348:19;;20366:1;20348:19;;;20284:91::o;1369:136::-;1427:7;1454:43;1458:1;1461;1454:43;;;;;;;;;;;;;;;;;:3;:43::i;34640:333::-;34735:5;-1:-1:-1;;;;;34715:25:0;:16;34723:7;34715;:16::i;:::-;-1:-1:-1;;;;;34715:25:0;;34707:75;;;;-1:-1:-1;;;34707:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34795:23;34810:7;34795:14;:23::i;:::-;-1:-1:-1;;;;;34831:24:0;;;;;;:17;:24;;;;;:36;;:34;:36::i;:::-;34909:1;34878:20;;;:11;:20;;;;;;:33;;-1:-1:-1;;;;;;34878:33:0;;;34929:36;34890:7;;34909:1;-1:-1:-1;;;;;34929:36:0;;;;;34909:1;;34929:36;34640:333;;:::o;45754:1082::-;46032:10;:17;46007:22;;46032:24;;46054:1;46032:24;:21;:24;:::i;:::-;46067:18;46088:24;;;:15;:24;;;;;;46461:10;:26;;46007:49;;-1:-1:-1;46088:24:0;;46007:49;;46461:26;;;;;;;;;;;;;;46439:48;;46525:11;46500:10;46511;46500:22;;;;;;;;;;;;;;;;;;;:36;;;;46605:28;;;:15;:28;;;;;;:41;;;46770:10;:19;;;;;-1:-1:-1;;46770:19:0;;;:::i;:::-;-1:-1:-1;;;46827:1:0;46800:24;;;-1:-1:-1;46800:15:0;:24;;;;;:28;45754:1082::o;16539:810::-;16599:4;17258:20;;17101:66;17298:15;;;;;:42;;-1:-1:-1;17317:23:0;;;17290:51;-1:-1:-1;;16539:810:0:o;1842:192::-;1928:7;1964:12;1956:6;;;;1948:29;;;;-1:-1:-1;;;1948:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1948:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2000:5:0;;;1842:192::o;81867:5219::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;81867:5219:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81867:5219:0;;;-1:-1:-1;81867:5219:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Swarm Source
bzzr://b93b24d099220b03f870c50afc3fe9a8da20b24718ccdab067816283bd1e1776
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.