Contract
0xbdacf94ddcab51c39c2dd50bffee60bb8021949a
7
Contract Overview
Balance:
0 FTM
FTM Value:
$0.00
[ Download CSV Export ]
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0x116d3ba367d11a98fc7da0d7d4108acdbb139b83ffd0f923e660a366a0f42920 | 51395712 | 75 days 5 hrs ago | 0xea2f99fe93e5d07f61334c5eb9c54c5d5c957a6a | Contract Creation | 0 FTM |
[ Download CSV Export ]
Contract Name:
FlexiPunkTLD
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at FtmScan.com on 2022-12-20 */ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.4; interface IFlexiPunkMetadata { function getMetadata(string calldata _domainName, string calldata _tld, uint256 _tokenId) external view returns(string memory); } pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; } pragma solidity ^0.8.4; interface IBasePunkTLD is IERC721 { struct Domain { string name; // domain name that goes before the TLD name; example: "tempetechie" in "tempetechie.web3" uint256 tokenId; address holder; string data; // stringified JSON object, example: {"description": "Some text", "twitter": "@techie1239", "friends": ["0x123..."], "url": "https://punk.domains"} } event DomainCreated(address indexed user, address indexed owner, string fullDomainName); event DomainBurned(address indexed user, string fullDomainName); event DefaultDomainChanged(address indexed user, string defaultDomain); event DataChanged(address indexed user); event TldPriceChanged(address indexed user, uint256 tldPrice); event ReferralFeeChanged(address indexed user, uint256 referralFee); event TldRoyaltyChanged(address indexed user, uint256 tldRoyalty); event DomainBuyingToggle(address indexed user, bool domainBuyingToggle); function domains(string calldata _domainName) external view returns(string memory, uint256, address, string memory); function defaultNames(address) external view returns(string memory); function getDomainData(string calldata _domainName) external view returns(string memory); function getDomainHolder(string calldata _domainName) external view returns(address); function price() external view returns (uint256); function referral() external view returns (uint256); function changeNameMaxLength(uint256 _maxLength) external; function changePrice(uint256 _price) external; function changeReferralFee(uint256 _referral) external; function mint( string memory _domainName, address _domainHolder, address _referrer ) external payable returns(uint256); } pragma solidity ^0.8.0; library strings { struct slice { uint _len; uint _ptr; } function memcpy(uint dest, uint src, uint _len) private pure { // Copy word-length chunks while possible for(; _len >= 32; _len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = type(uint).max; if (_len > 0) { mask = 256 ** (32 - _len) - 1; } assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } /* * @dev Returns a slice containing the entire string. * @param self The string to make a slice from. * @return A newly allocated slice containing the entire string. */ function toSlice(string memory self) internal pure returns (slice memory) { uint ptr; assembly { ptr := add(self, 0x20) } return slice(bytes(self).length, ptr); } /* * @dev Returns the length of a null-terminated bytes32 string. * @param self The value to find the length of. * @return The length of the string, from 0 to 32. */ function len(bytes32 self) internal pure returns (uint) { uint ret; if (self == 0) return 0; if (uint(self) & type(uint128).max == 0) { ret += 16; self = bytes32(uint(self) / 0x100000000000000000000000000000000); } if (uint(self) & type(uint64).max == 0) { ret += 8; self = bytes32(uint(self) / 0x10000000000000000); } if (uint(self) & type(uint32).max == 0) { ret += 4; self = bytes32(uint(self) / 0x100000000); } if (uint(self) & type(uint16).max == 0) { ret += 2; self = bytes32(uint(self) / 0x10000); } if (uint(self) & type(uint8).max == 0) { ret += 1; } return 32 - ret; } /* * @dev Returns a slice containing the entire bytes32, interpreted as a * null-terminated utf-8 string. * @param self The bytes32 value to convert to a slice. * @return A new slice containing the value of the input argument up to the * first null. */ function toSliceB32(bytes32 self) internal pure returns (slice memory ret) { // Allocate space for `self` in memory, copy it there, and point ret at it assembly { let ptr := mload(0x40) mstore(0x40, add(ptr, 0x20)) mstore(ptr, self) mstore(add(ret, 0x20), ptr) } ret._len = len(self); } /* * @dev Returns a new slice containing the same data as the current slice. * @param self The slice to copy. * @return A new slice containing the same data as `self`. */ function copy(slice memory self) internal pure returns (slice memory) { return slice(self._len, self._ptr); } /* * @dev Copies a slice to a new string. * @param self The slice to copy. * @return A newly allocated string containing the slice's text. */ function toString(slice memory self) internal pure returns (string memory) { string memory ret = new string(self._len); uint retptr; assembly { retptr := add(ret, 32) } memcpy(retptr, self._ptr, self._len); return ret; } /* * @dev Returns the length in runes of the slice. Note that this operation * takes time proportional to the length of the slice; avoid using it * in loops, and call `slice.empty()` if you only need to know whether * the slice is empty or not. * @param self The slice to operate on. * @return The length of the slice in runes. */ function len(slice memory self) internal pure returns (uint l) { // Starting at ptr-31 means the LSB will be the byte we care about uint ptr = self._ptr - 31; uint end = ptr + self._len; for (l = 0; ptr < end; l++) { uint8 b; assembly { b := and(mload(ptr), 0xFF) } if (b < 0x80) { ptr += 1; } else if(b < 0xE0) { ptr += 2; } else if(b < 0xF0) { ptr += 3; } else if(b < 0xF8) { ptr += 4; } else if(b < 0xFC) { ptr += 5; } else { ptr += 6; } } } /* * @dev Returns true if the slice is empty (has a length of 0). * @param self The slice to operate on. * @return True if the slice is empty, False otherwise. */ function empty(slice memory self) internal pure returns (bool) { return self._len == 0; } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two slices are equal. Comparison is done per-rune, * on unicode codepoints. * @param self The first slice to compare. * @param other The second slice to compare. * @return The result of the comparison. */ function compare(slice memory self, slice memory other) internal pure returns (int) { uint shortest = self._len; if (other._len < self._len) shortest = other._len; uint selfptr = self._ptr; uint otherptr = other._ptr; for (uint idx = 0; idx < shortest; idx += 32) { uint a; uint b; assembly { a := mload(selfptr) b := mload(otherptr) } if (a != b) { // Mask out irrelevant bytes and check again uint mask = type(uint).max; // 0xffff... if(shortest < 32) { mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); } unchecked { uint diff = (a & mask) - (b & mask); if (diff != 0) return int(diff); } } selfptr += 32; otherptr += 32; } return int(self._len) - int(other._len); } /* * @dev Returns true if the two slices contain the same text. * @param self The first slice to compare. * @param self The second slice to compare. * @return True if the slices are equal, false otherwise. */ function equals(slice memory self, slice memory other) internal pure returns (bool) { return compare(self, other) == 0; } /* * @dev Extracts the first rune in the slice into `rune`, advancing the * slice to point to the next rune and returning `self`. * @param self The slice to operate on. * @param rune The slice that will contain the first rune. * @return `rune`. */ function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) { rune._ptr = self._ptr; if (self._len == 0) { rune._len = 0; return rune; } uint l; uint b; // Load the first byte of the rune into the LSBs of b assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) } if (b < 0x80) { l = 1; } else if(b < 0xE0) { l = 2; } else if(b < 0xF0) { l = 3; } else { l = 4; } // Check for truncated codepoints if (l > self._len) { rune._len = self._len; self._ptr += self._len; self._len = 0; return rune; } self._ptr += l; self._len -= l; rune._len = l; return rune; } /* * @dev Returns the first rune in the slice, advancing the slice to point * to the next rune. * @param self The slice to operate on. * @return A slice containing only the first rune from `self`. */ function nextRune(slice memory self) internal pure returns (slice memory ret) { nextRune(self, ret); } /* * @dev Returns the number of the first codepoint in the slice. * @param self The slice to operate on. * @return The number of the first codepoint in the slice. */ function ord(slice memory self) internal pure returns (uint ret) { if (self._len == 0) { return 0; } uint word; uint length; uint divisor = 2 ** 248; // Load the rune into the MSBs of b assembly { word:= mload(mload(add(self, 32))) } uint b = word / divisor; if (b < 0x80) { ret = b; length = 1; } else if(b < 0xE0) { ret = b & 0x1F; length = 2; } else if(b < 0xF0) { ret = b & 0x0F; length = 3; } else { ret = b & 0x07; length = 4; } // Check for truncated codepoints if (length > self._len) { return 0; } for (uint i = 1; i < length; i++) { divisor = divisor / 256; b = (word / divisor) & 0xFF; if (b & 0xC0 != 0x80) { // Invalid UTF-8 sequence return 0; } ret = (ret * 64) | (b & 0x3F); } return ret; } /* * @dev Returns the keccak-256 hash of the slice. * @param self The slice to hash. * @return The hash of the slice. */ function keccak(slice memory self) internal pure returns (bytes32 ret) { assembly { ret := keccak256(mload(add(self, 32)), mload(self)) } } /* * @dev Returns true if `self` starts with `needle`. * @param self The slice to operate on. * @param needle The slice to search for. * @return True if the slice starts with the provided text, false otherwise. */ function startsWith(slice memory self, slice memory needle) internal pure returns (bool) { if (self._len < needle._len) { return false; } if (self._ptr == needle._ptr) { return true; } bool equal; assembly { let length := mload(needle) let selfptr := mload(add(self, 0x20)) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } return equal; } /* * @dev If `self` starts with `needle`, `needle` is removed from the * beginning of `self`. Otherwise, `self` is unmodified. * @param self The slice to operate on. * @param needle The slice to search for. * @return `self` */ function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) { if (self._len < needle._len) { return self; } bool equal = true; if (self._ptr != needle._ptr) { assembly { let length := mload(needle) let selfptr := mload(add(self, 0x20)) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } } if (equal) { self._len -= needle._len; self._ptr += needle._len; } return self; } /* * @dev Returns true if the slice ends with `needle`. * @param self The slice to operate on. * @param needle The slice to search for. * @return True if the slice starts with the provided text, false otherwise. */ function endsWith(slice memory self, slice memory needle) internal pure returns (bool) { if (self._len < needle._len) { return false; } uint selfptr = self._ptr + self._len - needle._len; if (selfptr == needle._ptr) { return true; } bool equal; assembly { let length := mload(needle) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } return equal; } /* * @dev If `self` ends with `needle`, `needle` is removed from the * end of `self`. Otherwise, `self` is unmodified. * @param self The slice to operate on. * @param needle The slice to search for. * @return `self` */ function until(slice memory self, slice memory needle) internal pure returns (slice memory) { if (self._len < needle._len) { return self; } uint selfptr = self._ptr + self._len - needle._len; bool equal = true; if (selfptr != needle._ptr) { assembly { let length := mload(needle) let needleptr := mload(add(needle, 0x20)) equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) } } if (equal) { self._len -= needle._len; } return self; } // Returns the memory address of the first byte of the first occurrence of // `needle` in `self`, or the first byte after `self` if not found. function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { uint ptr = selfptr; uint idx; if (needlelen <= selflen) { if (needlelen <= 32) { bytes32 mask; if (needlelen > 0) { mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); } bytes32 needledata; assembly { needledata := and(mload(needleptr), mask) } uint end = selfptr + selflen - needlelen; bytes32 ptrdata; assembly { ptrdata := and(mload(ptr), mask) } while (ptrdata != needledata) { if (ptr >= end) return selfptr + selflen; ptr++; assembly { ptrdata := and(mload(ptr), mask) } } return ptr; } else { // For long needles, use hashing bytes32 hash; assembly { hash := keccak256(needleptr, needlelen) } for (idx = 0; idx <= selflen - needlelen; idx++) { bytes32 testHash; assembly { testHash := keccak256(ptr, needlelen) } if (hash == testHash) return ptr; ptr += 1; } } } return selfptr + selflen; } // Returns the memory address of the first byte after the last occurrence of // `needle` in `self`, or the address of `self` if not found. function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { uint ptr; if (needlelen <= selflen) { if (needlelen <= 32) { bytes32 mask; if (needlelen > 0) { mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); } bytes32 needledata; assembly { needledata := and(mload(needleptr), mask) } ptr = selfptr + selflen - needlelen; bytes32 ptrdata; assembly { ptrdata := and(mload(ptr), mask) } while (ptrdata != needledata) { if (ptr <= selfptr) return selfptr; ptr--; assembly { ptrdata := and(mload(ptr), mask) } } return ptr + needlelen; } else { // For long needles, use hashing bytes32 hash; assembly { hash := keccak256(needleptr, needlelen) } ptr = selfptr + (selflen - needlelen); while (ptr >= selfptr) { bytes32 testHash; assembly { testHash := keccak256(ptr, needlelen) } if (hash == testHash) return ptr + needlelen; ptr -= 1; } } } return selfptr; } /* * @dev Modifies `self` to contain everything from the first occurrence of * `needle` to the end of the slice. `self` is set to the empty slice * if `needle` is not found. * @param self The slice to search and modify. * @param needle The text to search for. * @return `self`. */ function find(slice memory self, slice memory needle) internal pure returns (slice memory) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); self._len -= ptr - self._ptr; self._ptr = ptr; return self; } /* * @dev Modifies `self` to contain the part of the string from the start of * `self` to the end of the first occurrence of `needle`. If `needle` * is not found, `self` is set to the empty slice. * @param self The slice to search and modify. * @param needle The text to search for. * @return `self`. */ function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) { uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); self._len = ptr - self._ptr; return self; } /* * @dev Splits the slice, setting `self` to everything after the first * occurrence of `needle`, and `token` to everything before it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and `token` is set to the entirety of `self`. * @param self The slice to split. * @param needle The text to search for in `self`. * @param token An output parameter to which the first token is written. * @return `token`. */ function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); token._ptr = self._ptr; token._len = ptr - self._ptr; if (ptr == self._ptr + self._len) { // Not found self._len = 0; } else { self._len -= token._len + needle._len; self._ptr = ptr + needle._len; } return token; } /* * @dev Splits the slice, setting `self` to everything after the first * occurrence of `needle`, and returning everything before it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and the entirety of `self` is returned. * @param self The slice to split. * @param needle The text to search for in `self`. * @return The part of `self` up to the first occurrence of `delim`. */ function split(slice memory self, slice memory needle) internal pure returns (slice memory token) { split(self, needle, token); } /* * @dev Splits the slice, setting `self` to everything before the last * occurrence of `needle`, and `token` to everything after it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and `token` is set to the entirety of `self`. * @param self The slice to split. * @param needle The text to search for in `self`. * @param token An output parameter to which the first token is written. * @return `token`. */ function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); token._ptr = ptr; token._len = self._len - (ptr - self._ptr); if (ptr == self._ptr) { // Not found self._len = 0; } else { self._len -= token._len + needle._len; } return token; } /* * @dev Splits the slice, setting `self` to everything before the last * occurrence of `needle`, and returning everything after it. If * `needle` does not occur in `self`, `self` is set to the empty slice, * and the entirety of `self` is returned. * @param self The slice to split. * @param needle The text to search for in `self`. * @return The part of `self` after the last occurrence of `delim`. */ function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) { rsplit(self, needle, token); } /* * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`. * @param self The slice to search. * @param needle The text to search for in `self`. * @return The number of occurrences of `needle` found in `self`. */ function count(slice memory self, slice memory needle) internal pure returns (uint cnt) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len; while (ptr <= self._ptr + self._len) { cnt++; ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len; } } /* * @dev Returns True if `self` contains `needle`. * @param self The slice to search. * @param needle The text to search for in `self`. * @return True if `needle` is found in `self`, false otherwise. */ function contains(slice memory self, slice memory needle) internal pure returns (bool) { return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr; } /* * @dev Returns a newly allocated string containing the concatenation of * `self` and `other`. * @param self The first slice to concatenate. * @param other The second slice to concatenate. * @return The concatenation of the two strings. */ function concat(slice memory self, slice memory other) internal pure returns (string memory) { string memory ret = new string(self._len + other._len); uint retptr; assembly { retptr := add(ret, 32) } memcpy(retptr, self._ptr, self._len); memcpy(retptr + self._len, other._ptr, other._len); return ret; } /* * @dev Joins an array of slices, using `self` as a delimiter, returning a * newly allocated string. * @param self The delimiter to use. * @param parts A list of slices to join. * @return A newly allocated string containing all the slices in `parts`, * joined with `self`. */ function join(slice memory self, slice[] memory parts) internal pure returns (string memory) { if (parts.length == 0) return ""; uint length = self._len * (parts.length - 1); for(uint i = 0; i < parts.length; i++) length += parts[i]._len; string memory ret = new string(length); uint retptr; assembly { retptr := add(ret, 32) } for(uint i = 0; i < parts.length; i++) { memcpy(retptr, parts[i]._ptr, parts[i]._len); retptr += parts[i]._len; if (i < parts.length - 1) { memcpy(retptr, self._ptr, self._len); retptr += self._len; } } return ret; } /** * Lower * * Converts all the values of a string to their corresponding lower case * value. * * @param _base When being used for a data type this is the extended object * otherwise this is the string base to convert to lower case * @return string */ function lower(string memory _base) internal pure returns (string memory) { bytes memory _baseBytes = bytes(_base); for (uint i = 0; i < _baseBytes.length; i++) { _baseBytes[i] = _lower(_baseBytes[i]); } return string(_baseBytes); } /** * Lower * * Convert an alphabetic character to lower case and return the original * value when not alphabetic * * @param _b1 The byte to be converted to lower case * @return bytes1 The converted value if the passed value was alphabetic * and in a upper case otherwise returns the original value */ function _lower(bytes1 _b1) private pure returns (bytes1) { if (_b1 >= 0x41 && _b1 <= 0x5A) { return bytes1(uint8(_b1) + 32); } return _b1; } } pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits a {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } /// @title Base64 /// @author Brecht Devos - <[email protected]> /// @notice Provides a function for encoding some bytes in base64 library Base64 { string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function encode(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; // load the table into memory string memory table = TABLE; // multiply by 4/3 rounded up uint256 encodedLen = 4 * ((data.length + 2) / 3); // add some extra buffer at the end required for the writing string memory result = new string(encodedLen + 32); assembly { // set the actual output length mstore(result, encodedLen) // prepare the lookup table let tablePtr := add(table, 1) // input ptr let dataPtr := data let endPtr := add(dataPtr, mload(data)) // result ptr, jump over length let resultPtr := add(result, 32) // run over the input, 3 bytes at a time for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) // read 3 bytes let input := mload(dataPtr) // write 4 characters mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F))))) resultPtr := add(resultPtr, 1) } // padding with '=' switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } } pragma solidity ^0.8.4; /// @title Punk Domains TLD contract (Flexi) /// @author Tempe Techie /// @notice Dynamically generated NFT contract which represents a top-level domain contract FlexiPunkTLD is IBasePunkTLD, ERC721, Ownable, ReentrancyGuard { using strings for string; // Domain struct is defined in IBasePunkTLD address public immutable factoryAddress; // FlexiPunkTLDFactory address address public metadataAddress; // FlexiPunkMetadata address address public minter; // address which is allowed to mint domains even if contract is paused address public royaltyFeeUpdater; // address which is allowed to change the royalty fee address public royaltyFeeReceiver; // address which receives the royalty fee bool public buyingEnabled = false; // buying domains enabled bool public buyingDisabledForever = false; // buying domains disabled forever bool public metadataFrozen = false; // metadata address frozen forever uint256 public totalSupply; uint256 public idCounter = 1; // up only uint256 public override price; // domain price uint256 public royalty; // share of each domain purchase (in bips) that goes to Punk Domains uint256 public override referral = 1000; // share of each domain purchase (in bips) that goes to the referrer (referral fee) uint256 public nameMaxLength = 140; // max length of a domain name mapping (string => Domain) public override domains; // mapping (domain name => Domain struct); Domain struct is defined in IBasePunkTLD mapping (uint256 => string) public domainIdsNames; // mapping (tokenId => domain name) mapping (address => string) public override defaultNames; // user's default domain event MintingDisabledForever(address user); constructor( string memory _name, string memory _symbol, address _tldOwner, uint256 _domainPrice, bool _buyingEnabled, uint256 _royalty, address _factoryAddress, address _metadataAddress ) ERC721(_name, _symbol) { price = _domainPrice; buyingEnabled = _buyingEnabled; royalty = _royalty; metadataAddress = _metadataAddress; Ownable factory = Ownable(_factoryAddress); factoryAddress = _factoryAddress; royaltyFeeUpdater = factory.owner(); royaltyFeeReceiver = factory.owner(); transferOwnership(_tldOwner); } // READ // Domain getters - you can also get all Domain data by calling the auto-generated domains(domainName) method function getDomainHolder(string calldata _domainName) public override view returns(address) { return domains[strings.lower(_domainName)].holder; } function getDomainData(string calldata _domainName) public override view returns(string memory) { return domains[strings.lower(_domainName)].data; // should be a JSON object } function tokenURI(uint256 _tokenId) public view override returns (string memory) { return IFlexiPunkMetadata(metadataAddress).getMetadata( domains[domainIdsNames[_tokenId]].name, name(), _tokenId ); } // WRITE /// @notice Flexi-specific function function burn(string calldata _domainName) external { string memory dName = strings.lower(_domainName); require(domains[dName].holder == _msgSender(), "You do not own the selected domain"); uint256 tokenId = domains[dName].tokenId; delete domainIdsNames[tokenId]; // delete tokenId => domainName mapping delete domains[dName]; // delete string => Domain struct mapping if (keccak256(bytes(defaultNames[_msgSender()])) == keccak256(bytes(dName))) { delete defaultNames[_msgSender()]; } _burn(tokenId); // burn the token --totalSupply; emit DomainBurned(_msgSender(), dName); } /// @notice Default domain is the domain name that reverse resolver returns for a given address. function editDefaultDomain(string calldata _domainName) external { string memory dName = strings.lower(_domainName); require(domains[dName].holder == _msgSender(), "You do not own the selected domain"); defaultNames[_msgSender()] = dName; emit DefaultDomainChanged(_msgSender(), dName); } /// @notice Edit domain custom data. Make sure to not accidentally delete previous data. Fetch previous data first. /// @param _domainName Only domain name, no TLD/extension. /// @param _data Custom data needs to be in a JSON object format. function editData(string calldata _domainName, string calldata _data) external { string memory dName = strings.lower(_domainName); require(domains[dName].holder == _msgSender(), "Only domain holder can edit their data"); domains[dName].data = _data; emit DataChanged(_msgSender()); } /// @notice Mint a new domain name as NFT (no dots and spaces allowed). /// @param _domainName Enter domain name without TLD and make sure letters are in lowercase form. /// @return token ID function mint( string memory _domainName, address _domainHolder, address _referrer ) external payable override nonReentrant returns(uint256) { require(!buyingDisabledForever, "Domain minting disabled forever"); require(buyingEnabled || _msgSender() == owner() || _msgSender() == minter, "Buying domains disabled"); require(msg.value >= price, "Value below price"); _sendPayment(msg.value, _referrer); return _mintDomain(_domainName, _domainHolder, ""); } function _mintDomain( string memory _domainNameRaw, address _domainHolder, string memory _data ) internal returns(uint256) { // convert domain name to lowercase (only works for ascii, clients should enforce ascii domains only) string memory _domainName = strings.lower(_domainNameRaw); require(strings.len(strings.toSlice(_domainName)) > 0, "Domain name empty"); require(bytes(_domainName).length < nameMaxLength, "Domain name is too long"); require(strings.count(strings.toSlice(_domainName), strings.toSlice(".")) == 0, "There should be no dots in the name"); require(strings.count(strings.toSlice(_domainName), strings.toSlice(" ")) == 0, "There should be no spaces in the name"); require(domains[_domainName].holder == address(0), "Domain with this name already exists"); _mint(_domainHolder, idCounter); Domain memory newDomain; // Domain struct is defined in IBasePunkTLD // store data in Domain struct newDomain.name = _domainName; newDomain.tokenId = idCounter; newDomain.holder = _domainHolder; newDomain.data = _data; // add to both mappings domains[_domainName] = newDomain; domainIdsNames[idCounter] = _domainName; if (bytes(defaultNames[_domainHolder]).length == 0) { defaultNames[_domainHolder] = _domainName; // if default domain name is not set for that holder, set it now } emit DomainCreated(_msgSender(), _domainHolder, string(abi.encodePacked(_domainName, name()))); ++idCounter; ++totalSupply; return idCounter-1; } function _sendPayment(uint256 _paymentAmount, address _referrer) internal { if (royalty > 0 && royalty < 5000) { // send royalty - must be less than 50% (5000 bips) (bool sentRoyalty, ) = payable(royaltyFeeReceiver).call{value: ((_paymentAmount * royalty) / 10000)}(""); require(sentRoyalty, "Failed to send royalty to factory owner"); } if (_referrer != address(0) && referral > 0 && referral < 5000) { // send referral fee - must be less than 50% (5000 bips) (bool sentReferralFee, ) = payable(_referrer).call{value: ((_paymentAmount * referral) / 10000)}(""); require(sentReferralFee, "Failed to send referral fee"); } // send the rest to TLD owner (bool sent, ) = payable(owner()).call{value: address(this).balance}(""); require(sent, "Failed to send domain payment to TLD owner"); } ///@dev Hook that is called before any token transfer. This includes minting and burning. function _beforeTokenTransfer(address from,address to,uint256 tokenId) internal override virtual { if (from != address(0)) { // run on every transfer but not on mint domains[domainIdsNames[tokenId]].holder = to; // change holder address in Domain struct if (bytes(defaultNames[to]).length == 0 && to != address(0)) { defaultNames[to] = domains[domainIdsNames[tokenId]].name; // if default domain name is not set for that holder, set it now } if (strings.equals(strings.toSlice(domains[domainIdsNames[tokenId]].name), strings.toSlice(defaultNames[from]))) { delete defaultNames[from]; // if previous owner had this domain name as default, unset it as default } } } // OWNER /// @notice Only TLD contract owner can call this function. Flexi-specific function. function changeMetadataAddress(address _metadataAddress) external onlyOwner { require(!metadataFrozen, "Cannot change metadata address anymore"); metadataAddress = _metadataAddress; } /// @notice Only TLD contract owner can call this function. Flexi-specific function. function changeMinter(address _minter) external onlyOwner { minter = _minter; } /// @notice Only TLD contract owner can call this function. function changeNameMaxLength(uint256 _maxLength) external override onlyOwner { nameMaxLength = _maxLength; } /// @notice Only TLD contract owner can call this function. function changePrice(uint256 _price) external override onlyOwner { price = _price; emit TldPriceChanged(_msgSender(), _price); } /// @notice Only TLD contract owner can call this function. function changeReferralFee(uint256 _referral) external override onlyOwner { require(_referral < 5000, "Referral fee cannot be 50% or higher"); referral = _referral; // referral must be in bips emit ReferralFeeChanged(_msgSender(), _referral); } /// @notice Only TLD contract owner can call this function. Flexi-specific function. function disableBuyingForever() external onlyOwner { buyingDisabledForever = true; // this action is irreversible emit MintingDisabledForever(_msgSender()); } /// @notice Freeze metadata address. Only TLD contract owner can call this function. function freezeMetadata() external onlyOwner { metadataFrozen = true; // this action is irreversible } /// @notice Only TLD contract owner can call this function. function toggleBuyingDomains() external onlyOwner { buyingEnabled = !buyingEnabled; emit DomainBuyingToggle(_msgSender(), buyingEnabled); } // ROYALTY FEE UPDATER /// @notice This changes royalty fee in the wrapper contract function changeRoyalty(uint256 _royalty) external { require(_royalty <= 5000, "Cannot exceed 50%"); require(_msgSender() == royaltyFeeUpdater, "Sender is not royalty fee updater"); royalty = _royalty; emit TldRoyaltyChanged(_msgSender(), _royalty); } /// @notice This changes royalty fee receiver address. Flexi-specific function. function changeRoyaltyFeeReceiver(address _newReceiver) external { require(_msgSender() == royaltyFeeReceiver, "Sender is not royalty fee receiver"); royaltyFeeReceiver = _newReceiver; } /// @notice This changes royalty fee updater address. Flexi-specific function. function changeRoyaltyFeeUpdater(address _newUpdater) external { require(_msgSender() == royaltyFeeUpdater, "Sender is not royalty fee updater"); royaltyFeeUpdater = _newUpdater; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_tldOwner","type":"address"},{"internalType":"uint256","name":"_domainPrice","type":"uint256"},{"internalType":"bool","name":"_buyingEnabled","type":"bool"},{"internalType":"uint256","name":"_royalty","type":"uint256"},{"internalType":"address","name":"_factoryAddress","type":"address"},{"internalType":"address","name":"_metadataAddress","type":"address"}],"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":"user","type":"address"}],"name":"DataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"string","name":"defaultDomain","type":"string"}],"name":"DefaultDomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"string","name":"fullDomainName","type":"string"}],"name":"DomainBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"domainBuyingToggle","type":"bool"}],"name":"DomainBuyingToggle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"string","name":"fullDomainName","type":"string"}],"name":"DomainCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"MintingDisabledForever","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"referralFee","type":"uint256"}],"name":"ReferralFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tldPrice","type":"uint256"}],"name":"TldPriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tldRoyalty","type":"uint256"}],"name":"TldRoyaltyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_domainName","type":"string"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buyingDisabledForever","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_metadataAddress","type":"address"}],"name":"changeMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"changeMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxLength","type":"uint256"}],"name":"changeNameMaxLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"changePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_referral","type":"uint256"}],"name":"changeReferralFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_royalty","type":"uint256"}],"name":"changeRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newReceiver","type":"address"}],"name":"changeRoyaltyFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newUpdater","type":"address"}],"name":"changeRoyaltyFeeUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"defaultNames","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableBuyingForever","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"domainIdsNames","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"domains","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"holder","type":"address"},{"internalType":"string","name":"data","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_domainName","type":"string"},{"internalType":"string","name":"_data","type":"string"}],"name":"editData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_domainName","type":"string"}],"name":"editDefaultDomain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factoryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freezeMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_domainName","type":"string"}],"name":"getDomainData","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_domainName","type":"string"}],"name":"getDomainHolder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"idCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_domainName","type":"string"},{"internalType":"address","name":"_domainHolder","type":"address"},{"internalType":"address","name":"_referrer","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nameMaxLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyFeeReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyFeeUpdater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleBuyingDomains","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a0604052600b805462ffffff60a01b191690556001600d556103e8601055608c6011553480156200003057600080fd5b506040516200452438038062004524833981016040819052620000539162000507565b8751889088906200006c9060009060208501906200036d565b508051620000829060019060208401906200036d565b5050506200009f620000996200024260201b60201c565b62000246565b6001600755600e859055600b805460ff60a01b1916600160a01b86151502179055600f839055600880546001600160a01b0319166001600160a01b0383811691909117909155606083901b6001600160601b03191660805260408051638da5cb5b60e01b815290518492831691638da5cb5b916004808301926020929190829003018186803b1580156200013257600080fd5b505afa15801562000147573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016d9190620004e3565b600a60006101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015620001cd57600080fd5b505afa158015620001e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002089190620004e3565b600b80546001600160a01b0319166001600160a01b0392909216919091179055620002338762000298565b50505050505050505062000625565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6006546001600160a01b03163314620002f85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6001600160a01b0381166200035f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620002ef565b6200036a8162000246565b50565b8280546200037b90620005d2565b90600052602060002090601f0160209004810192826200039f5760008555620003ea565b82601f10620003ba57805160ff1916838001178555620003ea565b82800160010185558215620003ea579182015b82811115620003ea578251825591602001919060010190620003cd565b50620003f8929150620003fc565b5090565b5b80821115620003f85760008155600101620003fd565b80516001600160a01b03811681146200042b57600080fd5b919050565b600082601f83011262000441578081fd5b81516001600160401b03808211156200045e576200045e6200060f565b604051601f8301601f19908116603f011681019082821181831017156200048957620004896200060f565b81604052838152602092508683858801011115620004a5578485fd5b8491505b83821015620004c85785820183015181830184015290820190620004a9565b83821115620004d957848385830101525b9695505050505050565b600060208284031215620004f5578081fd5b620005008262000413565b9392505050565b600080600080600080600080610100898b03121562000524578384fd5b88516001600160401b03808211156200053b578586fd5b620005498c838d0162000430565b995060208b01519150808211156200055f578586fd5b506200056e8b828c0162000430565b9750506200057f60408a0162000413565b955060608901519450608089015180151581146200059b578485fd5b60a08a01519094509250620005b360c08a0162000413565b9150620005c360e08a0162000413565b90509295985092959890939650565b600181811c90821680620005e757607f821691505b602082108114156200060957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b60805160601c613ee062000644600039600061066d0152613ee06000f3fe6080604052600436106102c95760003560e01c80638da5cb5b11610175578063bfcdd7c3116100dc578063dafa1d2d11610095578063e985e9c51161006f578063e985e9c51461087b578063eb08ab28146108c4578063f2fde38b146108da578063fb3cc6c2146108fa57600080fd5b8063dafa1d2d14610826578063db6bf92014610846578063dbd843b51461086657600080fd5b8063bfcdd7c314610770578063c1e2515114610790578063c87b56dd146107b0578063d111515d146107d0578063d2b525d3146107e5578063d85451ff1461080557600080fd5b8063a035b1fe1161012e578063a035b1fe146106c5578063a22cb465146106db578063a2b40d19146106fb578063b88d4fde1461071b578063ba833c4b1461073b578063bf70e90d1461075b57600080fd5b80638da5cb5b146106075780638ed2fe911461062557806395d89b4114610646578063966dae0e1461065b5780639f0346911461068f5780639fbb8e86146106a557600080fd5b80633a516d17116102345780636eb3500d116101ed57806374305d09116101c757806374305d091461059457806378a6743b146105b45780637afdfb4f146105d45780637e6d945e146105f457600080fd5b80636eb3500d1461053f57806370a082311461055f578063715018a61461057f57600080fd5b80633a516d171461047f57806342842e0e1461049f5780634c6dcb7f146104bf5780635dedf3b5146104df57806362ac7a84146104ff5780636352211e1461051f57600080fd5b806318160ddd1161028657806318160ddd146103c35780631fd21214146103d957806323b872dd146103f9578063264492351461041957806329ee566c146104495780632c4d4d181461045f57600080fd5b806301ffc9a7146102ce57806306fdde03146103035780630754617214610325578063081812fc1461035d578063095ea7b31461037d5780631441a5a91461039f575b600080fd5b3480156102da57600080fd5b506102ee6102e936600461365e565b61091b565b60405190151581526020015b60405180910390f35b34801561030f57600080fd5b5061031861096d565b6040516102fa9190613972565b34801561033157600080fd5b50600954610345906001600160a01b031681565b6040516001600160a01b0390911681526020016102fa565b34801561036957600080fd5b50610345610378366004613841565b6109ff565b34801561038957600080fd5b5061039d610398366004613635565b610a99565b005b3480156103ab57600080fd5b506103b560105481565b6040519081526020016102fa565b3480156103cf57600080fd5b506103b5600c5481565b3480156103e557600080fd5b50600a54610345906001600160a01b031681565b34801561040557600080fd5b5061039d610414366004613547565b610baf565b34801561042557600080fd5b5061043961043436600461373f565b610be0565b6040516102fa9493929190613985565b34801561045557600080fd5b506103b5600f5481565b34801561046b57600080fd5b5061039d61047a3660046134fb565b610d31565b34801561048b57600080fd5b5061039d61049a3660046134fb565b610d7d565b3480156104ab57600080fd5b5061039d6104ba366004613547565b610e32565b3480156104cb57600080fd5b5061039d6104da3660046134fb565b610e4d565b3480156104eb57600080fd5b5061039d6104fa366004613841565b610ea2565b34801561050b57600080fd5b5061031861051a3660046134fb565b610ed1565b34801561052b57600080fd5b5061034561053a366004613841565b610f6b565b34801561054b57600080fd5b50600854610345906001600160a01b031681565b34801561056b57600080fd5b506103b561057a3660046134fb565b610fe2565b34801561058b57600080fd5b5061039d611069565b3480156105a057600080fd5b5061039d6105af3660046134fb565b61109f565b3480156105c057600080fd5b5061039d6105cf366004613841565b61112f565b3480156105e057600080fd5b506103186105ef366004613696565b6111f4565b6103b56106023660046137e5565b6112e6565b34801561061357600080fd5b506006546001600160a01b0316610345565b34801561063157600080fd5b50600b546102ee90600160a01b900460ff1681565b34801561065257600080fd5b5061031861149d565b34801561066757600080fd5b506103457f000000000000000000000000000000000000000000000000000000000000000081565b34801561069b57600080fd5b506103b560115481565b3480156106b157600080fd5b50600b54610345906001600160a01b031681565b3480156106d157600080fd5b506103b5600e5481565b3480156106e757600080fd5b5061039d6106f63660046135fb565b6114ac565b34801561070757600080fd5b5061039d610716366004613841565b6114bb565b34801561072757600080fd5b5061039d610736366004613582565b61151c565b34801561074757600080fd5b5061039d6107563660046136d6565b611554565b34801561076757600080fd5b5061039d61168c565b34801561077c57600080fd5b5061034561078b366004613696565b611719565b34801561079c57600080fd5b5061039d6107ab366004613841565b61178d565b3480156107bc57600080fd5b506103186107cb366004613841565b61183d565b3480156107dc57600080fd5b5061039d6118fb565b3480156107f157600080fd5b50610318610800366004613841565b61193a565b34801561081157600080fd5b50600b546102ee90600160a81b900460ff1681565b34801561083257600080fd5b5061039d610841366004613696565b611953565b34801561085257600080fd5b5061039d610861366004613696565b611b46565b34801561087257600080fd5b5061039d611c43565b34801561088757600080fd5b506102ee610896366004613515565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156108d057600080fd5b506103b5600d5481565b3480156108e657600080fd5b5061039d6108f53660046134fb565b611cc5565b34801561090657600080fd5b50600b546102ee90600160b01b900460ff1681565b60006001600160e01b031982166380ac58cd60e01b148061094c57506001600160e01b03198216635b5e139f60e01b145b8061096757506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461097c90613e12565b80601f01602080910402602001604051908101604052809291908181526020018280546109a890613e12565b80156109f55780601f106109ca576101008083540402835291602001916109f5565b820191906000526020600020905b8154815290600101906020018083116109d857829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610a7d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610aa482610f6b565b9050806001600160a01b0316836001600160a01b03161415610b125760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610a74565b336001600160a01b0382161480610b2e5750610b2e8133610896565b610ba05760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610a74565b610baa8383611d60565b505050565b610bb93382611dce565b610bd55760405162461bcd60e51b8152600401610a7490613b26565b610baa838383611ec5565b8051602081830181018051601282529282019190930120915280548190610c0690613e12565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3290613e12565b8015610c7f5780601f10610c5457610100808354040283529160200191610c7f565b820191906000526020600020905b815481529060010190602001808311610c6257829003601f168201915b5050505060018301546002840154600385018054949592946001600160a01b03909216935090610cae90613e12565b80601f0160208091040260200160405190810160405280929190818152602001828054610cda90613e12565b8015610d275780601f10610cfc57610100808354040283529160200191610d27565b820191906000526020600020905b815481529060010190602001808311610d0a57829003601f168201915b5050505050905084565b6006546001600160a01b03163314610d5b5760405162461bcd60e51b8152600401610a7490613af1565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b03163314610da75760405162461bcd60e51b8152600401610a7490613af1565b600b54600160b01b900460ff1615610e105760405162461bcd60e51b815260206004820152602660248201527f43616e6e6f74206368616e6765206d65746164617461206164647265737320616044820152656e796d6f726560d01b6064820152608401610a74565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b610baa8383836040518060200160405280600081525061151c565b600a546001600160a01b0316336001600160a01b031614610e805760405162461bcd60e51b8152600401610a7490613a5e565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b03163314610ecc5760405162461bcd60e51b8152600401610a7490613af1565b601155565b60146020526000908152604090208054610eea90613e12565b80601f0160208091040260200160405190810160405280929190818152602001828054610f1690613e12565b8015610f635780601f10610f3857610100808354040283529160200191610f63565b820191906000526020600020905b815481529060010190602001808311610f4657829003601f168201915b505050505081565b6000818152600260205260408120546001600160a01b0316806109675760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610a74565b60006001600160a01b03821661104d5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610a74565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b031633146110935760405162461bcd60e51b8152600401610a7490613af1565b61109d6000612070565b565b600b546001600160a01b0316336001600160a01b03161461110d5760405162461bcd60e51b815260206004820152602260248201527f53656e646572206973206e6f7420726f79616c7479206665652072656365697660448201526132b960f11b6064820152608401610a74565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b031633146111595760405162461bcd60e51b8152600401610a7490613af1565b61138881106111b65760405162461bcd60e51b8152602060048201526024808201527f526566657272616c206665652063616e6e6f7420626520353025206f7220686960448201526333b432b960e11b6064820152608401610a74565b601081905560405181815233907f38d0cf7a8174d3978a2d52052d658cfb52bae5c6ffdad178bf1052ba56ea122e906020015b60405180910390a250565b6060601261123784848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120c292505050565b60405161124491906138f4565b9081526020016040518091039020600301805461126090613e12565b80601f016020809104026020016040519081016040528092919081815260200182805461128c90613e12565b80156112d95780601f106112ae576101008083540402835291602001916112d9565b820191906000526020600020905b8154815290600101906020018083116112bc57829003601f168201915b5050505050905092915050565b60006002600754141561133b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a74565b6002600755600b54600160a81b900460ff161561139a5760405162461bcd60e51b815260206004820152601f60248201527f446f6d61696e206d696e74696e672064697361626c656420666f7265766572006044820152606401610a74565b600b54600160a01b900460ff16806113bc57506006546001600160a01b031633145b806113da57506009546001600160a01b0316336001600160a01b0316145b6114265760405162461bcd60e51b815260206004820152601760248201527f427579696e6720646f6d61696e732064697361626c65640000000000000000006044820152606401610a74565b600e5434101561146c5760405162461bcd60e51b815260206004820152601160248201527056616c75652062656c6f7720707269636560781b6044820152606401610a74565b6114763483612158565b6114908484604051806020016040528060008152506123f1565b6001600755949350505050565b60606001805461097c90613e12565b6114b7338383612859565b5050565b6006546001600160a01b031633146114e55760405162461bcd60e51b8152600401610a7490613af1565b600e81905560405181815233907fee635c8a0d26ec216072a8c63e35b6ae1a6c900a63c37c014e4ebaac51861041906020016111e9565b6115263383611dce565b6115425760405162461bcd60e51b8152600401610a7490613b26565b61154e84848484612928565b50505050565b600061159585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120c292505050565b9050336001600160a01b03166012826040516115b191906138f4565b908152604051908190036020019020600201546001600160a01b0316146116295760405162461bcd60e51b815260206004820152602660248201527f4f6e6c7920646f6d61696e20686f6c6465722063616e2065646974207468656960448201526572206461746160d01b6064820152608401610a74565b828260128360405161163b91906138f4565b90815260200160405180910390206003019190611659929190613276565b5060405133907f5f5a32e7aa0e6d5ba247a155a472ba8f212ee1885baaf457683f3f5dae89480190600090a25050505050565b6006546001600160a01b031633146116b65760405162461bcd60e51b8152600401610a7490613af1565b600b805460ff600160a01b808304821615810260ff60a01b199093169290921792839055604051919092049091161515815233907f8e6cbfe6ffa62410f48c7f382a4560f2b634197f39f7ba9b666914af6674cfdb9060200160405180910390a2565b6000601261175c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120c292505050565b60405161176991906138f4565b908152604051908190036020019020600201546001600160a01b0316905092915050565b6113888111156117d35760405162461bcd60e51b815260206004820152601160248201527043616e6e6f74206578636565642035302560781b6044820152606401610a74565b600a546001600160a01b0316336001600160a01b0316146118065760405162461bcd60e51b8152600401610a7490613a5e565b600f81905560405181815233907ff76f683b30b41f9eb23902413792df5ff4569a8a274170d9e1b9a16e53558dec906020016111e9565b6008546000828152601360205260409081902090516060926001600160a01b0316916348189f129160129161187191613885565b90815260405190819003602001902061188861096d565b856040518463ffffffff1660e01b81526004016118a7939291906139c0565b60006040518083038186803b1580156118bf57600080fd5b505afa1580156118d3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109679190810190613772565b6006546001600160a01b031633146119255760405162461bcd60e51b8152600401610a7490613af1565b600b805460ff60b01b1916600160b01b179055565b60136020526000908152604090208054610eea90613e12565b600061199483838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120c292505050565b9050336001600160a01b03166012826040516119b091906138f4565b908152604051908190036020019020600201546001600160a01b0316146119e95760405162461bcd60e51b8152600401610a7490613b77565b60006012826040516119fb91906138f4565b9081526020016040518091039020600101549050601360008281526020019081526020016000206000611a2e91906132f6565b601282604051611a3e91906138f4565b9081526040519081900360200190206000611a5982826132f6565b6000600183018190556002830180546001600160a01b0319169055611a829060038401906132f6565b50508151602083012060146000336001600160a01b03166001600160a01b03168152602001908152602001600020604051611abd9190613885565b60405180910390201415611ae357336000908152601460205260408120611ae3916132f6565b611aec8161295b565b600c60008154611afb90613dfb565b90915550336001600160a01b03167fa37475cf96c0b9779814af0b62cf67583091c685221d6a2c12369240539cb9ef83604051611b389190613972565b60405180910390a250505050565b6000611b8783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506120c292505050565b9050336001600160a01b0316601282604051611ba391906138f4565b908152604051908190036020019020600201546001600160a01b031614611bdc5760405162461bcd60e51b8152600401610a7490613b77565b3360009081526014602090815260409091208251611bfc92840190613330565b50336001600160a01b03167f068caa4b2fe151c4db5ef003b9da9f85e1f84c0fa8eaf77f66a095b19998b98882604051611c369190613972565b60405180910390a2505050565b6006546001600160a01b03163314611c6d5760405162461bcd60e51b8152600401610a7490613af1565b600b805460ff60a81b1916600160a81b1790557f6d74cc13fa7ed2a0177961820c3be5913f7b4cf15397d50b80357e80ec4ea78a611ca83390565b6040516001600160a01b03909116815260200160405180910390a1565b6006546001600160a01b03163314611cef5760405162461bcd60e51b8152600401610a7490613af1565b6001600160a01b038116611d545760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a74565b611d5d81612070565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611d9582610f6b565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b0316611e475760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610a74565b6000611e5283610f6b565b9050806001600160a01b0316846001600160a01b03161480611e8d5750836001600160a01b0316611e82846109ff565b6001600160a01b0316145b80611ebd57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611ed882610f6b565b6001600160a01b031614611f405760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610a74565b6001600160a01b038216611fa25760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610a74565b611fad838383612a02565b611fb8600082611d60565b6001600160a01b0383166000908152600360205260408120805460019290611fe1908490613db8565b90915550506001600160a01b038216600090815260036020526040812080546001929061200f908490613c12565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60608160005b8151811015612151576121088282815181106120f457634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916612c1c565b82828151811061212857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053508061214981613e4d565b9150506120c8565b5092915050565b6000600f5411801561216d5750611388600f54105b1561224157600b54600f546000916001600160a01b031690612710906121939086613d5a565b61219d9190613c4f565b604051600081818185875af1925050503d80600081146121d9576040519150601f19603f3d011682016040523d82523d6000602084013e6121de565b606091505b505090508061223f5760405162461bcd60e51b815260206004820152602760248201527f4661696c656420746f2073656e6420726f79616c747920746f20666163746f726044820152663c9037bbb732b960c91b6064820152608401610a74565b505b6001600160a01b0381161580159061225b57506000601054115b801561226a5750611388601054105b1561232a576000816001600160a01b03166127106010548561228c9190613d5a565b6122969190613c4f565b604051600081818185875af1925050503d80600081146122d2576040519150601f19603f3d011682016040523d82523d6000602084013e6122d7565b606091505b50509050806123285760405162461bcd60e51b815260206004820152601b60248201527f4661696c656420746f2073656e6420726566657272616c2066656500000000006044820152606401610a74565b505b600061233e6006546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114612388576040519150601f19603f3d011682016040523d82523d6000602084013e61238d565b606091505b5050905080610baa5760405162461bcd60e51b815260206004820152602a60248201527f4661696c656420746f2073656e6420646f6d61696e207061796d656e7420746f604482015269102a26221037bbb732b960b11b6064820152608401610a74565b6000806123fd856120c2565b9050600061241261240d83612c6b565b612c98565b116124535760405162461bcd60e51b8152602060048201526011602482015270446f6d61696e206e616d6520656d70747960781b6044820152606401610a74565b6011548151106124a55760405162461bcd60e51b815260206004820152601760248201527f446f6d61696e206e616d6520697320746f6f206c6f6e670000000000000000006044820152606401610a74565b6124d86124b182612c6b565b6124d3604051806040016040528060018152602001601760f91b815250612c6b565b612d71565b156125315760405162461bcd60e51b815260206004820152602360248201527f54686572652073686f756c64206265206e6f20646f747320696e20746865206e604482015262616d6560e81b6064820152608401610a74565b61255f61253d82612c6b565b6124d3604051806040016040528060018152602001600160fd1b815250612c6b565b156125ba5760405162461bcd60e51b815260206004820152602560248201527f54686572652073686f756c64206265206e6f2073706163657320696e20746865604482015264206e616d6560d81b6064820152608401610a74565b60006001600160a01b03166012826040516125d591906138f4565b908152604051908190036020019020600201546001600160a01b03161461264a5760405162461bcd60e51b8152602060048201526024808201527f446f6d61696e20776974682074686973206e616d6520616c72656164792065786044820152636973747360e01b6064820152608401610a74565b61265684600d54612e0b565b61268a6040518060800160405280606081526020016000815260200160006001600160a01b03168152602001606081525090565b818152600d5460208201526001600160a01b038516604080830191909152606082018590525181906012906126c09085906138f4565b908152602001604051809103902060008201518160000190805190602001906126ea929190613330565b50602082810151600183015560408301516002830180546001600160a01b0319166001600160a01b03909216919091179055606083015180516127339260038501920190613330565b5050600d546000908152601360209081526040909120845161275a93509091850190613330565b506001600160a01b0385166000908152601460205260409020805461277e90613e12565b151590506127b1576001600160a01b038516600090815260146020908152604090912083516127af92850190613330565b505b6001600160a01b038516337f6a48f46f419774a1b2d37bbb2e1214ca73c6d3367d4e9ae39c08a9cf99bdd19b846127e661096d565b6040516020016127f7929190613910565b60408051601f198184030181529082905261281191613972565b60405180910390a3600d6000815461282890613e4d565b90915550600c805460009061283c90613e4d565b90915550600d5461284f90600190613db8565b9695505050505050565b816001600160a01b0316836001600160a01b031614156128bb5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610a74565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612933848484611ec5565b61293f84848484612f59565b61154e5760405162461bcd60e51b8152600401610a7490613a9f565b600061296682610f6b565b905061297481600084612a02565b61297f600083611d60565b6001600160a01b03811660009081526003602052604081208054600192906129a8908490613db8565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6001600160a01b03831615610baa5781601260136000848152602001908152602001600020604051612a349190613885565b908152604080516020928190038301902060020180546001600160a01b0319166001600160a01b0394851617905591841660009081526014909152208054612a7b90613e12565b1590508015612a9257506001600160a01b03821615155b15612b0457600081815260136020526040908190209051601291612ab591613885565b908152602001604051809103902060000160146000846001600160a01b03166001600160a01b03168152602001908152602001600020908054612af790613e12565b612b029291906133a4565b505b612bf6612bc9601260136000858152602001908152602001600020604051612b2c9190613885565b9081526040519081900360200190208054612b4690613e12565b80601f0160208091040260200160405190810160405280929190818152602001828054612b7290613e12565b8015612bbf5780601f10612b9457610100808354040283529160200191612bbf565b820191906000526020600020905b815481529060010190602001808311612ba257829003601f168201915b5050505050612c6b565b6001600160a01b03851660009081526014602052604090208054612bf19190612b4690613e12565b613066565b15610baa576001600160a01b0383166000908152601460205260408120610baa916132f6565b6000604160f81b6001600160f81b0319831610801590612c4a5750602d60f91b6001600160f81b0319831611155b15612c6757612c5e60f883901c6020613c2a565b60f81b92915050565b5090565b60408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b600080601f8360200151612cac9190613db8565b8351909150600090612cbe9083613c12565b9050600092505b80821015612d6a57815160ff166080811015612ced57612ce6600184613c12565b9250612d57565b60e08160ff161015612d0457612ce6600284613c12565b60f08160ff161015612d1b57612ce6600384613c12565b60f88160ff161015612d3257612ce6600484613c12565b60fc8160ff161015612d4957612ce6600584613c12565b612d54600684613c12565b92505b5082612d6281613e4d565b935050612cc5565b5050919050565b6000808260000151612d95856000015186602001518660000151876020015161307a565b612d9f9190613c12565b90505b83516020850151612db39190613c12565b81116121515781612dc381613e4d565b9250508260000151612dfa856020015183612dde9190613db8565b8651612dea9190613db8565b838660000151876020015161307a565b612e049190613c12565b9050612da2565b6001600160a01b038216612e615760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610a74565b6000818152600260205260409020546001600160a01b031615612ec65760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610a74565b612ed260008383612a02565b6001600160a01b0382166000908152600360205260408120805460019290612efb908490613c12565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b1561305b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612f9d90339089908890889060040161393f565b602060405180830381600087803b158015612fb757600080fd5b505af1925050508015612fe7575060408051601f3d908101601f19168201909252612fe49181019061367a565b60015b613041573d808015613015576040519150601f19603f3d011682016040523d82523d6000602084013e61301a565b606091505b5080516130395760405162461bcd60e51b8152600401610a7490613a9f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611ebd565b506001949350505050565b6000613072838361319b565b159392505050565b60008381868511613186576020851161313457600085156130c65760016130a2876020613db8565b6130ad906008613d5a565b6130b8906002613cb2565b6130c29190613db8565b1990505b845181166000876130d78b8b613c12565b6130e19190613db8565b855190915083165b8281146131265781861061310e576131018b8b613c12565b9650505050505050611ebd565b8561311881613e4d565b9650508386511690506130e9565b859650505050505050611ebd565b508383206000905b6131468689613db8565b821161318457858320818114156131635783945050505050611ebd565b61316e600185613c12565b935050818061317c90613e4d565b92505061313c565b505b6131908787613c12565b979650505050505050565b81518151600091908111156131ae575081515b6020808501519084015160005b838110156132675782518251808214613237576000196020871015613216576001846131e8896020613db8565b6131f29190613c12565b6131fd906008613d5a565b613208906002613cb2565b6132129190613db8565b1990505b81811683821681810391146132345797506109679650505050505050565b50505b613242602086613c12565b945061324f602085613c12565b935050506020816132609190613c12565b90506131bb565b508451865161284f9190613d79565b82805461328290613e12565b90600052602060002090601f0160209004810192826132a457600085556132ea565b82601f106132bd5782800160ff198235161785556132ea565b828001600101855582156132ea579182015b828111156132ea5782358255916020019190600101906132cf565b50612c6792915061341f565b50805461330290613e12565b6000825580601f10613312575050565b601f016020900490600052602060002090810190611d5d919061341f565b82805461333c90613e12565b90600052602060002090601f01602090048101928261335e57600085556132ea565b82601f1061337757805160ff19168380011785556132ea565b828001600101855582156132ea579182015b828111156132ea578251825591602001919060010190613389565b8280546133b090613e12565b90600052602060002090601f0160209004810192826133d257600085556132ea565b82601f106133e357805485556132ea565b828001600101855582156132ea57600052602060002091601f016020900482015b828111156132ea578254825591600101919060010190613404565b5b80821115612c675760008155600101613420565b600061344761344284613bea565b613bb9565b905082815283838301111561345b57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461348957600080fd5b919050565b60008083601f84011261349f578182fd5b50813567ffffffffffffffff8111156134b6578182fd5b6020830191508360208285010111156134ce57600080fd5b9250929050565b600082601f8301126134e5578081fd5b6134f483833560208501613434565b9392505050565b60006020828403121561350c578081fd5b6134f482613472565b60008060408385031215613527578081fd5b61353083613472565b915061353e60208401613472565b90509250929050565b60008060006060848603121561355b578081fd5b61356484613472565b925061357260208501613472565b9150604084013590509250925092565b60008060008060808587031215613597578081fd5b6135a085613472565b93506135ae60208601613472565b925060408501359150606085013567ffffffffffffffff8111156135d0578182fd5b8501601f810187136135e0578182fd5b6135ef87823560208401613434565b91505092959194509250565b6000806040838503121561360d578182fd5b61361683613472565b91506020830135801515811461362a578182fd5b809150509250929050565b60008060408385031215613647578182fd5b61365083613472565b946020939093013593505050565b60006020828403121561366f578081fd5b81356134f481613e94565b60006020828403121561368b578081fd5b81516134f481613e94565b600080602083850312156136a8578182fd5b823567ffffffffffffffff8111156136be578283fd5b6136ca8582860161348e565b90969095509350505050565b600080600080604085870312156136eb578384fd5b843567ffffffffffffffff80821115613702578586fd5b61370e8883890161348e565b90965094506020870135915080821115613726578384fd5b506137338782880161348e565b95989497509550505050565b600060208284031215613750578081fd5b813567ffffffffffffffff811115613766578182fd5b611ebd848285016134d5565b600060208284031215613783578081fd5b815167ffffffffffffffff811115613799578182fd5b8201601f810184136137a9578182fd5b80516137b761344282613bea565b8181528560208385010111156137cb578384fd5b6137dc826020830160208601613dcf565b95945050505050565b6000806000606084860312156137f9578081fd5b833567ffffffffffffffff81111561380f578182fd5b61381b868287016134d5565b93505061382a60208501613472565b915061383860408501613472565b90509250925092565b600060208284031215613852578081fd5b5035919050565b60008151808452613871816020860160208601613dcf565b601f01601f19169290920160200192915050565b600080835461389381613e12565b600182811680156138ab57600181146138bc576138e8565b60ff198416875282870194506138e8565b8786526020808720875b858110156138df5781548a8201529084019082016138c6565b50505082870194505b50929695505050505050565b60008251613906818460208701613dcf565b9190910192915050565b60008351613922818460208801613dcf565b835190830190613936818360208801613dcf565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061284f90830184613859565b6020815260006134f46020830184613859565b6080815260006139986080830187613859565b602083018690526001600160a01b038516604084015282810360608401526131908185613859565b6060815260008085546139d281613e12565b80606086015260806001808416600081146139f45760018114613a0857613a36565b60ff1985168884015260a088019550613a36565b8a87526020808820885b86811015613a2d5781548b8201870152908401908201613a12565b8a018501975050505b50505050508281036020840152613a4d8186613859565b915050826040830152949350505050565b60208082526021908201527f53656e646572206973206e6f7420726f79616c747920666565207570646174656040820152603960f91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526022908201527f596f7520646f206e6f74206f776e207468652073656c656374656420646f6d6160408201526134b760f11b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715613be257613be2613e7e565b604052919050565b600067ffffffffffffffff821115613c0457613c04613e7e565b50601f01601f191660200190565b60008219821115613c2557613c25613e68565b500190565b600060ff821660ff84168060ff03821115613c4757613c47613e68565b019392505050565b600082613c6a57634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115613caa578160001904821115613c9057613c90613e68565b80851615613c9d57918102915b93841c9390800290613c74565b509250929050565b60006134f48383600082613cc857506001610967565b81613cd557506000610967565b8160018114613ceb5760028114613cf557613d11565b6001915050610967565b60ff841115613d0657613d06613e68565b50506001821b610967565b5060208310610133831016604e8410600b8410161715613d34575081810a610967565b613d3e8383613c6f565b8060001904821115613d5257613d52613e68565b029392505050565b6000816000190483118215151615613d7457613d74613e68565b500290565b60008083128015600160ff1b850184121615613d9757613d97613e68565b6001600160ff1b0384018313811615613db257613db2613e68565b50500390565b600082821015613dca57613dca613e68565b500390565b60005b83811015613dea578181015183820152602001613dd2565b8381111561154e5750506000910152565b600081613e0a57613e0a613e68565b506000190190565b600181811c90821680613e2657607f821691505b60208210811415613e4757634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613e6157613e61613e68565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114611d5d57600080fdfea26469706673582212203310dd47ca7d19bae3bd9b8a4b6f5e8a618c55eab4dedbf648a2bc5e5a3583ff64736f6c6343000804003300000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000b29050965a5ac70ab487aa47546cdcbc97dae45d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea2f99fe93e5d07f61334c5eb9c54c5d5c957a6a000000000000000000000000f51f7a532a2aadfe8e2320bf5ba8275503bb378900000000000000000000000000000000000000000000000000000000000000072e66616e746f6d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072e46414e544f4d00000000000000000000000000000000000000000000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000b29050965a5ac70ab487aa47546cdcbc97dae45d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea2f99fe93e5d07f61334c5eb9c54c5d5c957a6a000000000000000000000000f51f7a532a2aadfe8e2320bf5ba8275503bb378900000000000000000000000000000000000000000000000000000000000000072e66616e746f6d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072e46414e544f4d00000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): .fantom
Arg [1] : _symbol (string): .FANTOM
Arg [2] : _tldOwner (address): 0xb29050965a5ac70ab487aa47546cdcbc97dae45d
Arg [3] : _domainPrice (uint256): 0
Arg [4] : _buyingEnabled (bool): False
Arg [5] : _royalty (uint256): 0
Arg [6] : _factoryAddress (address): 0xea2f99fe93e5d07f61334c5eb9c54c5d5c957a6a
Arg [7] : _metadataAddress (address): 0xf51f7a532a2aadfe8e2320bf5ba8275503bb3789
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 000000000000000000000000b29050965a5ac70ab487aa47546cdcbc97dae45d
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 000000000000000000000000ea2f99fe93e5d07f61334c5eb9c54c5d5c957a6a
Arg [7] : 000000000000000000000000f51f7a532a2aadfe8e2320bf5ba8275503bb3789
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [9] : 2e66616e746f6d00000000000000000000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [11] : 2e46414e544f4d00000000000000000000000000000000000000000000000000
Deployed ByteCode Sourcemap
67691:11469:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47719:305;;;;;;;;;;-1:-1:-1;47719:305:0;;;;;:::i;:::-;;:::i;:::-;;;10490:14:1;;10483:22;10465:41;;10453:2;10438:18;47719:305:0;;;;;;;;48664:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;67987:21::-;;;;;;;;;;-1:-1:-1;67987:21:0;;;;-1:-1:-1;;;;;67987:21:0;;;;;;-1:-1:-1;;;;;9788:32:1;;;9770:51;;9758:2;9743:18;67987:21:0;9725:102:1;50223:221:0;;;;;;;;;;-1:-1:-1;50223:221:0;;;;;:::i;:::-;;:::i;49746:411::-;;;;;;;;;;-1:-1:-1;49746:411:0;;;;;:::i;:::-;;:::i;:::-;;68701:39;;;;;;;;;;;;;;;;;;;25842:25:1;;;25830:2;25815:18;68701:39:0;25797:76:1;68478:26:0;;;;;;;;;;;;;;;;68084:32;;;;;;;;;;-1:-1:-1;68084:32:0;;;;-1:-1:-1;;;;;68084:32:0;;;50973:339;;;;;;;;;;-1:-1:-1;50973:339:0;;;;;:::i;:::-;;:::i;68903:50::-;;;;;;;;;;-1:-1:-1;68903:50:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;68605:22::-;;;;;;;;;;;;;;;;76712:87;;;;;;;;;;-1:-1:-1;76712:87:0;;;;;:::i;:::-;;:::i;76422:196::-;;;;;;;;;;-1:-1:-1;76422:196:0;;;;;:::i;:::-;;:::i;51383:185::-;;;;;;;;;;-1:-1:-1;51383:185:0;;;;;:::i;:::-;;:::i;78964:193::-;;;;;;;;;;-1:-1:-1;78964:193:0;;;;;:::i;:::-;;:::i;76868:116::-;;;;;;;;;;-1:-1:-1;76868:116:0;;;;;:::i;:::-;;:::i;69132:56::-;;;;;;;;;;-1:-1:-1;69132:56:0;;;;;:::i;:::-;;:::i;48358:239::-;;;;;;;;;;-1:-1:-1;48358:239:0;;;;;:::i;:::-;;:::i;67923:30::-;;;;;;;;;;-1:-1:-1;67923:30:0;;;;-1:-1:-1;;;;;67923:30:0;;;48088:208;;;;;;;;;;-1:-1:-1;48088:208:0;;;;;:::i;:::-;;:::i;61756:103::-;;;;;;;;;;;;;:::i;78677:199::-;;;;;;;;;;-1:-1:-1;78677:199:0;;;;;:::i;:::-;;:::i;77263:262::-;;;;;;;;;;-1:-1:-1;77263:262:0;;;;;:::i;:::-;;:::i;70166:183::-;;;;;;;;;;-1:-1:-1;70166:183:0;;;;;:::i;:::-;;:::i;72474:504::-;;;;;;:::i;:::-;;:::i;61105:87::-;;;;;;;;;;-1:-1:-1;61178:6:0;;-1:-1:-1;;;;;61178:6:0;61105:87;;68257:33;;;;;;;;;;-1:-1:-1;68257:33:0;;;;-1:-1:-1;;;68257:33:0;;;;;;48833:104;;;;;;;;;;;;;:::i;67848:39::-;;;;;;;;;;;;;;;68829:34;;;;;;;;;;;;;;;;68175:33;;;;;;;;;;-1:-1:-1;68175:33:0;;;;-1:-1:-1;;;;;68175:33:0;;;68555:29;;;;;;;;;;;;;;;;50516:155;;;;;;;;;;-1:-1:-1;50516:155:0;;;;;:::i;:::-;;:::i;77053:141::-;;;;;;;;;;-1:-1:-1;77053:141:0;;;;;:::i;:::-;;:::i;51639:328::-;;;;;;;;;;-1:-1:-1;51639:328:0;;;;;:::i;:::-;;:::i;71962:306::-;;;;;;;;;;-1:-1:-1;71962:306:0;;;;;:::i;:::-;;:::i;78063:152::-;;;;;;;;;;;;;:::i;70006:154::-;;;;;;;;;;-1:-1:-1;70006:154:0;;;;;:::i;:::-;;:::i;78315:273::-;;;;;;;;;;-1:-1:-1;78315:273:0;;;;;:::i;:::-;;:::i;70355:236::-;;;;;;;;;;-1:-1:-1;70355:236:0;;;;;:::i;:::-;;:::i;77884:110::-;;;;;;;;;;;;;:::i;69042:49::-;;;;;;;;;;-1:-1:-1;69042:49:0;;;;;:::i;:::-;;:::i;68321:41::-;;;;;;;;;;-1:-1:-1;68321:41:0;;;;-1:-1:-1;;;68321:41:0;;;;;;70650:639;;;;;;;;;;-1:-1:-1;70650:639:0;;;;;:::i;:::-;;:::i;71395:311::-;;;;;;;;;;-1:-1:-1;71395:311:0;;;;;:::i;:::-;;:::i;77619:171::-;;;;;;;;;;;;;:::i;50742:164::-;;;;;;;;;;-1:-1:-1;50742:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;50863:25:0;;;50839:4;50863:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;50742:164;68509:28;;;;;;;;;;;;;;;;62014:201;;;;;;;;;;-1:-1:-1;62014:201:0;;;;;:::i;:::-;;:::i;68402:34::-;;;;;;;;;;-1:-1:-1;68402:34:0;;;;-1:-1:-1;;;68402:34:0;;;;;;47719:305;47821:4;-1:-1:-1;;;;;;47858:40:0;;-1:-1:-1;;;47858:40:0;;:105;;-1:-1:-1;;;;;;;47915:48:0;;-1:-1:-1;;;47915:48:0;47858:105;:158;;;-1:-1:-1;;;;;;;;;;46410:40:0;;;47980:36;47838:178;47719:305;-1:-1:-1;;47719:305:0:o;48664:100::-;48718:13;48751:5;48744:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48664:100;:::o;50223:221::-;50299:7;53566:16;;;:7;:16;;;;;;-1:-1:-1;;;;;53566:16:0;50319:73;;;;-1:-1:-1;;;50319:73:0;;19645:2:1;50319:73:0;;;19627:21:1;19684:2;19664:18;;;19657:30;19723:34;19703:18;;;19696:62;-1:-1:-1;;;19774:18:1;;;19767:42;19826:19;;50319:73:0;;;;;;;;;-1:-1:-1;50412:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;50412:24:0;;50223:221::o;49746:411::-;49827:13;49843:23;49858:7;49843:14;:23::i;:::-;49827:39;;49891:5;-1:-1:-1;;;;;49885:11:0;:2;-1:-1:-1;;;;;49885:11:0;;;49877:57;;;;-1:-1:-1;;;49877:57:0;;21993:2:1;49877:57:0;;;21975:21:1;22032:2;22012:18;;;22005:30;22071:34;22051:18;;;22044:62;-1:-1:-1;;;22122:18:1;;;22115:31;22163:19;;49877:57:0;21965:223:1;49877:57:0;43430:10;-1:-1:-1;;;;;49969:21:0;;;;:62;;-1:-1:-1;49994:37:0;50011:5;43430:10;50742:164;:::i;49994:37::-;49947:168;;;;-1:-1:-1;;;49947:168:0;;16917:2:1;49947:168:0;;;16899:21:1;16956:2;16936:18;;;16929:30;16995:34;16975:18;;;16968:62;17066:26;17046:18;;;17039:54;17110:19;;49947:168:0;16889:246:1;49947:168:0;50128:21;50137:2;50141:7;50128:8;:21::i;:::-;49746:411;;;:::o;50973:339::-;51168:41;43430:10;51201:7;51168:18;:41::i;:::-;51160:103;;;;-1:-1:-1;;;51160:103:0;;;;;;;:::i;:::-;51276:28;51286:4;51292:2;51296:7;51276:9;:28::i;68903:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;68903:50:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68903:50:0;;;;-1:-1:-1;68903:50:0;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;76712:87::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;76777:6:::1;:16:::0;;-1:-1:-1;;;;;;76777:16:0::1;-1:-1:-1::0;;;;;76777:16:0;;;::::1;::::0;;;::::1;::::0;;76712:87::o;76422:196::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;76514:14:::1;::::0;-1:-1:-1;;;76514:14:0;::::1;;;76513:15;76505:66;;;::::0;-1:-1:-1;;;76505:66:0;;23219:2:1;76505:66:0::1;::::0;::::1;23201:21:1::0;23258:2;23238:18;;;23231:30;23297:34;23277:18;;;23270:62;-1:-1:-1;;;23348:18:1;;;23341:36;23394:19;;76505:66:0::1;23191:228:1::0;76505:66:0::1;76578:15;:34:::0;;-1:-1:-1;;;;;;76578:34:0::1;-1:-1:-1::0;;;;;76578:34:0;;;::::1;::::0;;;::::1;::::0;;76422:196::o;51383:185::-;51521:39;51538:4;51544:2;51548:7;51521:39;;;;;;;;;;;;:16;:39::i;78964:193::-;79058:17;;-1:-1:-1;;;;;79058:17:0;43430:10;-1:-1:-1;;;;;79042:33:0;;79034:79;;;;-1:-1:-1;;;79034:79:0;;;;;;;:::i;:::-;79120:17;:31;;-1:-1:-1;;;;;;79120:31:0;-1:-1:-1;;;;;79120:31:0;;;;;;;;;;78964:193::o;76868:116::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;76952:13:::1;:26:::0;76868:116::o;69132:56::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;48358:239::-;48430:7;48466:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48466:16:0;48501:19;48493:73;;;;-1:-1:-1;;;48493:73:0;;18109:2:1;48493:73:0;;;18091:21:1;18148:2;18128:18;;;18121:30;18187:34;18167:18;;;18160:62;-1:-1:-1;;;18238:18:1;;;18231:39;18287:19;;48493:73:0;18081:231:1;48088:208:0;48160:7;-1:-1:-1;;;;;48188:19:0;;48180:74;;;;-1:-1:-1;;;48180:74:0;;17698:2:1;48180:74:0;;;17680:21:1;17737:2;17717:18;;;17710:30;17776:34;17756:18;;;17749:62;-1:-1:-1;;;17827:18:1;;;17820:40;17877:19;;48180:74:0;17670:232:1;48180:74:0;-1:-1:-1;;;;;;48272:16:0;;;;;:9;:16;;;;;;;48088:208::o;61756:103::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;61821:30:::1;61848:1;61821:18;:30::i;:::-;61756:103::o:0;78677:199::-;78773:18;;-1:-1:-1;;;;;78773:18:0;43430:10;-1:-1:-1;;;;;78757:34:0;;78749:81;;;;-1:-1:-1;;;78749:81:0;;24029:2:1;78749:81:0;;;24011:21:1;24068:2;24048:18;;;24041:30;24107:34;24087:18;;;24080:62;-1:-1:-1;;;24158:18:1;;;24151:32;24200:19;;78749:81:0;24001:224:1;78749:81:0;78837:18;:33;;-1:-1:-1;;;;;;78837:33:0;-1:-1:-1;;;;;78837:33:0;;;;;;;;;;78677:199::o;77263:262::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;77364:4:::1;77352:9;:16;77344:65;;;::::0;-1:-1:-1;;;77344:65:0;;14238:2:1;77344:65:0::1;::::0;::::1;14220:21:1::0;14277:2;14257:18;;;14250:30;14316:34;14296:18;;;14289:62;-1:-1:-1;;;14367:18:1;;;14360:34;14411:19;;77344:65:0::1;14210:226:1::0;77344:65:0::1;77416:8;:20:::0;;;77476:43:::1;::::0;25842:25:1;;;43430:10:0;;77476:43:::1;::::0;25830:2:1;25815:18;77476:43:0::1;;;;;;;;77263:262:::0;:::o;70166:183::-;70247:13;70276:7;70284:26;70298:11;;70284:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70284:13:0;;-1:-1:-1;;;70284:26:0:i;:::-;70276:35;;;;;;:::i;:::-;;;;;;;;;;;;;:40;;70269:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70166:183;;;;:::o;72474:504::-;72624:7;64251:1;64849:7;;:19;;64841:63;;;;-1:-1:-1;;;64841:63:0;;25192:2:1;64841:63:0;;;25174:21:1;25231:2;25211:18;;;25204:30;25270:33;25250:18;;;25243:61;25321:18;;64841:63:0;25164:181:1;64841:63:0;64251:1;64982:7;:18;72649:21:::1;::::0;-1:-1:-1;;;72649:21:0;::::1;;;72648:22;72640:66;;;::::0;-1:-1:-1;;;72640:66:0;;18519:2:1;72640:66:0::1;::::0;::::1;18501:21:1::0;18558:2;18538:18;;;18531:30;18597:33;18577:18;;;18570:61;18648:18;;72640:66:0::1;18491:181:1::0;72640:66:0::1;72721:13;::::0;-1:-1:-1;;;72721:13:0;::::1;;;::::0;:40:::1;;-1:-1:-1::0;61178:6:0;;-1:-1:-1;;;;;61178:6:0;43430:10;72738:23:::1;72721:40;:66;;;-1:-1:-1::0;72781:6:0::1;::::0;-1:-1:-1;;;;;72781:6:0::1;43430:10:::0;-1:-1:-1;;;;;72765:22:0::1;;72721:66;72713:102;;;::::0;-1:-1:-1;;;72713:102:0;;24432:2:1;72713:102:0::1;::::0;::::1;24414:21:1::0;24471:2;24451:18;;;24444:30;24510:25;24490:18;;;24483:53;24553:18;;72713:102:0::1;24404:173:1::0;72713:102:0::1;72843:5;;72830:9;:18;;72822:48;;;::::0;-1:-1:-1;;;72822:48:0;;21236:2:1;72822:48:0::1;::::0;::::1;21218:21:1::0;21275:2;21255:18;;;21248:30;-1:-1:-1;;;21294:18:1;;;21287:47;21351:18;;72822:48:0::1;21208:167:1::0;72822:48:0::1;72879:34;72892:9;72903;72879:12;:34::i;:::-;72929:43;72941:11;72954:13;72929:43;;;;;;;;;;;::::0;:11:::1;:43::i;:::-;64207:1:::0;65161:7;:22;72922:50;72474:504;-1:-1:-1;;;;72474:504:0:o;48833:104::-;48889:13;48922:7;48915:14;;;;;:::i;50516:155::-;50611:52;43430:10;50644:8;50654;50611:18;:52::i;:::-;50516:155;;:::o;77053:141::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;77125:5:::1;:14:::0;;;77151:37:::1;::::0;25842:25:1;;;43430:10:0;;77151:37:::1;::::0;25830:2:1;25815:18;77151:37:0::1;25797:76:1::0;51639:328:0;51814:41;43430:10;51847:7;51814:18;:41::i;:::-;51806:103;;;;-1:-1:-1;;;51806:103:0;;;;;;;:::i;:::-;51920:39;51934:4;51940:2;51944:7;51953:5;51920:13;:39::i;:::-;51639:328;;;;:::o;71962:306::-;72048:19;72070:26;72084:11;;72070:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72070:13:0;;-1:-1:-1;;;72070:26:0:i;:::-;72048:48;-1:-1:-1;43430:10:0;-1:-1:-1;;;;;72111:37:0;:7;72119:5;72111:14;;;;;;:::i;:::-;;;;;;;;;;;;;;:21;;;-1:-1:-1;;;;;72111:21:0;:37;72103:88;;;;-1:-1:-1;;;72103:88:0;;20829:2:1;72103:88:0;;;20811:21:1;20868:2;20848:18;;;20841:30;20907:34;20887:18;;;20880:62;-1:-1:-1;;;20958:18:1;;;20951:36;21004:19;;72103:88:0;20801:228:1;72103:88:0;72220:5;;72198:7;72206:5;72198:14;;;;;;:::i;:::-;;;;;;;;;;;;;:19;;:27;;;;;;;:::i;:::-;-1:-1:-1;72237:25:0;;43430:10;;72237:25;;;;;71962:306;;;;;:::o;78063:152::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;78137:13:::1;::::0;;::::1;-1:-1:-1::0;;;78137:13:0;;::::1;::::0;::::1;78136:14;78120:30:::0;::::1;-1:-1:-1::0;;;;78120:30:0;;::::1;::::0;;;::::1;::::0;;;;78162:47:::1;::::0;78195:13;;;::::1;::::0;;::::1;10490:14:1::0;10483:22;10465:41;;43430:10:0;;78162:47:::1;::::0;10453:2:1;10438:18;78162:47:0::1;;;;;;;78063:152::o:0;70006:154::-;70089:7;70112;70120:26;70134:11;;70120:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70120:13:0;;-1:-1:-1;;;70120:26:0:i;:::-;70112:35;;;;;;:::i;:::-;;;;;;;;;;;;;;:42;;;-1:-1:-1;;;;;70112:42:0;;-1:-1:-1;70006:154:0;;;;:::o;78315:273::-;78392:4;78380:8;:16;;78372:46;;;;-1:-1:-1;;;78372:46:0;;25552:2:1;78372:46:0;;;25534:21:1;25591:2;25571:18;;;25564:30;-1:-1:-1;;;25610:18:1;;;25603:47;25667:18;;78372:46:0;25524:167:1;78372:46:0;78449:17;;-1:-1:-1;;;;;78449:17:0;43430:10;-1:-1:-1;;;;;78433:33:0;;78425:79;;;;-1:-1:-1;;;78425:79:0;;;;;;;:::i;:::-;78511:7;:18;;;78541:41;;25842:25:1;;;43430:10:0;;78541:41;;25830:2:1;25815:18;78541:41:0;25797:76:1;70355:236:0;70469:15;;;70514:24;;;:14;:24;;;;;;;70506:33;;70421:13;;-1:-1:-1;;;;;70469:15:0;;70450:47;;70506:7;;:33;;;:::i;:::-;;;;;;;;;;;;;;70554:6;:4;:6::i;:::-;70570:8;70450:135;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70450:135:0;;;;;;;;;;;;:::i;77884:110::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;77936:14:::1;:21:::0;;-1:-1:-1;;;;77936:21:0::1;-1:-1:-1::0;;;77936:21:0::1;::::0;;77884:110::o;69042:49::-;;;;;;;;;;;;;;;;:::i;70650:639::-;70709:19;70731:26;70745:11;;70731:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70731:13:0;;-1:-1:-1;;;70731:26:0:i;:::-;70709:48;-1:-1:-1;43430:10:0;-1:-1:-1;;;;;70772:37:0;:7;70780:5;70772:14;;;;;;:::i;:::-;;;;;;;;;;;;;;:21;;;-1:-1:-1;;;;;70772:21:0;:37;70764:84;;;;-1:-1:-1;;;70764:84:0;;;;;;;:::i;:::-;70855:15;70873:7;70881:5;70873:14;;;;;;:::i;:::-;;;;;;;;;;;;;:22;;;70855:40;;70909:14;:23;70924:7;70909:23;;;;;;;;;;;;70902:30;;;;:::i;:::-;70986:7;70994:5;70986:14;;;;;;:::i;:::-;;;;;;;;;;;;;;;70979:21;70986:14;;70979:21;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;;70979:21:0;;;;;;;;;;:::i;:::-;-1:-1:-1;;71103:23:0;;;;;;71071:12;:26;43430:10;-1:-1:-1;;;;;71071:26:0;-1:-1:-1;;;;;71071:26:0;;;;;;;;;;;;71055:44;;;;;;:::i;:::-;;;;;;;;:71;71051:127;;;43430:10;71144:26;;;;:12;:26;;;;;71137:33;;;:::i;:::-;71186:14;71192:7;71186:5;:14::i;:::-;71227:11;;71225:13;;;;;:::i;:::-;;;;-1:-1:-1;43430:10:0;-1:-1:-1;;;;;71250:33:0;;71277:5;71250:33;;;;;;:::i;:::-;;;;;;;;70650:639;;;;:::o;71395:311::-;71467:19;71489:26;71503:11;;71489:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71489:13:0;;-1:-1:-1;;;71489:26:0:i;:::-;71467:48;-1:-1:-1;43430:10:0;-1:-1:-1;;;;;71530:37:0;:7;71538:5;71530:14;;;;;;:::i;:::-;;;;;;;;;;;;;;:21;;;-1:-1:-1;;;;;71530:21:0;:37;71522:84;;;;-1:-1:-1;;;71522:84:0;;;;;;;:::i;:::-;43430:10;71613:26;;;;:12;:26;;;;;;;;:34;;;;;;;;:::i;:::-;-1:-1:-1;43430:10:0;-1:-1:-1;;;;;71659:41:0;;71694:5;71659:41;;;;;;:::i;:::-;;;;;;;;71395:311;;;:::o;77619:171::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;77677:21:::1;:28:::0;;-1:-1:-1;;;;77677:28:0::1;-1:-1:-1::0;;;77677:28:0::1;::::0;;77748:36:::1;77771:12;43430:10:::0;;43350:98;77771:12:::1;77748:36;::::0;-1:-1:-1;;;;;9788:32:1;;;9770:51;;9758:2;9743:18;77748:36:0::1;;;;;;;77619:171::o:0;62014:201::-;61178:6;;-1:-1:-1;;;;;61178:6:0;43430:10;61325:23;61317:68;;;;-1:-1:-1;;;61317:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;62103:22:0;::::1;62095:73;;;::::0;-1:-1:-1;;;62095:73:0;;13474:2:1;62095:73:0::1;::::0;::::1;13456:21:1::0;13513:2;13493:18;;;13486:30;13552:34;13532:18;;;13525:62;-1:-1:-1;;;13603:18:1;;;13596:36;13649:19;;62095:73:0::1;13446:228:1::0;62095:73:0::1;62179:28;62198:8;62179:18;:28::i;:::-;62014:201:::0;:::o;57459:174::-;57534:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;57534:29:0;-1:-1:-1;;;;;57534:29:0;;;;;;;;:24;;57588:23;57534:24;57588:14;:23::i;:::-;-1:-1:-1;;;;;57579:46:0;;;;;;;;;;;57459:174;;:::o;53771:348::-;53864:4;53566:16;;;:7;:16;;;;;;-1:-1:-1;;;;;53566:16:0;53881:73;;;;-1:-1:-1;;;53881:73:0;;16152:2:1;53881:73:0;;;16134:21:1;16191:2;16171:18;;;16164:30;16230:34;16210:18;;;16203:62;-1:-1:-1;;;16281:18:1;;;16274:42;16333:19;;53881:73:0;16124:234:1;53881:73:0;53965:13;53981:23;53996:7;53981:14;:23::i;:::-;53965:39;;54034:5;-1:-1:-1;;;;;54023:16:0;:7;-1:-1:-1;;;;;54023:16:0;;:51;;;;54067:7;-1:-1:-1;;;;;54043:31:0;:20;54055:7;54043:11;:20::i;:::-;-1:-1:-1;;;;;54043:31:0;;54023:51;:87;;;-1:-1:-1;;;;;;50863:25:0;;;50839:4;50863:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;54078:32;54015:96;53771:348;-1:-1:-1;;;;53771:348:0:o;56763:578::-;56922:4;-1:-1:-1;;;;;56895:31:0;:23;56910:7;56895:14;:23::i;:::-;-1:-1:-1;;;;;56895:31:0;;56887:85;;;;-1:-1:-1;;;56887:85:0;;20419:2:1;56887:85:0;;;20401:21:1;20458:2;20438:18;;;20431:30;20497:34;20477:18;;;20470:62;-1:-1:-1;;;20548:18:1;;;20541:39;20597:19;;56887:85:0;20391:231:1;56887:85:0;-1:-1:-1;;;;;56991:16:0;;56983:65;;;;-1:-1:-1;;;56983:65:0;;15393:2:1;56983:65:0;;;15375:21:1;15432:2;15412:18;;;15405:30;15471:34;15451:18;;;15444:62;-1:-1:-1;;;15522:18:1;;;15515:34;15566:19;;56983:65:0;15365:226:1;56983:65:0;57061:39;57082:4;57088:2;57092:7;57061:20;:39::i;:::-;57165:29;57182:1;57186:7;57165:8;:29::i;:::-;-1:-1:-1;;;;;57207:15:0;;;;;;:9;:15;;;;;:20;;57226:1;;57207:15;:20;;57226:1;;57207:20;:::i;:::-;;;;-1:-1:-1;;;;;;;57238:13:0;;;;;;:9;:13;;;;;:18;;57255:1;;57238:13;:18;;57255:1;;57238:18;:::i;:::-;;;;-1:-1:-1;;57267:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;57267:21:0;-1:-1:-1;;;;;57267:21:0;;;;;;;;;57306:27;;57267:16;;57306:27;;;;;;;56763:578;;;:::o;62375:191::-;62468:6;;;-1:-1:-1;;;;;62485:17:0;;;-1:-1:-1;;;;;;62485:17:0;;;;;;;62518:40;;62468:6;;;62485:17;62468:6;;62518:40;;62449:16;;62518:40;62375:191;;:::o;32285:313::-;32371:13;32429:5;32397:23;32446:109;32467:10;:17;32463:1;:21;32446:109;;;32522:21;32529:10;32540:1;32529:13;;;;;;-1:-1:-1;;;32529:13:0;;;;;;;;;;;;;-1:-1:-1;;;;;;32529:13:0;32522:6;:21::i;:::-;32506:10;32517:1;32506:13;;;;;;-1:-1:-1;;;32506:13:0;;;;;;;;;;;;:37;-1:-1:-1;;;;;32506:37:0;;;;;;;;-1:-1:-1;32486:3:0;;;;:::i;:::-;;;;32446:109;;;-1:-1:-1;32579:10:0;32285:313;-1:-1:-1;;32285:313:0:o;74596:872::-;74691:1;74681:7;;:11;:29;;;;;74706:4;74696:7;;:14;74681:29;74677:288;;;74812:18;;74863:7;;74782:16;;-1:-1:-1;;;;;74812:18:0;;74874:5;;74846:24;;:14;:24;:::i;:::-;74845:34;;;;:::i;:::-;74804:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74781:104;;;74902:11;74894:63;;;;-1:-1:-1;;;74894:63:0;;24784:2:1;74894:63:0;;;24766:21:1;24823:2;24803:18;;;24796:30;24862:34;24842:18;;;24835:62;-1:-1:-1;;;24913:18:1;;;24906:37;24960:19;;74894:63:0;24756:229:1;74894:63:0;74677:288;;-1:-1:-1;;;;;74977:23:0;;;;;;:39;;;75015:1;75004:8;;:12;74977:39;:58;;;;;75031:4;75020:8;;:15;74977:58;74973:309;;;75111:20;75145:9;-1:-1:-1;;;;;75137:23:0;75199:5;75187:8;;75170:14;:25;;;;:::i;:::-;75169:35;;;;:::i;:::-;75137:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75110:100;;;75227:15;75219:55;;;;-1:-1:-1;;;75219:55:0;;17342:2:1;75219:55:0;;;17324:21:1;17381:2;17361:18;;;17354:30;17420:29;17400:18;;;17393:57;17467:18;;75219:55:0;17314:177:1;75219:55:0;74973:309;;75326:9;75349:7;61178:6;;-1:-1:-1;;;;;61178:6:0;;61105:87;75349:7;-1:-1:-1;;;;;75341:21:0;75370;75341:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75325:71;;;75411:4;75403:59;;;;-1:-1:-1;;;75403:59:0;;21582:2:1;75403:59:0;;;21564:21:1;21621:2;21601:18;;;21594:30;21660:34;21640:18;;;21633:62;-1:-1:-1;;;21711:18:1;;;21704:40;21761:19;;75403:59:0;21554:232:1;72984:1606:0;73117:7;73240:25;73268:29;73282:14;73268:13;:29::i;:::-;73240:57;;73358:1;73314:41;73326:28;73342:11;73326:15;:28::i;:::-;73314:11;:41::i;:::-;:45;73306:75;;;;-1:-1:-1;;;73306:75:0;;14643:2:1;73306:75:0;;;14625:21:1;14682:2;14662:18;;;14655:30;-1:-1:-1;;;14701:18:1;;;14694:47;14758:18;;73306:75:0;14615:167:1;73306:75:0;73424:13;;73402:11;73396:25;:41;73388:77;;;;-1:-1:-1;;;73388:77:0;;16565:2:1;73388:77:0;;;16547:21:1;16604:2;16584:18;;;16577:30;16643:25;16623:18;;;16616:53;16686:18;;73388:77:0;16537:173:1;73388:77:0;73480:65;73494:28;73510:11;73494:15;:28::i;:::-;73524:20;;;;;;;;;;;;;;-1:-1:-1;;;73524:20:0;;;:15;:20::i;:::-;73480:13;:65::i;:::-;:70;73472:118;;;;-1:-1:-1;;;73472:118:0;;14989:2:1;73472:118:0;;;14971:21:1;15028:2;15008:18;;;15001:30;15067:34;15047:18;;;15040:62;-1:-1:-1;;;15118:18:1;;;15111:33;15161:19;;73472:118:0;14961:225:1;73472:118:0;73605:65;73619:28;73635:11;73619:15;:28::i;:::-;73649:20;;;;;;;;;;;;;;-1:-1:-1;;;73649:20:0;;;:15;:20::i;73605:65::-;:70;73597:120;;;;-1:-1:-1;;;73597:120:0;;22395:2:1;73597:120:0;;;22377:21:1;22434:2;22414:18;;;22407:30;22473:34;22453:18;;;22446:62;-1:-1:-1;;;22524:18:1;;;22517:35;22569:19;;73597:120:0;22367:227:1;73597:120:0;73771:1;-1:-1:-1;;;;;73732:41:0;:7;73740:11;73732:20;;;;;;:::i;:::-;;;;;;;;;;;;;;:27;;;-1:-1:-1;;;;;73732:27:0;:41;73724:90;;;;-1:-1:-1;;;73724:90:0;;18879:2:1;73724:90:0;;;18861:21:1;18918:2;18898:18;;;18891:30;18957:34;18937:18;;;18930:62;-1:-1:-1;;;19008:18:1;;;19001:34;19052:19;;73724:90:0;18851:226:1;73724:90:0;73823:31;73829:13;73844:9;;73823:5;:31::i;:::-;73863:23;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73863:23:0;73979:28;;;74034:9;;74014:17;;;:29;-1:-1:-1;;;;;74050:32:0;;:16;;;;:32;;;;74089:14;;;:22;;;74149:20;73979:9;;74149:7;;:20;;73996:11;;74149:20;:::i;:::-;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;74149:32:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;74149:32:0;-1:-1:-1;;;;;74149:32:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;74203:9:0;;74188:25;;;;:14;:25;;;;;;;;:39;;;;-1:-1:-1;74188:25:0;;:39;;;;:::i;:::-;-1:-1:-1;;;;;;74246:27:0;;;;;;:12;:27;;;;;74240:41;;;;;:::i;:::-;:46;74236:175;;-1:-1:-1;74236:175:0;;-1:-1:-1;;;;;74297:27:0;;;;;;:12;:27;;;;;;;;:41;;;;;;;;:::i;:::-;;74236:175;-1:-1:-1;;;;;74428:89:0;;43430:10;74428:89;74495:11;74508:6;:4;:6::i;:::-;74478:37;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;74478:37:0;;;;;;;;;;74428:89;;;:::i;:::-;;;;;;;;74528:9;;74526:11;;;;;:::i;:::-;;;;-1:-1:-1;74546:11:0;74544:13;;74546:11;;74544:13;;;:::i;:::-;;;;-1:-1:-1;74573:9:0;;:11;;74583:1;;74573:11;:::i;:::-;74566:18;72984:1606;-1:-1:-1;;;;;;72984:1606:0:o;57775:315::-;57930:8;-1:-1:-1;;;;;57921:17:0;:5;-1:-1:-1;;;;;57921:17:0;;;57913:55;;;;-1:-1:-1;;;57913:55:0;;15798:2:1;57913:55:0;;;15780:21:1;15837:2;15817:18;;;15810:30;15876:27;15856:18;;;15849:55;15921:18;;57913:55:0;15770:175:1;57913:55:0;-1:-1:-1;;;;;57979:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;57979:46:0;;;;;;;;;;58041:41;;10465::1;;;58041::0;;10438:18:1;58041:41:0;;;;;;;57775:315;;;:::o;52849:::-;53006:28;53016:4;53022:2;53026:7;53006:9;:28::i;:::-;53053:48;53076:4;53082:2;53086:7;53095:5;53053:22;:48::i;:::-;53045:111;;;;-1:-1:-1;;;53045:111:0;;;;;;;:::i;56066:360::-;56126:13;56142:23;56157:7;56142:14;:23::i;:::-;56126:39;;56178:48;56199:5;56214:1;56218:7;56178:20;:48::i;:::-;56267:29;56284:1;56288:7;56267:8;:29::i;:::-;-1:-1:-1;;;;;56309:16:0;;;;;;:9;:16;;;;;:21;;56329:1;;56309:16;:21;;56329:1;;56309:21;:::i;:::-;;;;-1:-1:-1;;56348:16:0;;;;:7;:16;;;;;;56341:23;;-1:-1:-1;;;;;;56341:23:0;;;56382:36;56356:7;;56348:16;-1:-1:-1;;;;;56382:36:0;;;;;56348:16;;56382:36;56066:360;;:::o;75567:747::-;-1:-1:-1;;;;;75677:18:0;;;75673:630;;75789:2;75747:7;75755:14;:23;75770:7;75755:23;;;;;;;;;;;75747:32;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:39;;:44;;-1:-1:-1;;;;;;75747:44:0;-1:-1:-1;;;;;75747:44:0;;;;;;75860:16;;;-1:-1:-1;75860:16:0;;;:12;:16;;;;75854:30;;;;;:::i;:::-;:35;;-1:-1:-1;75854:55:0;;;;-1:-1:-1;;;;;;75893:16:0;;;;75854:55;75850:203;;;75949:23;;;;:14;:23;;;;;;;75941:32;;:7;;:32;;;:::i;:::-;;;;;;;;;;;;;:37;;75922:12;:16;75935:2;-1:-1:-1;;;;;75922:16:0;-1:-1:-1;;;;;75922:16:0;;;;;;;;;;;;:56;;;;;;:::i;:::-;;;;;;:::i;:::-;;75850:203;76067:107;76082:54;76098:7;76106:14;:23;76121:7;76106:23;;;;;;;;;;;76098:32;;;;;;:::i;:::-;;;;;;;;;;;;;;76082:54;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:15;:54::i;:::-;-1:-1:-1;;;;;76154:18:0;;;;;;:12;:18;;;;;76138:35;;;;76154:18;76138:35;;;:::i;:::-;76067:14;:107::i;:::-;76063:233;;;-1:-1:-1;;;;;76194:18:0;;;;;;:12;:18;;;;;76187:25;;;:::i;32984:217::-;33061:6;-1:-1:-1;;;;;;;;;33086:11:0;;;;;;:26;;-1:-1:-1;;;;;;;;;;33101:11:0;;;;33086:26;33082:89;;;33143:15;:10;;;;33156:2;33143:15;:::i;:::-;33136:23;;;32984:217;-1:-1:-1;;32984:217:0:o;33082:89::-;-1:-1:-1;33190:3:0;32984:217::o;8516:216::-;-1:-1:-1;;;;;;;;;;;;;;;;;8694:30:0;;;;;;;;8700:18;;8694:30;;8651:15;;;8694:30;;;;;;;;8516:216::o;11642:713::-;11697:6;11792:8;11815:2;11803:4;:9;;;:14;;;;:::i;:::-;11845:9;;11792:25;;-1:-1:-1;11828:8:0;;11839:15;;11792:25;11839:15;:::i;:::-;11828:26;;11874:1;11870:5;;11865:483;11883:3;11877;:9;11865:483;;;11950:10;;11962:4;11946:21;11991:4;11987:8;;11983:354;;;12016:8;12023:1;12016:8;;:::i;:::-;;;11983:354;;;12053:4;12049:1;:8;;;12046:291;;;12078:8;12085:1;12078:8;;:::i;12046:291::-;12115:4;12111:1;:8;;;12108:229;;;12140:8;12147:1;12140:8;;:::i;12108:229::-;12177:4;12173:1;:8;;;12170:167;;;12202:8;12209:1;12202:8;;:::i;12170:167::-;12239:4;12235:1;:8;;;12232:105;;;12264:8;12271:1;12264:8;;:::i;12232:105::-;12313:8;12320:1;12313:8;;:::i;:::-;;;12232:105;-1:-1:-1;11888:3:0;;;;:::i;:::-;;;;11865:483;;;11642:713;;;;;:::o;29396:370::-;29474:8;29495;29564:6;:11;;;29506:55;29514:4;:9;;;29525:4;:9;;;29536:6;:11;;;29549:6;:11;;;29506:7;:55::i;:::-;:69;;;;:::i;:::-;29495:80;;29586:173;29612:9;;29600;;;;:21;;29612:9;29600:21;:::i;:::-;29593:3;:28;29586:173;;29638:5;;;;:::i;:::-;;;;29736:6;:11;;;29664:69;29691:4;:9;;;29685:3;:15;;;;:::i;:::-;29672:9;;:29;;;;:::i;:::-;29703:3;29708:6;:11;;;29721:6;:11;;;29664:7;:69::i;:::-;:83;;;;:::i;:::-;29658:89;;29586:173;;55455:382;-1:-1:-1;;;;;55535:16:0;;55527:61;;;;-1:-1:-1;;;55527:61:0;;19284:2:1;55527:61:0;;;19266:21:1;;;19303:18;;;19296:30;19362:34;19342:18;;;19335:62;19414:18;;55527:61:0;19256:182:1;55527:61:0;53542:4;53566:16;;;:7;:16;;;;;;-1:-1:-1;;;;;53566:16:0;:30;55599:58;;;;-1:-1:-1;;;55599:58:0;;13881:2:1;55599:58:0;;;13863:21:1;13920:2;13900:18;;;13893:30;13959;13939:18;;;13932:58;14007:18;;55599:58:0;13853:178:1;55599:58:0;55670:45;55699:1;55703:2;55707:7;55670:20;:45::i;:::-;-1:-1:-1;;;;;55728:13:0;;;;;;:9;:13;;;;;:18;;55745:1;;55728:13;:18;;55745:1;;55728:18;:::i;:::-;;;;-1:-1:-1;;55757:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;55757:21:0;-1:-1:-1;;;;;55757:21:0;;;;;;;;55796:33;;55757:16;;;55796:33;;55757:16;;55796:33;55455:382;;:::o;58655:799::-;58810:4;-1:-1:-1;;;;;58831:13:0;;35775:20;35823:8;58827:620;;58867:72;;-1:-1:-1;;;58867:72:0;;-1:-1:-1;;;;;58867:36:0;;;;;:72;;43430:10;;58918:4;;58924:7;;58933:5;;58867:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58867:72:0;;;;;;;;-1:-1:-1;;58867:72:0;;;;;;;;;;;;:::i;:::-;;;58863:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59109:13:0;;59105:272;;59152:60;;-1:-1:-1;;;59152:60:0;;;;;;;:::i;59105:272::-;59327:6;59321:13;59312:6;59308:2;59304:15;59297:38;58863:529;-1:-1:-1;;;;;;58990:51:0;-1:-1:-1;;;58990:51:0;;-1:-1:-1;58983:58:0;;58827:620;-1:-1:-1;59431:4:0;58655:799;;;;;;:::o;14425:135::-;14503:4;14527:20;14535:4;14541:5;14527:7;:20::i;:::-;:25;;14425:135;-1:-1:-1;;;14425:135:0:o;21486:1493::-;21585:4;21613:7;21585:4;21656:20;;;21652:1285;;21710:2;21697:9;:15;21693:1233;;21733:12;21768:13;;21764:112;;21853:1;21834:14;21839:9;21834:2;:14;:::i;:::-;21829:20;;:1;:20;:::i;:::-;21823:27;;:1;:27;:::i;:::-;:31;;;;:::i;:::-;21821:34;;-1:-1:-1;21764:112:0;21962:16;;21958:27;;21896:18;22038:9;22018:17;22028:7;22018;:17;:::i;:::-;:29;;;;:::i;:::-;22126:10;;22007:40;;-1:-1:-1;22122:21:0;;22165:233;22183:10;22172:7;:21;22165:233;;22229:3;22222;:10;22218:65;;22266:17;22276:7;22266;:17;:::i;:::-;22259:24;;;;;;;;;;22218:65;22306:5;;;;:::i;:::-;;;;22372:4;22366:3;22360:10;22356:21;22345:32;;22343:36;;;22423:3;22416:10;;;;;;;;;;21693:1233;-1:-1:-1;22567:31:0;;;22517:12;;22620:291;22641:19;22651:9;22641:7;:19;:::i;:::-;22634:3;:26;22620:291;;22754:25;;;22807:16;;;22803:57;;;22857:3;22850:10;;;;;;;;22803:57;22883:8;22890:1;22883:8;;:::i;:::-;;;22620:291;22662:5;;;;;:::i;:::-;;;;22620:291;;;21693:1233;;22954:17;22964:7;22954;:17;:::i;:::-;22947:24;21486:1493;-1:-1:-1;;;;;;;21486:1493:0:o;13097:1076::-;13208:9;;13232:10;;13176:3;;13208:9;13232:22;-1:-1:-1;13228:62:0;;;-1:-1:-1;13280:10:0;;13228:62;13318:9;;;;;13354:10;;;;13303:12;13375:741;13400:8;13394:3;:14;13375:741;;;13511:14;;13548:15;;13596:6;;;13592:456;;-1:-1:-1;;13757:2:0;13746:13;;13743:105;;;13826:1;13818:3;13802:13;13807:8;13802:2;:13;:::i;:::-;:19;;;;:::i;:::-;13797:25;;:1;:25;:::i;:::-;13791:32;;:1;:32;:::i;:::-;:36;;;;:::i;:::-;13789:39;13782:46;;13743:105;13925:8;;;13912;;;13911:23;;;;13961:9;13957:56;;14008:4;-1:-1:-1;13997:16:0;;-1:-1:-1;;;;;;;13997:16:0;13957:56;13592:456;;;14062:13;14073:2;14062:13;;:::i;:::-;;-1:-1:-1;14090:14:0;14102:2;14090:14;;:::i;:::-;;;13375:741;;13417:2;13410:9;;;;;:::i;:::-;;;13375:741;;;-1:-1:-1;14154:10:0;;14137:9;;14133:32;;14154:10;14133:32;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:336:1;78:5;107:52;123:35;151:6;123:35;:::i;:::-;107:52;:::i;:::-;98:61;;182:6;175:5;168:21;222:3;213:6;208:3;204:16;201:25;198:2;;;239:1;236;229:12;198:2;288:6;283:3;276:4;269:5;265:16;252:43;342:1;335:4;326:6;319:5;315:18;311:29;304:40;88:262;;;;;:::o;355:173::-;423:20;;-1:-1:-1;;;;;472:31:1;;462:42;;452:2;;518:1;515;508:12;452:2;404:124;;;:::o;533:376::-;585:8;595:6;649:3;642:4;634:6;630:17;626:27;616:2;;674:8;664;657:26;616:2;-1:-1:-1;704:20:1;;747:18;736:30;;733:2;;;786:8;776;769:26;733:2;830:4;822:6;818:17;806:29;;882:3;875:4;866:6;858;854:19;850:30;847:39;844:2;;;899:1;896;889:12;844:2;606:303;;;;;:::o;914:229::-;957:5;1010:3;1003:4;995:6;991:17;987:27;977:2;;1032:5;1025;1018:20;977:2;1058:79;1133:3;1124:6;1111:20;1104:4;1096:6;1092:17;1058:79;:::i;:::-;1049:88;967:176;-1:-1:-1;;;967:176:1:o;1148:196::-;1207:6;1260:2;1248:9;1239:7;1235:23;1231:32;1228:2;;;1281:6;1273;1266:22;1228:2;1309:29;1328:9;1309:29;:::i;1349:270::-;1417:6;1425;1478:2;1466:9;1457:7;1453:23;1449:32;1446:2;;;1499:6;1491;1484:22;1446:2;1527:29;1546:9;1527:29;:::i;:::-;1517:39;;1575:38;1609:2;1598:9;1594:18;1575:38;:::i;:::-;1565:48;;1436:183;;;;;:::o;1624:338::-;1701:6;1709;1717;1770:2;1758:9;1749:7;1745:23;1741:32;1738:2;;;1791:6;1783;1776:22;1738:2;1819:29;1838:9;1819:29;:::i;:::-;1809:39;;1867:38;1901:2;1890:9;1886:18;1867:38;:::i;:::-;1857:48;;1952:2;1941:9;1937:18;1924:32;1914:42;;1728:234;;;;;:::o;1967:696::-;2062:6;2070;2078;2086;2139:3;2127:9;2118:7;2114:23;2110:33;2107:2;;;2161:6;2153;2146:22;2107:2;2189:29;2208:9;2189:29;:::i;:::-;2179:39;;2237:38;2271:2;2260:9;2256:18;2237:38;:::i;:::-;2227:48;;2322:2;2311:9;2307:18;2294:32;2284:42;;2377:2;2366:9;2362:18;2349:32;2404:18;2396:6;2393:30;2390:2;;;2441:6;2433;2426:22;2390:2;2469:22;;2522:4;2514:13;;2510:27;-1:-1:-1;2500:2:1;;2556:6;2548;2541:22;2500:2;2584:73;2649:7;2644:2;2631:16;2626:2;2622;2618:11;2584:73;:::i;:::-;2574:83;;;2097:566;;;;;;;:::o;2668:367::-;2733:6;2741;2794:2;2782:9;2773:7;2769:23;2765:32;2762:2;;;2815:6;2807;2800:22;2762:2;2843:29;2862:9;2843:29;:::i;:::-;2833:39;;2922:2;2911:9;2907:18;2894:32;2969:5;2962:13;2955:21;2948:5;2945:32;2935:2;;2996:6;2988;2981:22;2935:2;3024:5;3014:15;;;2752:283;;;;;:::o;3040:264::-;3108:6;3116;3169:2;3157:9;3148:7;3144:23;3140:32;3137:2;;;3190:6;3182;3175:22;3137:2;3218:29;3237:9;3218:29;:::i;:::-;3208:39;3294:2;3279:18;;;;3266:32;;-1:-1:-1;;;3127:177:1:o;3309:255::-;3367:6;3420:2;3408:9;3399:7;3395:23;3391:32;3388:2;;;3441:6;3433;3426:22;3388:2;3485:9;3472:23;3504:30;3528:5;3504:30;:::i;3569:259::-;3638:6;3691:2;3679:9;3670:7;3666:23;3662:32;3659:2;;;3712:6;3704;3697:22;3659:2;3749:9;3743:16;3768:30;3792:5;3768:30;:::i;3833:431::-;3904:6;3912;3965:2;3953:9;3944:7;3940:23;3936:32;3933:2;;;3986:6;3978;3971:22;3933:2;4031:9;4018:23;4064:18;4056:6;4053:30;4050:2;;;4101:6;4093;4086:22;4050:2;4145:59;4196:7;4187:6;4176:9;4172:22;4145:59;:::i;:::-;4223:8;;4119:85;;-1:-1:-1;3923:341:1;-1:-1:-1;;;;3923:341:1:o;4269:751::-;4361:6;4369;4377;4385;4438:2;4426:9;4417:7;4413:23;4409:32;4406:2;;;4459:6;4451;4444:22;4406:2;4504:9;4491:23;4533:18;4574:2;4566:6;4563:14;4560:2;;;4595:6;4587;4580:22;4560:2;4639:59;4690:7;4681:6;4670:9;4666:22;4639:59;:::i;:::-;4717:8;;-1:-1:-1;4613:85:1;-1:-1:-1;4805:2:1;4790:18;;4777:32;;-1:-1:-1;4821:16:1;;;4818:2;;;4855:6;4847;4840:22;4818:2;;4899:61;4952:7;4941:8;4930:9;4926:24;4899:61;:::i;:::-;4396:624;;;;-1:-1:-1;4979:8:1;-1:-1:-1;;;;4396:624:1:o;5025:342::-;5094:6;5147:2;5135:9;5126:7;5122:23;5118:32;5115:2;;;5168:6;5160;5153:22;5115:2;5213:9;5200:23;5246:18;5238:6;5235:30;5232:2;;;5283:6;5275;5268:22;5232:2;5311:50;5353:7;5344:6;5333:9;5329:22;5311:50;:::i;5372:675::-;5452:6;5505:2;5493:9;5484:7;5480:23;5476:32;5473:2;;;5526:6;5518;5511:22;5473:2;5564:9;5558:16;5597:18;5589:6;5586:30;5583:2;;;5634:6;5626;5619:22;5583:2;5662:22;;5715:4;5707:13;;5703:27;-1:-1:-1;5693:2:1;;5749:6;5741;5734:22;5693:2;5783;5777:9;5808:48;5824:31;5852:2;5824:31;:::i;5808:48::-;5879:2;5872:5;5865:17;5919:7;5914:2;5909;5905;5901:11;5897:20;5894:33;5891:2;;;5945:6;5937;5930:22;5891:2;5963:54;6014:2;6009;6002:5;5998:14;5993:2;5989;5985:11;5963:54;:::i;:::-;6036:5;5463:584;-1:-1:-1;;;;;5463:584:1:o;6052:490::-;6139:6;6147;6155;6208:2;6196:9;6187:7;6183:23;6179:32;6176:2;;;6229:6;6221;6214:22;6176:2;6274:9;6261:23;6307:18;6299:6;6296:30;6293:2;;;6344:6;6336;6329:22;6293:2;6372:50;6414:7;6405:6;6394:9;6390:22;6372:50;:::i;:::-;6362:60;;;6441:38;6475:2;6464:9;6460:18;6441:38;:::i;:::-;6431:48;;6498:38;6532:2;6521:9;6517:18;6498:38;:::i;:::-;6488:48;;6166:376;;;;;:::o;6547:190::-;6606:6;6659:2;6647:9;6638:7;6634:23;6630:32;6627:2;;;6680:6;6672;6665:22;6627:2;-1:-1:-1;6708:23:1;;6617:120;-1:-1:-1;6617:120:1:o;6742:257::-;6783:3;6821:5;6815:12;6848:6;6843:3;6836:19;6864:63;6920:6;6913:4;6908:3;6904:14;6897:4;6890:5;6886:16;6864:63;:::i;:::-;6981:2;6960:15;-1:-1:-1;;6956:29:1;6947:39;;;;6988:4;6943:50;;6791:208;-1:-1:-1;;6791:208:1:o;7004:823::-;7134:3;7163;7198:6;7192:13;7228:36;7254:9;7228:36;:::i;:::-;7283:1;7300:18;;;7327:104;;;;7445:1;7440:362;;;;7293:509;;7327:104;-1:-1:-1;;7360:24:1;;7348:37;;7405:16;;;;-1:-1:-1;7327:104:1;;7440:362;7473:6;7468:3;7461:19;7503:4;7550:2;7545:3;7535:18;7575:3;7591:165;7605:6;7602:1;7599:13;7591:165;;;7683:14;;7670:11;;;7663:35;7726:16;;;;7620:10;;7591:165;;;7595:3;;;7785:6;7780:3;7776:16;7769:23;;7293:509;-1:-1:-1;7818:3:1;;7142:685;-1:-1:-1;;;;;;7142:685:1:o;7832:276::-;7963:3;8001:6;7995:13;8017:53;8063:6;8058:3;8051:4;8043:6;8039:17;8017:53;:::i;:::-;8086:16;;;;;7971:137;-1:-1:-1;;7971:137:1:o;8113:470::-;8292:3;8330:6;8324:13;8346:53;8392:6;8387:3;8380:4;8372:6;8368:17;8346:53;:::i;:::-;8462:13;;8421:16;;;;8484:57;8462:13;8421:16;8518:4;8506:17;;8484:57;:::i;:::-;8557:20;;8300:283;-1:-1:-1;;;;8300:283:1:o;9832:488::-;-1:-1:-1;;;;;10101:15:1;;;10083:34;;10153:15;;10148:2;10133:18;;10126:43;10200:2;10185:18;;10178:34;;;10248:3;10243:2;10228:18;;10221:31;;;10026:4;;10269:45;;10294:19;;10286:6;10269:45;:::i;10517:219::-;10666:2;10655:9;10648:21;10629:4;10686:44;10726:2;10715:9;10711:18;10703:6;10686:44;:::i;10741:551::-;10994:3;10983:9;10976:22;10957:4;11021:45;11061:3;11050:9;11046:19;11038:6;11021:45;:::i;:::-;11097:2;11082:18;;11075:34;;;-1:-1:-1;;;;;11145:32:1;;11140:2;11125:18;;11118:60;11214:22;;;11209:2;11194:18;;11187:50;11254:32;11218:6;11271;11254:32;:::i;11297:1149::-;11519:2;11508:9;11501:21;11482:4;11542;11578:6;11572:13;11608:36;11634:9;11608:36;:::i;:::-;11680:6;11675:2;11664:9;11660:18;11653:34;11706:3;11728:1;11760:2;11749:9;11745:18;11777:1;11772:122;;;;11908:1;11903:390;;;;11738:555;;11772:122;-1:-1:-1;;11820:24:1;;11800:18;;;11793:52;11880:3;11865:19;;;-1:-1:-1;11772:122:1;;11903:390;11937:6;11931:4;11924:20;11967:4;12015:2;12009:4;11999:19;12040:4;12057:180;12071:6;12068:1;12065:13;12057:180;;;12164:14;;12140:17;;;12136:26;;12129:50;12207:16;;;;12086:10;;12057:180;;;12261:17;;12257:26;;;-1:-1:-1;;;11738:555:1;;;;;;12340:9;12335:3;12331:19;12324:4;12313:9;12309:20;12302:49;12368:29;12393:3;12385:6;12368:29;:::i;:::-;12360:37;;;12433:6;12428:2;12417:9;12413:18;12406:34;11491:955;;;;;;:::o;12451:397::-;12653:2;12635:21;;;12692:2;12672:18;;;12665:30;12731:34;12726:2;12711:18;;12704:62;-1:-1:-1;;;12797:2:1;12782:18;;12775:31;12838:3;12823:19;;12625:223::o;12853:414::-;13055:2;13037:21;;;13094:2;13074:18;;;13067:30;13133:34;13128:2;13113:18;;13106:62;-1:-1:-1;;;13199:2:1;13184:18;;13177:48;13257:3;13242:19;;13027:240::o;19856:356::-;20058:2;20040:21;;;20077:18;;;20070:30;20136:34;20131:2;20116:18;;20109:62;20203:2;20188:18;;20030:182::o;22599:413::-;22801:2;22783:21;;;22840:2;22820:18;;;22813:30;22879:34;22874:2;22859:18;;22852:62;-1:-1:-1;;;22945:2:1;22930:18;;22923:47;23002:3;22987:19;;22773:239::o;23424:398::-;23626:2;23608:21;;;23665:2;23645:18;;;23638:30;23704:34;23699:2;23684:18;;23677:62;-1:-1:-1;;;23770:2:1;23755:18;;23748:32;23812:3;23797:19;;23598:224::o;25878:275::-;25949:2;25943:9;26014:2;25995:13;;-1:-1:-1;;25991:27:1;25979:40;;26049:18;26034:34;;26070:22;;;26031:62;26028:2;;;26096:18;;:::i;:::-;26132:2;26125:22;25923:230;;-1:-1:-1;25923:230:1:o;26158:186::-;26206:4;26239:18;26231:6;26228:30;26225:2;;;26261:18;;:::i;:::-;-1:-1:-1;26327:2:1;26306:15;-1:-1:-1;;26302:29:1;26333:4;26298:40;;26215:129::o;26349:128::-;26389:3;26420:1;26416:6;26413:1;26410:13;26407:2;;;26426:18;;:::i;:::-;-1:-1:-1;26462:9:1;;26397:80::o;26482:204::-;26520:3;26556:4;26553:1;26549:12;26588:4;26585:1;26581:12;26623:3;26617:4;26613:14;26608:3;26605:23;26602:2;;;26631:18;;:::i;:::-;26667:13;;26528:158;-1:-1:-1;;;26528:158:1:o;26691:217::-;26731:1;26757;26747:2;;-1:-1:-1;;;26782:31:1;;26836:4;26833:1;26826:15;26864:4;26789:1;26854:15;26747:2;-1:-1:-1;26893:9:1;;26737:171::o;26913:422::-;27002:1;27045:5;27002:1;27059:270;27080:7;27070:8;27067:21;27059:270;;;27139:4;27135:1;27131:6;27127:17;27121:4;27118:27;27115:2;;;27148:18;;:::i;:::-;27198:7;27188:8;27184:22;27181:2;;;27218:16;;;;27181:2;27297:22;;;;27257:15;;;;27059:270;;;27063:3;26977:358;;;;;:::o;27340:131::-;27400:5;27429:36;27456:8;27450:4;27525:5;27555:8;27545:2;;-1:-1:-1;27596:1:1;27610:5;;27545:2;27644:4;27634:2;;-1:-1:-1;27681:1:1;27695:5;;27634:2;27726:4;27744:1;27739:59;;;;27812:1;27807:130;;;;27719:218;;27739:59;27769:1;27760:10;;27783:5;;;27807:130;27844:3;27834:8;27831:17;27828:2;;;27851:18;;:::i;:::-;-1:-1:-1;;27907:1:1;27893:16;;27922:5;;27719:218;;28021:2;28011:8;28008:16;28002:3;27996:4;27993:13;27989:36;27983:2;27973:8;27970:16;27965:2;27959:4;27956:12;27952:35;27949:77;27946:2;;;-1:-1:-1;28058:19:1;;;28090:5;;27946:2;28137:34;28162:8;28156:4;28137:34;:::i;:::-;28207:6;28203:1;28199:6;28195:19;28186:7;28183:32;28180:2;;;28218:18;;:::i;:::-;28256:20;;27535:747;-1:-1:-1;;;27535:747:1:o;28287:168::-;28327:7;28393:1;28389;28385:6;28381:14;28378:1;28375:21;28370:1;28363:9;28356:17;28352:45;28349:2;;;28400:18;;:::i;:::-;-1:-1:-1;28440:9:1;;28339:116::o;28460:270::-;28499:4;28528:12;;;28556:10;;-1:-1:-1;;;28575:19:1;;28568:27;;28552:44;28549:2;;;28599:18;;:::i;:::-;-1:-1:-1;;;;;28646:27:1;;28639:35;;28631:44;;28628:2;;;28678:18;;:::i;:::-;-1:-1:-1;;28715:9:1;;28508:222::o;28735:125::-;28775:4;28803:1;28800;28797:8;28794:2;;;28808:18;;:::i;:::-;-1:-1:-1;28845:9:1;;28784:76::o;28865:258::-;28937:1;28947:113;28961:6;28958:1;28955:13;28947:113;;;29037:11;;;29031:18;29018:11;;;29011:39;28983:2;28976:10;28947:113;;;29078:6;29075:1;29072:13;29069:2;;;-1:-1:-1;;29113:1:1;29095:16;;29088:27;28918:205::o;29128:136::-;29167:3;29195:5;29185:2;;29204:18;;:::i;:::-;-1:-1:-1;;;29240:18:1;;29175:89::o;29269:380::-;29348:1;29344:12;;;;29391;;;29412:2;;29466:4;29458:6;29454:17;29444:27;;29412:2;29519;29511:6;29508:14;29488:18;29485:38;29482:2;;;29565:10;29560:3;29556:20;29553:1;29546:31;29600:4;29597:1;29590:15;29628:4;29625:1;29618:15;29482:2;;29324:325;;;:::o;29654:135::-;29693:3;-1:-1:-1;;29714:17:1;;29711:2;;;29734:18;;:::i;:::-;-1:-1:-1;29781:1:1;29770:13;;29701:88::o;29794:127::-;29855:10;29850:3;29846:20;29843:1;29836:31;29886:4;29883:1;29876:15;29910:4;29907:1;29900:15;29926:127;29987:10;29982:3;29978:20;29975:1;29968:31;30018:4;30015:1;30008:15;30042:4;30039:1;30032:15;30058:131;-1:-1:-1;;;;;;30132:32:1;;30122:43;;30112:2;;30179:1;30176;30169:12
Swarm Source
ipfs://3310dd47ca7d19bae3bd9b8a4b6f5e8a618c55eab4dedbf648a2bc5e5a3583ff
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Validator ID :
0 FTM
Amount Staked
0
Amount Delegated
0
Staking Total
0
Staking Start Epoch
0
Staking Start Time
0
Proof of Importance
0
Origination Score
0
Validation Score
0
Active
0
Online
0
Downtime
0 s
Address | Amount | claimed Rewards | Created On Epoch | Created On |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.