Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 9 from a total of 9 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Approval For... | 16237873 | 1180 days ago | IN | 0 ETH | 0.00058925 | ||||
| Safe Mint | 16237583 | 1180 days ago | IN | 0 ETH | 0.02117369 | ||||
| Safe Mint | 16237400 | 1180 days ago | IN | 0 ETH | 0.06402322 | ||||
| Safe Mint | 16237394 | 1180 days ago | IN | 0 ETH | 0.06462849 | ||||
| Safe Mint | 16237360 | 1180 days ago | IN | 0 ETH | 0.01793946 | ||||
| Safe Mint | 16237360 | 1180 days ago | IN | 0 ETH | 0.04777018 | ||||
| Safe Mint | 16237308 | 1180 days ago | IN | 0 ETH | 0.07042582 | ||||
| Safe Mint | 16237261 | 1180 days ago | IN | 0 ETH | 0.07106278 | ||||
| Safe Mint | 16237238 | 1180 days ago | IN | 0 ETH | 0.03841377 |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Catnap
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "./ERC721.sol";
import "./Ownable.sol";
import "./Counters.sol";
import "./ERC2981.sol";
import "./Base64.sol";
contract Catnap is ERC721, Ownable, ERC2981 {
using Strings for uint256;
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
mapping(uint256 => string) private names;
mapping(uint256 => string) private images;
constructor() ERC721("Islands of the Mind - Catnap", "CATNAP") {
_setDefaultRoyalty(msg.sender, 500);
}
function safeMint(string memory name, string memory image) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
names[tokenId] = name;
images[tokenId] = image;
_safeMint(msg.sender, tokenId);
}
function tokenURI(uint256 _tokenId)
public
view
virtual
override
returns (string memory)
{
require(_exists(_tokenId));
return buildMetadata(_tokenId);
}
function buildMetadata(uint256 _tokenId)
private
view
returns (string memory)
{
string memory name = names[_tokenId];
string memory image = images[_tokenId];
string memory description= "Figure featured in 'Islands of the Mind - Catnap' by Hyunjeong Lim";
string memory url = string(
abi.encodePacked(
"https://nft.hyunjeonglim.com/catnap/",
_tokenId.toString()
)
);
return string(
abi.encodePacked(
"data:application/json;base64,",
Base64.encode(
bytes(
abi.encodePacked(
'{"name":"', name, '",',
'"description":"', description, '",',
'"external_url":"', url, '",',
'"image":"', image,
'"}'
)
)
)
)
);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) {
return super.supportsInterface(interfaceId);
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
/**
*Submitted for verification at Etherscan.io on 2021-09-05
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <brecht@loopring.org>
library Base64 {
bytes internal constant TABLE =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/// @notice Encodes some bytes to the base64 representation
function encode(bytes memory data) internal pure returns (string memory) {
uint256 len = data.length;
if (len == 0) return "";
// multiply by 4/3 rounded up
uint256 encodedLen = 4 * ((len + 2) / 3);
// Add some extra buffer at the end
bytes memory result = new bytes(encodedLen + 32);
bytes memory table = TABLE;
assembly {
let tablePtr := add(table, 1)
let resultPtr := add(result, 32)
for {
let i := 0
} lt(i, len) {
} {
i := add(i, 3)
let input := and(mload(add(data, i)), 0xffffff)
let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
out := shl(8, out)
out := add(
out,
and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)
)
out := shl(8, out)
out := add(
out,
and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)
)
out := shl(8, out)
out := add(
out,
and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)
)
out := shl(224, out)
mstore(resultPtr, out)
resultPtr := add(resultPtr, 4)
}
switch mod(len, 3)
case 1 {
mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
}
case 2 {
mstore(sub(resultPtr, 1), shl(248, 0x3d))
}
mstore(result, encodedLen)
}
return string(result);
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
pragma solidity ^0.8.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
*/
library Counters {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)
pragma solidity ^0.8.0;
import "./IERC2981.sol";
import "./ERC165.sol";
/**
* @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
*
* Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
* specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
*
* Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
* fee is specified in basis points by default.
*
* IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
* https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
* voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
*
* _Available since v4.5._
*/
abstract contract ERC2981 is IERC2981, ERC165 {
struct RoyaltyInfo {
address receiver;
uint96 royaltyFraction;
}
RoyaltyInfo private _defaultRoyaltyInfo;
mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @inheritdoc IERC2981
*/
function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];
if (royalty.receiver == address(0)) {
royalty = _defaultRoyaltyInfo;
}
uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();
return (royalty.receiver, royaltyAmount);
}
/**
* @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
* fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
* override.
*/
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
/**
* @dev Sets the royalty information that all ids in this contract will default to.
*
* Requirements:
*
* - `receiver` cannot be the zero address.
* - `feeNumerator` cannot be greater than the fee denominator.
*/
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: invalid receiver");
_defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
}
/**
* @dev Removes default royalty information.
*/
function _deleteDefaultRoyalty() internal virtual {
delete _defaultRoyaltyInfo;
}
/**
* @dev Sets the royalty information for a specific token id, overriding the global default.
*
* Requirements:
*
* - `receiver` cannot be the zero address.
* - `feeNumerator` cannot be greater than the fee denominator.
*/
function _setTokenRoyalty(
uint256 tokenId,
address receiver,
uint96 feeNumerator
) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: Invalid parameters");
_tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
}
/**
* @dev Resets royalty information for the token id back to the global default.
*/
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
delete _tokenRoyaltyInfo[tokenId];
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./Context.sol";
import "./Strings.sol";
import "./ERC165.sol";
/**
* @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: address zero is not a valid owner");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _ownerOf(tokenId);
require(owner != address(0), "ERC721: invalid token ID");
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) {
_requireMinted(tokenId);
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 overridden 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 token owner or approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
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: caller is not token owner or 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: caller is not token owner or 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist
*/
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
/**
* @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 _ownerOf(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) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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, 1);
// Check that tokenId was not minted by `_beforeTokenTransfer` hook
require(!_exists(tokenId), "ERC721: token already minted");
unchecked {
// Will not overflow unless all 2**256 token ids are minted to the same owner.
// Given that tokens are minted one by one, it is impossible in practice that
// this ever happens. Might change if we allow batch minting.
// The ERC fails to describe this case.
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId, 1);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
* This is an internal function that does not check if the sender is authorized to operate on the token.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId, 1);
// Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
owner = ERC721.ownerOf(tokenId);
// Clear approvals
delete _tokenApprovals[tokenId];
unchecked {
// Cannot overflow, as that would require more tokens to be burned/transferred
// out than the owner initially received through minting and transferring in.
_balances[owner] -= 1;
}
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId, 1);
}
/**
* @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 from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId, 1);
// Check that tokenId was not transferred by `_beforeTokenTransfer` hook
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
// Clear approvals from the previous owner
delete _tokenApprovals[tokenId];
unchecked {
// `_balances[from]` cannot overflow for the same reason as described in `_burn`:
// `from`'s balance is the number of token held, which is at least one before the current
// transfer.
// `_balances[to]` could overflow in the conditions described in `_mint`. That would require
// all 2**256 token ids to be minted, which in practice is impossible.
_balances[from] -= 1;
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId, 1);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits an {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {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 Reverts if the `tokenId` has not been minted yet.
*/
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "ERC721: invalid token ID");
}
/**
* @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 {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
* used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
* - When `from` is zero, the tokens will be minted for `to`.
* - When `to` is zero, ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
* - `batchSize` is non-zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256, /* firstTokenId */
uint256 batchSize
) internal virtual {
if (batchSize > 1) {
if (from != address(0)) {
_balances[from] -= batchSize;
}
if (to != address(0)) {
_balances[to] += batchSize;
}
}
}
/**
* @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
* used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
* - When `from` is zero, the tokens were minted for `to`.
* - When `to` is zero, ``from``'s tokens were burned.
* - `from` and `to` are never both zero.
* - `batchSize` is non-zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual {}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Interface for the NFT Royalty Standard.
*
* A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
* support for royalty payments across all NFT marketplaces and ecosystem participants.
*
* _Available since v4.5._
*/
interface IERC2981 is IERC165 {
/**
* @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
* exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
*/
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
returns (address receiver, uint256 royaltyAmount);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @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`.
*
* 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;
/**
* @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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* 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 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 the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @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);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "./IERC721.sol";
/**
* @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);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "./Context.sol";
/**
* @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 Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
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);
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./Math.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"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":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"image","type":"string"}],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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
60806040523480156200001157600080fd5b506040518060400160405280601c81526020017f49736c616e6473206f6620746865204d696e64202d204361746e6170000000008152506040518060400160405280600681526020017f4341544e4150000000000000000000000000000000000000000000000000000081525081600090805190602001906200009692919062000368565b508060019080519060200190620000af92919062000368565b505050620000d2620000c6620000ec60201b60201c565b620000f460201b60201c565b620000e6336101f4620001ba60201b60201c565b62000598565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620001ca6200035e60201b60201c565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156200022b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000222906200049f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200029e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002959062000511565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600760008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b6000612710905090565b828054620003769062000562565b90600052602060002090601f0160209004810192826200039a5760008555620003e6565b82601f10620003b557805160ff1916838001178555620003e6565b82800160010185558215620003e6579182015b82811115620003e5578251825591602001919060010190620003c8565b5b509050620003f59190620003f9565b5090565b5b8082111562000414576000816000905550600101620003fa565b5090565b600082825260208201905092915050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b600062000487602a8362000418565b9150620004948262000429565b604082019050919050565b60006020820190508181036000830152620004ba8162000478565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b6000620004f960198362000418565b91506200050682620004c1565b602082019050919050565b600060208201905081810360008301526200052c81620004ea565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200057b57607f821691505b6020821081141562000592576200059162000533565b5b50919050565b61371f80620005a86000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c806370a08231116100a2578063a22cb46511610071578063a22cb465146102e0578063b88d4fde146102fc578063c87b56dd14610318578063e985e9c514610348578063f2fde38b1461037857610116565b806370a082311461026a578063715018a61461029a5780638da5cb5b146102a457806395d89b41146102c257610116565b806323b872dd116100e957806323b872dd146101b55780632a55205a146101d157806342842e0e146102025780634fa1f7ae1461021e5780636352211e1461023a57610116565b806301ffc9a71461011b57806306fdde031461014b578063081812fc14610169578063095ea7b314610199575b600080fd5b6101356004803603810190610130919061228f565b610394565b60405161014291906122d7565b60405180910390f35b6101536103a6565b604051610160919061238b565b60405180910390f35b610183600480360381019061017e91906123e3565b610438565b6040516101909190612451565b60405180910390f35b6101b360048036038101906101ae9190612498565b61047e565b005b6101cf60048036038101906101ca91906124d8565b610596565b005b6101eb60048036038101906101e6919061252b565b6105f6565b6040516101f992919061257a565b60405180910390f35b61021c600480360381019061021791906124d8565b6107e1565b005b610238600480360381019061023391906126d8565b610801565b005b610254600480360381019061024f91906123e3565b610880565b6040516102619190612451565b60405180910390f35b610284600480360381019061027f9190612750565b610907565b604051610291919061277d565b60405180910390f35b6102a26109bf565b005b6102ac6109d3565b6040516102b99190612451565b60405180910390f35b6102ca6109fd565b6040516102d7919061238b565b60405180910390f35b6102fa60048036038101906102f591906127c4565b610a8f565b005b610316600480360381019061031191906128a5565b610aa5565b005b610332600480360381019061032d91906123e3565b610b07565b60405161033f919061238b565b60405180910390f35b610362600480360381019061035d9190612928565b610b2b565b60405161036f91906122d7565b60405180910390f35b610392600480360381019061038d9190612750565b610bbf565b005b600061039f82610c43565b9050919050565b6060600080546103b590612997565b80601f01602080910402602001604051908101604052809291908181526020018280546103e190612997565b801561042e5780601f106104035761010080835404028352916020019161042e565b820191906000526020600020905b81548152906001019060200180831161041157829003601f168201915b5050505050905090565b600061044382610cbd565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061048982610880565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156104fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f190612a3b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610519610d08565b73ffffffffffffffffffffffffffffffffffffffff161480610548575061054781610542610d08565b610b2b565b5b610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90612acd565b60405180910390fd5b6105918383610d10565b505050565b6105a76105a1610d08565b82610dc9565b6105e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105dd90612b5f565b60405180910390fd5b6105f1838383610e5e565b505050565b6000806000600860008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16141561078c5760076040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610796611158565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff16866107c29190612bae565b6107cc9190612c37565b90508160000151819350935050509250929050565b6107fc83838360405180602001604052806000815250610aa5565b505050565b610809611162565b600061081560096111e0565b905061082160096111ee565b82600a60008381526020019081526020016000209080519060200190610848929190612180565b5081600b60008381526020019081526020016000209080519060200190610870929190612180565b5061087b3382611204565b505050565b60008061088c83611222565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156108fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f590612cb4565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610978576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096f90612d46565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6109c7611162565b6109d1600061125f565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610a0c90612997565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3890612997565b8015610a855780601f10610a5a57610100808354040283529160200191610a85565b820191906000526020600020905b815481529060010190602001808311610a6857829003601f168201915b5050505050905090565b610aa1610a9a610d08565b8383611325565b5050565b610ab6610ab0610d08565b83610dc9565b610af5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aec90612b5f565b60405180910390fd5b610b0184848484611492565b50505050565b6060610b12826114ee565b610b1b57600080fd5b610b248261152f565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610bc7611162565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610c37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2e90612dd8565b60405180910390fd5b610c408161125f565b50565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610cb65750610cb582611712565b5b9050919050565b610cc6816114ee565b610d05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cfc90612cb4565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610d8383610880565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610dd583610880565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610e175750610e168185610b2b565b5b80610e5557508373ffffffffffffffffffffffffffffffffffffffff16610e3d84610438565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610e7e82610880565b73ffffffffffffffffffffffffffffffffffffffff1614610ed4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ecb90612e6a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3b90612efc565b60405180910390fd5b610f5183838360016117f4565b8273ffffffffffffffffffffffffffffffffffffffff16610f7182610880565b73ffffffffffffffffffffffffffffffffffffffff1614610fc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fbe90612e6a565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611153838383600161191a565b505050565b6000612710905090565b61116a610d08565b73ffffffffffffffffffffffffffffffffffffffff166111886109d3565b73ffffffffffffffffffffffffffffffffffffffff16146111de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d590612f68565b60405180910390fd5b565b600081600001549050919050565b6001816000016000828254019250508190555050565b61121e828260405180602001604052806000815250611920565b5050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611394576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138b90612fd4565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161148591906122d7565b60405180910390a3505050565b61149d848484610e5e565b6114a98484848461197b565b6114e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114df90613066565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff1661151083611222565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60606000600a6000848152602001908152602001600020805461155190612997565b80601f016020809104026020016040519081016040528092919081815260200182805461157d90612997565b80156115ca5780601f1061159f576101008083540402835291602001916115ca565b820191906000526020600020905b8154815290600101906020018083116115ad57829003601f168201915b505050505090506000600b600085815260200190815260200160002080546115f190612997565b80601f016020809104026020016040519081016040528092919081815260200182805461161d90612997565b801561166a5780601f1061163f5761010080835404028352916020019161166a565b820191906000526020600020905b81548152906001019060200180831161164d57829003601f168201915b505050505090506000604051806080016040528060428152602001613668604291399050600061169986611b12565b6040516020016116a99190613134565b60405160208183030381529060405290506116e8848383866040516020016116d4949392919061331e565b604051602081830303815290604052611bea565b6040516020016116f89190613400565b604051602081830303815290604052945050505050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806117dd57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806117ed57506117ec82611d82565b5b9050919050565b600181111561191457600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146118885780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118809190613422565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146119135780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461190b9190613456565b925050819055505b5b50505050565b50505050565b61192a8383611dec565b611937600084848461197b565b611976576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196d90613066565b60405180910390fd5b505050565b600061199c8473ffffffffffffffffffffffffffffffffffffffff1661200a565b15611b05578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026119c5610d08565b8786866040518563ffffffff1660e01b81526004016119e79493929190613501565b602060405180830381600087803b158015611a0157600080fd5b505af1925050508015611a3257506040513d601f19601f82011682018060405250810190611a2f9190613562565b60015b611ab5573d8060008114611a62576040519150601f19603f3d011682016040523d82523d6000602084013e611a67565b606091505b50600081511415611aad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa490613066565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611b0a565b600190505b949350505050565b606060006001611b218461202d565b01905060008167ffffffffffffffff811115611b4057611b3f6125ad565b5b6040519080825280601f01601f191660200182016040528015611b725781602001600182028036833780820191505090505b509050600082602001820190505b600115611bdf578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611bc957611bc8612c08565b5b0494506000851415611bda57611bdf565b611b80565b819350505050919050565b60606000825190506000811415611c135760405180602001604052806000815250915050611d7d565b60006003600283611c249190613456565b611c2e9190612c37565b6004611c3a9190612bae565b90506000602082611c4b9190613456565b67ffffffffffffffff811115611c6457611c636125ad565b5b6040519080825280601f01601f191660200182016040528015611c965781602001600182028036833780820191505090505b50905060006040518060600160405280604081526020016136aa604091399050600181016020830160005b86811015611d3a5760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050611cc1565b506003860660018114611d545760028114611d6457611d6f565b613d3d60f01b6002830352611d6f565b603d60f81b60018303525b508484525050819450505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e53906135db565b60405180910390fd5b611e65816114ee565b15611ea5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9c90613647565b60405180910390fd5b611eb36000838360016117f4565b611ebc816114ee565b15611efc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef390613647565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461200660008383600161191a565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061208b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161208157612080612c08565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106120c8576d04ee2d6d415b85acef810000000083816120be576120bd612c08565b5b0492506020810190505b662386f26fc1000083106120f757662386f26fc1000083816120ed576120ec612c08565b5b0492506010810190505b6305f5e1008310612120576305f5e100838161211657612115612c08565b5b0492506008810190505b612710831061214557612710838161213b5761213a612c08565b5b0492506004810190505b60648310612168576064838161215e5761215d612c08565b5b0492506002810190505b600a8310612177576001810190505b80915050919050565b82805461218c90612997565b90600052602060002090601f0160209004810192826121ae57600085556121f5565b82601f106121c757805160ff19168380011785556121f5565b828001600101855582156121f5579182015b828111156121f45782518255916020019190600101906121d9565b5b5090506122029190612206565b5090565b5b8082111561221f576000816000905550600101612207565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61226c81612237565b811461227757600080fd5b50565b60008135905061228981612263565b92915050565b6000602082840312156122a5576122a461222d565b5b60006122b38482850161227a565b91505092915050565b60008115159050919050565b6122d1816122bc565b82525050565b60006020820190506122ec60008301846122c8565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561232c578082015181840152602081019050612311565b8381111561233b576000848401525b50505050565b6000601f19601f8301169050919050565b600061235d826122f2565b61236781856122fd565b935061237781856020860161230e565b61238081612341565b840191505092915050565b600060208201905081810360008301526123a58184612352565b905092915050565b6000819050919050565b6123c0816123ad565b81146123cb57600080fd5b50565b6000813590506123dd816123b7565b92915050565b6000602082840312156123f9576123f861222d565b5b6000612407848285016123ce565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061243b82612410565b9050919050565b61244b81612430565b82525050565b60006020820190506124666000830184612442565b92915050565b61247581612430565b811461248057600080fd5b50565b6000813590506124928161246c565b92915050565b600080604083850312156124af576124ae61222d565b5b60006124bd85828601612483565b92505060206124ce858286016123ce565b9150509250929050565b6000806000606084860312156124f1576124f061222d565b5b60006124ff86828701612483565b935050602061251086828701612483565b9250506040612521868287016123ce565b9150509250925092565b600080604083850312156125425761254161222d565b5b6000612550858286016123ce565b9250506020612561858286016123ce565b9150509250929050565b612574816123ad565b82525050565b600060408201905061258f6000830185612442565b61259c602083018461256b565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125e582612341565b810181811067ffffffffffffffff82111715612604576126036125ad565b5b80604052505050565b6000612617612223565b905061262382826125dc565b919050565b600067ffffffffffffffff821115612643576126426125ad565b5b61264c82612341565b9050602081019050919050565b82818337600083830152505050565b600061267b61267684612628565b61260d565b905082815260208101848484011115612697576126966125a8565b5b6126a2848285612659565b509392505050565b600082601f8301126126bf576126be6125a3565b5b81356126cf848260208601612668565b91505092915050565b600080604083850312156126ef576126ee61222d565b5b600083013567ffffffffffffffff81111561270d5761270c612232565b5b612719858286016126aa565b925050602083013567ffffffffffffffff81111561273a57612739612232565b5b612746858286016126aa565b9150509250929050565b6000602082840312156127665761276561222d565b5b600061277484828501612483565b91505092915050565b6000602082019050612792600083018461256b565b92915050565b6127a1816122bc565b81146127ac57600080fd5b50565b6000813590506127be81612798565b92915050565b600080604083850312156127db576127da61222d565b5b60006127e985828601612483565b92505060206127fa858286016127af565b9150509250929050565b600067ffffffffffffffff82111561281f5761281e6125ad565b5b61282882612341565b9050602081019050919050565b600061284861284384612804565b61260d565b905082815260208101848484011115612864576128636125a8565b5b61286f848285612659565b509392505050565b600082601f83011261288c5761288b6125a3565b5b813561289c848260208601612835565b91505092915050565b600080600080608085870312156128bf576128be61222d565b5b60006128cd87828801612483565b94505060206128de87828801612483565b93505060406128ef878288016123ce565b925050606085013567ffffffffffffffff8111156129105761290f612232565b5b61291c87828801612877565b91505092959194509250565b6000806040838503121561293f5761293e61222d565b5b600061294d85828601612483565b925050602061295e85828601612483565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806129af57607f821691505b602082108114156129c3576129c2612968565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000612a256021836122fd565b9150612a30826129c9565b604082019050919050565b60006020820190508181036000830152612a5481612a18565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612ab7603d836122fd565b9150612ac282612a5b565b604082019050919050565b60006020820190508181036000830152612ae681612aaa565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000612b49602d836122fd565b9150612b5482612aed565b604082019050919050565b60006020820190508181036000830152612b7881612b3c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb9826123ad565b9150612bc4836123ad565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612bfd57612bfc612b7f565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612c42826123ad565b9150612c4d836123ad565b925082612c5d57612c5c612c08565b5b828204905092915050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000612c9e6018836122fd565b9150612ca982612c68565b602082019050919050565b60006020820190508181036000830152612ccd81612c91565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612d306029836122fd565b9150612d3b82612cd4565b604082019050919050565b60006020820190508181036000830152612d5f81612d23565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612dc26026836122fd565b9150612dcd82612d66565b604082019050919050565b60006020820190508181036000830152612df181612db5565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000612e546025836122fd565b9150612e5f82612df8565b604082019050919050565b60006020820190508181036000830152612e8381612e47565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000612ee66024836122fd565b9150612ef182612e8a565b604082019050919050565b60006020820190508181036000830152612f1581612ed9565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612f526020836122fd565b9150612f5d82612f1c565b602082019050919050565b60006020820190508181036000830152612f8181612f45565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000612fbe6019836122fd565b9150612fc982612f88565b602082019050919050565b60006020820190508181036000830152612fed81612fb1565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006130506032836122fd565b915061305b82612ff4565b604082019050919050565b6000602082019050818103600083015261307f81613043565b9050919050565b600081905092915050565b7f68747470733a2f2f6e66742e6879756e6a656f6e676c696d2e636f6d2f63617460008201527f6e61702f00000000000000000000000000000000000000000000000000000000602082015250565b60006130ed602483613086565b91506130f882613091565b602482019050919050565b600061310e826122f2565b6131188185613086565b935061312881856020860161230e565b80840191505092915050565b600061313f826130e0565b915061314b8284613103565b915081905092915050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000600082015250565b600061318c600983613086565b915061319782613156565b600982019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b60006131d8600283613086565b91506131e3826131a2565b600282019050919050565b7f226465736372697074696f6e223a220000000000000000000000000000000000600082015250565b6000613224600f83613086565b915061322f826131ee565b600f82019050919050565b7f2265787465726e616c5f75726c223a2200000000000000000000000000000000600082015250565b6000613270601083613086565b915061327b8261323a565b601082019050919050565b7f22696d616765223a220000000000000000000000000000000000000000000000600082015250565b60006132bc600983613086565b91506132c782613286565b600982019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b6000613308600283613086565b9150613313826132d2565b600282019050919050565b60006133298261317f565b91506133358287613103565b9150613340826131cb565b915061334b82613217565b91506133578286613103565b9150613362826131cb565b915061336d82613263565b91506133798285613103565b9150613384826131cb565b915061338f826132af565b915061339b8284613103565b91506133a6826132fb565b915081905095945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006133ea601d83613086565b91506133f5826133b4565b601d82019050919050565b600061340b826133dd565b91506134178284613103565b915081905092915050565b600061342d826123ad565b9150613438836123ad565b92508282101561344b5761344a612b7f565b5b828203905092915050565b6000613461826123ad565b915061346c836123ad565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156134a1576134a0612b7f565b5b828201905092915050565b600081519050919050565b600082825260208201905092915050565b60006134d3826134ac565b6134dd81856134b7565b93506134ed81856020860161230e565b6134f681612341565b840191505092915050565b60006080820190506135166000830187612442565b6135236020830186612442565b613530604083018561256b565b818103606083015261354281846134c8565b905095945050505050565b60008151905061355c81612263565b92915050565b6000602082840312156135785761357761222d565b5b60006135868482850161354d565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006135c56020836122fd565b91506135d08261358f565b602082019050919050565b600060208201905081810360008301526135f4816135b8565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000613631601c836122fd565b915061363c826135fb565b602082019050919050565b6000602082019050818103600083015261366081613624565b905091905056fe46696775726520666561747572656420696e202749736c616e6473206f6620746865204d696e64202d204361746e617027206279204879756e6a656f6e67204c696d4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212207074158534e3cfdf447f7eeadce51c7cb7f828ac51bf5efdbc4239ffa61a821664736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101165760003560e01c806370a08231116100a2578063a22cb46511610071578063a22cb465146102e0578063b88d4fde146102fc578063c87b56dd14610318578063e985e9c514610348578063f2fde38b1461037857610116565b806370a082311461026a578063715018a61461029a5780638da5cb5b146102a457806395d89b41146102c257610116565b806323b872dd116100e957806323b872dd146101b55780632a55205a146101d157806342842e0e146102025780634fa1f7ae1461021e5780636352211e1461023a57610116565b806301ffc9a71461011b57806306fdde031461014b578063081812fc14610169578063095ea7b314610199575b600080fd5b6101356004803603810190610130919061228f565b610394565b60405161014291906122d7565b60405180910390f35b6101536103a6565b604051610160919061238b565b60405180910390f35b610183600480360381019061017e91906123e3565b610438565b6040516101909190612451565b60405180910390f35b6101b360048036038101906101ae9190612498565b61047e565b005b6101cf60048036038101906101ca91906124d8565b610596565b005b6101eb60048036038101906101e6919061252b565b6105f6565b6040516101f992919061257a565b60405180910390f35b61021c600480360381019061021791906124d8565b6107e1565b005b610238600480360381019061023391906126d8565b610801565b005b610254600480360381019061024f91906123e3565b610880565b6040516102619190612451565b60405180910390f35b610284600480360381019061027f9190612750565b610907565b604051610291919061277d565b60405180910390f35b6102a26109bf565b005b6102ac6109d3565b6040516102b99190612451565b60405180910390f35b6102ca6109fd565b6040516102d7919061238b565b60405180910390f35b6102fa60048036038101906102f591906127c4565b610a8f565b005b610316600480360381019061031191906128a5565b610aa5565b005b610332600480360381019061032d91906123e3565b610b07565b60405161033f919061238b565b60405180910390f35b610362600480360381019061035d9190612928565b610b2b565b60405161036f91906122d7565b60405180910390f35b610392600480360381019061038d9190612750565b610bbf565b005b600061039f82610c43565b9050919050565b6060600080546103b590612997565b80601f01602080910402602001604051908101604052809291908181526020018280546103e190612997565b801561042e5780601f106104035761010080835404028352916020019161042e565b820191906000526020600020905b81548152906001019060200180831161041157829003601f168201915b5050505050905090565b600061044382610cbd565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061048982610880565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156104fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f190612a3b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610519610d08565b73ffffffffffffffffffffffffffffffffffffffff161480610548575061054781610542610d08565b610b2b565b5b610587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161057e90612acd565b60405180910390fd5b6105918383610d10565b505050565b6105a76105a1610d08565b82610dc9565b6105e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105dd90612b5f565b60405180910390fd5b6105f1838383610e5e565b505050565b6000806000600860008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16141561078c5760076040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610796611158565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff16866107c29190612bae565b6107cc9190612c37565b90508160000151819350935050509250929050565b6107fc83838360405180602001604052806000815250610aa5565b505050565b610809611162565b600061081560096111e0565b905061082160096111ee565b82600a60008381526020019081526020016000209080519060200190610848929190612180565b5081600b60008381526020019081526020016000209080519060200190610870929190612180565b5061087b3382611204565b505050565b60008061088c83611222565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156108fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f590612cb4565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610978576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096f90612d46565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6109c7611162565b6109d1600061125f565b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060018054610a0c90612997565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3890612997565b8015610a855780601f10610a5a57610100808354040283529160200191610a85565b820191906000526020600020905b815481529060010190602001808311610a6857829003601f168201915b5050505050905090565b610aa1610a9a610d08565b8383611325565b5050565b610ab6610ab0610d08565b83610dc9565b610af5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aec90612b5f565b60405180910390fd5b610b0184848484611492565b50505050565b6060610b12826114ee565b610b1b57600080fd5b610b248261152f565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610bc7611162565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610c37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2e90612dd8565b60405180910390fd5b610c408161125f565b50565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610cb65750610cb582611712565b5b9050919050565b610cc6816114ee565b610d05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cfc90612cb4565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610d8383610880565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610dd583610880565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610e175750610e168185610b2b565b5b80610e5557508373ffffffffffffffffffffffffffffffffffffffff16610e3d84610438565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610e7e82610880565b73ffffffffffffffffffffffffffffffffffffffff1614610ed4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ecb90612e6a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3b90612efc565b60405180910390fd5b610f5183838360016117f4565b8273ffffffffffffffffffffffffffffffffffffffff16610f7182610880565b73ffffffffffffffffffffffffffffffffffffffff1614610fc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fbe90612e6a565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611153838383600161191a565b505050565b6000612710905090565b61116a610d08565b73ffffffffffffffffffffffffffffffffffffffff166111886109d3565b73ffffffffffffffffffffffffffffffffffffffff16146111de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d590612f68565b60405180910390fd5b565b600081600001549050919050565b6001816000016000828254019250508190555050565b61121e828260405180602001604052806000815250611920565b5050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611394576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138b90612fd4565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161148591906122d7565b60405180910390a3505050565b61149d848484610e5e565b6114a98484848461197b565b6114e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114df90613066565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff1661151083611222565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b60606000600a6000848152602001908152602001600020805461155190612997565b80601f016020809104026020016040519081016040528092919081815260200182805461157d90612997565b80156115ca5780601f1061159f576101008083540402835291602001916115ca565b820191906000526020600020905b8154815290600101906020018083116115ad57829003601f168201915b505050505090506000600b600085815260200190815260200160002080546115f190612997565b80601f016020809104026020016040519081016040528092919081815260200182805461161d90612997565b801561166a5780601f1061163f5761010080835404028352916020019161166a565b820191906000526020600020905b81548152906001019060200180831161164d57829003601f168201915b505050505090506000604051806080016040528060428152602001613668604291399050600061169986611b12565b6040516020016116a99190613134565b60405160208183030381529060405290506116e8848383866040516020016116d4949392919061331e565b604051602081830303815290604052611bea565b6040516020016116f89190613400565b604051602081830303815290604052945050505050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806117dd57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806117ed57506117ec82611d82565b5b9050919050565b600181111561191457600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146118885780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118809190613422565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146119135780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461190b9190613456565b925050819055505b5b50505050565b50505050565b61192a8383611dec565b611937600084848461197b565b611976576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196d90613066565b60405180910390fd5b505050565b600061199c8473ffffffffffffffffffffffffffffffffffffffff1661200a565b15611b05578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026119c5610d08565b8786866040518563ffffffff1660e01b81526004016119e79493929190613501565b602060405180830381600087803b158015611a0157600080fd5b505af1925050508015611a3257506040513d601f19601f82011682018060405250810190611a2f9190613562565b60015b611ab5573d8060008114611a62576040519150601f19603f3d011682016040523d82523d6000602084013e611a67565b606091505b50600081511415611aad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa490613066565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050611b0a565b600190505b949350505050565b606060006001611b218461202d565b01905060008167ffffffffffffffff811115611b4057611b3f6125ad565b5b6040519080825280601f01601f191660200182016040528015611b725781602001600182028036833780820191505090505b509050600082602001820190505b600115611bdf578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611bc957611bc8612c08565b5b0494506000851415611bda57611bdf565b611b80565b819350505050919050565b60606000825190506000811415611c135760405180602001604052806000815250915050611d7d565b60006003600283611c249190613456565b611c2e9190612c37565b6004611c3a9190612bae565b90506000602082611c4b9190613456565b67ffffffffffffffff811115611c6457611c636125ad565b5b6040519080825280601f01601f191660200182016040528015611c965781602001600182028036833780820191505090505b50905060006040518060600160405280604081526020016136aa604091399050600181016020830160005b86811015611d3a5760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050611cc1565b506003860660018114611d545760028114611d6457611d6f565b613d3d60f01b6002830352611d6f565b603d60f81b60018303525b508484525050819450505050505b919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e53906135db565b60405180910390fd5b611e65816114ee565b15611ea5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9c90613647565b60405180910390fd5b611eb36000838360016117f4565b611ebc816114ee565b15611efc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef390613647565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461200660008383600161191a565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061208b577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161208157612080612c08565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106120c8576d04ee2d6d415b85acef810000000083816120be576120bd612c08565b5b0492506020810190505b662386f26fc1000083106120f757662386f26fc1000083816120ed576120ec612c08565b5b0492506010810190505b6305f5e1008310612120576305f5e100838161211657612115612c08565b5b0492506008810190505b612710831061214557612710838161213b5761213a612c08565b5b0492506004810190505b60648310612168576064838161215e5761215d612c08565b5b0492506002810190505b600a8310612177576001810190505b80915050919050565b82805461218c90612997565b90600052602060002090601f0160209004810192826121ae57600085556121f5565b82601f106121c757805160ff19168380011785556121f5565b828001600101855582156121f5579182015b828111156121f45782518255916020019190600101906121d9565b5b5090506122029190612206565b5090565b5b8082111561221f576000816000905550600101612207565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61226c81612237565b811461227757600080fd5b50565b60008135905061228981612263565b92915050565b6000602082840312156122a5576122a461222d565b5b60006122b38482850161227a565b91505092915050565b60008115159050919050565b6122d1816122bc565b82525050565b60006020820190506122ec60008301846122c8565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561232c578082015181840152602081019050612311565b8381111561233b576000848401525b50505050565b6000601f19601f8301169050919050565b600061235d826122f2565b61236781856122fd565b935061237781856020860161230e565b61238081612341565b840191505092915050565b600060208201905081810360008301526123a58184612352565b905092915050565b6000819050919050565b6123c0816123ad565b81146123cb57600080fd5b50565b6000813590506123dd816123b7565b92915050565b6000602082840312156123f9576123f861222d565b5b6000612407848285016123ce565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061243b82612410565b9050919050565b61244b81612430565b82525050565b60006020820190506124666000830184612442565b92915050565b61247581612430565b811461248057600080fd5b50565b6000813590506124928161246c565b92915050565b600080604083850312156124af576124ae61222d565b5b60006124bd85828601612483565b92505060206124ce858286016123ce565b9150509250929050565b6000806000606084860312156124f1576124f061222d565b5b60006124ff86828701612483565b935050602061251086828701612483565b9250506040612521868287016123ce565b9150509250925092565b600080604083850312156125425761254161222d565b5b6000612550858286016123ce565b9250506020612561858286016123ce565b9150509250929050565b612574816123ad565b82525050565b600060408201905061258f6000830185612442565b61259c602083018461256b565b9392505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125e582612341565b810181811067ffffffffffffffff82111715612604576126036125ad565b5b80604052505050565b6000612617612223565b905061262382826125dc565b919050565b600067ffffffffffffffff821115612643576126426125ad565b5b61264c82612341565b9050602081019050919050565b82818337600083830152505050565b600061267b61267684612628565b61260d565b905082815260208101848484011115612697576126966125a8565b5b6126a2848285612659565b509392505050565b600082601f8301126126bf576126be6125a3565b5b81356126cf848260208601612668565b91505092915050565b600080604083850312156126ef576126ee61222d565b5b600083013567ffffffffffffffff81111561270d5761270c612232565b5b612719858286016126aa565b925050602083013567ffffffffffffffff81111561273a57612739612232565b5b612746858286016126aa565b9150509250929050565b6000602082840312156127665761276561222d565b5b600061277484828501612483565b91505092915050565b6000602082019050612792600083018461256b565b92915050565b6127a1816122bc565b81146127ac57600080fd5b50565b6000813590506127be81612798565b92915050565b600080604083850312156127db576127da61222d565b5b60006127e985828601612483565b92505060206127fa858286016127af565b9150509250929050565b600067ffffffffffffffff82111561281f5761281e6125ad565b5b61282882612341565b9050602081019050919050565b600061284861284384612804565b61260d565b905082815260208101848484011115612864576128636125a8565b5b61286f848285612659565b509392505050565b600082601f83011261288c5761288b6125a3565b5b813561289c848260208601612835565b91505092915050565b600080600080608085870312156128bf576128be61222d565b5b60006128cd87828801612483565b94505060206128de87828801612483565b93505060406128ef878288016123ce565b925050606085013567ffffffffffffffff8111156129105761290f612232565b5b61291c87828801612877565b91505092959194509250565b6000806040838503121561293f5761293e61222d565b5b600061294d85828601612483565b925050602061295e85828601612483565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806129af57607f821691505b602082108114156129c3576129c2612968565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000612a256021836122fd565b9150612a30826129c9565b604082019050919050565b60006020820190508181036000830152612a5481612a18565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000612ab7603d836122fd565b9150612ac282612a5b565b604082019050919050565b60006020820190508181036000830152612ae681612aaa565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000612b49602d836122fd565b9150612b5482612aed565b604082019050919050565b60006020820190508181036000830152612b7881612b3c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb9826123ad565b9150612bc4836123ad565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612bfd57612bfc612b7f565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612c42826123ad565b9150612c4d836123ad565b925082612c5d57612c5c612c08565b5b828204905092915050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000612c9e6018836122fd565b9150612ca982612c68565b602082019050919050565b60006020820190508181036000830152612ccd81612c91565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000612d306029836122fd565b9150612d3b82612cd4565b604082019050919050565b60006020820190508181036000830152612d5f81612d23565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612dc26026836122fd565b9150612dcd82612d66565b604082019050919050565b60006020820190508181036000830152612df181612db5565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000612e546025836122fd565b9150612e5f82612df8565b604082019050919050565b60006020820190508181036000830152612e8381612e47565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000612ee66024836122fd565b9150612ef182612e8a565b604082019050919050565b60006020820190508181036000830152612f1581612ed9565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612f526020836122fd565b9150612f5d82612f1c565b602082019050919050565b60006020820190508181036000830152612f8181612f45565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000612fbe6019836122fd565b9150612fc982612f88565b602082019050919050565b60006020820190508181036000830152612fed81612fb1565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006130506032836122fd565b915061305b82612ff4565b604082019050919050565b6000602082019050818103600083015261307f81613043565b9050919050565b600081905092915050565b7f68747470733a2f2f6e66742e6879756e6a656f6e676c696d2e636f6d2f63617460008201527f6e61702f00000000000000000000000000000000000000000000000000000000602082015250565b60006130ed602483613086565b91506130f882613091565b602482019050919050565b600061310e826122f2565b6131188185613086565b935061312881856020860161230e565b80840191505092915050565b600061313f826130e0565b915061314b8284613103565b915081905092915050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000600082015250565b600061318c600983613086565b915061319782613156565b600982019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b60006131d8600283613086565b91506131e3826131a2565b600282019050919050565b7f226465736372697074696f6e223a220000000000000000000000000000000000600082015250565b6000613224600f83613086565b915061322f826131ee565b600f82019050919050565b7f2265787465726e616c5f75726c223a2200000000000000000000000000000000600082015250565b6000613270601083613086565b915061327b8261323a565b601082019050919050565b7f22696d616765223a220000000000000000000000000000000000000000000000600082015250565b60006132bc600983613086565b91506132c782613286565b600982019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b6000613308600283613086565b9150613313826132d2565b600282019050919050565b60006133298261317f565b91506133358287613103565b9150613340826131cb565b915061334b82613217565b91506133578286613103565b9150613362826131cb565b915061336d82613263565b91506133798285613103565b9150613384826131cb565b915061338f826132af565b915061339b8284613103565b91506133a6826132fb565b915081905095945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006133ea601d83613086565b91506133f5826133b4565b601d82019050919050565b600061340b826133dd565b91506134178284613103565b915081905092915050565b600061342d826123ad565b9150613438836123ad565b92508282101561344b5761344a612b7f565b5b828203905092915050565b6000613461826123ad565b915061346c836123ad565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156134a1576134a0612b7f565b5b828201905092915050565b600081519050919050565b600082825260208201905092915050565b60006134d3826134ac565b6134dd81856134b7565b93506134ed81856020860161230e565b6134f681612341565b840191505092915050565b60006080820190506135166000830187612442565b6135236020830186612442565b613530604083018561256b565b818103606083015261354281846134c8565b905095945050505050565b60008151905061355c81612263565b92915050565b6000602082840312156135785761357761222d565b5b60006135868482850161354d565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b60006135c56020836122fd565b91506135d08261358f565b602082019050919050565b600060208201905081810360008301526135f4816135b8565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000613631601c836122fd565b915061363c826135fb565b602082019050919050565b6000602082019050818103600083015261366081613624565b905091905056fe46696775726520666561747572656420696e202749736c616e6473206f6620746865204d696e64202d204361746e617027206279204879756e6a656f6e67204c696d4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212207074158534e3cfdf447f7eeadce51c7cb7f828ac51bf5efdbc4239ffa61a821664736f6c63430008090033
Deployed Bytecode Sourcemap
177:2176:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2183:168;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2406:98:7;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3870:167;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3403:406;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4547:326;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1632:432:6;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;4939:179:7;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;562:279:2;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2125:219:7;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1864:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1824:101:14;;;:::i;:::-;;1194:85;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2568:102:7;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4104:153;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5184:314;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;847:216:2;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4323:162:7;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2074:198:14;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2183:168:2;2285:4;2308:36;2332:11;2308:23;:36::i;:::-;2301:43;;2183:168;;;:::o;2406:98:7:-;2460:13;2492:5;2485:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2406:98;:::o;3870:167::-;3946:7;3965:23;3980:7;3965:14;:23::i;:::-;4006:15;:24;4022:7;4006:24;;;;;;;;;;;;;;;;;;;;;3999:31;;3870:167;;;:::o;3403:406::-;3483:13;3499:23;3514:7;3499:14;:23::i;:::-;3483:39;;3546:5;3540:11;;:2;:11;;;;3532:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;3637:5;3621:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;3646:37;3663:5;3670:12;:10;:12::i;:::-;3646:16;:37::i;:::-;3621:62;3600:170;;;;;;;;;;;;:::i;:::-;;;;;;;;;3781:21;3790:2;3794:7;3781:8;:21::i;:::-;3473:336;3403:406;;:::o;4547:326::-;4736:41;4755:12;:10;:12::i;:::-;4769:7;4736:18;:41::i;:::-;4728:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;4838:28;4848:4;4854:2;4858:7;4838:9;:28::i;:::-;4547:326;;;:::o;1632:432:6:-;1729:7;1738;1757:26;1786:17;:27;1804:8;1786:27;;;;;;;;;;;1757:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1856:1;1828:30;;:7;:16;;;:30;;;1824:90;;;1884:19;1874:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1824:90;1924:21;1989:17;:15;:17::i;:::-;1948:58;;1962:7;:23;;;1949:36;;:10;:36;;;;:::i;:::-;1948:58;;;;:::i;:::-;1924:82;;2025:7;:16;;;2043:13;2017:40;;;;;;1632:432;;;;;:::o;4939:179:7:-;5072:39;5089:4;5095:2;5099:7;5072:39;;;;;;;;;;;;:16;:39::i;:::-;4939:179;;;:::o;562:279:2:-;1087:13:14;:11;:13::i;:::-;648:15:2::1;666:25;:15;:23;:25::i;:::-;648:43;;701:27;:15;:25;:27::i;:::-;756:4;739:5;:14;745:7;739:14;;;;;;;;;;;:21;;;;;;;;;;;;:::i;:::-;;788:5;770:6;:15;777:7;770:15;;;;;;;;;;;:23;;;;;;;;;;;;:::i;:::-;;804:30;814:10;826:7;804:9;:30::i;:::-;638:203;562:279:::0;;:::o;2125:219:7:-;2197:7;2216:13;2232:17;2241:7;2232:8;:17::i;:::-;2216:33;;2284:1;2267:19;;:5;:19;;;;2259:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;2332:5;2325:12;;;2125:219;;;:::o;1864:204::-;1936:7;1980:1;1963:19;;:5;:19;;;;1955:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2045:9;:16;2055:5;2045:16;;;;;;;;;;;;;;;;2038:23;;1864:204;;;:::o;1824:101:14:-;1087:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;1194:85::-;1240:7;1266:6;;;;;;;;;;;1259:13;;1194:85;:::o;2568:102:7:-;2624:13;2656:7;2649:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2568:102;:::o;4104:153::-;4198:52;4217:12;:10;:12::i;:::-;4231:8;4241;4198:18;:52::i;:::-;4104:153;;:::o;5184:314::-;5352:41;5371:12;:10;:12::i;:::-;5385:7;5352:18;:41::i;:::-;5344:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;5453:38;5467:4;5473:2;5477:7;5486:4;5453:13;:38::i;:::-;5184:314;;;;:::o;847:216:2:-;961:13;998:17;1006:8;998:7;:17::i;:::-;990:26;;;;;;1033:23;1047:8;1033:13;:23::i;:::-;1026:30;;847:216;;;:::o;4323:162:7:-;4420:4;4443:18;:25;4462:5;4443:25;;;;;;;;;;;;;;;:35;4469:8;4443:35;;;;;;;;;;;;;;;;;;;;;;;;;4436:42;;4323:162;;;;:::o;2074:198:14:-;1087:13;:11;:13::i;:::-;2182:1:::1;2162:22;;:8;:22;;;;2154:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2237:28;2256:8;2237:18;:28::i;:::-;2074:198:::0;:::o;1369:213:6:-;1471:4;1509:26;1494:41;;;:11;:41;;;;:81;;;;1539:36;1563:11;1539:23;:36::i;:::-;1494:81;1487:88;;1369:213;;;:::o;13401:133:7:-;13482:16;13490:7;13482;:16::i;:::-;13474:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;13401:133;:::o;640:96:3:-;693:7;719:10;712:17;;640:96;:::o;12703:171:7:-;12804:2;12777:15;:24;12793:7;12777:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;12859:7;12855:2;12821:46;;12830:23;12845:7;12830:14;:23::i;:::-;12821:46;;;;;;;;;;;;12703:171;;:::o;7475:261::-;7568:4;7584:13;7600:23;7615:7;7600:14;:23::i;:::-;7584:39;;7652:5;7641:16;;:7;:16;;;:52;;;;7661:32;7678:5;7685:7;7661:16;:32::i;:::-;7641:52;:87;;;;7721:7;7697:31;;:20;7709:7;7697:11;:20::i;:::-;:31;;;7641:87;7633:96;;;7475:261;;;;:::o;11358:1233::-;11512:4;11485:31;;:23;11500:7;11485:14;:23::i;:::-;:31;;;11477:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;11590:1;11576:16;;:2;:16;;;;11568:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;11644:42;11665:4;11671:2;11675:7;11684:1;11644:20;:42::i;:::-;11813:4;11786:31;;:23;11801:7;11786:14;:23::i;:::-;:31;;;11778:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;11928:15;:24;11944:7;11928:24;;;;;;;;;;;;11921:31;;;;;;;;;;;12415:1;12396:9;:15;12406:4;12396:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;12447:1;12430:9;:13;12440:2;12430:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;12487:2;12468:7;:16;12476:7;12468:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;12524:7;12520:2;12505:27;;12514:4;12505:27;;;;;;;;;;;;12543:41;12563:4;12569:2;12573:7;12582:1;12543:19;:41::i;:::-;11358:1233;;;:::o;2339:95:6:-;2397:6;2422:5;2415:12;;2339:95;:::o;1352:130:14:-;1426:12;:10;:12::i;:::-;1415:23;;:7;:5;:7::i;:::-;:23;;;1407:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1352:130::o;827:112:4:-;892:7;918;:14;;;911:21;;827:112;;;:::o;945:123::-;1050:1;1032:7;:14;;;:19;;;;;;;;;;;945:123;:::o;8066:108:7:-;8141:26;8151:2;8155:7;8141:26;;;;;;;;;;;;:9;:26::i;:::-;8066:108;;:::o;6773:115::-;6839:7;6865;:16;6873:7;6865:16;;;;;;;;;;;;;;;;;;;;;6858:23;;6773:115;;;:::o;2426:187:14:-;2499:16;2518:6;;;;;;;;;;;2499:25;;2543:8;2534:6;;:17;;;;;;;;;;;;;;;;;;2597:8;2566:40;;2587:8;2566:40;;;;;;;;;;;;2489:124;2426:187;:::o;13010:307:7:-;13160:8;13151:17;;:5;:17;;;;13143:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;13246:8;13208:18;:25;13227:5;13208:25;;;;;;;;;;;;;;;:35;13234:8;13208:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;13291:8;13269:41;;13284:5;13269:41;;;13301:8;13269:41;;;;;;:::i;:::-;;;;;;;;13010:307;;;:::o;6359:305::-;6509:28;6519:4;6525:2;6529:7;6509:9;:28::i;:::-;6555:47;6578:4;6584:2;6588:7;6597:4;6555:22;:47::i;:::-;6547:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;6359:305;;;;:::o;7191:126::-;7256:4;7308:1;7279:31;;:17;7288:7;7279:8;:17::i;:::-;:31;;;;7272:38;;7191:126;;;:::o;1069:1108:2:-;1156:13;1185:18;1206:5;:15;1212:8;1206:15;;;;;;;;;;;1185:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1231:19;1253:6;:16;1260:8;1253:16;;;;;;;;;;;1231:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1279:25;:95;;;;;;;;;;;;;;;;;;;1384:17;1514:19;:8;:17;:19::i;:::-;1424:123;;;;;;;;:::i;:::-;;;;;;;;;;;;;1384:173;;1690:448;1827:4;1890:11;1961:3;2017:5;1764:326;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1690:13;:448::i;:::-;1599:557;;;;;;;;:::i;:::-;;;;;;;;;;;;;1568:602;;;;;;1069:1108;;;:::o;1505:300:7:-;1607:4;1657:25;1642:40;;;:11;:40;;;;:104;;;;1713:33;1698:48;;;:11;:48;;;;1642:104;:156;;;;1762:36;1786:11;1762:23;:36::i;:::-;1642:156;1623:175;;1505:300;;;:::o;15633:396::-;15817:1;15805:9;:13;15801:222;;;15854:1;15838:18;;:4;:18;;;15834:85;;15895:9;15876;:15;15886:4;15876:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;15834:85;15950:1;15936:16;;:2;:16;;;15932:81;;15989:9;15972;:13;15982:2;15972:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;15932:81;15801:222;15633:396;;;;:::o;16735:153::-;;;;;:::o;8395:309::-;8519:18;8525:2;8529:7;8519:5;:18::i;:::-;8568:53;8599:1;8603:2;8607:7;8616:4;8568:22;:53::i;:::-;8547:150;;;;;;;;;;;;:::i;:::-;;;;;;;;;8395:309;;;:::o;14086:831::-;14235:4;14255:15;:2;:13;;;:15::i;:::-;14251:660;;;14306:2;14290:36;;;14327:12;:10;:12::i;:::-;14341:4;14347:7;14356:4;14290:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;14286:573;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14545:1;14528:6;:13;:18;14524:321;;;14570:60;;;;;;;;;;:::i;:::-;;;;;;;;14524:321;14797:6;14791:13;14782:6;14778:2;14774:15;14767:38;14286:573;14421:41;;;14411:51;;;:6;:51;;;;14404:58;;;;;14251:660;14896:4;14889:11;;14086:831;;;;;;;:::o;410:696:15:-;466:13;515:14;552:1;532:17;543:5;532:10;:17::i;:::-;:21;515:38;;567:20;601:6;590:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;567:41;;622:11;748:6;744:2;740:15;732:6;728:28;721:35;;783:280;790:4;783:280;;;814:5;;;;;;;;953:8;948:2;941:5;937:14;932:30;927:3;919:44;1007:2;998:11;;;;;;:::i;:::-;;;;;1040:1;1031:5;:10;1027:21;;;1043:5;;1027:21;783:280;;;1083:6;1076:13;;;;;410:696;;;:::o;473:1731:1:-;531:13;556:11;570:4;:11;556:25;;602:1;595:3;:8;591:23;;;605:9;;;;;;;;;;;;;;;;;591:23;663:18;701:1;696;690:3;:7;;;;:::i;:::-;689:13;;;;:::i;:::-;684:1;:19;;;;:::i;:::-;663:40;;758:19;803:2;790:10;:15;;;;:::i;:::-;780:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;758:48;;817:18;838:5;;;;;;;;;;;;;;;;;817:26;;904:1;897:5;893:13;948:2;940:6;936:15;996:1;965:931;1018:3;1015:1;1012:10;965:931;;;1070:1;1067;1063:9;1058:14;;1127:8;1122:1;1116:4;1112:12;1106:19;1102:34;1205:4;1197:5;1193:2;1189:14;1185:25;1175:8;1171:40;1165:47;1243:3;1240:1;1236:11;1229:18;;1374:4;1365;1357:5;1353:2;1349:14;1345:25;1335:8;1331:40;1325:47;1321:58;1296:3;1271:126;1264:133;;1428:3;1425:1;1421:11;1414:18;;1558:4;1549;1541:5;1538:1;1534:13;1530:24;1520:8;1516:39;1510:46;1506:57;1481:3;1456:125;1449:132;;1612:3;1609:1;1605:11;1598:18;;1734:4;1725;1718:5;1714:16;1704:8;1700:31;1694:38;1690:49;1665:3;1640:117;1633:124;;1790:3;1785;1781:13;1774:20;;1830:3;1819:9;1812:22;1880:1;1869:9;1865:17;1852:30;;1040:856;;965:931;;;969:42;1926:1;1921:3;1917:11;1946:1;1941:82;;;;2041:1;2036:80;;;;1910:206;;1941:82;2001:6;1996:3;1992:16;1988:1;1977:9;1973:17;1966:43;1941:82;;2036:80;2096:4;2091:3;2087:14;2083:1;2072:9;2068:17;2061:41;1910:206;;2145:10;2137:6;2130:26;863:1303;;2190:6;2176:21;;;;;;473:1731;;;;:::o;829:155:5:-;914:4;952:25;937:40;;;:11;:40;;;;930:47;;829:155;;;:::o;9026:920:7:-;9119:1;9105:16;;:2;:16;;;;9097:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;9177:16;9185:7;9177;:16::i;:::-;9176:17;9168:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;9237:48;9266:1;9270:2;9274:7;9283:1;9237:20;:48::i;:::-;9381:16;9389:7;9381;:16::i;:::-;9380:17;9372:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;9789:1;9772:9;:13;9782:2;9772:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;9830:2;9811:7;:16;9819:7;9811:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;9873:7;9869:2;9848:33;;9865:1;9848:33;;;;;;;;;;;;9892:47;9920:1;9924:2;9928:7;9937:1;9892:19;:47::i;:::-;9026:920;;:::o;1175:320:0:-;1235:4;1487:1;1465:7;:19;;;:23;1458:30;;1175:320;;;:::o;9889:890:13:-;9942:7;9961:14;9978:1;9961:18;;10026:6;10017:5;:15;10013:99;;10061:6;10052:15;;;;;;:::i;:::-;;;;;10095:2;10085:12;;;;10013:99;10138:6;10129:5;:15;10125:99;;10173:6;10164:15;;;;;;:::i;:::-;;;;;10207:2;10197:12;;;;10125:99;10250:6;10241:5;:15;10237:99;;10285:6;10276:15;;;;;;:::i;:::-;;;;;10319:2;10309:12;;;;10237:99;10362:5;10353;:14;10349:96;;10396:5;10387:14;;;;;;:::i;:::-;;;;;10429:1;10419:11;;;;10349:96;10471:5;10462;:14;10458:96;;10505:5;10496:14;;;;;;:::i;:::-;;;;;10538:1;10528:11;;;;10458:96;10580:5;10571;:14;10567:96;;10614:5;10605:14;;;;;;:::i;:::-;;;;;10647:1;10637:11;;;;10567:96;10689:5;10680;:14;10676:64;;10724:1;10714:11;;;;10676:64;10766:6;10759:13;;;9889:890;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:16:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:619::-;5015:6;5023;5031;5080:2;5068:9;5059:7;5055:23;5051:32;5048:119;;;5086:79;;:::i;:::-;5048:119;5206:1;5231:53;5276:7;5267:6;5256:9;5252:22;5231:53;:::i;:::-;5221:63;;5177:117;5333:2;5359:53;5404:7;5395:6;5384:9;5380:22;5359:53;:::i;:::-;5349:63;;5304:118;5461:2;5487:53;5532:7;5523:6;5512:9;5508:22;5487:53;:::i;:::-;5477:63;;5432:118;4938:619;;;;;:::o;5563:474::-;5631:6;5639;5688:2;5676:9;5667:7;5663:23;5659:32;5656:119;;;5694:79;;:::i;:::-;5656:119;5814:1;5839:53;5884:7;5875:6;5864:9;5860:22;5839:53;:::i;:::-;5829:63;;5785:117;5941:2;5967:53;6012:7;6003:6;5992:9;5988:22;5967:53;:::i;:::-;5957:63;;5912:118;5563:474;;;;;:::o;6043:118::-;6130:24;6148:5;6130:24;:::i;:::-;6125:3;6118:37;6043:118;;:::o;6167:332::-;6288:4;6326:2;6315:9;6311:18;6303:26;;6339:71;6407:1;6396:9;6392:17;6383:6;6339:71;:::i;:::-;6420:72;6488:2;6477:9;6473:18;6464:6;6420:72;:::i;:::-;6167:332;;;;;:::o;6505:117::-;6614:1;6611;6604:12;6628:117;6737:1;6734;6727:12;6751:180;6799:77;6796:1;6789:88;6896:4;6893:1;6886:15;6920:4;6917:1;6910:15;6937:281;7020:27;7042:4;7020:27;:::i;:::-;7012:6;7008:40;7150:6;7138:10;7135:22;7114:18;7102:10;7099:34;7096:62;7093:88;;;7161:18;;:::i;:::-;7093:88;7201:10;7197:2;7190:22;6980:238;6937:281;;:::o;7224:129::-;7258:6;7285:20;;:::i;:::-;7275:30;;7314:33;7342:4;7334:6;7314:33;:::i;:::-;7224:129;;;:::o;7359:308::-;7421:4;7511:18;7503:6;7500:30;7497:56;;;7533:18;;:::i;:::-;7497:56;7571:29;7593:6;7571:29;:::i;:::-;7563:37;;7655:4;7649;7645:15;7637:23;;7359:308;;;:::o;7673:154::-;7757:6;7752:3;7747;7734:30;7819:1;7810:6;7805:3;7801:16;7794:27;7673:154;;;:::o;7833:412::-;7911:5;7936:66;7952:49;7994:6;7952:49;:::i;:::-;7936:66;:::i;:::-;7927:75;;8025:6;8018:5;8011:21;8063:4;8056:5;8052:16;8101:3;8092:6;8087:3;8083:16;8080:25;8077:112;;;8108:79;;:::i;:::-;8077:112;8198:41;8232:6;8227:3;8222;8198:41;:::i;:::-;7917:328;7833:412;;;;;:::o;8265:340::-;8321:5;8370:3;8363:4;8355:6;8351:17;8347:27;8337:122;;8378:79;;:::i;:::-;8337:122;8495:6;8482:20;8520:79;8595:3;8587:6;8580:4;8572:6;8568:17;8520:79;:::i;:::-;8511:88;;8327:278;8265:340;;;;:::o;8611:834::-;8699:6;8707;8756:2;8744:9;8735:7;8731:23;8727:32;8724:119;;;8762:79;;:::i;:::-;8724:119;8910:1;8899:9;8895:17;8882:31;8940:18;8932:6;8929:30;8926:117;;;8962:79;;:::i;:::-;8926:117;9067:63;9122:7;9113:6;9102:9;9098:22;9067:63;:::i;:::-;9057:73;;8853:287;9207:2;9196:9;9192:18;9179:32;9238:18;9230:6;9227:30;9224:117;;;9260:79;;:::i;:::-;9224:117;9365:63;9420:7;9411:6;9400:9;9396:22;9365:63;:::i;:::-;9355:73;;9150:288;8611:834;;;;;:::o;9451:329::-;9510:6;9559:2;9547:9;9538:7;9534:23;9530:32;9527:119;;;9565:79;;:::i;:::-;9527:119;9685:1;9710:53;9755:7;9746:6;9735:9;9731:22;9710:53;:::i;:::-;9700:63;;9656:117;9451:329;;;;:::o;9786:222::-;9879:4;9917:2;9906:9;9902:18;9894:26;;9930:71;9998:1;9987:9;9983:17;9974:6;9930:71;:::i;:::-;9786:222;;;;:::o;10014:116::-;10084:21;10099:5;10084:21;:::i;:::-;10077:5;10074:32;10064:60;;10120:1;10117;10110:12;10064:60;10014:116;:::o;10136:133::-;10179:5;10217:6;10204:20;10195:29;;10233:30;10257:5;10233:30;:::i;:::-;10136:133;;;;:::o;10275:468::-;10340:6;10348;10397:2;10385:9;10376:7;10372:23;10368:32;10365:119;;;10403:79;;:::i;:::-;10365:119;10523:1;10548:53;10593:7;10584:6;10573:9;10569:22;10548:53;:::i;:::-;10538:63;;10494:117;10650:2;10676:50;10718:7;10709:6;10698:9;10694:22;10676:50;:::i;:::-;10666:60;;10621:115;10275:468;;;;;:::o;10749:307::-;10810:4;10900:18;10892:6;10889:30;10886:56;;;10922:18;;:::i;:::-;10886:56;10960:29;10982:6;10960:29;:::i;:::-;10952:37;;11044:4;11038;11034:15;11026:23;;10749:307;;;:::o;11062:410::-;11139:5;11164:65;11180:48;11221:6;11180:48;:::i;:::-;11164:65;:::i;:::-;11155:74;;11252:6;11245:5;11238:21;11290:4;11283:5;11279:16;11328:3;11319:6;11314:3;11310:16;11307:25;11304:112;;;11335:79;;:::i;:::-;11304:112;11425:41;11459:6;11454:3;11449;11425:41;:::i;:::-;11145:327;11062:410;;;;;:::o;11491:338::-;11546:5;11595:3;11588:4;11580:6;11576:17;11572:27;11562:122;;11603:79;;:::i;:::-;11562:122;11720:6;11707:20;11745:78;11819:3;11811:6;11804:4;11796:6;11792:17;11745:78;:::i;:::-;11736:87;;11552:277;11491:338;;;;:::o;11835:943::-;11930:6;11938;11946;11954;12003:3;11991:9;11982:7;11978:23;11974:33;11971:120;;;12010:79;;:::i;:::-;11971:120;12130:1;12155:53;12200:7;12191:6;12180:9;12176:22;12155:53;:::i;:::-;12145:63;;12101:117;12257:2;12283:53;12328:7;12319:6;12308:9;12304:22;12283:53;:::i;:::-;12273:63;;12228:118;12385:2;12411:53;12456:7;12447:6;12436:9;12432:22;12411:53;:::i;:::-;12401:63;;12356:118;12541:2;12530:9;12526:18;12513:32;12572:18;12564:6;12561:30;12558:117;;;12594:79;;:::i;:::-;12558:117;12699:62;12753:7;12744:6;12733:9;12729:22;12699:62;:::i;:::-;12689:72;;12484:287;11835:943;;;;;;;:::o;12784:474::-;12852:6;12860;12909:2;12897:9;12888:7;12884:23;12880:32;12877:119;;;12915:79;;:::i;:::-;12877:119;13035:1;13060:53;13105:7;13096:6;13085:9;13081:22;13060:53;:::i;:::-;13050:63;;13006:117;13162:2;13188:53;13233:7;13224:6;13213:9;13209:22;13188:53;:::i;:::-;13178:63;;13133:118;12784:474;;;;;:::o;13264:180::-;13312:77;13309:1;13302:88;13409:4;13406:1;13399:15;13433:4;13430:1;13423:15;13450:320;13494:6;13531:1;13525:4;13521:12;13511:22;;13578:1;13572:4;13568:12;13599:18;13589:81;;13655:4;13647:6;13643:17;13633:27;;13589:81;13717:2;13709:6;13706:14;13686:18;13683:38;13680:84;;;13736:18;;:::i;:::-;13680:84;13501:269;13450:320;;;:::o;13776:220::-;13916:34;13912:1;13904:6;13900:14;13893:58;13985:3;13980:2;13972:6;13968:15;13961:28;13776:220;:::o;14002:366::-;14144:3;14165:67;14229:2;14224:3;14165:67;:::i;:::-;14158:74;;14241:93;14330:3;14241:93;:::i;:::-;14359:2;14354:3;14350:12;14343:19;;14002:366;;;:::o;14374:419::-;14540:4;14578:2;14567:9;14563:18;14555:26;;14627:9;14621:4;14617:20;14613:1;14602:9;14598:17;14591:47;14655:131;14781:4;14655:131;:::i;:::-;14647:139;;14374:419;;;:::o;14799:248::-;14939:34;14935:1;14927:6;14923:14;14916:58;15008:31;15003:2;14995:6;14991:15;14984:56;14799:248;:::o;15053:366::-;15195:3;15216:67;15280:2;15275:3;15216:67;:::i;:::-;15209:74;;15292:93;15381:3;15292:93;:::i;:::-;15410:2;15405:3;15401:12;15394:19;;15053:366;;;:::o;15425:419::-;15591:4;15629:2;15618:9;15614:18;15606:26;;15678:9;15672:4;15668:20;15664:1;15653:9;15649:17;15642:47;15706:131;15832:4;15706:131;:::i;:::-;15698:139;;15425:419;;;:::o;15850:232::-;15990:34;15986:1;15978:6;15974:14;15967:58;16059:15;16054:2;16046:6;16042:15;16035:40;15850:232;:::o;16088:366::-;16230:3;16251:67;16315:2;16310:3;16251:67;:::i;:::-;16244:74;;16327:93;16416:3;16327:93;:::i;:::-;16445:2;16440:3;16436:12;16429:19;;16088:366;;;:::o;16460:419::-;16626:4;16664:2;16653:9;16649:18;16641:26;;16713:9;16707:4;16703:20;16699:1;16688:9;16684:17;16677:47;16741:131;16867:4;16741:131;:::i;:::-;16733:139;;16460:419;;;:::o;16885:180::-;16933:77;16930:1;16923:88;17030:4;17027:1;17020:15;17054:4;17051:1;17044:15;17071:348;17111:7;17134:20;17152:1;17134:20;:::i;:::-;17129:25;;17168:20;17186:1;17168:20;:::i;:::-;17163:25;;17356:1;17288:66;17284:74;17281:1;17278:81;17273:1;17266:9;17259:17;17255:105;17252:131;;;17363:18;;:::i;:::-;17252:131;17411:1;17408;17404:9;17393:20;;17071:348;;;;:::o;17425:180::-;17473:77;17470:1;17463:88;17570:4;17567:1;17560:15;17594:4;17591:1;17584:15;17611:185;17651:1;17668:20;17686:1;17668:20;:::i;:::-;17663:25;;17702:20;17720:1;17702:20;:::i;:::-;17697:25;;17741:1;17731:35;;17746:18;;:::i;:::-;17731:35;17788:1;17785;17781:9;17776:14;;17611:185;;;;:::o;17802:174::-;17942:26;17938:1;17930:6;17926:14;17919:50;17802:174;:::o;17982:366::-;18124:3;18145:67;18209:2;18204:3;18145:67;:::i;:::-;18138:74;;18221:93;18310:3;18221:93;:::i;:::-;18339:2;18334:3;18330:12;18323:19;;17982:366;;;:::o;18354:419::-;18520:4;18558:2;18547:9;18543:18;18535:26;;18607:9;18601:4;18597:20;18593:1;18582:9;18578:17;18571:47;18635:131;18761:4;18635:131;:::i;:::-;18627:139;;18354:419;;;:::o;18779:228::-;18919:34;18915:1;18907:6;18903:14;18896:58;18988:11;18983:2;18975:6;18971:15;18964:36;18779:228;:::o;19013:366::-;19155:3;19176:67;19240:2;19235:3;19176:67;:::i;:::-;19169:74;;19252:93;19341:3;19252:93;:::i;:::-;19370:2;19365:3;19361:12;19354:19;;19013:366;;;:::o;19385:419::-;19551:4;19589:2;19578:9;19574:18;19566:26;;19638:9;19632:4;19628:20;19624:1;19613:9;19609:17;19602:47;19666:131;19792:4;19666:131;:::i;:::-;19658:139;;19385:419;;;:::o;19810:225::-;19950:34;19946:1;19938:6;19934:14;19927:58;20019:8;20014:2;20006:6;20002:15;19995:33;19810:225;:::o;20041:366::-;20183:3;20204:67;20268:2;20263:3;20204:67;:::i;:::-;20197:74;;20280:93;20369:3;20280:93;:::i;:::-;20398:2;20393:3;20389:12;20382:19;;20041:366;;;:::o;20413:419::-;20579:4;20617:2;20606:9;20602:18;20594:26;;20666:9;20660:4;20656:20;20652:1;20641:9;20637:17;20630:47;20694:131;20820:4;20694:131;:::i;:::-;20686:139;;20413:419;;;:::o;20838:224::-;20978:34;20974:1;20966:6;20962:14;20955:58;21047:7;21042:2;21034:6;21030:15;21023:32;20838:224;:::o;21068:366::-;21210:3;21231:67;21295:2;21290:3;21231:67;:::i;:::-;21224:74;;21307:93;21396:3;21307:93;:::i;:::-;21425:2;21420:3;21416:12;21409:19;;21068:366;;;:::o;21440:419::-;21606:4;21644:2;21633:9;21629:18;21621:26;;21693:9;21687:4;21683:20;21679:1;21668:9;21664:17;21657:47;21721:131;21847:4;21721:131;:::i;:::-;21713:139;;21440:419;;;:::o;21865:223::-;22005:34;22001:1;21993:6;21989:14;21982:58;22074:6;22069:2;22061:6;22057:15;22050:31;21865:223;:::o;22094:366::-;22236:3;22257:67;22321:2;22316:3;22257:67;:::i;:::-;22250:74;;22333:93;22422:3;22333:93;:::i;:::-;22451:2;22446:3;22442:12;22435:19;;22094:366;;;:::o;22466:419::-;22632:4;22670:2;22659:9;22655:18;22647:26;;22719:9;22713:4;22709:20;22705:1;22694:9;22690:17;22683:47;22747:131;22873:4;22747:131;:::i;:::-;22739:139;;22466:419;;;:::o;22891:182::-;23031:34;23027:1;23019:6;23015:14;23008:58;22891:182;:::o;23079:366::-;23221:3;23242:67;23306:2;23301:3;23242:67;:::i;:::-;23235:74;;23318:93;23407:3;23318:93;:::i;:::-;23436:2;23431:3;23427:12;23420:19;;23079:366;;;:::o;23451:419::-;23617:4;23655:2;23644:9;23640:18;23632:26;;23704:9;23698:4;23694:20;23690:1;23679:9;23675:17;23668:47;23732:131;23858:4;23732:131;:::i;:::-;23724:139;;23451:419;;;:::o;23876:175::-;24016:27;24012:1;24004:6;24000:14;23993:51;23876:175;:::o;24057:366::-;24199:3;24220:67;24284:2;24279:3;24220:67;:::i;:::-;24213:74;;24296:93;24385:3;24296:93;:::i;:::-;24414:2;24409:3;24405:12;24398:19;;24057:366;;;:::o;24429:419::-;24595:4;24633:2;24622:9;24618:18;24610:26;;24682:9;24676:4;24672:20;24668:1;24657:9;24653:17;24646:47;24710:131;24836:4;24710:131;:::i;:::-;24702:139;;24429:419;;;:::o;24854:237::-;24994:34;24990:1;24982:6;24978:14;24971:58;25063:20;25058:2;25050:6;25046:15;25039:45;24854:237;:::o;25097:366::-;25239:3;25260:67;25324:2;25319:3;25260:67;:::i;:::-;25253:74;;25336:93;25425:3;25336:93;:::i;:::-;25454:2;25449:3;25445:12;25438:19;;25097:366;;;:::o;25469:419::-;25635:4;25673:2;25662:9;25658:18;25650:26;;25722:9;25716:4;25712:20;25708:1;25697:9;25693:17;25686:47;25750:131;25876:4;25750:131;:::i;:::-;25742:139;;25469:419;;;:::o;25894:148::-;25996:11;26033:3;26018:18;;25894:148;;;;:::o;26048:231::-;26188:34;26184:1;26176:6;26172:14;26165:58;26261:6;26256:2;26248:6;26244:15;26237:31;26048:231;:::o;26289:418::-;26449:3;26474:85;26556:2;26551:3;26474:85;:::i;:::-;26467:92;;26572:93;26661:3;26572:93;:::i;:::-;26694:2;26689:3;26685:12;26678:19;;26289:418;;;:::o;26717:397::-;26823:3;26855:39;26888:5;26855:39;:::i;:::-;26914:89;26996:6;26991:3;26914:89;:::i;:::-;26907:96;;27016:52;27061:6;27056:3;27049:4;27042:5;27038:16;27016:52;:::i;:::-;27097:6;27092:3;27088:16;27081:23;;26827:287;26717:397;;;;:::o;27124:557::-;27357:3;27383:148;27527:3;27383:148;:::i;:::-;27376:155;;27552:95;27643:3;27634:6;27552:95;:::i;:::-;27545:102;;27668:3;27661:10;;27124:557;;;;:::o;27691:222::-;27835:66;27831:1;27823:6;27819:14;27812:90;27691:222;:::o;27923:416::-;28083:3;28108:84;28190:1;28185:3;28108:84;:::i;:::-;28101:91;;28205:93;28294:3;28205:93;:::i;:::-;28327:1;28322:3;28318:11;28311:18;;27923:416;;;:::o;28349:222::-;28493:66;28489:1;28481:6;28477:14;28470:90;28349:222;:::o;28581:416::-;28741:3;28766:84;28848:1;28843:3;28766:84;:::i;:::-;28759:91;;28863:93;28952:3;28863:93;:::i;:::-;28985:1;28980:3;28976:11;28969:18;;28581:416;;;:::o;29007:222::-;29151:66;29147:1;29139:6;29135:14;29128:90;29007:222;:::o;29239:418::-;29399:3;29424:85;29506:2;29501:3;29424:85;:::i;:::-;29417:92;;29522:93;29611:3;29522:93;:::i;:::-;29644:2;29639:3;29635:12;29628:19;;29239:418;;;:::o;29667:222::-;29811:66;29807:1;29799:6;29795:14;29788:90;29667:222;:::o;29899:418::-;30059:3;30084:85;30166:2;30161:3;30084:85;:::i;:::-;30077:92;;30182:93;30271:3;30182:93;:::i;:::-;30304:2;30299:3;30295:12;30288:19;;29899:418;;;:::o;30327:222::-;30471:66;30467:1;30459:6;30455:14;30448:90;30327:222;:::o;30559:416::-;30719:3;30744:84;30826:1;30821:3;30744:84;:::i;:::-;30737:91;;30841:93;30930:3;30841:93;:::i;:::-;30963:1;30958:3;30954:11;30947:18;;30559:416;;;:::o;30985:222::-;31129:66;31125:1;31117:6;31113:14;31106:90;30985:222;:::o;31217:416::-;31377:3;31402:84;31484:1;31479:3;31402:84;:::i;:::-;31395:91;;31499:93;31588:3;31499:93;:::i;:::-;31621:1;31616:3;31612:11;31605:18;;31217:416;;;:::o;31643:2939::-;32727:3;32753:148;32897:3;32753:148;:::i;:::-;32746:155;;32922:95;33013:3;33004:6;32922:95;:::i;:::-;32915:102;;33038:148;33182:3;33038:148;:::i;:::-;33031:155;;33207:148;33351:3;33207:148;:::i;:::-;33200:155;;33376:95;33467:3;33458:6;33376:95;:::i;:::-;33369:102;;33492:148;33636:3;33492:148;:::i;:::-;33485:155;;33661:148;33805:3;33661:148;:::i;:::-;33654:155;;33830:95;33921:3;33912:6;33830:95;:::i;:::-;33823:102;;33946:148;34090:3;33946:148;:::i;:::-;33939:155;;34115:148;34259:3;34115:148;:::i;:::-;34108:155;;34284:95;34375:3;34366:6;34284:95;:::i;:::-;34277:102;;34400:148;34544:3;34400:148;:::i;:::-;34393:155;;34569:3;34562:10;;31643:2939;;;;;;;:::o;34592:187::-;34736:31;34732:1;34724:6;34720:14;34713:55;34592:187;:::o;34789:418::-;34949:3;34974:85;35056:2;35051:3;34974:85;:::i;:::-;34967:92;;35072:93;35161:3;35072:93;:::i;:::-;35194:2;35189:3;35185:12;35178:19;;34789:418;;;:::o;35217:557::-;35450:3;35476:148;35620:3;35476:148;:::i;:::-;35469:155;;35645:95;35736:3;35727:6;35645:95;:::i;:::-;35638:102;;35761:3;35754:10;;35217:557;;;;:::o;35784:211::-;35824:4;35848:20;35866:1;35848:20;:::i;:::-;35843:25;;35886:20;35904:1;35886:20;:::i;:::-;35881:25;;35929:1;35926;35923:8;35920:34;;;35934:18;;:::i;:::-;35920:34;35983:1;35980;35976:9;35968:17;;35784:211;;;;:::o;36005:329::-;36045:3;36068:20;36086:1;36068:20;:::i;:::-;36063:25;;36106:20;36124:1;36106:20;:::i;:::-;36101:25;;36268:1;36200:66;36196:74;36193:1;36190:81;36187:107;;;36274:18;;:::i;:::-;36187:107;36322:1;36319;36315:9;36308:16;;36005:329;;;;:::o;36344:106::-;36395:6;36433:5;36427:12;36417:22;;36344:106;;;:::o;36460:180::-;36543:11;36581:6;36576:3;36569:19;36625:4;36620:3;36616:14;36601:29;;36460:180;;;;:::o;36650:380::-;36736:3;36768:38;36800:5;36768:38;:::i;:::-;36826:70;36889:6;36884:3;36826:70;:::i;:::-;36819:77;;36909:52;36954:6;36949:3;36942:4;36935:5;36931:16;36909:52;:::i;:::-;36990:29;37012:6;36990:29;:::i;:::-;36985:3;36981:39;36974:46;;36740:290;36650:380;;;;:::o;37040:668::-;37235:4;37277:3;37266:9;37262:19;37254:27;;37295:71;37363:1;37352:9;37348:17;37339:6;37295:71;:::i;:::-;37380:72;37448:2;37437:9;37433:18;37424:6;37380:72;:::i;:::-;37466;37534:2;37523:9;37519:18;37510:6;37466:72;:::i;:::-;37589:9;37583:4;37579:20;37574:2;37563:9;37559:18;37552:48;37621:76;37692:4;37683:6;37621:76;:::i;:::-;37613:84;;37040:668;;;;;;;:::o;37718:153::-;37774:5;37809:6;37803:13;37794:22;;37829:32;37855:5;37829:32;:::i;:::-;37718:153;;;;:::o;37881:373::-;37950:6;38003:2;37991:9;37982:7;37978:23;37974:32;37971:119;;;38009:79;;:::i;:::-;37971:119;38137:1;38166:63;38221:7;38212:6;38201:9;38197:22;38166:63;:::i;:::-;38156:73;;38104:139;37881:373;;;;:::o;38264:190::-;38408:34;38404:1;38396:6;38392:14;38385:58;38264:190;:::o;38464:382::-;38606:3;38631:67;38695:2;38690:3;38631:67;:::i;:::-;38624:74;;38711:93;38800:3;38711:93;:::i;:::-;38833:2;38828:3;38824:12;38817:19;;38464:382;;;:::o;38856:435::-;39022:4;39064:2;39053:9;39049:18;39041:26;;39117:9;39111:4;39107:20;39103:1;39092:9;39088:17;39081:47;39149:131;39275:4;39149:131;:::i;:::-;39141:139;;38856:435;;;:::o;39301:186::-;39445:30;39441:1;39433:6;39429:14;39422:54;39301:186;:::o;39497:382::-;39639:3;39664:67;39728:2;39723:3;39664:67;:::i;:::-;39657:74;;39744:93;39833:3;39744:93;:::i;:::-;39866:2;39861:3;39857:12;39850:19;;39497:382;;;:::o;39889:435::-;40055:4;40097:2;40086:9;40082:18;40074:26;;40150:9;40144:4;40140:20;40136:1;40125:9;40121:17;40114:47;40182:131;40308:4;40182:131;:::i;:::-;40174:139;;39889:435;;;:::o
Swarm Source
ipfs://7074158534e3cfdf447f7eeadce51c7cb7f828ac51bf5efdbc4239ffa61a8216
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.